Update webscoket server failling
This commit is contained in:
parent
d81ef73bcf
commit
545bb96b9d
|
|
@ -170,8 +170,6 @@ public static class Program
|
||||||
statusrecord.InverterRecord.WarningMainCode.WriteLine(" = WarningMainCode"); // 30408 this the duration
|
statusrecord.InverterRecord.WarningMainCode.WriteLine(" = WarningMainCode"); // 30408 this the duration
|
||||||
statusrecord.InverterRecord.WarningSubCode.WriteLine(" = WarningSubCode"); // 30408 this the duration
|
statusrecord.InverterRecord.WarningSubCode.WriteLine(" = WarningSubCode"); // 30408 this the duration
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
EssModeControl(statusrecord);
|
EssModeControl(statusrecord);
|
||||||
|
|
||||||
statusrecord.ApplyDefaultSettings();
|
statusrecord.ApplyDefaultSettings();
|
||||||
|
|
@ -182,7 +180,6 @@ public static class Program
|
||||||
statusrecord.Config.Save(); // save the config file
|
statusrecord.Config.Save(); // save the config file
|
||||||
growattDeviceT415K.Write(statusrecord.InverterRecord);
|
growattDeviceT415K.Write(statusrecord.InverterRecord);
|
||||||
Console.WriteLine(DateTime.Now.ToString("HH:mm:ss.fff"));
|
Console.WriteLine(DateTime.Now.ToString("HH:mm:ss.fff"));
|
||||||
|
|
||||||
}
|
}
|
||||||
return statusrecord;
|
return statusrecord;
|
||||||
}
|
}
|
||||||
|
|
@ -342,8 +339,7 @@ public static class Program
|
||||||
var s3Bucket = Config.Load().S3?.Bucket;
|
var s3Bucket = Config.Load().S3?.Bucket;
|
||||||
var subscribedNow = false;
|
var subscribedNow = false;
|
||||||
|
|
||||||
//When the controller boots, it tries to subscribe to the queue
|
if (_subscribeToQueueForTheFirstTime == false)
|
||||||
if (_subscribeToQueueForTheFirstTime == false)
|
|
||||||
{
|
{
|
||||||
subscribedNow = true;
|
subscribedNow = true;
|
||||||
_subscribeToQueueForTheFirstTime = true;
|
_subscribeToQueueForTheFirstTime = true;
|
||||||
|
|
@ -356,9 +352,30 @@ public static class Program
|
||||||
var stateChanged = currentSalimaxState.Status != _prevSodiohomeAlarmState;
|
var stateChanged = currentSalimaxState.Status != _prevSodiohomeAlarmState;
|
||||||
var contentChanged = HasErrorsOrWarningsChanged(currentSalimaxState);
|
var contentChanged = HasErrorsOrWarningsChanged(currentSalimaxState);
|
||||||
var needsHeartbeat = (DateTime.Now - _lastHeartbeatTime).TotalSeconds >= HeartbeatIntervalSeconds;
|
var needsHeartbeat = (DateTime.Now - _lastHeartbeatTime).TotalSeconds >= HeartbeatIntervalSeconds;
|
||||||
|
Console.WriteLine($"subscribedNow={subscribedNow}");
|
||||||
|
Console.WriteLine($"_subscribedToQueue={_subscribedToQueue}");
|
||||||
|
Console.WriteLine($"stateChanged={stateChanged}");
|
||||||
|
Console.WriteLine($"contentChanged={contentChanged}");
|
||||||
|
Console.WriteLine($"needsHeartbeat={needsHeartbeat}");
|
||||||
|
Console.WriteLine($"s3Bucket null? {s3Bucket == null}");
|
||||||
|
|
||||||
// Send message if: state changed, content changed, OR heartbeat needed
|
if (s3Bucket == null)
|
||||||
if (!subscribedNow && _subscribedToQueue && (stateChanged || contentChanged || needsHeartbeat))
|
{
|
||||||
|
Console.WriteLine("⚠ S3 bucket not configured. Skipping middleware send.");
|
||||||
|
LogMiddlewareFailure(new Exception("S3 Bucket not configured"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure connection FIRST
|
||||||
|
if (!RabbitMqManager.EnsureConnected(currentSalimaxState, s3Bucket, VpnServerIp))
|
||||||
|
{
|
||||||
|
Console.WriteLine($"❌ RabbitMQ EnsureConnected FAILED at {DateTime.Now:HH:mm:ss.fff}");
|
||||||
|
LogMiddlewareFailure(new Exception("EnsureConnected returned false"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//If already subscribed to the queue and the status has been changed, update the queue
|
||||||
|
if (!subscribedNow && (stateChanged || contentChanged || needsHeartbeat))
|
||||||
{
|
{
|
||||||
_prevSodiohomeAlarmState = currentSalimaxState.Status;
|
_prevSodiohomeAlarmState = currentSalimaxState.Status;
|
||||||
|
|
||||||
|
|
@ -375,12 +392,17 @@ public static class Program
|
||||||
_lastHeartbeatTime = DateTime.Now;
|
_lastHeartbeatTime = DateTime.Now;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (s3Bucket != null) // why this is based on s3 bucket?
|
try
|
||||||
{
|
{
|
||||||
RabbitMqManager.InformMiddleware(currentSalimaxState);
|
RabbitMqManager.InformMiddleware(currentSalimaxState);
|
||||||
|
//LogMiddlewareFailure(new Exception($"✅ Middleware message sent at {DateTime.Now:HH:mm:ss.fff}"));
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Console.WriteLine($"❌ Failed to send middleware message: {ex.Message}");
|
||||||
|
LogMiddlewareFailure(ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//If there is an available message from the RabbitMQ Broker, apply the configuration file
|
//If there is an available message from the RabbitMQ Broker, apply the configuration file
|
||||||
Configuration? config = SetConfigurationFile();
|
Configuration? config = SetConfigurationFile();
|
||||||
if (config != null)
|
if (config != null)
|
||||||
|
|
@ -439,6 +461,27 @@ public static class Program
|
||||||
return registers;
|
return registers;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void LogMiddlewareFailure(Exception ex)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var logPath = "/home/inesco/SodiStoreHome/middleware_failures.log";
|
||||||
|
|
||||||
|
var logEntry =
|
||||||
|
$"[{DateTime.Now:yyyy-MM-dd HH:mm:ss.fff}]\n" +
|
||||||
|
$"Exception: {ex.GetType().FullName}\n" +
|
||||||
|
$"Message: {ex.Message}\n" +
|
||||||
|
$"StackTrace:\n{ex.StackTrace}\n" +
|
||||||
|
$"--------------------------------------------------\n";
|
||||||
|
|
||||||
|
File.AppendAllText(logPath, logEntry);
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
// Never allow logging to crash the service
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
[RequiresUnreferencedCode("Calls System.Text.Json.JsonSerializer.Serialize<System.Collections.Generic.Dictionary<string, ushort>>(System.Collections.Generic.Dictionary<string, ushort>, System.Text.Json.JsonSerializerOptions?)")]
|
[RequiresUnreferencedCode("Calls System.Text.Json.JsonSerializer.Serialize<System.Collections.Generic.Dictionary<string, ushort>>(System.Collections.Generic.Dictionary<string, ushort>, System.Text.Json.JsonSerializerOptions?)")]
|
||||||
private static async Task<Boolean> SaveModbusTcpFile(StatusRecord status)
|
private static async Task<Boolean> SaveModbusTcpFile(StatusRecord status)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,8 @@ using JsonSerializer = System.Text.Json.JsonSerializer;
|
||||||
using static InnovEnergy.App.SinexcelCommunication.MiddlewareClasses.MiddlewareAgent;
|
using static InnovEnergy.App.SinexcelCommunication.MiddlewareClasses.MiddlewareAgent;
|
||||||
using System.Diagnostics.CodeAnalysis;
|
using System.Diagnostics.CodeAnalysis;
|
||||||
using InnovEnergy.Lib.Devices.Sinexcel_12K_TL.DataType;
|
using InnovEnergy.Lib.Devices.Sinexcel_12K_TL.DataType;
|
||||||
|
using InnovEnergy.Lib.Protocols.Modbus.Protocol;
|
||||||
|
using static InnovEnergy.Lib.Devices.Sinexcel_12K_TL.DataType.WorkingMode;
|
||||||
|
|
||||||
#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring as nullable.
|
#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring as nullable.
|
||||||
|
|
||||||
|
|
@ -36,17 +38,28 @@ internal static class Program
|
||||||
private static readonly TimeSpan UpdateInterval = TimeSpan.FromSeconds(5);
|
private static readonly TimeSpan UpdateInterval = TimeSpan.FromSeconds(5);
|
||||||
private const UInt16 NbrOfFileToConcatenate = 15; // add this to config file
|
private const UInt16 NbrOfFileToConcatenate = 15; // add this to config file
|
||||||
private static UInt16 _fileCounter = 0;
|
private static UInt16 _fileCounter = 0;
|
||||||
private static Channel _sinexcelChannel;
|
private static Channel _sinexcelChannel1;
|
||||||
|
private static Channel _sinexcelChannel2;
|
||||||
|
|
||||||
private const String SwVersionNumber =" V1.00.131025 beta";
|
private static readonly String SwVersionNumber = " V1.00." + DateTime.Today;
|
||||||
private const String VpnServerIp = "10.2.0.11";
|
private const String VpnServerIp = "10.2.0.11";
|
||||||
private static Boolean _subscribedToQueue = false;
|
private static Boolean _subscribedToQueue = false;
|
||||||
private static Boolean _subscribeToQueueForTheFirstTime = false;
|
private static Boolean _subscribeToQueueForTheFirstTime = false;
|
||||||
private static SodistoreAlarmState _prevSodiohomeAlarmState = SodistoreAlarmState.Green;
|
private static SodistoreAlarmState _prevSodiohomeAlarmState = SodistoreAlarmState.Green;
|
||||||
private static SodistoreAlarmState _sodiohomeAlarmState = SodistoreAlarmState.Green;
|
private static SodistoreAlarmState _sodiohomeAlarmState = SodistoreAlarmState.Green;
|
||||||
|
|
||||||
|
// Tracking for error/warning content changes
|
||||||
|
private static List<String> _prevErrorCodes = new List<String>();
|
||||||
|
private static List<String> _prevWarningCodes = new List<String>();
|
||||||
|
|
||||||
|
// Heartbeat tracking
|
||||||
|
private static DateTime _lastHeartbeatTime = DateTime.MinValue;
|
||||||
|
private const Int32 HeartbeatIntervalSeconds = 60;
|
||||||
|
|
||||||
|
|
||||||
// move all this to config file
|
// move all this to config file
|
||||||
private const String Port = "/dev/ttyUSB0";
|
private const String Port1 = "/dev/ttyUSB0";
|
||||||
|
private const String Port2 = "/dev/ttyUSB1";
|
||||||
private const Byte SlaveId = 1;
|
private const Byte SlaveId = 1;
|
||||||
private const Parity Parity = 0; //none
|
private const Parity Parity = 0; //none
|
||||||
private const Int32 StopBits = 1;
|
private const Int32 StopBits = 1;
|
||||||
|
|
@ -55,7 +68,9 @@ internal static class Program
|
||||||
|
|
||||||
public static async Task Main(String[] args)
|
public static async Task Main(String[] args)
|
||||||
{
|
{
|
||||||
_sinexcelChannel = new SerialPortChannel(Port, BaudRate, Parity, DataBits, StopBits);
|
_sinexcelChannel1 = new SerialPortChannel(Port1, BaudRate, Parity, DataBits, StopBits);
|
||||||
|
_sinexcelChannel2 = new SerialPortChannel(Port2, BaudRate, Parity, DataBits, StopBits);
|
||||||
|
|
||||||
InitializeCommunicationToMiddleware();
|
InitializeCommunicationToMiddleware();
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
|
|
@ -75,19 +90,22 @@ internal static class Program
|
||||||
{
|
{
|
||||||
Watchdog.NotifyReady();
|
Watchdog.NotifyReady();
|
||||||
|
|
||||||
Console.WriteLine("Starting Sinexcel Communication");
|
Console.WriteLine("Starting Sinexcel Communication, SW Version : " + SwVersionNumber);
|
||||||
|
|
||||||
var sinexcelDevice = new SinexcelDevice(_sinexcelChannel, SlaveId);
|
var sinexcelDevice1 = new SinexcelDevice(_sinexcelChannel1, SlaveId);
|
||||||
// var sinexcelDevice = new sinexcelDevices(new List<sinexcelDevice> { growattDeviceT415K });
|
var sinexcelDevice2 = new SinexcelDevice(_sinexcelChannel2, SlaveId);
|
||||||
|
|
||||||
StatusRecord? ReadStatus()
|
StatusRecord? ReadStatus()
|
||||||
{
|
{
|
||||||
var config = Config.Load();
|
var config = Config.Load();
|
||||||
var sinexcelRecord = sinexcelDevice.Read();
|
var sinexcelRecord1 = sinexcelDevice1.Read();
|
||||||
|
var sinexcelRecord2 = sinexcelDevice2.Read();
|
||||||
|
|
||||||
|
|
||||||
return new StatusRecord
|
return new StatusRecord
|
||||||
{
|
{
|
||||||
InverterRecord = sinexcelRecord,
|
InverterRecord1 = sinexcelRecord1,
|
||||||
|
InverterRecord2 = sinexcelRecord2,
|
||||||
Config = config // load from disk every iteration, so config can be changed while running
|
Config = config // load from disk every iteration, so config can be changed while running
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
@ -120,63 +138,176 @@ internal static class Program
|
||||||
if (statusrecord == null)
|
if (statusrecord == null)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
// Console.WriteLine( statusrecord.InverterRecord.TimedChargeAndDischargeOff + " TimedChargeAndDischargeOff ");
|
Console.WriteLine(" ************************************************ Inverter 1 ************************************************ ");
|
||||||
Console.WriteLine( statusrecord.InverterRecord.Battery1Power + " Battery1Power ");
|
Console.WriteLine( statusrecord.InverterRecord1.SystemDateTime + " SystemDateTime ");
|
||||||
Console.WriteLine( statusrecord.InverterRecord.Battery1Soc + " Battery1Soc ");
|
|
||||||
Console.WriteLine( statusrecord.InverterRecord.RepetitiveWeeks + " RepetitiveWeeks ");
|
|
||||||
Console.WriteLine( statusrecord.InverterRecord.EffectiveStartDate + " EffectiveStartDate ");
|
|
||||||
Console.WriteLine( statusrecord.InverterRecord.EffectiveEndDate + " EffectiveEndDate ");
|
|
||||||
Console.WriteLine( statusrecord.InverterRecord.ChargingPowerPeriod1 + " ChargingPowerPeriod1 ");
|
|
||||||
Console.WriteLine( statusrecord.InverterRecord.ChargeStartTimePeriod1 + " ChargeStartTimePeriod1 ");
|
|
||||||
Console.WriteLine( statusrecord.InverterRecord.ChargeEndTimePeriod1 + " ChargeEndTimePeriod1 ");
|
|
||||||
|
|
||||||
Console.WriteLine( statusrecord.InverterRecord.DischargeStartTimePeriod1 + " DischargeStartTimePeriod1 ");
|
Console.WriteLine( statusrecord.InverterRecord1.TotalPhotovoltaicPower + " TotalPhotovoltaicPower ");
|
||||||
Console.WriteLine( statusrecord.InverterRecord.DischargeEndTimePeriod1 + " DischargeEndTimePeriod1 ");
|
Console.WriteLine( statusrecord.InverterRecord1.TotalBatteryPower + " TotalBatteryPower ");
|
||||||
|
Console.WriteLine( statusrecord.InverterRecord1.TotalLoadPower + " TotalLoadPower ");
|
||||||
|
Console.WriteLine( statusrecord.InverterRecord1.TotalGridPower + " TotalGridPower ");
|
||||||
|
|
||||||
Console.WriteLine( statusrecord.InverterRecord.PowerOn + " PowerOn ");
|
|
||||||
Console.WriteLine( statusrecord.InverterRecord.PowerOff + " PowerOff ");
|
Console.WriteLine( statusrecord.InverterRecord1.Battery1Power + " Battery1Power ");
|
||||||
Console.WriteLine( statusrecord.InverterRecord.WorkingMode + " WorkingMode ");
|
Console.WriteLine( statusrecord.InverterRecord1.Battery1Soc + " Battery1Soc ");
|
||||||
// Console.WriteLine( statusrecord.InverterRecord.FaultClearing + " FaultClearing ");
|
Console.WriteLine( statusrecord.InverterRecord1.Battery1BackupSoc + " Battery1BackupSoc ");
|
||||||
SendSalimaxStateAlarm(GetSodiHomeStateAlarm(statusrecord),statusrecord);
|
Console.WriteLine( statusrecord.InverterRecord1.Battery1MinSoc + " Battery1MinSoc ");
|
||||||
|
|
||||||
|
Console.WriteLine( statusrecord.InverterRecord1.Battery2Power + " Battery2Power ");
|
||||||
|
Console.WriteLine( statusrecord.InverterRecord1.Battery2Soc + " Battery2Soc ");
|
||||||
|
Console.WriteLine( statusrecord.InverterRecord1.Battery2BackupSoc + " Battery2BackupSoc ");
|
||||||
|
Console.WriteLine( statusrecord.InverterRecord1.Battery2MinSoc + " Battery2MinSoc ");
|
||||||
|
|
||||||
|
Console.WriteLine( statusrecord.InverterRecord1.EnableGridExport + " EnableGridExport ");
|
||||||
|
Console.WriteLine( statusrecord.InverterRecord1.PowerGridExportLimit + " PowerGridExportLimit ");
|
||||||
|
|
||||||
|
Console.WriteLine( statusrecord.InverterRecord1.PowerOn + " PowerOn ");
|
||||||
|
Console.WriteLine( statusrecord.InverterRecord1.PowerOff + " PowerOff ");
|
||||||
|
|
||||||
|
|
||||||
|
Console.WriteLine( statusrecord.InverterRecord1.WorkingMode + " WorkingMode ");
|
||||||
|
|
||||||
|
Console.WriteLine( statusrecord.InverterRecord1.GridSwitchMethod + " GridSwitchMethod ");
|
||||||
|
|
||||||
|
Console.WriteLine( statusrecord.InverterRecord1.ThreePhaseWireSystem + " ThreePhaseWireSystem ");
|
||||||
|
|
||||||
|
Console.WriteLine(" ************************************************ Inverter 2 ************************************************ ");
|
||||||
|
|
||||||
|
Console.WriteLine( statusrecord.InverterRecord2.SystemDateTime + " SystemDateTime ");
|
||||||
|
Console.WriteLine( statusrecord.InverterRecord2.TotalPhotovoltaicPower + " TotalPhotovoltaicPower ");
|
||||||
|
Console.WriteLine( statusrecord.InverterRecord2.TotalBatteryPower + " TotalBatteryPower ");
|
||||||
|
Console.WriteLine( statusrecord.InverterRecord2.TotalLoadPower + " TotalLoadPower ");
|
||||||
|
Console.WriteLine( statusrecord.InverterRecord2.TotalGridPower + " TotalGridPower ");
|
||||||
|
Console.WriteLine( statusrecord.InverterRecord2.Battery1Power + " Battery1Power ");
|
||||||
|
Console.WriteLine( statusrecord.InverterRecord2.Battery1Soc + " Battery1Soc ");
|
||||||
|
Console.WriteLine( statusrecord.InverterRecord2.Battery1BackupSoc + " Battery1BackupSoc ");
|
||||||
|
Console.WriteLine( statusrecord.InverterRecord2.Battery1MinSoc + " Battery1MinSoc ");
|
||||||
|
Console.WriteLine( statusrecord.InverterRecord2.Battery2Power + " Battery2Power ");
|
||||||
|
Console.WriteLine( statusrecord.InverterRecord2.Battery2Soc + " Battery2Soc ");
|
||||||
|
Console.WriteLine( statusrecord.InverterRecord2.Battery2BackupSoc + " Battery2BackupSoc ");
|
||||||
|
Console.WriteLine( statusrecord.InverterRecord2.Battery2MinSoc + " Battery2MinSoc ");
|
||||||
|
|
||||||
|
Console.WriteLine( statusrecord.InverterRecord2.EnableGridExport + " EnableGridExport ");
|
||||||
|
Console.WriteLine( statusrecord.InverterRecord2.PowerGridExportLimit + " PowerGridExportLimit ");
|
||||||
|
Console.WriteLine( statusrecord.InverterRecord2.PowerOn + " PowerOn ");
|
||||||
|
Console.WriteLine( statusrecord.InverterRecord2.PowerOff + " PowerOff ");
|
||||||
|
Console.WriteLine( statusrecord.InverterRecord2.WorkingMode + " WorkingMode ");
|
||||||
|
Console.WriteLine( statusrecord.InverterRecord2.GridSwitchMethod + " GridSwitchMethod ");
|
||||||
|
Console.WriteLine( statusrecord.InverterRecord2.ThreePhaseWireSystem + " ThreePhaseWireSystem ");
|
||||||
|
/*
|
||||||
|
Console.WriteLine( statusrecord.InverterRecord1.RepetitiveWeeks + " RepetitiveWeeks ");
|
||||||
|
Console.WriteLine( statusrecord.InverterRecord1.EffectiveStartDate + " EffectiveStartDate ");
|
||||||
|
Console.WriteLine( statusrecord.InverterRecord1.EffectiveEndDate + " EffectiveEndDate ");
|
||||||
|
Console.WriteLine( statusrecord.InverterRecord1.ChargingPowerPeriod1 + " ChargingPowerPeriod1 ");
|
||||||
|
Console.WriteLine( statusrecord.InverterRecord1.DishargingPowerPeriod1 + " dischargingPowerPeriod1 ");
|
||||||
|
Console.WriteLine( statusrecord.InverterRecord1.ChargeStartTimePeriod1 + " ChargeStartTimePeriod1 ");
|
||||||
|
Console.WriteLine( statusrecord.InverterRecord1.ChargeEndTimePeriod1 + " ChargeEndTimePeriod1 ");
|
||||||
|
|
||||||
|
Console.WriteLine( statusrecord.InverterRecord1.DischargeStartTimePeriod1 + " DischargeStartTimePeriod1 ");
|
||||||
|
Console.WriteLine( statusrecord.InverterRecord1.DischargeEndTimePeriod1 + " DischargeEndTimePeriod1 ");*/
|
||||||
|
|
||||||
|
SendSalimaxStateAlarm(GetSodiHomeStateAlarm(statusrecord),statusrecord);
|
||||||
|
statusrecord.ControlConstants();
|
||||||
|
|
||||||
Console.WriteLine( " ************************************ We are writing ************************************");
|
Console.WriteLine( " ************************************ We are writing ************************************");
|
||||||
var startWritingTime = DateTime.Now;
|
var startWritingTime = DateTime.Now;
|
||||||
Console.WriteLine(startWritingTime.ToString("HH:mm:ss.fff ") +"start Writing");
|
Console.WriteLine(startWritingTime.ToString("HH:mm:ss.fff ") +"start Writing");
|
||||||
statusrecord?.Config.Save(); // save the config file
|
statusrecord?.Config.Save(); // save the config file
|
||||||
|
|
||||||
if (statusrecord != null)
|
if (statusrecord is { Config.ControlPermission: true })
|
||||||
{
|
{
|
||||||
statusrecord.InverterRecord.WorkingMode = WorkingMode.TimeChargeDischarge;
|
Console.WriteLine(" We have the Right to Write");
|
||||||
|
sinexcelDevice1.Write(statusrecord.InverterRecord1);
|
||||||
|
sinexcelDevice2.Write(statusrecord.InverterRecord2);
|
||||||
|
|
||||||
//statusrecord.InverterRecord.TimedChargeAndDischargeOff = 0;
|
|
||||||
statusrecord.InverterRecord.RepetitiveWeeks = SinexcelWeekDays.All;
|
|
||||||
statusrecord.InverterRecord.EffectiveStartDate = DateTime.Today.AddDays(-1);
|
|
||||||
statusrecord.InverterRecord.EffectiveEndDate = DateTime.Today.AddDays(2);
|
|
||||||
statusrecord.InverterRecord.ChargingPowerPeriod1 = 3;
|
|
||||||
statusrecord.InverterRecord.DishargingPowerPeriod1 = 3;
|
|
||||||
statusrecord.InverterRecord.DischargeStartTimePeriod1 = new TimeSpan(16, 00, 0);
|
|
||||||
statusrecord.InverterRecord.DischargeEndTimePeriod1 = new TimeSpan(17, 03, 0);
|
|
||||||
statusrecord.InverterRecord.PowerOn = 1;
|
|
||||||
statusrecord.InverterRecord.PowerOff = 0;
|
|
||||||
//statusrecord.InverterRecord.FaultClearing = 1;
|
|
||||||
}
|
}
|
||||||
if (statusrecord?.InverterRecord != null) sinexcelDevice.Write(statusrecord.InverterRecord);
|
else
|
||||||
|
{
|
||||||
|
Console.WriteLine(" Nooooooo We cant' have the Right to Write");
|
||||||
|
}
|
||||||
|
|
||||||
var stopTime = DateTime.Now;
|
|
||||||
Console.WriteLine(stopTime.ToString("HH:mm:ss.fff ")+ "run iteration time finish");
|
|
||||||
return statusrecord;
|
return statusrecord;
|
||||||
}
|
}
|
||||||
|
catch (CrcException e)
|
||||||
|
{
|
||||||
|
Console.WriteLine(e);
|
||||||
|
throw; // restart only on CRC
|
||||||
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
// Handle exception and print the error
|
Console.WriteLine(e);
|
||||||
Console.WriteLine(e );
|
return null; // keep running for non-critical errors
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static StatusMessage GetSodiHomeStateAlarm(StatusRecord? record)
|
private static void ControlConstants(this StatusRecord? statusrecord)
|
||||||
|
{
|
||||||
|
if (statusrecord == null) return;
|
||||||
|
|
||||||
|
statusrecord.InverterRecord1.Battery1BackupSoc = (Single)statusrecord.Config.MinSoc ;
|
||||||
|
statusrecord.InverterRecord1.Battery2BackupSoc = (Single)statusrecord.Config.MinSoc ;
|
||||||
|
statusrecord.InverterRecord1.RepetitiveWeeks = SinexcelWeekDays.All;
|
||||||
|
|
||||||
|
|
||||||
|
var isChargePeriod = IsNowInsideDateAndTime(statusrecord.Config.StartTimeChargeandDischargeDayandTime, statusrecord.Config.StopTimeChargeandDischargeDayandTime);
|
||||||
|
|
||||||
|
|
||||||
|
Console.WriteLine("Are we inside the charge/Discharge time " + isChargePeriod);
|
||||||
|
|
||||||
|
if (statusrecord.Config.OperatingPriority != TimeChargeDischarge)
|
||||||
|
{
|
||||||
|
statusrecord.InverterRecord1.WorkingMode = statusrecord.Config.OperatingPriority;
|
||||||
|
}
|
||||||
|
else if (statusrecord.Config.OperatingPriority == TimeChargeDischarge && isChargePeriod)
|
||||||
|
{
|
||||||
|
statusrecord.InverterRecord1.WorkingMode = statusrecord.Config.OperatingPriority;
|
||||||
|
|
||||||
|
if (statusrecord.Config.TimeChargeandDischargePower > 0)
|
||||||
|
{
|
||||||
|
statusrecord.InverterRecord1.EffectiveStartDate = statusrecord.Config.StartTimeChargeandDischargeDayandTime.Date;
|
||||||
|
statusrecord.InverterRecord1.EffectiveEndDate = statusrecord.Config.StopTimeChargeandDischargeDayandTime.Date;
|
||||||
|
statusrecord.InverterRecord1.ChargingPowerPeriod1 = Math.Abs(statusrecord.Config.TimeChargeandDischargePower);
|
||||||
|
statusrecord.InverterRecord1.ChargeStartTimePeriod1 = statusrecord.Config.StartTimeChargeandDischargeDayandTime.TimeOfDay;
|
||||||
|
statusrecord.InverterRecord1.ChargeEndTimePeriod1 = statusrecord.Config.StopTimeChargeandDischargeDayandTime.TimeOfDay;
|
||||||
|
|
||||||
|
statusrecord.InverterRecord1.DischargeStartTimePeriod1 = TimeSpan.Zero;
|
||||||
|
statusrecord.InverterRecord1.DischargeEndTimePeriod1 = TimeSpan.Zero;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
statusrecord.InverterRecord1.EffectiveStartDate = statusrecord.Config.StartTimeChargeandDischargeDayandTime.Date;
|
||||||
|
statusrecord.InverterRecord1.EffectiveEndDate = statusrecord.Config.StopTimeChargeandDischargeDayandTime.Date;
|
||||||
|
statusrecord.InverterRecord1.DishargingPowerPeriod1 = Math.Abs(statusrecord.Config.TimeChargeandDischargePower);
|
||||||
|
statusrecord.InverterRecord1.DischargeStartTimePeriod1 = statusrecord.Config.StartTimeChargeandDischargeDayandTime.TimeOfDay;
|
||||||
|
statusrecord.InverterRecord1.DischargeEndTimePeriod1 = statusrecord.Config.StopTimeChargeandDischargeDayandTime.TimeOfDay;
|
||||||
|
|
||||||
|
statusrecord.InverterRecord1.ChargeStartTimePeriod1 = TimeSpan.Zero;
|
||||||
|
statusrecord.InverterRecord1.ChargeEndTimePeriod1 = TimeSpan.Zero;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
statusrecord.InverterRecord1.WorkingMode = SpontaneousSelfUse;
|
||||||
|
}
|
||||||
|
statusrecord.InverterRecord1.PowerOn = 1;
|
||||||
|
statusrecord.InverterRecord1.PowerOff = 0;
|
||||||
|
//statusrecord.InverterRecord.FaultClearing = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool IsNowInsideDateAndTime(DateTime effectiveStart, DateTime effectiveEnd)
|
||||||
|
{
|
||||||
|
DateTime now = DateTime.Now;
|
||||||
|
|
||||||
|
// Date check
|
||||||
|
if (now < effectiveStart || now > effectiveEnd)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static StatusMessage GetSodiHomeStateAlarm(StatusRecord? record)
|
||||||
{
|
{
|
||||||
var s3Bucket = Config.Load().S3?.Bucket;
|
var s3Bucket = Config.Load().S3?.Bucket;
|
||||||
|
|
||||||
|
|
@ -231,6 +362,43 @@ internal static class Program
|
||||||
return returnedStatus;
|
return returnedStatus;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Checks if the error or warning content has changed compared to the previous state.
|
||||||
|
/// This allows detection of new/cleared errors even when the overall alarm state (Red/Orange/Green) remains the same.
|
||||||
|
/// </summary>
|
||||||
|
private static Boolean HasErrorsOrWarningsChanged(StatusMessage currentState)
|
||||||
|
{
|
||||||
|
// Get current error codes (descriptions)
|
||||||
|
var currentErrors = currentState.Alarms?
|
||||||
|
.Select(a => a.Description ?? String.Empty)
|
||||||
|
.OrderBy(d => d) // Sort for consistent comparison
|
||||||
|
.ToList() ?? new List<String>();
|
||||||
|
|
||||||
|
// Get current warning codes (descriptions)
|
||||||
|
var currentWarnings = currentState.Warnings?
|
||||||
|
.Select(w => w.Description ?? String.Empty)
|
||||||
|
.OrderBy(d => d) // Sort for consistent comparison
|
||||||
|
.ToList() ?? new List<String>();
|
||||||
|
|
||||||
|
// Check if lists have changed (new items added or existing items removed)
|
||||||
|
var errorsChanged = !currentErrors.SequenceEqual(_prevErrorCodes);
|
||||||
|
var warningsChanged = !currentWarnings.SequenceEqual(_prevWarningCodes);
|
||||||
|
|
||||||
|
// Update tracking if changes detected
|
||||||
|
if (errorsChanged || warningsChanged)
|
||||||
|
{
|
||||||
|
Console.WriteLine($"Error/Warning content changed:");
|
||||||
|
Console.WriteLine($" Errors: {String.Join(", ", currentErrors)} (was: {String.Join(", ", _prevErrorCodes)})");
|
||||||
|
Console.WriteLine($" Warnings: {String.Join(", ", currentWarnings)} (was: {String.Join(", ", _prevWarningCodes)})");
|
||||||
|
|
||||||
|
_prevErrorCodes = currentErrors;
|
||||||
|
_prevWarningCodes = currentWarnings;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
private static Int32 GetInstallationId(String s3Bucket)
|
private static Int32 GetInstallationId(String s3Bucket)
|
||||||
{
|
{
|
||||||
var part = s3Bucket.Split('-').FirstOrDefault();
|
var part = s3Bucket.Split('-').FirstOrDefault();
|
||||||
|
|
@ -249,14 +417,63 @@ internal static class Program
|
||||||
_subscribeToQueueForTheFirstTime = true;
|
_subscribeToQueueForTheFirstTime = true;
|
||||||
_prevSodiohomeAlarmState = currentSalimaxState.Status;
|
_prevSodiohomeAlarmState = currentSalimaxState.Status;
|
||||||
_subscribedToQueue = RabbitMqManager.SubscribeToQueue(currentSalimaxState, s3Bucket, VpnServerIp);
|
_subscribedToQueue = RabbitMqManager.SubscribeToQueue(currentSalimaxState, s3Bucket, VpnServerIp);
|
||||||
|
_lastHeartbeatTime = DateTime.Now; // Initialize heartbeat timer
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if we should send a message
|
||||||
|
var stateChanged = currentSalimaxState.Status != _prevSodiohomeAlarmState;
|
||||||
|
var contentChanged = HasErrorsOrWarningsChanged(currentSalimaxState);
|
||||||
|
var needsHeartbeat = (DateTime.Now - _lastHeartbeatTime).TotalSeconds >= HeartbeatIntervalSeconds;
|
||||||
|
Console.WriteLine($"subscribedNow={subscribedNow}");
|
||||||
|
Console.WriteLine($"_subscribedToQueue={_subscribedToQueue}");
|
||||||
|
Console.WriteLine($"stateChanged={stateChanged}");
|
||||||
|
Console.WriteLine($"contentChanged={contentChanged}");
|
||||||
|
Console.WriteLine($"needsHeartbeat={needsHeartbeat}");
|
||||||
|
Console.WriteLine($"s3Bucket null? {s3Bucket == null}");
|
||||||
|
|
||||||
|
if (s3Bucket == null)
|
||||||
|
{
|
||||||
|
Console.WriteLine("⚠ S3 bucket not configured. Skipping middleware send.");
|
||||||
|
LogMiddlewareFailure(new Exception("S3 Bucket not configured"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure connection FIRST
|
||||||
|
if (!RabbitMqManager.EnsureConnected(currentSalimaxState, s3Bucket, VpnServerIp))
|
||||||
|
{
|
||||||
|
Console.WriteLine($"❌ RabbitMQ EnsureConnected FAILED at {DateTime.Now:HH:mm:ss.fff}");
|
||||||
|
LogMiddlewareFailure(new Exception("EnsureConnected returned false"));
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
//If already subscribed to the queue and the status has been changed, update the queue
|
//If already subscribed to the queue and the status has been changed, update the queue
|
||||||
if (!subscribedNow && _subscribedToQueue && currentSalimaxState.Status != _prevSodiohomeAlarmState)
|
if (!subscribedNow && (stateChanged || contentChanged || needsHeartbeat))
|
||||||
{
|
{
|
||||||
_prevSodiohomeAlarmState = currentSalimaxState.Status;
|
_prevSodiohomeAlarmState = currentSalimaxState.Status;
|
||||||
if (s3Bucket != null)
|
|
||||||
|
// Set appropriate message type
|
||||||
|
if (stateChanged || contentChanged)
|
||||||
|
{
|
||||||
|
currentSalimaxState.Type = MessageType.AlarmOrWarning;
|
||||||
|
Console.WriteLine($"Sending AlarmOrWarning message - StateChanged: {stateChanged}, ContentChanged: {contentChanged}");
|
||||||
|
}
|
||||||
|
else if (needsHeartbeat)
|
||||||
|
{
|
||||||
|
currentSalimaxState.Type = MessageType.Heartbit;
|
||||||
|
Console.WriteLine($"Sending Heartbeat message - {HeartbeatIntervalSeconds}s interval reached");
|
||||||
|
_lastHeartbeatTime = DateTime.Now;
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
RabbitMqManager.InformMiddleware(currentSalimaxState);
|
RabbitMqManager.InformMiddleware(currentSalimaxState);
|
||||||
|
LogMiddlewareFailure(new Exception($"✅ Middleware message sent at {DateTime.Now:HH:mm:ss.fff}"));
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Console.WriteLine($"❌ Failed to send middleware message: {ex.Message}");
|
||||||
|
LogMiddlewareFailure(ex);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//If there is an available message from the RabbitMQ Broker, apply the configuration file
|
//If there is an available message from the RabbitMQ Broker, apply the configuration file
|
||||||
|
|
@ -267,31 +484,89 @@ internal static class Program
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void LogMiddlewareFailure(Exception ex)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var logPath = "/home/inesco/SodiStoreHome/middleware_failures.log";
|
||||||
|
|
||||||
|
var logEntry =
|
||||||
|
$"[{DateTime.Now:yyyy-MM-dd HH:mm:ss.fff}]\n" +
|
||||||
|
$"Exception: {ex.GetType().FullName}\n" +
|
||||||
|
$"Message: {ex.Message}\n" +
|
||||||
|
$"StackTrace:\n{ex.StackTrace}\n" +
|
||||||
|
$"--------------------------------------------------\n";
|
||||||
|
|
||||||
|
File.AppendAllText(logPath, logEntry);
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
// Never allow logging to crash the service
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private static void ApplyConfigFile(this StatusRecord? status, Configuration? config)
|
private static void ApplyConfigFile(this StatusRecord? status, Configuration? config)
|
||||||
{
|
{
|
||||||
if (config == null) return;
|
if (config == null) return;
|
||||||
if (status == null) return;
|
if (status == null) return;
|
||||||
|
|
||||||
status.Config.MinSoc = config.MinimumSoC;
|
status.Config.MinSoc = config.MinimumSoC;
|
||||||
status.Config.MaximumChargingCurrent = config.MaximumChargingCurrent;
|
status.Config.MaximumChargingCurrent = config.MaximumChargingCurrent;
|
||||||
status.Config.MaximumDischargingCurrent = config.MaximumDischargingCurrent;
|
status.Config.MaximumDischargingCurrent = config.MaximumDischargingCurrent;
|
||||||
status.Config.OperatingPriority = config.OperatingPriority;
|
status.Config.OperatingPriority = config.OperatingPriority;
|
||||||
status.Config.BatteriesCount = config.BatteriesCount;
|
status.Config.BatteriesCount = config.BatteriesCount;
|
||||||
|
status.Config.ClusterNumber = config.ClusterNumber;
|
||||||
|
status.Config.StartTimeChargeandDischargeDayandTime = config.StartTimeChargeandDischargeDayandTime;
|
||||||
|
status.Config.StopTimeChargeandDischargeDayandTime = config.StopTimeChargeandDischargeDayandTime;
|
||||||
|
status.Config.TimeChargeandDischargePower = config.TimeChargeandDischargePower;
|
||||||
|
|
||||||
|
status.Config.PvNumber = config.PvNumber;
|
||||||
|
status.Config.ControlPermission = config.ControlPermission;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static async Task<Boolean> SaveModbusTcpFile(StatusRecord status)
|
private static async Task<Boolean> SaveModbusTcpFile(StatusRecord status)
|
||||||
{
|
{
|
||||||
var modbusData = new Dictionary<String, UInt16>();
|
var modbusData = new Dictionary<String, UInt16>();
|
||||||
|
|
||||||
// SYSTEM DATA
|
// SYSTEM DATA
|
||||||
var result1 = ConvertToModbusRegisters((status.Config.ModbusProtcolNumber * 10), "UInt16", 30001); // this to be updated to modbusTCP version
|
var result1 = ConvertToModbusRegisters((status.Config.ModbusProtcolNumber * 10), "UInt16", 30001); // this to be updated to modbusTCP version
|
||||||
var result2 = ConvertToModbusRegisters(status.InverterRecord.SystemDateTime.ToUnixTime(), "UInt32", 30002);
|
var result2 = ConvertToModbusRegisters(status.InverterRecord1.SystemDateTime.ToUnixTime(), "UInt32", 30002);
|
||||||
|
// SYSTEM DATA
|
||||||
|
var result3 = ConvertToModbusRegisters(status.InverterRecord1.WorkingMode, "UInt16", 30004);
|
||||||
|
|
||||||
|
// BATTERY SUMMARY (assuming single battery [0]) // this to be improved
|
||||||
|
|
||||||
|
var result4 = ConvertToModbusRegisters((status.Config.BatteriesCount), "UInt16", 31000);
|
||||||
|
var result8 = ConvertToModbusRegisters((status.InverterRecord1.Battery1Voltage.Value * 10), "UInt16", 31001);
|
||||||
|
var result12 = ConvertToModbusRegisters((status.InverterRecord1.Battery2Voltage.Value * 10), "Int16", 31002);
|
||||||
|
var result13 = ConvertToModbusRegisters((status.InverterRecord1.Battery1Current.Value * 10), "Int32", 31003);
|
||||||
|
var result16 = ConvertToModbusRegisters((status.InverterRecord1.Battery2Current.Value * 10), "Int32", 31005);
|
||||||
|
var result9 = ConvertToModbusRegisters((status.InverterRecord1.Battery1Soc.Value * 100), "UInt16", 31007);
|
||||||
|
var result14 = ConvertToModbusRegisters((status.InverterRecord1.Battery2Soc.Value * 100), "UInt16", 31008);
|
||||||
|
var result5 = ConvertToModbusRegisters((status.InverterRecord1.TotalBatteryPower.Value * 10), "Int32", 31009);
|
||||||
|
|
||||||
|
var result7 = ConvertToModbusRegisters((status.InverterRecord1.Battery1BackupSoc * 100), "UInt16", 31011);
|
||||||
|
var result20 = ConvertToModbusRegisters((status.InverterRecord1.Battery2BackupSoc * 100), "UInt16", 31012);
|
||||||
|
var result15 = ConvertToModbusRegisters((status.InverterRecord1.Battery1Soh.Value * 100), "UInt16", 31013);
|
||||||
|
var result26 = ConvertToModbusRegisters((status.InverterRecord1.Battery2Soh.Value * 100), "UInt16", 31014);
|
||||||
|
var result21 = ConvertToModbusRegisters((status.InverterRecord1.Battery1MaxChargingCurrent * 10), "UInt16", 31016);
|
||||||
|
var result22 = ConvertToModbusRegisters((status.InverterRecord1.Battery1MaxDischargingCurrent * 10), "UInt16", 31017);
|
||||||
|
|
||||||
|
var result18 = ConvertToModbusRegisters((status.InverterRecord1.PvTotalPower * 10), "UInt32", 32000);
|
||||||
|
var result19 = ConvertToModbusRegisters((status.InverterRecord1.GridPower * 10), "Int32", 33000);
|
||||||
|
var result23 = ConvertToModbusRegisters((status.InverterRecord1.GridVoltageFrequency * 10), "UInt16", 33002);
|
||||||
|
|
||||||
|
var result24 = ConvertToModbusRegisters((status.InverterRecord1.WorkingMode), "UInt16", 34000);
|
||||||
|
var result25 = ConvertToModbusRegisters((status.InverterRecord1.InverterActivePower * 10), "Int32", 34001);
|
||||||
|
var result29 = ConvertToModbusRegisters((status.InverterRecord1.EnableGridExport ), "UInt16", 34003);
|
||||||
|
var result27 = ConvertToModbusRegisters((status.InverterRecord1.PowerGridExportLimit ), "Int16", 34004);
|
||||||
|
|
||||||
// Merge all results into one dictionary
|
// Merge all results into one dictionary
|
||||||
|
|
||||||
var allResults = new[]
|
var allResults = new[]
|
||||||
{
|
{
|
||||||
result1,result2
|
result1, result2, result3, result4, result5, result23, result24, result25, result29, result27, result26, result7, result8, result9, result16, result20, result12, result13, result14, result15, result18, result19, result21, result22
|
||||||
};
|
};
|
||||||
|
|
||||||
foreach (var result in allResults)
|
foreach (var result in allResults)
|
||||||
|
|
@ -518,7 +793,7 @@ internal static class Program
|
||||||
Console.WriteLine(error);
|
Console.WriteLine(error);
|
||||||
|
|
||||||
await SaveToLocalCompressedFallback(compressedBytes, fileNameWithoutExtension);
|
await SaveToLocalCompressedFallback(compressedBytes, fileNameWithoutExtension);
|
||||||
Heartbit();
|
// Heartbit();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -526,7 +801,7 @@ internal static class Program
|
||||||
Console.WriteLine("✅ File uploaded to S3 successfully.");
|
Console.WriteLine("✅ File uploaded to S3 successfully.");
|
||||||
|
|
||||||
Console.WriteLine("---------------------------------------- Resending FailedUploadedFiles----------------------------------------");
|
Console.WriteLine("---------------------------------------- Resending FailedUploadedFiles----------------------------------------");
|
||||||
Heartbit();
|
// Heartbit();
|
||||||
|
|
||||||
await ResendLocalFailedFilesAsync(s3Config); // retry any pending failed files
|
await ResendLocalFailedFilesAsync(s3Config); // retry any pending failed files
|
||||||
}
|
}
|
||||||
|
|
@ -539,7 +814,7 @@ internal static class Program
|
||||||
await SaveToLocalCompressedFallback(compressedBytes, fileNameWithoutExtension);
|
await SaveToLocalCompressedFallback(compressedBytes, fileNameWithoutExtension);
|
||||||
}
|
}
|
||||||
|
|
||||||
Heartbit();
|
//Heartbit();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -548,11 +823,10 @@ internal static class Program
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void Heartbit()
|
/* private static void Heartbit()
|
||||||
{
|
{
|
||||||
var s3Bucket = Config.Load().S3?.Bucket;
|
var s3Bucket = Config.Load().S3?.Bucket;
|
||||||
var tryParse = int.TryParse(s3Bucket?.Split("-")[0], out var installationId);
|
var tryParse = int.TryParse(s3Bucket?.Split("-")[0], out var installationId);
|
||||||
|
|
||||||
if (tryParse)
|
if (tryParse)
|
||||||
{
|
{
|
||||||
var returnedStatus = new StatusMessage
|
var returnedStatus = new StatusMessage
|
||||||
|
|
@ -565,7 +839,7 @@ internal static class Program
|
||||||
if (s3Bucket != null)
|
if (s3Bucket != null)
|
||||||
RabbitMqManager.InformMiddleware(returnedStatus);
|
RabbitMqManager.InformMiddleware(returnedStatus);
|
||||||
}
|
}
|
||||||
}
|
}*/
|
||||||
|
|
||||||
private static async Task SaveToLocalCompressedFallback(Byte[] compressedData, String fileNameWithoutExtension)
|
private static async Task SaveToLocalCompressedFallback(Byte[] compressedData, String fileNameWithoutExtension)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -55,7 +55,7 @@ public class ModbusDevice<[DynamicallyAccessedMembers(All)] R> where R : notnull
|
||||||
{
|
{
|
||||||
_modbusClient.Channel.ClearBuffers();
|
_modbusClient.Channel.ClearBuffers();
|
||||||
batch.Write(record);
|
batch.Write(record);
|
||||||
//Thread.Sleep(50); // this added mainly for Growatt reading
|
//Thread.Sleep(50); // this added mainly for Growatt writing
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Loading…
Reference in New Issue