Merge branch 'main' of 91.92.155.224:Innovenergy/Innovenergy_trunk
This commit is contained in:
commit
5f1bcdb0c1
|
|
@ -6,11 +6,10 @@ namespace InnovEnergy.App.GrowattCommunication.DataTypes;
|
||||||
public class Configuration
|
public class Configuration
|
||||||
{
|
{
|
||||||
public Double MinimumSoC { get; set; }
|
public Double MinimumSoC { get; set; }
|
||||||
public Double GridSetPoint { get; set; }
|
|
||||||
public Double MaximumDischargingCurrent { get; set; }
|
public Double MaximumDischargingCurrent { get; set; }
|
||||||
public Double MaximumChargingCurrent { get; set; }
|
public Double MaximumChargingCurrent { get; set; }
|
||||||
public EssMode OperatingPriority { get; set; }
|
public EssMode OperatingPriority { get; set; }
|
||||||
public required Int16 BatteriesCount { get; set; }
|
public Int16 BatteriesCount { get; set; }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,6 @@ namespace InnovEnergy.App.GrowattCommunication.ESS;
|
||||||
|
|
||||||
public record StatusRecord
|
public record StatusRecord
|
||||||
{
|
{
|
||||||
public required WITGrowatRecord AcDcGrowatt { get; set; }
|
public required WITGrowatRecord InverterRecord { get; set; }
|
||||||
public required Config Config { get; set; }
|
public required Config Config { get; set; }
|
||||||
}
|
}
|
||||||
|
|
@ -67,8 +67,8 @@ public static class MiddlewareAgent
|
||||||
|
|
||||||
if (config != null)
|
if (config != null)
|
||||||
{
|
{
|
||||||
Console.WriteLine($"Received a configuration message: GridSetPoint is " + config.GridSetPoint +
|
Console.WriteLine($"Received a configuration message: " +
|
||||||
", MinimumSoC is " + config.MinimumSoC + " and operating priorty is " +config.OperatingPriority + "Number of batteries is " + config.BatteriesCount );
|
"MinimumSoC is " + config.MinimumSoC + " and operating priorty is " +config.OperatingPriority + "Number of batteries is " + config.BatteriesCount + config.MaximumChargingCurrent + config.MaximumDischargingCurrent);
|
||||||
|
|
||||||
// Send the reply to the sender's endpoint
|
// Send the reply to the sender's endpoint
|
||||||
_udpListener.Send(replyData, replyData.Length, serverEndpoint);
|
_udpListener.Send(replyData, replyData.Length, serverEndpoint);
|
||||||
|
|
|
||||||
|
|
@ -96,7 +96,7 @@ public static class Program
|
||||||
|
|
||||||
return new StatusRecord
|
return new StatusRecord
|
||||||
{
|
{
|
||||||
AcDcGrowatt = growattRecord,
|
InverterRecord = growattRecord,
|
||||||
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
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
@ -129,42 +129,39 @@ public static class Program
|
||||||
|
|
||||||
SendSalimaxStateAlarm(GetSodiHomeStateAlarm(statusrecord),statusrecord);
|
SendSalimaxStateAlarm(GetSodiHomeStateAlarm(statusrecord),statusrecord);
|
||||||
|
|
||||||
//await DataLogging(statusrecord, timestamp); // save a csv file locally
|
|
||||||
//await SaveModbusTcpFile(statusrecord); // save the JSON file for modbuscTCP
|
|
||||||
|
|
||||||
Debug.Assert(statusrecord != null, nameof(statusrecord) + " != null");
|
Debug.Assert(statusrecord != null, nameof(statusrecord) + " != null");
|
||||||
statusrecord.AcDcGrowatt.RemotePowerControl.WriteLine(" = RemotePowerControl");
|
statusrecord.InverterRecord.RemotePowerControl.WriteLine(" = RemotePowerControl");
|
||||||
statusrecord.AcDcGrowatt.EnableEmsCommunicationFailureTime.WriteLine(" = EnableEmsCommunicationFailureTime");
|
statusrecord.InverterRecord.EnableEmsCommunicationFailureTime.WriteLine(" = EnableEmsCommunicationFailureTime");
|
||||||
|
|
||||||
statusrecord.AcDcGrowatt.EnableCommand.WriteLine(" = EnableCommand");
|
statusrecord.InverterRecord.EnableCommand.WriteLine(" = EnableCommand");
|
||||||
statusrecord.AcDcGrowatt.ControlPermession.WriteLine(" = ControlPermession");
|
statusrecord.InverterRecord.ControlPermession.WriteLine(" = ControlPermession");
|
||||||
statusrecord.AcDcGrowatt.MeterPower.WriteLine(" MeterPower");
|
statusrecord.InverterRecord.GridPower.WriteLine(" MeterPower");
|
||||||
statusrecord.AcDcGrowatt.ConsumptionPower.WriteLine(" ConsumptionPower");
|
statusrecord.InverterRecord.ConsumptionPower.WriteLine(" ConsumptionPower");
|
||||||
statusrecord.AcDcGrowatt.ExportedPowerToGridMeter.WriteLine(" ExportedPowerToGrid");
|
statusrecord.InverterRecord.ExportedPowerToGridMeter.WriteLine(" ExportedPowerToGrid");
|
||||||
statusrecord.AcDcGrowatt.ImportedPowerFromGrid.WriteLine(" ImportedPowerFromGrid");
|
statusrecord.InverterRecord.ImportedPowerFromGrid.WriteLine(" ImportedPowerFromGrid");
|
||||||
statusrecord.AcDcGrowatt.InverterActivePower.WriteLine(" InverterActivePower");
|
statusrecord.InverterRecord.InverterActivePower.WriteLine(" InverterActivePower");
|
||||||
statusrecord.AcDcGrowatt.BatteryChargeCutoffVoltage.WriteLine(" BatteryChargeCutoffVoltage "); //30409 we set power here
|
statusrecord.InverterRecord.MaxSoc.WriteLine(" BatteryChargeCutoffVoltage "); //30409 we set power here
|
||||||
statusrecord.AcDcGrowatt.BatteryDischargeCutoffVoltage.WriteLine(" BatteryDishargeCutoffVoltage "); //30409 we set power here
|
statusrecord.InverterRecord.MinSoc.WriteLine(" BatteryDishargeCutoffVoltage "); //30409 we set power here
|
||||||
statusrecord.AcDcGrowatt.PowerFactor.WriteLine(" = PowerFactor");
|
statusrecord.InverterRecord.PowerFactor.WriteLine(" = PowerFactor");
|
||||||
statusrecord.AcDcGrowatt.Batteries[0].Soc.WriteLine(" SOC");
|
statusrecord.InverterRecord.Battery1Soc.WriteLine(" SOC");
|
||||||
statusrecord.AcDcGrowatt.Batteries[0].Power.WriteLine(" Battery Power");
|
statusrecord.InverterRecord.Battery1Power.WriteLine(" Battery Power");
|
||||||
statusrecord.AcDcGrowatt.Batteries[0].Current.WriteLine(" Battery Current");
|
statusrecord.InverterRecord.Battery1Current.WriteLine(" Battery Current");
|
||||||
statusrecord.AcDcGrowatt.Batteries[0].Voltage.WriteLine(" Battery Voltage");
|
statusrecord.InverterRecord.Battery1Voltage.WriteLine(" Battery Voltage");
|
||||||
statusrecord.AcDcGrowatt.BatteryMaxChargeCurrent.WriteLine(" BatteryMaxChargeCurrent "); //30409 we set power here
|
statusrecord.InverterRecord.BatteryMaxChargingCurrent.WriteLine(" BatteryMaxChargeCurrent "); //30409 we set power here
|
||||||
statusrecord.AcDcGrowatt.BatteryMaxdischargeCurrent.WriteLine(" BatteryMaxDischargeCurrent "); //30409 we set power here
|
statusrecord.InverterRecord.BatteryMaxDischargingCurrent.WriteLine(" BatteryMaxDischargeCurrent "); //30409 we set power here
|
||||||
statusrecord.AcDcGrowatt.DischargeCutoffSoc.WriteLine(" DischargeCutoffSoc "); //30409 we set power here
|
statusrecord.InverterRecord.MinSoc.WriteLine(" MinSoc "); //30409 we set power here
|
||||||
statusrecord.AcDcGrowatt.ChargeCutoffSoc.WriteLine(" ChargeCutoffSoc "); //30409 we set power here
|
statusrecord.InverterRecord.ChargeCutoffSocVoltage.WriteLine(" ChargeCutoffSoc "); //30409 we set power here
|
||||||
|
|
||||||
statusrecord.AcDcGrowatt.TotalPvPower.WriteLine(" Pv Power "); //30409 we set power here
|
statusrecord.InverterRecord.PvPower.WriteLine(" Pv Power "); //30409 we set power here
|
||||||
|
|
||||||
statusrecord.AcDcGrowatt.SystemOperatingMode.WriteLine(" = SystemOperatingMode");
|
statusrecord.InverterRecord.SystemOperatingMode.WriteLine(" = SystemOperatingMode");
|
||||||
statusrecord.AcDcGrowatt.BatteryOperatingMode.WriteLine(" = BatteryOperatingMode");
|
statusrecord.InverterRecord.BatteryOperatingMode.WriteLine(" = BatteryOperatingMode");
|
||||||
statusrecord.AcDcGrowatt.OperatingPriority.WriteLine(" = OperatingPriority"); // 30408 this the duration
|
statusrecord.InverterRecord.OperatingMode.WriteLine(" = OperatingPriority"); // 30408 this the duration
|
||||||
|
|
||||||
statusrecord.AcDcGrowatt.FaultMainCode.WriteLine(" = FaultMainCode"); // 30408 this the duration
|
statusrecord.InverterRecord.FaultMainCode.WriteLine(" = FaultMainCode"); // 30408 this the duration
|
||||||
statusrecord.AcDcGrowatt.FaultSubCode.WriteLine(" = FaultSubCode"); // 30408 this the duration
|
statusrecord.InverterRecord.FaultSubCode.WriteLine(" = FaultSubCode"); // 30408 this the duration
|
||||||
statusrecord.AcDcGrowatt.WarningMainCode.WriteLine(" = WarningMainCode"); // 30408 this the duration
|
statusrecord.InverterRecord.WarningMainCode.WriteLine(" = WarningMainCode"); // 30408 this the duration
|
||||||
statusrecord.AcDcGrowatt.WarningSubCode.WriteLine(" = WarningSubCode"); // 30408 this the duration
|
statusrecord.InverterRecord.WarningSubCode.WriteLine(" = WarningSubCode"); // 30408 this the duration
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -173,10 +170,13 @@ public static class Program
|
||||||
statusrecord.ApplyDefaultSettings();
|
statusrecord.ApplyDefaultSettings();
|
||||||
|
|
||||||
Console.WriteLine( " ************************************ We are writing ************************************");
|
Console.WriteLine( " ************************************ We are writing ************************************");
|
||||||
|
if (statusrecord != null)
|
||||||
|
{
|
||||||
statusrecord.Config.Save(); // save the config file
|
statusrecord.Config.Save(); // save the config file
|
||||||
growattDeviceT415K.Write(statusrecord.AcDcGrowatt);
|
growattDeviceT415K.Write(statusrecord.InverterRecord);
|
||||||
var stopTime = DateTime.Now;
|
Console.WriteLine(DateTime.Now.ToString("HH:mm:ss.fff"));
|
||||||
Console.WriteLine(stopTime.ToString("HH:mm:ss.fff"));
|
|
||||||
|
}
|
||||||
return statusrecord;
|
return statusrecord;
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
|
|
@ -185,7 +185,6 @@ public static class Program
|
||||||
Console.WriteLine(e );
|
Console.WriteLine(e );
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -195,7 +194,6 @@ public static class Program
|
||||||
if (status == null) return;
|
if (status == null) return;
|
||||||
|
|
||||||
status.Config.MinSoc = config.MinimumSoC;
|
status.Config.MinSoc = config.MinimumSoC;
|
||||||
status.Config.GridSetPoint = config.GridSetPoint * 1000; // converted from kW to W
|
|
||||||
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;
|
||||||
|
|
@ -211,23 +209,23 @@ public static class Program
|
||||||
case EssMode.Off:
|
case EssMode.Off:
|
||||||
return "no mode";
|
return "no mode";
|
||||||
case EssMode.GridPriority:
|
case EssMode.GridPriority:
|
||||||
statusrecord.AcDcGrowatt.RemotePowerControl = true;
|
statusrecord.InverterRecord.RemotePowerControl = true;
|
||||||
statusrecord.AcDcGrowatt.RemotePowerControlChargeDuration = 0; // 30408 this the duration
|
statusrecord.InverterRecord.RemotePowerControlChargeDuration = 0; // 30408 this the duration
|
||||||
//statusrecord.AcDcGrowatt.ActivePowerPercent = 50; // 30408 this the duration
|
//statusrecord.AcDcGrowatt.ActivePowerPercent = 50; // 30408 this the duration
|
||||||
//statusrecord.AcDcGrowatt.ActivePowerPercentDerating = 50; // 30408 this the duration
|
//statusrecord.AcDcGrowatt.ActivePowerPercentDerating = 50; // 30408 this the duration
|
||||||
|
|
||||||
statusrecord.AcDcGrowatt.RemoteChargDischargePower = - 100; //30409 we set power here // for grid priority from 0 to -100
|
statusrecord.InverterRecord.RemoteChargDischargePower = - 100; //30409 we set power here // for grid priority from 0 to -100
|
||||||
statusrecord.AcDcGrowatt.ActualChargeDischargePowerControlValue.WriteLine(" register 30474");; // this to check what was set
|
statusrecord.InverterRecord.ActualChargeDischargePowerControlValue.WriteLine(" register 30474");; // this to check what was set
|
||||||
return "Grid priority mode active";
|
return "Grid priority mode active";
|
||||||
case EssMode.BatteryPriority:
|
case EssMode.BatteryPriority:
|
||||||
statusrecord.AcDcGrowatt.RemotePowerControl = true;
|
statusrecord.InverterRecord.RemotePowerControl = true;
|
||||||
statusrecord.AcDcGrowatt.RemotePowerControlChargeDuration = 0; // 30408 this the duration
|
statusrecord.InverterRecord.RemotePowerControlChargeDuration = 0; // 30408 this the duration
|
||||||
|
|
||||||
statusrecord.AcDcGrowatt.RemoteChargDischargePower = 100; //30409 we set power here // for battery priority from 0 to 100
|
statusrecord.InverterRecord.RemoteChargDischargePower = 100; //30409 we set power here // for battery priority from 0 to 100
|
||||||
statusrecord.AcDcGrowatt.ActualChargeDischargePowerControlValue.WriteLine(" register 30474");; // this to check what was set
|
statusrecord.InverterRecord.ActualChargeDischargePowerControlValue.WriteLine(" register 30474");; // this to check what was set
|
||||||
return "Battery priority mode active";
|
return "Battery priority mode active";
|
||||||
case EssMode.LoadPriority:
|
case EssMode.LoadPriority:
|
||||||
statusrecord.AcDcGrowatt.RemotePowerControl = false;
|
statusrecord.InverterRecord.RemotePowerControl = false;
|
||||||
return "Load priority mode active";
|
return "Load priority mode active";
|
||||||
default:
|
default:
|
||||||
throw new ArgumentOutOfRangeException(nameof(mode), mode, null);
|
throw new ArgumentOutOfRangeException(nameof(mode), mode, null);
|
||||||
|
|
@ -241,27 +239,27 @@ public static class Program
|
||||||
var alarmList = new List<AlarmOrWarning>();
|
var alarmList = new List<AlarmOrWarning>();
|
||||||
var warningList = new List<AlarmOrWarning>();
|
var warningList = new List<AlarmOrWarning>();
|
||||||
|
|
||||||
if (record.AcDcGrowatt.SystemOperatingMode == GrowattSystemStatus.Fault)
|
if (record.InverterRecord.SystemOperatingMode == GrowattSystemStatus.Fault)
|
||||||
{
|
{
|
||||||
if (record.AcDcGrowatt.FaultMainCode != 0)
|
if (record.InverterRecord.FaultMainCode != 0)
|
||||||
{
|
{
|
||||||
alarmList.Add(new AlarmOrWarning
|
alarmList.Add(new AlarmOrWarning
|
||||||
{
|
{
|
||||||
Date = DateTime.Now.ToString("yyyy-MM-dd"),
|
Date = DateTime.Now.ToString("yyyy-MM-dd"),
|
||||||
Time = DateTime.Now.ToString("HH:mm:ss"),
|
Time = DateTime.Now.ToString("HH:mm:ss"),
|
||||||
CreatedBy = "Growatt Inverter",
|
CreatedBy = "Growatt Inverter",
|
||||||
Description = record.AcDcGrowatt.WarningMainCode.ToString(), // to add the sub code
|
Description = record.InverterRecord.WarningMainCode.ToString(), // to add the sub code
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (record.AcDcGrowatt.WarningMainCode != 0)
|
if (record.InverterRecord.WarningMainCode != 0)
|
||||||
{
|
{
|
||||||
warningList.Add(new AlarmOrWarning
|
warningList.Add(new AlarmOrWarning
|
||||||
{
|
{
|
||||||
Date = DateTime.Now.ToString("yyyy-MM-dd"),
|
Date = DateTime.Now.ToString("yyyy-MM-dd"),
|
||||||
Time = DateTime.Now.ToString("HH:mm:ss"),
|
Time = DateTime.Now.ToString("HH:mm:ss"),
|
||||||
CreatedBy = "Growatt inverter",
|
CreatedBy = "Growatt inverter",
|
||||||
Description = record.AcDcGrowatt.FaultMainCode.ToString(), //to add the sub code
|
Description = record.InverterRecord.FaultMainCode.ToString(), //to add the sub code
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -330,18 +328,19 @@ public static class Program
|
||||||
if (st is null)
|
if (st is null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
st.AcDcGrowatt.BatteryMaxChargeCurrent = st.Config.MaximumChargingCurrent;
|
st.InverterRecord.BatteryMaxChargingCurrent = st.Config.MaximumChargingCurrent;
|
||||||
st.AcDcGrowatt.BatteryMaxdischargeCurrent = st.Config.MaximumDischargingCurrent ;
|
st.InverterRecord.BatteryMaxDischargingCurrent = st.Config.MaximumDischargingCurrent;
|
||||||
st.AcDcGrowatt.DischargeCutoffSoc = st.Config.MinSoc;
|
st.InverterRecord.MinSoc = (UInt16)st.Config.MinSoc;
|
||||||
st.AcDcGrowatt.EmsCommunicationFailureTime = 20; // 20 sec
|
st.InverterRecord.EmsCommunicationFailureTime = 20; // 20 sec
|
||||||
st.AcDcGrowatt.EnableEmsCommunicationFailureTime = false;
|
st.InverterRecord.EnableEmsCommunicationFailureTime = false;
|
||||||
st.AcDcGrowatt.EnableCommand = true;
|
st.InverterRecord.EnableCommand = true;
|
||||||
st.AcDcGrowatt.ControlPermession = true;
|
st.InverterRecord.ControlPermession = true;
|
||||||
st.AcDcGrowatt.BatteryChargeCutoffVoltage = 60; //st.Config.BatteryChargeCutoffVoltage;
|
st.InverterRecord.MaxSoc = 60; //st.Config.BatteryChargeCutoffVoltage;
|
||||||
st.AcDcGrowatt.BatteryDischargeCutoffVoltage = 25; //st.Config.BatteryDischargeCutoffVoltage;
|
st.InverterRecord.MinSoc = 25; //st.Config.BatteryDischargeCutoffVoltage;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Dictionary<String, UInt16> ConvertToModbusRegisters(Object value, String outputType, Int32 startingAddress)
|
private static Dictionary<String, UInt16> ConvertToModbusRegisters(Object value, String outputType,
|
||||||
|
Int32 startingAddress)
|
||||||
{
|
{
|
||||||
var registers = new Dictionary<String, UInt16>();
|
var registers = new Dictionary<String, UInt16>();
|
||||||
|
|
||||||
|
|
@ -381,38 +380,40 @@ public static class Program
|
||||||
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 =
|
||||||
var result2 = ConvertToModbusRegisters(status.AcDcGrowatt.SystemDateTime.ToUnixTime(), "UInt32", 30002);
|
ConvertToModbusRegisters((status.Config.ModbusProtcolNumber * 10), "UInt16",
|
||||||
var result3 = ConvertToModbusRegisters(status.AcDcGrowatt.SystemOperatingMode, "UInt16", 30004);
|
30001); // this to be updated to modbusTCP version
|
||||||
var result17 = ConvertToModbusRegisters(status.AcDcGrowatt.OperatingPriority, "UInt16", 30005);
|
var result2 = ConvertToModbusRegisters(status.InverterRecord.SystemDateTime.ToUnixTime(), "UInt32", 30002);
|
||||||
|
var result3 = ConvertToModbusRegisters(status.InverterRecord.SystemOperatingMode, "UInt16", 30004);
|
||||||
|
var result17 = ConvertToModbusRegisters(status.InverterRecord.OperatingMode, "UInt16", 30005);
|
||||||
|
|
||||||
// BATTERY SUMMARY (assuming single battery [0]) // this to be improved
|
// BATTERY SUMMARY (assuming single battery [0]) // this to be improved
|
||||||
var battery = status.AcDcGrowatt.BatteriesRecords!.Batteries[0];
|
|
||||||
|
|
||||||
var result4 = ConvertToModbusRegisters((status.Config.BatteriesCount ), "UInt16", 31000);
|
var result4 = ConvertToModbusRegisters((status.Config.BatteriesCount), "UInt16", 31000);
|
||||||
var result8 = ConvertToModbusRegisters((status.AcDcGrowatt.BatteryOperatingMode), "UInt16", 31001);
|
var result8 = ConvertToModbusRegisters((status.InverterRecord.BatteryOperatingMode), "UInt16", 31001);
|
||||||
var result12 = ConvertToModbusRegisters((battery.Voltage.Value * 10), "Int16", 31002);
|
var result12 = ConvertToModbusRegisters((status.InverterRecord.Battery1Voltage.Value * 10), "Int16", 31002);
|
||||||
var result13 = ConvertToModbusRegisters((battery.Current.Value * 10), "Int32", 31003);
|
var result13 = ConvertToModbusRegisters((status.InverterRecord.Battery1Current.Value * 10), "Int32", 31003);
|
||||||
var result14 = ConvertToModbusRegisters((battery.Soc.Value * 100), "UInt16", 31005);
|
var result14 = ConvertToModbusRegisters((status.InverterRecord.Battery1Soc.Value * 100), "UInt16", 31005);
|
||||||
var result5 = ConvertToModbusRegisters((battery.Power.Value * 10), "Int32", 31006);
|
var result5 = ConvertToModbusRegisters((status.InverterRecord.Battery1Power.Value * 10), "Int32", 31006);
|
||||||
|
|
||||||
var result7 = ConvertToModbusRegisters((status.AcDcGrowatt.DischargeCutoffSoc * 100), "UInt16", 31008);
|
var result7 = ConvertToModbusRegisters((status.InverterRecord.MinSoc * 100), "UInt16", 31008);
|
||||||
var result20 = ConvertToModbusRegisters((status.AcDcGrowatt.ChargeCutoffSoc * 100), "UInt16", 31009);
|
var result20 = ConvertToModbusRegisters((status.InverterRecord.ChargeCutoffSocVoltage * 100), "UInt16", 31009);
|
||||||
var result15 = ConvertToModbusRegisters((status.AcDcGrowatt.BatteriesRecords!.AverageSoh * 100), "UInt16", 310010);
|
var result15 =
|
||||||
var result16 = ConvertToModbusRegisters((battery.BatteryAmbientTemperature.Value * 100), "UInt16", 31011);
|
ConvertToModbusRegisters((status.InverterRecord.Battery1Soh * 100), "UInt16", 310010);
|
||||||
var result21 = ConvertToModbusRegisters((status.AcDcGrowatt.BatteryMaxChargeCurrent * 10), "UInt16", 31012);
|
var result16 = ConvertToModbusRegisters((status.InverterRecord.Battery1AmbientTemperature.Value * 100), "UInt16", 31011);
|
||||||
var result22 = ConvertToModbusRegisters((status.AcDcGrowatt.BatteryMaxdischargeCurrent * 10), "UInt16", 31013);
|
var result21 = ConvertToModbusRegisters((status.InverterRecord.BatteryMaxChargingCurrent * 10), "UInt16", 31012);
|
||||||
var result23 = ConvertToModbusRegisters((status.AcDcGrowatt.BatteryChargeCutoffVoltage * 10), "UInt16", 31014);
|
var result22 = ConvertToModbusRegisters((status.InverterRecord.BatteryMaxDischargingCurrent * 10), "UInt16", 31013);
|
||||||
|
var result23 = ConvertToModbusRegisters((status.InverterRecord.MaxSoc * 10), "UInt16", 31014);
|
||||||
|
|
||||||
var result18 = ConvertToModbusRegisters((status.AcDcGrowatt.TotalPvPower.Value * 10), "UInt32", 32000);
|
var result18 = ConvertToModbusRegisters((status.InverterRecord.PvPower.Value * 10), "UInt32", 32000);
|
||||||
var result19 = ConvertToModbusRegisters((status.AcDcGrowatt.MeterPower * 10), "Int32", 33000);
|
var result19 = ConvertToModbusRegisters((status.InverterRecord.GridPower * 10), "Int32", 33000);
|
||||||
|
|
||||||
|
|
||||||
// Merge all results into one dictionary
|
// Merge all results into one dictionary
|
||||||
var allResults = new[]
|
var allResults = new[]
|
||||||
{
|
{
|
||||||
result1,result2, result3, result17, result4, result5, result7, result8,
|
result1, result2, result3, result17, result4, result5, result7, result8,
|
||||||
result12, result13, result14, result15, result16, result18, result19,result20,
|
result12, result13, result14, result15, result16, result18, result19, result20,
|
||||||
result21, result22, result23
|
result21, result22, result23
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -584,7 +585,8 @@ public static class Program
|
||||||
uploadSucceeded = true;
|
uploadSucceeded = true;
|
||||||
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
|
||||||
|
|
|
||||||
|
|
@ -142,9 +142,9 @@ public static class Aggregator
|
||||||
{
|
{
|
||||||
batterySoc.Add((double)jsonObject["Battery"]["Soc"]);
|
batterySoc.Add((double)jsonObject["Battery"]["Soc"]);
|
||||||
}
|
}
|
||||||
if (jsonObject["PvOnDc"] != null && jsonObject["PvOnDc"]["DcWh"] != null)
|
if (jsonObject["PvOnDc"] != null && jsonObject["PvOnDc"]["1"]["DcWh"] != null) // todo update to all pv
|
||||||
{
|
{
|
||||||
pvPowerSum.Add((double)jsonObject["PvOnDc"]["DcWh"]);
|
pvPowerSum.Add((double)jsonObject["PvOnDc"]["1"]["DcWh"]);
|
||||||
}
|
}
|
||||||
if (jsonObject["Battery"] != null && jsonObject["Battery"]["Dc"]["Power"] != null)
|
if (jsonObject["Battery"] != null && jsonObject["Battery"]["Dc"]["Power"] != null)
|
||||||
{
|
{
|
||||||
|
|
@ -316,7 +316,7 @@ public static class Aggregator
|
||||||
ChargingBatteryPower = batteryChargePower.Any() ? batteryChargePower.Average() : 0.0,
|
ChargingBatteryPower = batteryChargePower.Any() ? batteryChargePower.Average() : 0.0,
|
||||||
GridExportPower = gridPowerExport.Any() ? gridPowerExport.Sum() : 0.0,
|
GridExportPower = gridPowerExport.Any() ? gridPowerExport.Sum() : 0.0,
|
||||||
GridImportPower = gridPowerImport.Any() ? gridPowerImport.Sum() : 0.0,
|
GridImportPower = gridPowerImport.Any() ? gridPowerImport.Sum() : 0.0,
|
||||||
PvPower = pvPower.Any() ? pvPower.Last() : 0.0,
|
PvPower = pvPower.Any() ? pvPower.Max() : 0.0,
|
||||||
HeatingPower = heatingPowerAvg.Any() ? heatingPowerAvg.Average() : 0.0,
|
HeatingPower = heatingPowerAvg.Any() ? heatingPowerAvg.Average() : 0.0,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,13 @@
|
||||||
|
using InnovEnergy.Lib.Devices.Sinexcel_12K_TL.DataType;
|
||||||
|
|
||||||
namespace InnovEnergy.App.SinexcelCommunication.DataTypes;
|
namespace InnovEnergy.App.SinexcelCommunication.DataTypes;
|
||||||
|
|
||||||
public class Configuration
|
public class Configuration
|
||||||
{
|
{
|
||||||
public Double MinimumSoC { get; set; }
|
public Double MinimumSoC { get; set; }
|
||||||
public Double GridSetPoint { get; set; }
|
public Double MaximumDischargingCurrent { get; set; }
|
||||||
// public Double MaximumDischargingCurrent { get; set; }
|
public Double MaximumChargingCurrent { get; set; }
|
||||||
// public Double MaximumChargingCurrent { get; set; }
|
public WorkingMode OperatingPriority { get; set; }
|
||||||
// public EssMode OperatingPriority { get; set; }
|
public Int16 BatteriesCount { get; set; }
|
||||||
// public required Int16 BatteriesCount { get; set; }
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,8 +0,0 @@
|
||||||
namespace InnovEnergy.App.SinexcelCommunication;
|
|
||||||
|
|
||||||
public enum DeviceState
|
|
||||||
{
|
|
||||||
Disabled,
|
|
||||||
Measured,
|
|
||||||
Computed
|
|
||||||
}
|
|
||||||
|
|
@ -5,6 +5,6 @@ namespace InnovEnergy.App.SinexcelCommunication.ESS;
|
||||||
|
|
||||||
public record StatusRecord
|
public record StatusRecord
|
||||||
{
|
{
|
||||||
public required SinexcelRecord SinexcelRecord { get; set; }
|
public required SinexcelRecord InverterRecord { get; set; }
|
||||||
public required Config Config { get; set; }
|
public required Config Config { get; set; }
|
||||||
}
|
}
|
||||||
|
|
@ -67,8 +67,8 @@ public static class MiddlewareAgent
|
||||||
|
|
||||||
if (config != null)
|
if (config != null)
|
||||||
{
|
{
|
||||||
Console.WriteLine($"Received a configuration message: GridSetPoint is " + config.GridSetPoint +
|
Console.WriteLine($"Received a configuration message: " +
|
||||||
", MinimumSoC is " + config.MinimumSoC + " and operating priorty is " );
|
"MinimumSoC is " + config.MinimumSoC + " and operating priorty is " +config.OperatingPriority + "Number of batteries is " + config.BatteriesCount + config.MaximumChargingCurrent + config.MaximumDischargingCurrent);
|
||||||
|
|
||||||
// Send the reply to the sender's endpoint
|
// Send the reply to the sender's endpoint
|
||||||
_udpListener.Send(replyData, replyData.Length, serverEndpoint);
|
_udpListener.Send(replyData, replyData.Length, serverEndpoint);
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,8 @@ using Formatting = Newtonsoft.Json.Formatting;
|
||||||
using JsonSerializer = System.Text.Json.JsonSerializer;
|
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;
|
||||||
|
|
||||||
#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.
|
||||||
|
|
||||||
namespace InnovEnergy.App.SinexcelCommunication;
|
namespace InnovEnergy.App.SinexcelCommunication;
|
||||||
|
|
@ -31,7 +33,7 @@ namespace InnovEnergy.App.SinexcelCommunication;
|
||||||
[SuppressMessage("Trimming", "IL2026:Members annotated with \'RequiresUnreferencedCodeAttribute\' require dynamic access otherwise can break functionality when trimming application code")]
|
[SuppressMessage("Trimming", "IL2026:Members annotated with \'RequiresUnreferencedCodeAttribute\' require dynamic access otherwise can break functionality when trimming application code")]
|
||||||
internal static class Program
|
internal static class Program
|
||||||
{
|
{
|
||||||
private static readonly TimeSpan UpdateInterval = TimeSpan.FromSeconds(4);
|
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 _sinexcelChannel;
|
||||||
|
|
@ -54,7 +56,7 @@ 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);
|
_sinexcelChannel = new SerialPortChannel(Port, BaudRate, Parity, DataBits, StopBits);
|
||||||
|
InitializeCommunicationToMiddleware();
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
|
@ -85,7 +87,7 @@ internal static class Program
|
||||||
|
|
||||||
return new StatusRecord
|
return new StatusRecord
|
||||||
{
|
{
|
||||||
SinexcelRecord = sinexcelRecord,
|
InverterRecord = sinexcelRecord,
|
||||||
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
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
@ -111,61 +113,57 @@ internal static class Program
|
||||||
|
|
||||||
var startTime = DateTime.Now;
|
var startTime = DateTime.Now;
|
||||||
Console.WriteLine("***************************** Reading Battery Data *********************************************");
|
Console.WriteLine("***************************** Reading Battery Data *********************************************");
|
||||||
Console.WriteLine(startTime.ToString("HH:mm:ss.fff"));
|
Console.WriteLine(startTime.ToString("HH:mm:ss.fff ")+ "Start Reading");
|
||||||
|
|
||||||
// the order matter of the next three lines
|
// the order matter of the next three lines
|
||||||
var statusrecord = ReadStatus();
|
var statusrecord = ReadStatus();
|
||||||
if (statusrecord == null)
|
if (statusrecord == null)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
statusrecord.SinexcelRecord.GridAPhaseVoltage.WriteLine(" = Grid A PhaseVoltage");
|
// Console.WriteLine( statusrecord.InverterRecord.TimedChargeAndDischargeOff + " TimedChargeAndDischargeOff ");
|
||||||
statusrecord.SinexcelRecord.GridBPhaseVoltage.WriteLine(" = Grid B PhaseVoltage");
|
Console.WriteLine( statusrecord.InverterRecord.Battery1Power + " Battery1Power ");
|
||||||
statusrecord.SinexcelRecord.GridCPhaseVoltage.WriteLine(" = Grid C PhaseVoltage");
|
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 ");
|
||||||
|
|
||||||
statusrecord.SinexcelRecord.GridAPhaseCurrent.WriteLine(" = Grid A PhaseCurrent");
|
Console.WriteLine( statusrecord.InverterRecord.DischargeStartTimePeriod1 + " DischargeStartTimePeriod1 ");
|
||||||
statusrecord.SinexcelRecord.GridBPhaseCurrent.WriteLine(" = Grid B PhaseCurrent");
|
Console.WriteLine( statusrecord.InverterRecord.DischargeEndTimePeriod1 + " DischargeEndTimePeriod1 ");
|
||||||
statusrecord.SinexcelRecord.GridCPhaseCurrent.WriteLine(" = Grid C PhaseCurrent");
|
|
||||||
|
|
||||||
|
Console.WriteLine( statusrecord.InverterRecord.PowerOn + " PowerOn ");
|
||||||
|
Console.WriteLine( statusrecord.InverterRecord.PowerOff + " PowerOff ");
|
||||||
|
Console.WriteLine( statusrecord.InverterRecord.WorkingMode + " WorkingMode ");
|
||||||
|
// Console.WriteLine( statusrecord.InverterRecord.FaultClearing + " FaultClearing ");
|
||||||
|
SendSalimaxStateAlarm(GetSodiHomeStateAlarm(statusrecord),statusrecord);
|
||||||
|
|
||||||
statusrecord.SinexcelRecord.GridAPhaseActivePower.WriteLine(" = A Grid Active Power");
|
|
||||||
statusrecord.SinexcelRecord.GridBPhaseActivePower.WriteLine(" = B Grid Active Power");
|
|
||||||
statusrecord.SinexcelRecord.GridCPhaseActivePower.WriteLine(" = C Grid Active Power");
|
|
||||||
|
|
||||||
statusrecord.SinexcelRecord.GridVoltageFrequency.WriteLine(" = Frequency");
|
|
||||||
|
|
||||||
statusrecord.SinexcelRecord.ElectricMeterCPhaseActivePower.WriteLine(" Meter Phase C Power");
|
|
||||||
statusrecord.SinexcelRecord.ElectricMeterBPhaseActivePower.WriteLine(" Meter Phase B Power");
|
|
||||||
statusrecord.SinexcelRecord.ElectricMeterAPhaseActivePower.WriteLine(" Meter Phase A Power");
|
|
||||||
|
|
||||||
statusrecord.SinexcelRecord.ElectricMeterAPhaseCurrent.WriteLine(" Meter Phase C Current ");
|
|
||||||
statusrecord.SinexcelRecord.ElectricMeterBPhaseCurrent.WriteLine(" Meter Phase B Current ");
|
|
||||||
statusrecord.SinexcelRecord.ElectricMeterBPhaseCurrent.WriteLine(" Meter Phase A Current ");
|
|
||||||
statusrecord.SinexcelRecord.WorkingMode.WriteLine(" workingmode");
|
|
||||||
|
|
||||||
statusrecord.SinexcelRecord.BatteryVoltage.WriteLine(" BatteryVoltage");
|
|
||||||
statusrecord.SinexcelRecord.BatteryVoltage1.WriteLine(" BatteryVoltage1");
|
|
||||||
statusrecord.SinexcelRecord.BatteryVoltage2.WriteLine(" BatteryVoltage2");
|
|
||||||
|
|
||||||
statusrecord.SinexcelRecord.BatteryPower1.WriteLine(" BatteryPower1");
|
|
||||||
statusrecord.SinexcelRecord.BatteryPower2.WriteLine(" BatteryPower2");
|
|
||||||
statusrecord.SinexcelRecord.TotalBatteryPower.WriteLine(" TotalBatteryPower");
|
|
||||||
|
|
||||||
statusrecord.SinexcelRecord.EnableBattery1.WriteLine(" EnableBattery1");
|
|
||||||
statusrecord.SinexcelRecord.EnableBattery2.WriteLine(" EnableBattery2");
|
|
||||||
|
|
||||||
statusrecord.SinexcelRecord.MaxChargingCurrentBattery1.WriteLine(" MaxChargingCurrentBattery1");
|
|
||||||
statusrecord.SinexcelRecord.MaxChargingCurrentBattery2.WriteLine(" MaxChargingCurrentBattery2");
|
|
||||||
|
|
||||||
statusrecord.SinexcelRecord.MaxDischargingCurrentBattery1.WriteLine(" MaxChargingCurrentBattery1");
|
|
||||||
statusrecord.SinexcelRecord.MaxDischargingCurrentBattery2.WriteLine(" MaxChargingCurrentBattery2");
|
|
||||||
|
|
||||||
//EssModeControl(statusrecord);
|
|
||||||
// statusrecord.ApplyDefaultSettings();
|
|
||||||
Console.WriteLine( " ************************************ We are writing ************************************");
|
Console.WriteLine( " ************************************ We are writing ************************************");
|
||||||
|
var startWritingTime = DateTime.Now;
|
||||||
|
Console.WriteLine(startWritingTime.ToString("HH:mm:ss.fff ") +"start Writing");
|
||||||
statusrecord?.Config.Save(); // save the config file
|
statusrecord?.Config.Save(); // save the config file
|
||||||
//sinexcelDevice.Write(statusrecord?.SinexcelRecord);
|
|
||||||
|
if (statusrecord != null)
|
||||||
|
{
|
||||||
|
statusrecord.InverterRecord.WorkingMode = WorkingMode.TimeChargeDischarge;
|
||||||
|
|
||||||
|
//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);
|
||||||
|
|
||||||
var stopTime = DateTime.Now;
|
var stopTime = DateTime.Now;
|
||||||
Console.WriteLine(stopTime.ToString("HH:mm:ss.fff"));
|
Console.WriteLine(stopTime.ToString("HH:mm:ss.fff ")+ "run iteration time finish");
|
||||||
return statusrecord;
|
return statusrecord;
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
|
|
@ -178,6 +176,61 @@ internal static class Program
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static StatusMessage GetSodiHomeStateAlarm(StatusRecord? record)
|
||||||
|
{
|
||||||
|
var s3Bucket = Config.Load().S3?.Bucket;
|
||||||
|
|
||||||
|
var alarmList = new List<AlarmOrWarning>();
|
||||||
|
var warningList = new List<AlarmOrWarning>();
|
||||||
|
/*
|
||||||
|
if (record.SinexcelRecord.WorkingMode == GrowattSystemStatus.Fault)
|
||||||
|
{
|
||||||
|
if (record.AcDcGrowatt.FaultMainCode != 0)
|
||||||
|
{
|
||||||
|
alarmList.Add(new AlarmOrWarning
|
||||||
|
{
|
||||||
|
Date = DateTime.Now.ToString("yyyy-MM-dd"),
|
||||||
|
Time = DateTime.Now.ToString("HH:mm:ss"),
|
||||||
|
CreatedBy = "Growatt Inverter",
|
||||||
|
Description = record.AcDcGrowatt.WarningMainCode.ToString(), // to add the sub code
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (record.AcDcGrowatt.WarningMainCode != 0)
|
||||||
|
{
|
||||||
|
warningList.Add(new AlarmOrWarning
|
||||||
|
{
|
||||||
|
Date = DateTime.Now.ToString("yyyy-MM-dd"),
|
||||||
|
Time = DateTime.Now.ToString("HH:mm:ss"),
|
||||||
|
CreatedBy = "Growatt inverter",
|
||||||
|
Description = record.AcDcGrowatt.FaultMainCode.ToString(), //to add the sub code
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}*/
|
||||||
|
|
||||||
|
_sodiohomeAlarmState = warningList.Any()
|
||||||
|
? SodistoreAlarmState.Orange
|
||||||
|
: SodistoreAlarmState.Green; // this will be replaced by LedState
|
||||||
|
|
||||||
|
_sodiohomeAlarmState = alarmList.Any()
|
||||||
|
? SodistoreAlarmState.Red
|
||||||
|
: _sodiohomeAlarmState; // this will be replaced by LedState
|
||||||
|
|
||||||
|
var installationId = GetInstallationId(s3Bucket ?? string.Empty);
|
||||||
|
|
||||||
|
var returnedStatus = new StatusMessage
|
||||||
|
{
|
||||||
|
InstallationId = installationId,
|
||||||
|
Product = 2,
|
||||||
|
Status = _sodiohomeAlarmState,
|
||||||
|
Type = MessageType.AlarmOrWarning,
|
||||||
|
Alarms = alarmList,
|
||||||
|
Warnings = warningList
|
||||||
|
};
|
||||||
|
|
||||||
|
return returnedStatus;
|
||||||
|
}
|
||||||
|
|
||||||
private static Int32 GetInstallationId(String s3Bucket)
|
private static Int32 GetInstallationId(String s3Bucket)
|
||||||
{
|
{
|
||||||
var part = s3Bucket.Split('-').FirstOrDefault();
|
var part = s3Bucket.Split('-').FirstOrDefault();
|
||||||
|
|
@ -220,11 +273,10 @@ internal static class Program
|
||||||
if (status == null) return;
|
if (status == null) return;
|
||||||
|
|
||||||
status.Config.MinSoc = config.MinimumSoC;
|
status.Config.MinSoc = config.MinimumSoC;
|
||||||
status.Config.GridSetPoint = config.GridSetPoint * 1000; // converted from kW to W
|
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static async Task<Boolean> SaveModbusTcpFile(StatusRecord status)
|
private static async Task<Boolean> SaveModbusTcpFile(StatusRecord status)
|
||||||
|
|
@ -232,10 +284,11 @@ internal static class Program
|
||||||
var modbusData = new Dictionary<String, UInt16>();
|
var modbusData = new Dictionary<String, UInt16>();
|
||||||
|
|
||||||
// SYSTEM DATA
|
// SYSTEM DATA
|
||||||
var result1 = ConvertToModbusRegisters((status.Config.MinSoc * 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.SinexcelRecord.GridAPhaseVoltage, "UInt32", 30002);
|
var result2 = ConvertToModbusRegisters(status.InverterRecord.SystemDateTime.ToUnixTime(), "UInt32", 30002);
|
||||||
|
|
||||||
// Merge all results into one dictionary
|
// Merge all results into one dictionary
|
||||||
|
|
||||||
var allResults = new[]
|
var allResults = new[]
|
||||||
{
|
{
|
||||||
result1,result2
|
result1,result2
|
||||||
|
|
@ -254,43 +307,72 @@ internal static class Program
|
||||||
|
|
||||||
//Console.WriteLine("JSON file written successfully.");
|
//Console.WriteLine("JSON file written successfully.");
|
||||||
//Console.WriteLine(json);
|
//Console.WriteLine(json);
|
||||||
|
var stopTime = DateTime.Now;
|
||||||
|
Console.WriteLine(stopTime.ToString("HH:mm:ss.fff" )+ " Finish the loop");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Dictionary<String, UInt16> ConvertToModbusRegisters(Object value, String outputType, Int32 startingAddress)
|
private static Dictionary<string, ushort> ConvertToModbusRegisters(object value, string outputType, int startingAddress)
|
||||||
{
|
{
|
||||||
var registers = new Dictionary<String, UInt16>();
|
var regs = new Dictionary<string, ushort>(capacity: 2);
|
||||||
|
|
||||||
switch (outputType)
|
switch (outputType)
|
||||||
{
|
{
|
||||||
case "UInt16":
|
case "UInt16":
|
||||||
registers[startingAddress.ToString()] = Convert.ToUInt16(value);
|
{
|
||||||
|
regs[$"{startingAddress}"] = Convert.ToUInt16(value);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case "Int16":
|
case "Int16":
|
||||||
var int16Val = Convert.ToInt16(value);
|
{
|
||||||
registers[startingAddress.ToString()] = (UInt16)int16Val; // reinterpret signed as ushort
|
short v = Convert.ToInt16(value);
|
||||||
|
regs[$"{startingAddress}"] = unchecked((ushort)v); // reinterpret
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case "UInt32":
|
case "UInt32":
|
||||||
var uint32Val = Convert.ToUInt32(value);
|
{
|
||||||
registers[startingAddress.ToString()] = (UInt16)(uint32Val & 0xFFFF); // Low word
|
uint v = Convert.ToUInt32(value);
|
||||||
registers[(startingAddress + 1).ToString()] = (UInt16)(uint32Val >> 16); // High word
|
ushort hi = (ushort)(v >> 16);
|
||||||
|
ushort lo = (ushort)(v & 0xFFFF);
|
||||||
|
regs[$"{startingAddress}"] = hi; // HIGH word first (Modbus standard)
|
||||||
|
regs[$"{startingAddress + 1}"] = lo; // then LOW word
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case "Int32":
|
case "Int32":
|
||||||
var int32Val = Convert.ToInt32(value);
|
{
|
||||||
var raw = unchecked((UInt32)int32Val); // reinterprets signed int as unsigned
|
int v = Convert.ToInt32(value);
|
||||||
registers[startingAddress.ToString()] = (UInt16)(raw & 0xFFFF);
|
uint raw = unchecked((uint)v); // bit-reinterpret
|
||||||
registers[(startingAddress + 1).ToString()] = (UInt16)(raw >> 16);
|
ushort hi = (ushort)(raw >> 16);
|
||||||
|
ushort lo = (ushort)(raw & 0xFFFF);
|
||||||
|
regs[$"{startingAddress}"] = hi; // HIGH word
|
||||||
|
regs[$"{startingAddress + 1}"] = lo; // LOW word
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case "Float": // IEEE-754 single
|
||||||
|
{
|
||||||
|
float f = Convert.ToSingle(value);
|
||||||
|
// Convert to bytes, then to two big-endian 16-bit words
|
||||||
|
var bytes = BitConverter.GetBytes(f); // little-endian on most platforms
|
||||||
|
Array.Reverse(bytes); // to big-endian byte order
|
||||||
|
ushort hi = (ushort)((bytes[0] << 8) | bytes[1]);
|
||||||
|
ushort lo = (ushort)((bytes[2] << 8) | bytes[3]);
|
||||||
|
regs[$"{startingAddress}"] = hi;
|
||||||
|
regs[$"{startingAddress + 1}"] = lo;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
throw new ArgumentException("Unsupported output type: " + outputType);
|
throw new ArgumentException($"Unsupported output type: {outputType}");
|
||||||
}
|
}
|
||||||
return registers;
|
|
||||||
|
return regs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private static async Task<Boolean> DataLogging(StatusRecord status, DateTime timeStamp)
|
private static async Task<Boolean> DataLogging(StatusRecord status, DateTime timeStamp)
|
||||||
{
|
{
|
||||||
var csv = status.ToCsv();
|
var csv = status.ToCsv();
|
||||||
|
|
|
||||||
|
|
@ -1,13 +0,0 @@
|
||||||
using InnovEnergy.Lib.Utils.Net;
|
|
||||||
|
|
||||||
namespace InnovEnergy.App.SinexcelCommunication;
|
|
||||||
|
|
||||||
public class SalimaxDevice : Ip4Address
|
|
||||||
{
|
|
||||||
public required DeviceState DeviceState { get; init; }
|
|
||||||
|
|
||||||
public override String ToString() => $"{base.ToString()} ({DeviceState})";
|
|
||||||
|
|
||||||
public override int GetHashCode() => HashCode.Combine(base.GetHashCode(), DeviceState);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
using System.Diagnostics.CodeAnalysis;
|
using System.Diagnostics.CodeAnalysis;
|
||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
|
using InnovEnergy.Lib.Devices.Sinexcel_12K_TL.DataType;
|
||||||
using InnovEnergy.Lib.Utils;
|
using InnovEnergy.Lib.Utils;
|
||||||
using static System.Text.Json.JsonSerializer;
|
using static System.Text.Json.JsonSerializer;
|
||||||
|
|
||||||
|
|
@ -17,16 +18,25 @@ public class Config
|
||||||
|
|
||||||
public required Double MinSoc { get; set; }
|
public required Double MinSoc { get; set; }
|
||||||
public required Double GridSetPoint { get; set; }
|
public required Double GridSetPoint { get; set; }
|
||||||
|
public required Double MaximumDischargingCurrent { get; set; }
|
||||||
|
public required Double MaximumChargingCurrent { get; set; }
|
||||||
|
public required WorkingMode OperatingPriority { get; set; }
|
||||||
|
public required Int16 BatteriesCount { get; set; }
|
||||||
|
public required Double ModbusProtcolNumber { get; set; }
|
||||||
|
|
||||||
public required S3Config? S3 { get; set; }
|
public required S3Config? S3 { get; set; }
|
||||||
|
|
||||||
|
|
||||||
private static String? LastSavedData { get; set; }
|
private static String? LastSavedData { get; set; }
|
||||||
|
|
||||||
public static Config Default => new()
|
public static Config Default => new()
|
||||||
{
|
{
|
||||||
MinSoc = 20,
|
MinSoc = 20,
|
||||||
GridSetPoint = 0,
|
GridSetPoint = 0,
|
||||||
|
MaximumChargingCurrent = 180,
|
||||||
|
MaximumDischargingCurrent = 180,
|
||||||
|
OperatingPriority = WorkingMode.TimeChargeDischarge,
|
||||||
|
BatteriesCount = 0,
|
||||||
|
ModbusProtcolNumber = 1.2,
|
||||||
S3 = new()
|
S3 = new()
|
||||||
{
|
{
|
||||||
Bucket = "1-3e5b3069-214a-43ee-8d85-57d72000c19d",
|
Bucket = "1-3e5b3069-214a-43ee-8d85-57d72000c19d",
|
||||||
|
|
|
||||||
|
|
@ -137,9 +137,9 @@ public static class Aggregator
|
||||||
{
|
{
|
||||||
batterySoc.Add((double)jsonObject["Battery"]["Soc"]);
|
batterySoc.Add((double)jsonObject["Battery"]["Soc"]);
|
||||||
}
|
}
|
||||||
if (jsonObject["PvOnDc"] != null && jsonObject["PvOnDc"]["DcWh"] != null)
|
if (jsonObject["PvOnDc"] != null && jsonObject["PvOnDc"]["1"]["DcWh"] != null) // todo update to all pv
|
||||||
{
|
{
|
||||||
pvPowerSum.Add((double)jsonObject["PvOnDc"]["DcWh"]);
|
pvPowerSum.Add((double)jsonObject["PvOnDc"]["1"]["DcWh"]);
|
||||||
}
|
}
|
||||||
if (jsonObject["Battery"] != null && jsonObject["Battery"]["Power"] != null)
|
if (jsonObject["Battery"] != null && jsonObject["Battery"]["Power"] != null)
|
||||||
{
|
{
|
||||||
|
|
@ -295,7 +295,7 @@ public static class Aggregator
|
||||||
ChargingBatteryPower = batteryChargePower.Any() ? batteryChargePower.Average() : 0.0,
|
ChargingBatteryPower = batteryChargePower.Any() ? batteryChargePower.Average() : 0.0,
|
||||||
GridExportPower = gridPowerExport.Any() ? gridPowerExport.Sum() : 0.0,
|
GridExportPower = gridPowerExport.Any() ? gridPowerExport.Sum() : 0.0,
|
||||||
GridImportPower = gridPowerImport.Any() ? gridPowerImport.Sum() : 0.0,
|
GridImportPower = gridPowerImport.Any() ? gridPowerImport.Sum() : 0.0,
|
||||||
PvPower = pvPower.Any() ? pvPower.Last() : 0.0,
|
PvPower = pvPower.Any() ? pvPower.Max() : 0.0,
|
||||||
HeatingPower = heatingPowerAvg.Any() ? heatingPowerAvg.Average() : 0.0,
|
HeatingPower = heatingPowerAvg.Any() ? heatingPowerAvg.Average() : 0.0,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,272 +0,0 @@
|
||||||
using System.Text;
|
|
||||||
using Microsoft.AspNetCore.Mvc;
|
|
||||||
|
|
||||||
namespace DataCollectorWebApp;
|
|
||||||
|
|
||||||
public class LoginResponse
|
|
||||||
{
|
|
||||||
public string Token { get; set; }
|
|
||||||
public object User { get; set; } // or a User class if needed
|
|
||||||
public bool AccessToSalimax { get; set; }
|
|
||||||
public bool AccessToSalidomo { get; set; }
|
|
||||||
public bool AccessToSodiohome { get; set; }
|
|
||||||
public bool AccessToSodistoreMax { get; set; }
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public class Installation
|
|
||||||
{
|
|
||||||
//Each installation has 2 roles, a read role and a write role.
|
|
||||||
//There are 2 keys per role a public key and a secret
|
|
||||||
//Product can be 0 or 1, 0 for Salimax, 1 for Salidomo
|
|
||||||
public String Name { get; set; }
|
|
||||||
public String Location { get; set; }
|
|
||||||
public String Region { get; set; } = "";
|
|
||||||
public String Country { get; set; } = "";
|
|
||||||
public String VpnIp { get; set; } = "";
|
|
||||||
public String InstallationName { get; set; } = "";
|
|
||||||
|
|
||||||
public String S3Region { get; set; } = "sos-ch-dk-2";
|
|
||||||
public String S3Provider { get; set; } = "exo.io";
|
|
||||||
public String S3WriteKey { get; set; } = "";
|
|
||||||
public String S3Key { get; set; } = "";
|
|
||||||
public String S3WriteSecret { get; set; } = "";
|
|
||||||
public String S3Secret { get; set; } = "";
|
|
||||||
public int S3BucketId { get; set; } = 0;
|
|
||||||
public String ReadRoleId { get; set; } = "";
|
|
||||||
public String WriteRoleId { get; set; } = "";
|
|
||||||
public Boolean TestingMode { get; set; } = false;
|
|
||||||
public int Status { get; set; } = -1;
|
|
||||||
public int Product { get; set; } = 0;
|
|
||||||
public int Device { get; set; } = 0;
|
|
||||||
public string SerialNumber { get; set; } = "";
|
|
||||||
public string InverterSN { get; set; } = "";
|
|
||||||
public string DataloggerSN { get; set; } = "";
|
|
||||||
public String OrderNumbers { get; set; }
|
|
||||||
public String VrmLink { get; set; } = "";
|
|
||||||
}
|
|
||||||
|
|
||||||
[Controller]
|
|
||||||
public class InstallationsController : Controller
|
|
||||||
{
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
[HttpGet]
|
|
||||||
[Route("/Installations")]
|
|
||||||
[Produces("text/html")]
|
|
||||||
public async Task<IActionResult> Index()
|
|
||||||
{
|
|
||||||
const string HtmlHeader = @"
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<title>Inesco Energy Installations Overview</title>
|
|
||||||
<style>
|
|
||||||
body {
|
|
||||||
font-family: sans-serif;
|
|
||||||
margin: 2rem;
|
|
||||||
}
|
|
||||||
table {
|
|
||||||
border-collapse: collapse;
|
|
||||||
width: 100%;
|
|
||||||
font-size: 0.9rem;
|
|
||||||
}
|
|
||||||
th, td {
|
|
||||||
padding: 0.75rem;
|
|
||||||
border: 1px solid rgb(200, 200, 200);
|
|
||||||
text-align: left;
|
|
||||||
}
|
|
||||||
thead th {
|
|
||||||
background-color: #f0f0f0;
|
|
||||||
font-weight: bold;
|
|
||||||
border-bottom: 2px solid #EB9486;
|
|
||||||
}
|
|
||||||
tbody tr:nth-child(odd) {
|
|
||||||
background-color: #f9f9f9;
|
|
||||||
}
|
|
||||||
a {
|
|
||||||
color: #0645AD;
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
||||||
a:hover {
|
|
||||||
text-decoration: underline;
|
|
||||||
}
|
|
||||||
|
|
||||||
.status-circle {
|
|
||||||
display: inline-block;
|
|
||||||
width: 15px;
|
|
||||||
height: 15px;
|
|
||||||
border-radius: 50%;
|
|
||||||
margin-left: 50%;
|
|
||||||
}
|
|
||||||
.status-0 { background-color: #4CAF50; } /* Green */
|
|
||||||
.status-1 { background-color: #FF9800; } /* Orange */
|
|
||||||
.status-2 { background-color: #F44336; } /* Red */
|
|
||||||
|
|
||||||
.centered {
|
|
||||||
text-align: center;
|
|
||||||
vertical-align: middle;
|
|
||||||
}
|
|
||||||
|
|
||||||
.offline-symbol {
|
|
||||||
font-size: 1.2rem;
|
|
||||||
color: #F44336; /* Gray */
|
|
||||||
display: inline-block;
|
|
||||||
line-height: 1;
|
|
||||||
width: 15px;
|
|
||||||
height: 15px;
|
|
||||||
border-radius: 50%;
|
|
||||||
margin-left: 50%;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.status-cell {
|
|
||||||
text-align: center; /* center horizontally */
|
|
||||||
vertical-align: middle; /* center vertically */
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<h1>Installation Overview</h1>
|
|
||||||
<table>
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th class=""centered"">Name</th>
|
|
||||||
<th class=""centered"">Product</th>
|
|
||||||
<th class=""centered"">Location</th>
|
|
||||||
<th class=""centered"">VPN IP</th>
|
|
||||||
<th class=""centered"">Status</th>
|
|
||||||
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
";
|
|
||||||
|
|
||||||
const string HtmlFooter = @"
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
";
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
string GetProductName(int productId)
|
|
||||||
{
|
|
||||||
return productId switch
|
|
||||||
{
|
|
||||||
0 => "Salimax",
|
|
||||||
1 => "Salidomo",
|
|
||||||
2 => "SodioHome",
|
|
||||||
3 => "SodistoreMax",
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
string GetStatusHtml(int status)
|
|
||||||
{
|
|
||||||
if (status == -1)
|
|
||||||
{
|
|
||||||
return "<span class='offline-symbol' title='Offline'>×</span>";
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
var statusClass = $"status-{status}";
|
|
||||||
var title = status switch
|
|
||||||
{
|
|
||||||
0 => "Online",
|
|
||||||
1 => "Warning",
|
|
||||||
2 => "Error",
|
|
||||||
_ => "Unknown"
|
|
||||||
};
|
|
||||||
|
|
||||||
return $"<span class='status-circle {statusClass}' title='{title}'></span>";
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
string BuildRowHtml(Installation i) => $@"
|
|
||||||
<tr>
|
|
||||||
<td>{i.Name}</td>
|
|
||||||
<td>{GetProductName(i.Product)}</td>
|
|
||||||
<td>{i.Location}</td>
|
|
||||||
<td>{i.VpnIp}</td>
|
|
||||||
<td>{GetStatusHtml(i.Status)}</td>
|
|
||||||
</tr>
|
|
||||||
";
|
|
||||||
|
|
||||||
var installations = await FetchInstallationsFromApi();
|
|
||||||
|
|
||||||
var sb = new StringBuilder();
|
|
||||||
sb.Append(HtmlHeader);
|
|
||||||
|
|
||||||
foreach (var i in installations)
|
|
||||||
{
|
|
||||||
sb.Append(BuildRowHtml(i));
|
|
||||||
}
|
|
||||||
|
|
||||||
sb.Append(HtmlFooter);
|
|
||||||
return Content(sb.ToString(), "text/html");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public async Task<List<Installation>?> FetchInstallationsFromApi()
|
|
||||||
{
|
|
||||||
|
|
||||||
var username = "baumgartner@innov.energy";
|
|
||||||
var password = "1234";
|
|
||||||
|
|
||||||
using var http = new HttpClient { BaseAddress = new Uri("https://monitor.inesco.energy/api/") };
|
|
||||||
|
|
||||||
// Step 1: Login
|
|
||||||
var loginResponse = await http.PostAsync($"Login?username={username}&password={password}", null);
|
|
||||||
if (!loginResponse.IsSuccessStatusCode)
|
|
||||||
{
|
|
||||||
Console.WriteLine("Login failed with status code {StatusCode}", loginResponse.StatusCode);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
var loginData = await loginResponse.Content.ReadFromJsonAsync<LoginResponse>();
|
|
||||||
if (loginData?.Token is null)
|
|
||||||
{
|
|
||||||
Console.WriteLine("Login succeeded but token was missing");
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
var token = loginData.Token;
|
|
||||||
Console.WriteLine($"Token: {token}");
|
|
||||||
var installations = new List<Installation>();
|
|
||||||
|
|
||||||
var getInstallationsRequestResponse = await http.GetAsync($"GetAllInstallationsFromProduct?product=0&authToken={token}");
|
|
||||||
|
|
||||||
var newInstallations= await getInstallationsRequestResponse.Content.ReadFromJsonAsync<List<Installation>>();
|
|
||||||
if (newInstallations != null)
|
|
||||||
{
|
|
||||||
installations.AddRange(newInstallations);
|
|
||||||
}
|
|
||||||
|
|
||||||
getInstallationsRequestResponse = await http.GetAsync($"GetAllInstallationsFromProduct?product=1&authToken={token}");
|
|
||||||
newInstallations= await getInstallationsRequestResponse.Content.ReadFromJsonAsync<List<Installation>>();
|
|
||||||
if (newInstallations != null)
|
|
||||||
{
|
|
||||||
installations.AddRange(newInstallations);
|
|
||||||
}
|
|
||||||
|
|
||||||
getInstallationsRequestResponse = await http.GetAsync($"GetAllInstallationsFromProduct?product=2&authToken={token}");
|
|
||||||
newInstallations= await getInstallationsRequestResponse.Content.ReadFromJsonAsync<List<Installation>>();
|
|
||||||
if (newInstallations != null)
|
|
||||||
{
|
|
||||||
installations.AddRange(newInstallations);
|
|
||||||
}
|
|
||||||
|
|
||||||
getInstallationsRequestResponse = await http.GetAsync($"GetAllInstallationsFromProduct?product=3&authToken={token}");
|
|
||||||
newInstallations= await getInstallationsRequestResponse.Content.ReadFromJsonAsync<List<Installation>>();
|
|
||||||
if (newInstallations != null)
|
|
||||||
{
|
|
||||||
installations.AddRange(newInstallations);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//Console.WriteLine("Installations retrieved ",installations);
|
|
||||||
return installations;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -1,14 +0,0 @@
|
||||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
|
||||||
|
|
||||||
<PropertyGroup>
|
|
||||||
<TargetFramework>net7.0</TargetFramework>
|
|
||||||
<Nullable>enable</Nullable>
|
|
||||||
<ImplicitUsings>enable</ImplicitUsings>
|
|
||||||
</PropertyGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<PackageReference Include="Microsoft.OpenApi" Version="1.6.0" />
|
|
||||||
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.5.0" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
</Project>
|
|
||||||
|
|
@ -1,19 +0,0 @@
|
||||||
using Microsoft.AspNetCore.Builder;
|
|
||||||
|
|
||||||
namespace InnovEnergy.App.DataCollectorWebApp;
|
|
||||||
|
|
||||||
public static class Program
|
|
||||||
{
|
|
||||||
public static async Task Main(string[] args)
|
|
||||||
{
|
|
||||||
Console.WriteLine("Starting DataCollectorWebApp");
|
|
||||||
|
|
||||||
var builder = WebApplication.CreateBuilder(args);
|
|
||||||
|
|
||||||
builder.Services.AddControllers();
|
|
||||||
var app = builder.Build();
|
|
||||||
|
|
||||||
app.MapControllers();
|
|
||||||
await app.RunAsync();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -15,10 +15,10 @@ public partial class WITGrowatRecord
|
||||||
//public BatteriesRecord? BatteriesRecords => BatteriesRecord.FromBatteries(Batteries);
|
//public BatteriesRecord? BatteriesRecords => BatteriesRecord.FromBatteries(Batteries);
|
||||||
|
|
||||||
|
|
||||||
public ActivePower ConsumptionPower => MeterPower + InverterActivePower ;
|
public ActivePower ConsumptionPower => GridPower + InverterActivePower ;
|
||||||
public ActivePower InverterActivePower => _ActivePower;
|
public ActivePower InverterActivePower => _activePower;
|
||||||
public ReactivePower InverterReactivePower => _ReactivePower;
|
public ReactivePower InverterReactivePower => _reactivePower;
|
||||||
public Frequency Frequency => _Frequency;
|
public Frequency Frequency => _frequency;
|
||||||
|
|
||||||
public VoltageRms GridAbLineVoltage => _GridAbLineVoltage;
|
public VoltageRms GridAbLineVoltage => _GridAbLineVoltage;
|
||||||
public VoltageRms GridBcLineVoltage => _GridBcLineVoltage;
|
public VoltageRms GridBcLineVoltage => _GridBcLineVoltage;
|
||||||
|
|
@ -27,7 +27,7 @@ public partial class WITGrowatRecord
|
||||||
public CurrentRms PhaseBCurrent => _PhaseBCurrent;
|
public CurrentRms PhaseBCurrent => _PhaseBCurrent;
|
||||||
public CurrentRms PhaseCCurrent => _PhaseCCurrent;
|
public CurrentRms PhaseCCurrent => _PhaseCCurrent;
|
||||||
|
|
||||||
public ActivePower MeterPower => _importedPowerFromGrid - _exportedPowerToGrid;
|
public ActivePower GridPower => _importedPowerFromGrid - _exportedPowerToGrid;
|
||||||
public ActivePower ExportedPowerToGridMeter => _exportedPowerToGrid;
|
public ActivePower ExportedPowerToGridMeter => _exportedPowerToGrid;
|
||||||
public ActivePower ImportedPowerFromGrid => _importedPowerFromGrid;
|
public ActivePower ImportedPowerFromGrid => _importedPowerFromGrid;
|
||||||
|
|
||||||
|
|
@ -38,34 +38,33 @@ public partial class WITGrowatRecord
|
||||||
public Energy EnergyToGrid => _EnergyToGrid;
|
public Energy EnergyToGrid => _EnergyToGrid;
|
||||||
public Energy TotalEnergyToGrid => _TotalEnergyToGrid;
|
public Energy TotalEnergyToGrid => _TotalEnergyToGrid;
|
||||||
|
|
||||||
public GrowattSystemStatus SystemOperatingMode => (GrowattSystemStatus)_SystemOperatingMode;
|
public GrowattSystemStatus SystemOperatingMode => (GrowattSystemStatus)_systemOperatingMode;
|
||||||
public BatteryoperatinStatus BatteryOperatingMode => (BatteryoperatinStatus) _BatteryOperatingMode;
|
public BatteryoperatinStatus BatteryOperatingMode => (BatteryoperatinStatus) _batteryOperatingMode;
|
||||||
public OperatingPriority OperatingPriority => (OperatingPriority)_OperatingPriority;
|
public OperatingPriority OperatingMode => (OperatingPriority)_operatingPriority;
|
||||||
|
|
||||||
public UInt16 FaultMainCode => _FaultMainCode; // need to pre proceesed
|
public UInt16 FaultMainCode => _faultMainCode; // need to pre proceesed
|
||||||
public UInt16 FaultSubCode => _FaultSubCode; // need to pre proceesed
|
public UInt16 FaultSubCode => _faultSubCode; // need to pre proceesed
|
||||||
public UInt16 WarningMainCode => _WarningMainCode; // need to pre proceesed
|
public UInt16 WarningMainCode => _warningMainCode; // need to pre proceesed
|
||||||
public UInt16 WarningSubCode => _WarningSubCode; // need to pre proceesed
|
public UInt16 WarningSubCode => _warningSubCode; // need to pre proceesed
|
||||||
|
|
||||||
public Voltage Pv1Voltage => _Pv1Voltage;
|
public Voltage Pv1Voltage => _pv1Voltage;
|
||||||
public Current Pv1Current => _Pv1Current;
|
public Current Pv1Current => _pv1Current;
|
||||||
public Voltage Pv2Voltage => _Pv2Voltage;
|
public Voltage Pv2Voltage => _pv2Voltage;
|
||||||
public Current Pv2Current => _Pv2Current;
|
public Current Pv2Current => _pv2Current;
|
||||||
public Voltage Pv3Voltage => _Pv3Voltage;
|
public Voltage Pv3Voltage => _pv3Voltage;
|
||||||
public Current Pv3Current => _Pv3Current;
|
public Current Pv3Current => _pv3Current;
|
||||||
public Voltage Pv4Voltage => _Pv4Voltage;
|
public Voltage Pv4Voltage => _pv4Voltage;
|
||||||
public Current Pv4Current => _Pv4Current;
|
public Current Pv4Current => _pv4Current;
|
||||||
public Voltage Pv5Voltage => _Pv5Voltage;
|
public Voltage Pv5Voltage => _pv5Voltage;
|
||||||
public Current Pv5Current => _Pv5Current;
|
public Current Pv5Current => _pv5Current;
|
||||||
public Voltage Pv6Voltage => _Pv6Voltage;
|
public Voltage Pv6Voltage => _pv6Voltage;
|
||||||
public Current Pv6Current => _Pv6Current;
|
public Current Pv6Current => _pv6Current;
|
||||||
|
|
||||||
|
|
||||||
public DcPower Pv1InpuPower => _Pv1InpuPower;
|
public DcPower Pv1InpuPower => _pv1InpuPower;
|
||||||
|
|
||||||
|
|
||||||
|
public DcPower PvPower => (Pv1Voltage * Pv1Current) + (Pv2Voltage * Pv2Current) +
|
||||||
public DcPower TotalPvPower => (Pv1Voltage * Pv1Current) + (Pv2Voltage * Pv2Current) +
|
|
||||||
(Pv3Voltage * Pv3Current) + (Pv4Voltage * Pv4Current) +
|
(Pv3Voltage * Pv3Current) + (Pv4Voltage * Pv4Current) +
|
||||||
(Pv5Voltage * Pv5Current) + (Pv6Voltage * Pv6Current);
|
(Pv5Voltage * Pv5Current) + (Pv6Voltage * Pv6Current);
|
||||||
// ********************************** Holding Registers (Control) *************************************************************
|
// ********************************** Holding Registers (Control) *************************************************************
|
||||||
|
|
@ -173,16 +172,16 @@ public partial class WITGrowatRecord
|
||||||
set => _BatteryMaxDischargePower = value;
|
set => _BatteryMaxDischargePower = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Percent ChargeCutoffSoc
|
public Percent ChargeCutoffSocVoltage
|
||||||
{
|
{
|
||||||
get => _ChargeCutoffSoc;
|
get => _BatteryChargeCutoffVoltage;
|
||||||
set => _ChargeCutoffSoc = (UInt16)value;
|
set => _BatteryChargeCutoffVoltage = (UInt16)value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Percent DischargeCutoffSoc
|
public Percent DischargeCutoffVoltage
|
||||||
{
|
{
|
||||||
get => _DischargeCutoffSoc;
|
get => _BatteryDischargeCutoffVoltage;
|
||||||
set => _DischargeCutoffSoc = (UInt16)value;
|
set => _BatteryDischargeCutoffVoltage = (UInt16)value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Percent LoadPriorityDischargeCutoffSoc
|
public Percent LoadPriorityDischargeCutoffSoc
|
||||||
|
|
@ -226,98 +225,61 @@ public partial class WITGrowatRecord
|
||||||
set => _OffGridDischargeCutoffSoc = (UInt16)(value);
|
set => _OffGridDischargeCutoffSoc = (UInt16)(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public UInt16 BatteryChargeCutoffVoltage
|
public UInt16 MaxSoc
|
||||||
{
|
{
|
||||||
get => _BatteryChargeCutoffVoltage;
|
get => _maxSoc;
|
||||||
set => _BatteryChargeCutoffVoltage = value;
|
set => _maxSoc = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public UInt16 BatteryDischargeCutoffVoltage
|
public UInt16 MinSoc
|
||||||
{
|
{
|
||||||
get => _BatteryDischargeCutoffVoltage;
|
get => _minSoc;
|
||||||
set => _BatteryDischargeCutoffVoltage = value;
|
set => _minSoc = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Double BatteryMaxChargeCurrent
|
public Double BatteryMaxChargingCurrent
|
||||||
{
|
{
|
||||||
get => _BatteryMaxChargeCurrent;
|
get => _batteryMaxChargingCurrent;
|
||||||
set => _BatteryMaxChargeCurrent = (UInt16)value;
|
set => _batteryMaxChargingCurrent = (UInt16)value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Double BatteryMaxdischargeCurrent
|
public Double BatteryMaxDischargingCurrent
|
||||||
{
|
{
|
||||||
get => _BatteryMaxdischargeCurrent;
|
get => _batteryMaxDischargingCurrent;
|
||||||
set => _BatteryMaxdischargeCurrent = (UInt16) value;
|
set => _batteryMaxDischargingCurrent = (UInt16) value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Double Battery1MaxDischargingCurrent => _batteryMaxDischargingCurrent;
|
||||||
|
|
||||||
|
public Double Battery1MaxChargingCurrent => _batteryMaxChargingCurrent;
|
||||||
|
|
||||||
|
public Percent Battery1Soc => _BatterySoc1;
|
||||||
|
public Percent Battery1Soh => _BatterySoh1;
|
||||||
|
public Current Battery1Current => _BatteryCurrent1;
|
||||||
|
public Voltage Battery1Voltage => _BatteryVoltage1;
|
||||||
|
public ActivePower Battery1Power => _BatteryPower1;
|
||||||
|
public ActivePower Battery1MaxAllowableChargePower => _BatteryMaxAllowableChargePower1;
|
||||||
|
public ActivePower Battery1MaxAllowableDischargePower => _BatteryMaxAllowableDischargePower1;
|
||||||
|
public Energy Battery1DailyChargeEnergy => _DailyChargeEnergy1;
|
||||||
|
public Energy Battery1DailyDischargeEnergy => _DailyDischargeEnergy1;
|
||||||
|
public Energy Battery1AccumulatedChargeEnergy => _AccumulatedChargeEnergy1;
|
||||||
|
public Energy Battery1AccumulatedDischargeEnergy => _AccumulatedDishargeEnergy1;
|
||||||
|
public Temperature Battery1AmbientTemperature => _BatteryAmbientTemperature1;
|
||||||
|
|
||||||
public IReadOnlyList<BatteryRecord> Batteries => new List<BatteryRecord>
|
public Percent Battery2Soc => _BatterySoc2;
|
||||||
{
|
public Percent Battery2Soh => _BatterySoh2;
|
||||||
new BatteryRecord
|
public Current Battery2Current => _BatteryCurrent2;
|
||||||
{
|
public Voltage Battery2Voltage => _BatteryVoltage2;
|
||||||
Soc = _BatterySoc1,
|
public ActivePower Battery2Power => _batteryPower2;
|
||||||
Soh = _BatterySoh1,
|
public ActivePower Battery2MaxAllowableChargePower => _BatteryMaxAllowableChargePower2;
|
||||||
//ClusterTotalNumber = _ClusterTotalNumber1,
|
public ActivePower Battery2MaxAllowableDischargePower => _BatteryMaxAllowableDischargePower2;
|
||||||
Current = _BatteryCurrent1,
|
public Energy Battery2DailyChargeEnergy => _DailyChargeEnergy2;
|
||||||
Voltage = _BatteryVoltage1,
|
public Energy Battery2DailyDischargeEnergy => _DailyDischargeEnergy2;
|
||||||
Power = _BatteryPower1,
|
public Energy Battery2AccumulatedChargeEnergy => _AccumulatedChargeEnergy2;
|
||||||
MaxAllowableChargePower = _BatteryMaxAllowableChargePower1,
|
public Energy Battery2AccumulatedDischargeEnergy => _AccumulatedDischargeEnergy2;
|
||||||
MaxAllowableDischargePower = _BatteryMaxAllowableDischargePower1,
|
public Temperature Battery2AmbientTemperature => _BatteryAmbientTemperature2;
|
||||||
DailyChargeEnergy = _DailyChargeEnergy1,
|
|
||||||
DailyDischargeEnergy = _DailyDischargeEnergy1,
|
|
||||||
AccumulatedChargeEnergy = _AccumulatedChargeEnergy1,
|
|
||||||
AccumulatedDischargeEnergy = _AccumulatedDishargeEnergy1,
|
|
||||||
BatteryAmbientTemperature = _BatteryAmbientTemperature1
|
|
||||||
|
|
||||||
}
|
public Energy BatteryDailyChargeEnergy => _DailyChargeEnergy1 + _DailyChargeEnergy2;
|
||||||
/*
|
public Energy BatteryDailyDischargeEnergy => _DailyDischargeEnergy1 + _DailyDischargeEnergy2;
|
||||||
new BatteryRecord
|
|
||||||
{
|
|
||||||
Soc = _BatterySoc2,
|
|
||||||
Soh = _BatterySoh2,
|
|
||||||
// ClusterTotalNumber = _ClusterTotalNumber2,
|
|
||||||
Current = _BatteryCurrent2,
|
|
||||||
Voltage = _BatteryVoltage2,
|
|
||||||
Power = _BatteryPower2,
|
|
||||||
MaxAllowableChargePower = _BatteryMaxAllowableChargePower2,
|
|
||||||
MaxAllowableDischargePower = _BatteryMaxAllowableDischargePower2,
|
|
||||||
DailyChargeEnergy = _DailyChargeEnergy2,
|
|
||||||
DailyDischargeEnergy = _DailyDischargeEnergy2,
|
|
||||||
AccumulatedChargeEnergy = _AccumulatedChargeEnergy2,
|
|
||||||
AccumulatedDischargeEnergy = _AccumulatedDischargeEnergy2,
|
|
||||||
BatteryAmbientTemperature = _BatteryAmbientTemperature2
|
|
||||||
|
|
||||||
},*/
|
|
||||||
/*
|
|
||||||
new BatteryRecord
|
|
||||||
{
|
|
||||||
Soc = _BatterySoc3,
|
|
||||||
Soh = _BatterySoh3,
|
|
||||||
ClusterTotalNumber = _ClusterTotalNumber3,
|
|
||||||
Current = _BatteryCurrent3,
|
|
||||||
Voltage = _BatteryVoltage3,
|
|
||||||
Power = _BatteryPower3,
|
|
||||||
MaxAllowableChargePower = _BatteryMaxAllowableChargePower3,
|
|
||||||
MaxAllowableDischargePower = _BatteryMaxAllowableDischargePower3,
|
|
||||||
DailyChargeEnergy = _DailyChargeEnergy3,
|
|
||||||
DailyDischargeEnergy = _DailyDischargeEnergy3
|
|
||||||
},
|
|
||||||
|
|
||||||
new BatteryRecord
|
|
||||||
{
|
|
||||||
Soc = _BatterySoc4,
|
|
||||||
Soh = _BatterySoh4,
|
|
||||||
ClusterTotalNumber = _ClusterTotalNumber4,
|
|
||||||
Current = _BatteryCurrent4,
|
|
||||||
Voltage = _BatteryVoltage4,
|
|
||||||
Power = _BatteryPower4,
|
|
||||||
MaxAllowableChargePower = _BatteryMaxAllowableChargePower4,
|
|
||||||
MaxAllowableDischargePower = _BatteryMaxAllowableDischargePower4,
|
|
||||||
DailyChargeEnergy = _DailyChargeEnergy4,
|
|
||||||
DailyDischargeEnergy = _DailyDischargeEnergy4
|
|
||||||
}*/
|
|
||||||
};
|
|
||||||
public BatteriesRecord? BatteriesRecords => BatteriesRecord.FromBatteries(Batteries);
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,36 +14,36 @@ public partial class WITGrowatRecord
|
||||||
[InputRegister<Int32>(8083, Scale = 0.1)] private Int32 _exportedPowerToGrid;
|
[InputRegister<Int32>(8083, Scale = 0.1)] private Int32 _exportedPowerToGrid;
|
||||||
|
|
||||||
// 31000–31009 — Operating Status Info
|
// 31000–31009 — Operating Status Info
|
||||||
[InputRegister(31000)] private UInt16 _SystemOperatingMode;
|
[InputRegister(31000)] private UInt16 _systemOperatingMode;
|
||||||
[InputRegister(31001)] private UInt16 _BatteryOperatingMode;
|
[InputRegister(31001)] private UInt16 _batteryOperatingMode;
|
||||||
[InputRegister(31002)] private UInt16 _OperatingPriority;
|
[InputRegister(31002)] private UInt16 _operatingPriority;
|
||||||
[InputRegister(31003)] private UInt16 _Reserved1;
|
[InputRegister(31003)] private UInt16 _reserved1;
|
||||||
[InputRegister(31004)] private UInt16 _Reserved2;
|
[InputRegister(31004)] private UInt16 _reserved2;
|
||||||
[InputRegister(31005)] private UInt16 _FaultMainCode;// Can we change this to warning?
|
[InputRegister(31005)] private UInt16 _faultMainCode;// Can we change this to warning?
|
||||||
[InputRegister(31006)] private UInt16 _FaultSubCode; // Can we change this to warning?
|
[InputRegister(31006)] private UInt16 _faultSubCode; // Can we change this to warning?
|
||||||
[InputRegister(31007)] private UInt16 _WarningMainCode;
|
[InputRegister(31007)] private UInt16 _warningMainCode;
|
||||||
[InputRegister(31008)] private UInt16 _WarningSubCode;
|
[InputRegister(31008)] private UInt16 _warningSubCode;
|
||||||
[InputRegister(31009)] private UInt16 _Reserved3;
|
[InputRegister(31009)] private UInt16 _reserved3;
|
||||||
// 31010–31099 — PV Parameters
|
// 31010–31099 — PV Parameters
|
||||||
[InputRegister(31010,Scale = 0.1)] private Int16 _Pv1Voltage;
|
[InputRegister(31010,Scale = 0.1)] private Int16 _pv1Voltage;
|
||||||
[InputRegister(31011,Scale = 0.1)] private Int16 _Pv1Current;
|
[InputRegister(31011,Scale = 0.1)] private Int16 _pv1Current;
|
||||||
[InputRegister(31012,Scale = 0.1)] private Int16 _Pv2Voltage;
|
[InputRegister(31012,Scale = 0.1)] private Int16 _pv2Voltage;
|
||||||
[InputRegister(31013,Scale = 0.1)] private Int16 _Pv2Current;
|
[InputRegister(31013,Scale = 0.1)] private Int16 _pv2Current;
|
||||||
[InputRegister(31014,Scale = 0.1)] private Int16 _Pv3Voltage;
|
[InputRegister(31014,Scale = 0.1)] private Int16 _pv3Voltage;
|
||||||
[InputRegister(31015,Scale = 0.1)] private Int16 _Pv3Current;
|
[InputRegister(31015,Scale = 0.1)] private Int16 _pv3Current;
|
||||||
[InputRegister(31016,Scale = 0.1)] private Int16 _Pv4Voltage;
|
[InputRegister(31016,Scale = 0.1)] private Int16 _pv4Voltage;
|
||||||
[InputRegister(31017,Scale = 0.1)] private Int16 _Pv4Current;
|
[InputRegister(31017,Scale = 0.1)] private Int16 _pv4Current;
|
||||||
[InputRegister(31018,Scale = 0.1)] private Int16 _Pv5Voltage;
|
[InputRegister(31018,Scale = 0.1)] private Int16 _pv5Voltage;
|
||||||
[InputRegister(31019,Scale = 0.1)] private Int16 _Pv5Current;
|
[InputRegister(31019,Scale = 0.1)] private Int16 _pv5Current;
|
||||||
[InputRegister(31020,Scale = 0.1)] private Int16 _Pv6Voltage;
|
[InputRegister(31020,Scale = 0.1)] private Int16 _pv6Voltage;
|
||||||
[InputRegister(31021,Scale = 0.1)] private Int16 _Pv6Current;
|
[InputRegister(31021,Scale = 0.1)] private Int16 _pv6Current;
|
||||||
[InputRegister(31058)] private Int16 _Pv1InpuPower;
|
[InputRegister(31058)] private Int16 _pv1InpuPower;
|
||||||
|
|
||||||
//— AC Side 31100 - 31199
|
//— AC Side 31100 - 31199
|
||||||
[InputRegister<Int32>(31100, Scale = 0.1)] private Int32 _ActivePower; // Positive: feed to grid, Negative: draw from the grid
|
[InputRegister<Int32>(31100, Scale = 0.1)] private Int32 _activePower; // Positive: feed to grid, Negative: draw from the grid
|
||||||
[InputRegister<Int32>(31102, Scale = 0.1)] private Int32 _ReactivePower; // Positive: capacitive, Negative: Inductive
|
[InputRegister<Int32>(31102, Scale = 0.1)] private Int32 _reactivePower; // Positive: capacitive, Negative: Inductive
|
||||||
[InputRegister(31104, Scale = 0.1)] private Int16 _Reserved4;
|
[InputRegister(31104, Scale = 0.1)] private Int16 _reserved4;
|
||||||
[InputRegister(31105, Scale = 0.01)] private UInt16 _Frequency;
|
[InputRegister(31105, Scale = 0.01)] private UInt16 _frequency;
|
||||||
|
|
||||||
[InputRegister(31106, Scale = 0.1)] private UInt16 _GridAbLineVoltage;
|
[InputRegister(31106, Scale = 0.1)] private UInt16 _GridAbLineVoltage;
|
||||||
[InputRegister(31107, Scale = 0.1)] private UInt16 _GridBcLineVoltage;
|
[InputRegister(31107, Scale = 0.1)] private UInt16 _GridBcLineVoltage;
|
||||||
|
|
@ -88,7 +88,7 @@ public partial class WITGrowatRecord
|
||||||
|
|
||||||
|
|
||||||
// 31300–31399 — Second Battery Cluster Info (incl. BDC and BMS)
|
// 31300–31399 — Second Battery Cluster Info (incl. BDC and BMS)
|
||||||
/* [InputRegister<Int32>(31300)] private Int32 _BatteryPower2; // positive Charge, Negative Discharge
|
[InputRegister<Int32>(31300)] private Int32 _batteryPower2; // positive Charge, Negative Discharge
|
||||||
[InputRegister<UInt32>(31302)] private UInt32 _DailyChargeEnergy2;
|
[InputRegister<UInt32>(31302)] private UInt32 _DailyChargeEnergy2;
|
||||||
[InputRegister<UInt32>(31304)] private UInt32 _AccumulatedChargeEnergy2;
|
[InputRegister<UInt32>(31304)] private UInt32 _AccumulatedChargeEnergy2;
|
||||||
[InputRegister<UInt32>(31206)] private UInt32 _DailyDischargeEnergy2; //0.1kw
|
[InputRegister<UInt32>(31206)] private UInt32 _DailyDischargeEnergy2; //0.1kw
|
||||||
|
|
@ -171,8 +171,8 @@ public partial class WITGrowatRecord
|
||||||
|
|
||||||
[HoldingRegister<UInt32>(30400 , writable: true)] private UInt32 _BatteryMaxChargePower; //
|
[HoldingRegister<UInt32>(30400 , writable: true)] private UInt32 _BatteryMaxChargePower; //
|
||||||
[HoldingRegister<UInt32>(30402 , writable: true)] private UInt32 _BatteryMaxDischargePower; //
|
[HoldingRegister<UInt32>(30402 , writable: true)] private UInt32 _BatteryMaxDischargePower; //
|
||||||
[HoldingRegister(30404, writable: true)] private UInt16 _ChargeCutoffSoc; //
|
[HoldingRegister(30404, writable: true)] private UInt16 _maxSoc; //
|
||||||
[HoldingRegister(30405, writable: true)] private UInt16 _DischargeCutoffSoc; //
|
[HoldingRegister(30405, writable: true)] private UInt16 _minSoc; //
|
||||||
[HoldingRegister(30406, writable: true)] private UInt16 _LoadPriorityDischargeCutoffSoc; //
|
[HoldingRegister(30406, writable: true)] private UInt16 _LoadPriorityDischargeCutoffSoc; //
|
||||||
[HoldingRegister(30407, writable: true)] private Boolean _RemotePowerControl; //
|
[HoldingRegister(30407, writable: true)] private Boolean _RemotePowerControl; //
|
||||||
[HoldingRegister(30408, writable: true)] private UInt16 _RemotePowerControlChargeDuration; //
|
[HoldingRegister(30408, writable: true)] private UInt16 _RemotePowerControlChargeDuration; //
|
||||||
|
|
@ -184,6 +184,6 @@ public partial class WITGrowatRecord
|
||||||
|
|
||||||
[HoldingRegister(30496, writable: true, Scale = 0.1)] private UInt16 _BatteryChargeCutoffVoltage; //
|
[HoldingRegister(30496, writable: true, Scale = 0.1)] private UInt16 _BatteryChargeCutoffVoltage; //
|
||||||
[HoldingRegister(30497, writable: true, Scale = 0.1)] private UInt16 _BatteryDischargeCutoffVoltage; //
|
[HoldingRegister(30497, writable: true, Scale = 0.1)] private UInt16 _BatteryDischargeCutoffVoltage; //
|
||||||
[HoldingRegister(30498, writable: true, Scale = 0.1)] private UInt16 _BatteryMaxChargeCurrent; //
|
[HoldingRegister(30498, writable: true, Scale = 0.1)] private UInt16 _batteryMaxChargingCurrent; //
|
||||||
[HoldingRegister(30499, writable: true, Scale = 0.1)] private UInt16 _BatteryMaxdischargeCurrent; //*/
|
[HoldingRegister(30499, writable: true, Scale = 0.1)] private UInt16 _batteryMaxDischargingCurrent; //*/
|
||||||
}
|
}
|
||||||
|
|
@ -41,7 +41,7 @@ public class ModbusDevice<[DynamicallyAccessedMembers(All)] R> where R : notnull
|
||||||
foreach (var batch in _Batches)
|
foreach (var batch in _Batches)
|
||||||
{
|
{
|
||||||
batch.Read(record);
|
batch.Read(record);
|
||||||
Thread.Sleep(30); // this added mainly for Growatt reading
|
//Thread.Sleep(30); // this added mainly for Growatt reading
|
||||||
}
|
}
|
||||||
return record;
|
return record;
|
||||||
}
|
}
|
||||||
|
|
@ -51,7 +51,7 @@ public class ModbusDevice<[DynamicallyAccessedMembers(All)] R> where R : notnull
|
||||||
foreach (var batch in _Batches)
|
foreach (var batch in _Batches)
|
||||||
{
|
{
|
||||||
batch.Write(record);
|
batch.Write(record);
|
||||||
Thread.Sleep(50); // this added mainly for Growatt reading
|
//Thread.Sleep(50); // this added mainly for Growatt reading
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -0,0 +1,14 @@
|
||||||
|
namespace InnovEnergy.Lib.Devices.Sinexcel_12K_TL.DataType;
|
||||||
|
|
||||||
|
public enum SinexcelWeekDays : byte
|
||||||
|
{
|
||||||
|
None = 0b00000000,
|
||||||
|
Sunday = 0b00000001,
|
||||||
|
Monday = 0b00000010,
|
||||||
|
Tuesday = 0b00000100,
|
||||||
|
Wednesday= 0b00001000,
|
||||||
|
Thursday = 0b00010000,
|
||||||
|
Friday = 0b00100000,
|
||||||
|
Saturday = 0b01000000,
|
||||||
|
All = 0b01111111
|
||||||
|
}
|
||||||
|
|
@ -1,5 +1,3 @@
|
||||||
using System.Diagnostics.CodeAnalysis;
|
|
||||||
using System.Globalization;
|
|
||||||
using InnovEnergy.Lib.Devices.Sinexcel_12K_TL.DataType;
|
using InnovEnergy.Lib.Devices.Sinexcel_12K_TL.DataType;
|
||||||
using InnovEnergy.Lib.Units;
|
using InnovEnergy.Lib.Units;
|
||||||
using InnovEnergy.Lib.Units.Power;
|
using InnovEnergy.Lib.Units.Power;
|
||||||
|
|
@ -9,6 +7,7 @@ namespace InnovEnergy.Lib.Devices.Sinexcel_12K_TL;
|
||||||
public partial class SinexcelRecord
|
public partial class SinexcelRecord
|
||||||
{
|
{
|
||||||
|
|
||||||
|
private Int16 _factorFromKwtoW = 1000;
|
||||||
// ───────────────────────────────────────────────
|
// ───────────────────────────────────────────────
|
||||||
// Public API — Decoded Float Values
|
// Public API — Decoded Float Values
|
||||||
// ───────────────────────────────────────────────
|
// ───────────────────────────────────────────────
|
||||||
|
|
@ -30,17 +29,17 @@ public partial class SinexcelRecord
|
||||||
public Current GridCPhaseCurrent => UIntToFloat(_grid_C_Phase_Current);
|
public Current GridCPhaseCurrent => UIntToFloat(_grid_C_Phase_Current);
|
||||||
public Current GridNWireCurrent => UIntToFloat(_grid_N_Wire_Current);
|
public Current GridNWireCurrent => UIntToFloat(_grid_N_Wire_Current);
|
||||||
|
|
||||||
public ApparentPower GridAPhaseApparentPower => UIntToFloat(_gridAPhaseApparentPower);
|
public ApparentPower GridAPhaseApparentPower => UIntToFloat(_gridAPhaseApparentPower) * _factorFromKwtoW;
|
||||||
public ApparentPower GridBPhaseApparentPower => UIntToFloat(_gridBPhaseApparentPower);
|
public ApparentPower GridBPhaseApparentPower => UIntToFloat(_gridBPhaseApparentPower) * _factorFromKwtoW;
|
||||||
public ApparentPower GridCPhaseApparentPower => UIntToFloat(_gridCPhaseApparentPower);
|
public ApparentPower GridCPhaseApparentPower => UIntToFloat(_gridCPhaseApparentPower) * _factorFromKwtoW;
|
||||||
|
|
||||||
public ActivePower GridAPhaseActivePower => UIntToFloat(_gridAPhaseActivePower);
|
public ActivePower GridAPhaseActivePower => UIntToFloat(_gridAPhaseActivePower) * _factorFromKwtoW;
|
||||||
public ActivePower GridBPhaseActivePower => UIntToFloat(_gridBPhaseActivePower);
|
public ActivePower GridBPhaseActivePower => UIntToFloat(_gridBPhaseActivePower) * _factorFromKwtoW;
|
||||||
public ActivePower GridCPhaseActivePower => UIntToFloat(_gridCPhaseActivePower);
|
public ActivePower GridCPhaseActivePower => UIntToFloat(_gridCPhaseActivePower) * _factorFromKwtoW;
|
||||||
|
|
||||||
public ReactivePower GridAPhaseReactivePower => UIntToFloat(_gridAPhaseReactivePower);
|
public ReactivePower GridAPhaseReactivePower => UIntToFloat(_gridAPhaseReactivePower) * _factorFromKwtoW;
|
||||||
public ReactivePower GridBPhaseReactivePower => UIntToFloat(_gridBPhaseReactivePower);
|
public ReactivePower GridBPhaseReactivePower => UIntToFloat(_gridBPhaseReactivePower) * _factorFromKwtoW;
|
||||||
public ReactivePower GridCPhaseReactivePower => UIntToFloat(_gridCPhaseReactivePower);
|
public ReactivePower GridCPhaseReactivePower => UIntToFloat(_gridCPhaseReactivePower) * _factorFromKwtoW;
|
||||||
|
|
||||||
// ───────────────────────────────────────────────
|
// ───────────────────────────────────────────────
|
||||||
// Load Measurements
|
// Load Measurements
|
||||||
|
|
@ -60,17 +59,19 @@ public partial class SinexcelRecord
|
||||||
public Current LoadCPhaseCurrent => UIntToFloat(_loadCPhaseCurrent);
|
public Current LoadCPhaseCurrent => UIntToFloat(_loadCPhaseCurrent);
|
||||||
public Current LoadNWireCurrent => UIntToFloat(_loadNWireCurrent);
|
public Current LoadNWireCurrent => UIntToFloat(_loadNWireCurrent);
|
||||||
|
|
||||||
public ApparentPower LoadAPhaseApparentPower => UIntToFloat(_loadAPhaseApparentPower);
|
public ApparentPower LoadAPhaseApparentPower => UIntToFloat(_loadAPhaseApparentPower) * _factorFromKwtoW;
|
||||||
public ApparentPower LoadBPhaseApparentPower => UIntToFloat(_loadBPhaseApparentPower);
|
public ApparentPower LoadBPhaseApparentPower => UIntToFloat(_loadBPhaseApparentPower) * _factorFromKwtoW;
|
||||||
public ApparentPower LoadCPhaseApparentPower => UIntToFloat(_loadCPhaseApparentPower);
|
public ApparentPower LoadCPhaseApparentPower => UIntToFloat(_loadCPhaseApparentPower) * _factorFromKwtoW;
|
||||||
|
|
||||||
public ActivePower LoadAPhaseActivePower => UIntToFloat(_loadAPhaseActivePower);
|
public ActivePower LoadAPhaseActivePower => UIntToFloat(_loadAPhaseActivePower) * _factorFromKwtoW;
|
||||||
public ActivePower LoadBPhaseActivePower => UIntToFloat(_loadBPhaseActivePower);
|
public ActivePower LoadBPhaseActivePower => UIntToFloat(_loadBPhaseActivePower) * _factorFromKwtoW;
|
||||||
public ActivePower LoadCPhaseActivePower => UIntToFloat(_loadCPhaseActivePower);
|
public ActivePower LoadCPhaseActivePower => UIntToFloat(_loadCPhaseActivePower) * _factorFromKwtoW;
|
||||||
|
|
||||||
public ReactivePower LoadAPhaseReactivePower => UIntToFloat(_loadAPhaseReactivePower);
|
public ActivePower ConsumptionPower => TotalLoadPower;
|
||||||
public ReactivePower LoadBPhaseReactivePower => UIntToFloat(_loadBPhaseReactivePower);
|
|
||||||
public ReactivePower LoadCPhaseReactivePower => UIntToFloat(_loadCPhaseReactivePower);
|
public ReactivePower LoadAPhaseReactivePower => UIntToFloat(_loadAPhaseReactivePower) * _factorFromKwtoW;
|
||||||
|
public ReactivePower LoadBPhaseReactivePower => UIntToFloat(_loadBPhaseReactivePower) * _factorFromKwtoW;
|
||||||
|
public ReactivePower LoadCPhaseReactivePower => UIntToFloat(_loadCPhaseReactivePower) * _factorFromKwtoW;
|
||||||
|
|
||||||
// ───────────────────────────────────────────────
|
// ───────────────────────────────────────────────
|
||||||
// Inverter Measurements
|
// Inverter Measurements
|
||||||
|
|
@ -83,9 +84,11 @@ public partial class SinexcelRecord
|
||||||
public Voltage InverterBcWireVoltage => UIntToFloat(_inverterBCWireVoltage);
|
public Voltage InverterBcWireVoltage => UIntToFloat(_inverterBCWireVoltage);
|
||||||
public Voltage InverterCaWireVoltage => UIntToFloat(_inverterCAWireVoltage);
|
public Voltage InverterCaWireVoltage => UIntToFloat(_inverterCAWireVoltage);
|
||||||
|
|
||||||
public ActivePower InverterAPhaseActivePower => UIntToFloat(_inverterAPhaseActivePower);
|
public ActivePower InverterAPhaseActivePower => UIntToFloat(_inverterAPhaseActivePower) * _factorFromKwtoW;
|
||||||
public ActivePower InverterBPhaseActivePower => UIntToFloat(_inverterBPhaseActivePower);
|
public ActivePower InverterBPhaseActivePower => UIntToFloat(_inverterBPhaseActivePower) * _factorFromKwtoW;
|
||||||
public ActivePower InverterCPhaseActivePower => UIntToFloat(_inverterCPhaseActivePower);
|
public ActivePower InverterCPhaseActivePower => UIntToFloat(_inverterCPhaseActivePower) * _factorFromKwtoW;
|
||||||
|
|
||||||
|
public ActivePower InverterActivePower => InverterAPhaseActivePower + InverterBPhaseActivePower + InverterCPhaseActivePower;
|
||||||
|
|
||||||
// ───────────────────────────────────────────────
|
// ───────────────────────────────────────────────
|
||||||
// DC/AC Temperature Sensors (°C)
|
// DC/AC Temperature Sensors (°C)
|
||||||
|
|
@ -99,12 +102,14 @@ public partial class SinexcelRecord
|
||||||
// ───────────────────────────────────────────────
|
// ───────────────────────────────────────────────
|
||||||
// Date / Time Information
|
// Date / Time Information
|
||||||
// ───────────────────────────────────────────────
|
// ───────────────────────────────────────────────
|
||||||
public Single Year => UIntToFloat(_year);
|
public UInt16 Year => (UInt16) ConvertBitPatternToFloat(_year);
|
||||||
public Single Month => UIntToFloat(_month);
|
public UInt16 Month => (UInt16) ConvertBitPatternToFloat(_month);
|
||||||
public Single Day => UIntToFloat(_day);
|
public UInt16 Day => (UInt16) ConvertBitPatternToFloat(_day);
|
||||||
public Single Hour => UIntToFloat(_hour);
|
public UInt16 Hour => (UInt16) ConvertBitPatternToFloat(_hour);
|
||||||
public Single Minute => UIntToFloat(_minute);
|
public UInt16 Minute => (UInt16) ConvertBitPatternToFloat(_minute);
|
||||||
public Single Second => UIntToFloat(_second);
|
public UInt16 Second => (UInt16) ConvertBitPatternToFloat(_second);
|
||||||
|
|
||||||
|
public DateTime SystemDateTime => new(Year, Month, Day, Hour, Minute, Second);
|
||||||
|
|
||||||
// ───────────────────────────────────────────────
|
// ───────────────────────────────────────────────
|
||||||
// Diesel Generator Measurements
|
// Diesel Generator Measurements
|
||||||
|
|
@ -112,9 +117,9 @@ public partial class SinexcelRecord
|
||||||
public Voltage DieselGenAPhaseVoltage => ConvertBitPatternToFloat(_dieselGenAPhaseVoltage);
|
public Voltage DieselGenAPhaseVoltage => ConvertBitPatternToFloat(_dieselGenAPhaseVoltage);
|
||||||
public Voltage DieselGenBPhaseVoltage => ConvertBitPatternToFloat(_dieselGenBPhaseVoltage);
|
public Voltage DieselGenBPhaseVoltage => ConvertBitPatternToFloat(_dieselGenBPhaseVoltage);
|
||||||
public Voltage DieselGenCPhaseVoltage => ConvertBitPatternToFloat(_dieselGenCPhaseVoltage);
|
public Voltage DieselGenCPhaseVoltage => ConvertBitPatternToFloat(_dieselGenCPhaseVoltage);
|
||||||
public Voltage DieselGenABWireVoltage => ConvertBitPatternToFloat(_dieselGenABWireVoltage);
|
public Voltage DieselGenAbWireVoltage => ConvertBitPatternToFloat(_dieselGenABWireVoltage);
|
||||||
public Voltage DieselGenBCWireVoltage => ConvertBitPatternToFloat(_dieselGenBCWireVoltage);
|
public Voltage DieselGenBcWireVoltage => ConvertBitPatternToFloat(_dieselGenBCWireVoltage);
|
||||||
public Voltage DieselGenCAWireVoltage => ConvertBitPatternToFloat(_dieselGenCAWireVoltage);
|
public Voltage DieselGenCaWireVoltage => ConvertBitPatternToFloat(_dieselGenCAWireVoltage);
|
||||||
|
|
||||||
public Frequency DieselGenVoltageFrequency => ConvertBitPatternToFloat(_dieselGenVoltageFrequency);
|
public Frequency DieselGenVoltageFrequency => ConvertBitPatternToFloat(_dieselGenVoltageFrequency);
|
||||||
|
|
||||||
|
|
@ -123,38 +128,39 @@ public partial class SinexcelRecord
|
||||||
public Current DieselGenCPhaseCurrent => ConvertBitPatternToFloat(_dieselGenCPhaseCurrent);
|
public Current DieselGenCPhaseCurrent => ConvertBitPatternToFloat(_dieselGenCPhaseCurrent);
|
||||||
public Current DieselGenNWireCurrent => ConvertBitPatternToFloat(_dieselGenNWireCurrent);
|
public Current DieselGenNWireCurrent => ConvertBitPatternToFloat(_dieselGenNWireCurrent);
|
||||||
|
|
||||||
public ApparentPower DieselGenAPhaseApparentPower => ConvertBitPatternToFloat(_dieselGenAPhaseApparentPower);
|
public ApparentPower DieselGenAPhaseApparentPower => ConvertBitPatternToFloat(_dieselGenAPhaseApparentPower) * _factorFromKwtoW;
|
||||||
public ApparentPower DieselGenBPhaseApparentPower => ConvertBitPatternToFloat(_dieselGenBPhaseApparentPower);
|
public ApparentPower DieselGenBPhaseApparentPower => ConvertBitPatternToFloat(_dieselGenBPhaseApparentPower) * _factorFromKwtoW;
|
||||||
public ApparentPower DieselGenCPhaseApparentPower => ConvertBitPatternToFloat(_dieselGenCPhaseApparentPower);
|
public ApparentPower DieselGenCPhaseApparentPower => ConvertBitPatternToFloat(_dieselGenCPhaseApparentPower) * _factorFromKwtoW;
|
||||||
|
|
||||||
public ActivePower DieselGenAPhaseActivePower => ConvertBitPatternToFloat(_dieselGenAPhaseActivePower);
|
public ActivePower DieselGenAPhaseActivePower => ConvertBitPatternToFloat(_dieselGenAPhaseActivePower) * _factorFromKwtoW;
|
||||||
public ActivePower DieselGenBPhaseActivePower => ConvertBitPatternToFloat(_dieselGenBPhaseActivePower);
|
public ActivePower DieselGenBPhaseActivePower => ConvertBitPatternToFloat(_dieselGenBPhaseActivePower) * _factorFromKwtoW;
|
||||||
public ActivePower DieselGenCPhaseActivePower => ConvertBitPatternToFloat(_dieselGenCPhaseActivePower);
|
public ActivePower DieselGenCPhaseActivePower => ConvertBitPatternToFloat(_dieselGenCPhaseActivePower) * _factorFromKwtoW;
|
||||||
|
|
||||||
public ReactivePower DieselGenAPhaseReactivePower => ConvertBitPatternToFloat(_dieselGenAPhaseReactivePower);
|
public ReactivePower DieselGenAPhaseReactivePower => ConvertBitPatternToFloat(_dieselGenAPhaseReactivePower) * _factorFromKwtoW;
|
||||||
public ReactivePower DieselGenBPhaseReactivePower => ConvertBitPatternToFloat(_dieselGenBPhaseReactivePower);
|
public ReactivePower DieselGenBPhaseReactivePower => ConvertBitPatternToFloat(_dieselGenBPhaseReactivePower) * _factorFromKwtoW;
|
||||||
public ReactivePower DieselGenCPhaseReactivePower => ConvertBitPatternToFloat(_dieselGenCPhaseReactivePower);
|
public ReactivePower DieselGenCPhaseReactivePower => ConvertBitPatternToFloat(_dieselGenCPhaseReactivePower) * _factorFromKwtoW;
|
||||||
|
|
||||||
// ───────────────────────────────────────────────
|
// ───────────────────────────────────────────────
|
||||||
// Photovoltaic and Battery Measurements
|
// Photovoltaic and Battery Measurements
|
||||||
// ───────────────────────────────────────────────
|
// ───────────────────────────────────────────────
|
||||||
public Voltage PvVoltage1 => ConvertBitPatternToFloat(_pvVoltage1);
|
public Voltage PvVoltage1 => ConvertBitPatternToFloat(_pvVoltage1);
|
||||||
public Current PvCurrent1 => ConvertBitPatternToFloat(_pvCurrent1);
|
public Current PvCurrent1 => ConvertBitPatternToFloat(_pvCurrent1);
|
||||||
public ActivePower PvPower1 => ConvertBitPatternToFloat(_pvPower1);
|
public ActivePower PvPower1 => ConvertBitPatternToFloat(_pvPower1) *_factorFromKwtoW;
|
||||||
public Voltage PvVoltage2 => ConvertBitPatternToFloat(_pvVoltage2);
|
public Voltage PvVoltage2 => ConvertBitPatternToFloat(_pvVoltage2);
|
||||||
public Current PvCurrent2 => ConvertBitPatternToFloat(_pvCurrent2);
|
public Current PvCurrent2 => ConvertBitPatternToFloat(_pvCurrent2);
|
||||||
public ActivePower PvPower2 => ConvertBitPatternToFloat(_pvPower2);
|
public ActivePower PvPower2 => ConvertBitPatternToFloat(_pvPower2) * _factorFromKwtoW;
|
||||||
|
|
||||||
public Voltage BatteryVoltage1 => ConvertBitPatternToFloat(_batteryVoltage1);
|
|
||||||
public Current BatteryCurrent1 => ConvertBitPatternToFloat(_batteryCurrent1);
|
|
||||||
public ActivePower BatteryPower1 => ConvertBitPatternToFloat(_batteryPower1);
|
|
||||||
public Percent BatterySoc1 => ConvertBitPatternToFloat(_batterySoc1);
|
|
||||||
public float BatteryFullLoadDuration1 => ConvertBitPatternToFloat(_batteryFullLoadDuration1);
|
|
||||||
|
|
||||||
public Voltage BatteryVoltage2 => ConvertBitPatternToFloat(_batteryVoltage2);
|
public Voltage Battery1Voltage => ConvertBitPatternToFloat(_batteryVoltage1);
|
||||||
public Current BatteryCurrent2 => ConvertBitPatternToFloat(_batteryCurrent2);
|
public Current Battery1Current => ConvertBitPatternToFloat(_batteryCurrent1);
|
||||||
public ActivePower BatteryPower2 => ConvertBitPatternToFloat(_batteryPower2);
|
public ActivePower Battery1Power => ConvertBitPatternToFloat(_batteryPower1) * _factorFromKwtoW;
|
||||||
public Percent BatterySoc2 => ConvertBitPatternToFloat(_batterySoc2);
|
public Percent Battery1Soc => ConvertBitPatternToFloat(_batterySoc1);
|
||||||
|
public float BatteryFullLoadDuration1 => ConvertBitPatternToFloat(_batteryFullLoadDuration1); // this is in hour
|
||||||
|
|
||||||
|
public Voltage Battery2Voltage => ConvertBitPatternToFloat(_batteryVoltage2);
|
||||||
|
public Current Battery2Current => ConvertBitPatternToFloat(_batteryCurrent2);
|
||||||
|
public ActivePower Battery2Power => ConvertBitPatternToFloat(_batteryPower2) * _factorFromKwtoW;
|
||||||
|
public Percent Battery2Soc => ConvertBitPatternToFloat(_batterySoc2);
|
||||||
public float BatteryFullLoadDuration2 => ConvertBitPatternToFloat(_batteryFullLoadDuration2);
|
public float BatteryFullLoadDuration2 => ConvertBitPatternToFloat(_batteryFullLoadDuration2);
|
||||||
|
|
||||||
public Temperature DcdcTemperature1 => ConvertBitPatternToFloat(_dcdcTemperature1);
|
public Temperature DcdcTemperature1 => ConvertBitPatternToFloat(_dcdcTemperature1);
|
||||||
|
|
@ -166,8 +172,8 @@ public partial class SinexcelRecord
|
||||||
// ───────────────────────────────────────────────
|
// ───────────────────────────────────────────────
|
||||||
// Energy and Power Summary
|
// Energy and Power Summary
|
||||||
// ───────────────────────────────────────────────
|
// ───────────────────────────────────────────────
|
||||||
public Energy ElectricityPurchased => ConvertBitPatternToFloat(_electricityPurchased);
|
public Energy TotalEnergyToUser => ConvertBitPatternToFloat(_electricityPurchased);
|
||||||
public Energy ElectricityFed => ConvertBitPatternToFloat(_electricityFed);
|
public Energy TotalEnergyToGrid => ConvertBitPatternToFloat(_electricityFed);
|
||||||
public Energy SelfGeneratedElectricity => ConvertBitPatternToFloat(_selfGeneratedElectricity);
|
public Energy SelfGeneratedElectricity => ConvertBitPatternToFloat(_selfGeneratedElectricity);
|
||||||
public Energy BatteryCharge => ConvertBitPatternToFloat(_batteryCharge);
|
public Energy BatteryCharge => ConvertBitPatternToFloat(_batteryCharge);
|
||||||
public Energy BatteryDischarge => ConvertBitPatternToFloat(_batteryDischarge);
|
public Energy BatteryDischarge => ConvertBitPatternToFloat(_batteryDischarge);
|
||||||
|
|
@ -175,21 +181,21 @@ public partial class SinexcelRecord
|
||||||
public Energy DailySelfGeneratedElectricity => ConvertBitPatternToFloat(_dailySelfGeneratedElectricity);
|
public Energy DailySelfGeneratedElectricity => ConvertBitPatternToFloat(_dailySelfGeneratedElectricity);
|
||||||
public Energy DailyElectricityPurchased => ConvertBitPatternToFloat(_dailyElectricityPurchased);
|
public Energy DailyElectricityPurchased => ConvertBitPatternToFloat(_dailyElectricityPurchased);
|
||||||
public Energy DailyElectricityFed => ConvertBitPatternToFloat(_dailyElectricityFed);
|
public Energy DailyElectricityFed => ConvertBitPatternToFloat(_dailyElectricityFed);
|
||||||
public Energy DailyBatteryCharge => ConvertBitPatternToFloat(_dailyBatteryCharge);
|
public Energy BatteryDailyChargeEnergy => ConvertBitPatternToFloat(_dailyBatteryCharge);
|
||||||
public Energy DailyBatteryDischarge => ConvertBitPatternToFloat(_dailyBatteryDischarge);
|
public Energy BatteryDailyDischargeEnergy => ConvertBitPatternToFloat(_dailyBatteryDischarge);
|
||||||
public Energy DailyLoadPowerConsumption => ConvertBitPatternToFloat(_dailyLoadPowerConsumption);
|
public Energy DailyLoadPowerConsumption => ConvertBitPatternToFloat(_dailyLoadPowerConsumption);
|
||||||
public ActivePower TotalPhotovoltaicPower => ConvertBitPatternToFloat(_totalPhotovoltaicPower);
|
public ActivePower TotalPhotovoltaicPower => ConvertBitPatternToFloat(_totalPhotovoltaicPower) * _factorFromKwtoW;
|
||||||
public ActivePower TotalBatteryPower => ConvertBitPatternToFloat(_totalBatteryPower);
|
public ActivePower TotalBatteryPower => ConvertBitPatternToFloat(_totalBatteryPower) * _factorFromKwtoW;
|
||||||
public ActivePower TotalLoadPower => ConvertBitPatternToFloat(_totalLoadPower);
|
public ActivePower TotalLoadPower => ConvertBitPatternToFloat(_totalLoadPower) * _factorFromKwtoW ;
|
||||||
public ActivePower TotalGridPower => ConvertBitPatternToFloat(_totalGridPower);
|
public ActivePower TotalGridPower => ConvertBitPatternToFloat(_totalGridPower) * _factorFromKwtoW ;
|
||||||
public ActivePower ImportantLoadTotalPower => ConvertBitPatternToFloat(_importantLoadTotalPower);
|
public ActivePower ImportantLoadTotalPower => ConvertBitPatternToFloat(_importantLoadTotalPower)* _factorFromKwtoW;
|
||||||
public ActivePower GeneralLoadTotalPower => ConvertBitPatternToFloat(_generalLoadTotalPower);
|
public ActivePower GeneralLoadTotalPower => ConvertBitPatternToFloat(_generalLoadTotalPower)* _factorFromKwtoW;
|
||||||
public Voltage Pv3Voltage => ConvertBitPatternToFloat(_pv3Voltage);
|
public Voltage Pv3Voltage => ConvertBitPatternToFloat(_pv3Voltage);
|
||||||
public Current Pv3Current => ConvertBitPatternToFloat(_pv3Current);
|
public Current Pv3Current => ConvertBitPatternToFloat(_pv3Current);
|
||||||
public ActivePower Pv3Power => ConvertBitPatternToFloat(_pv3Power);
|
public ActivePower Pv3Power => ConvertBitPatternToFloat(_pv3Power) * _factorFromKwtoW;
|
||||||
public Voltage Pv4Voltage => ConvertBitPatternToFloat(_pv4Voltage);
|
public Voltage Pv4Voltage => ConvertBitPatternToFloat(_pv4Voltage);
|
||||||
public Current Pv4Current => ConvertBitPatternToFloat(_pv4Current);
|
public Current Pv4Current => ConvertBitPatternToFloat(_pv4Current);
|
||||||
public ActivePower Pv4Power => ConvertBitPatternToFloat(_pv4Power);
|
public ActivePower Pv4Power => ConvertBitPatternToFloat(_pv4Power) * _factorFromKwtoW;
|
||||||
public ActivePower GeneratorTotalPower => ConvertBitPatternToFloat(_generatorTotalPower);
|
public ActivePower GeneratorTotalPower => ConvertBitPatternToFloat(_generatorTotalPower);
|
||||||
|
|
||||||
// ───────────────────────────────────────────────
|
// ───────────────────────────────────────────────
|
||||||
|
|
@ -209,268 +215,269 @@ public partial class SinexcelRecord
|
||||||
public ApparentPower RatedPowerKva => _ratedPower / 100f; // 0x2008 (value / 100)
|
public ApparentPower RatedPowerKva => _ratedPower / 100f; // 0x2008 (value / 100)
|
||||||
public SinexcelModel Model => (SinexcelModel)_model; // 0x200D
|
public SinexcelModel Model => (SinexcelModel)_model; // 0x200D
|
||||||
|
|
||||||
public ThreePhaseWireSystem ThreePhaseWireSystem
|
//public ThreePhaseWireSystem ThreePhaseWireSystem
|
||||||
{
|
//{
|
||||||
get => (ThreePhaseWireSystem)_threePhaseWireSystem;
|
// get => (ThreePhaseWireSystem)_threePhaseWireSystem;
|
||||||
set => _threePhaseWireSystem = (UInt32)value;
|
// //set => _threePhaseWireSystem = (UInt32)value;
|
||||||
}
|
//}
|
||||||
|
//
|
||||||
public InputFrequency InputFrequencyClass
|
//public InputFrequency InputFrequencyClass
|
||||||
{
|
//{
|
||||||
get => (InputFrequency)_inputFrequencyClass;
|
// get => (InputFrequency)_inputFrequencyClass;
|
||||||
set => _inputFrequencyClass = (UInt32)value;
|
// //set => _inputFrequencyClass = (UInt32)value;
|
||||||
}
|
//}
|
||||||
|
//
|
||||||
public WorkingMode WorkingMode
|
public WorkingMode WorkingMode
|
||||||
{
|
{
|
||||||
get => (WorkingMode)ConvertBitPatternToFloat(_workingMode);
|
get => (WorkingMode)(int)BitConverter.Int32BitsToSingle(unchecked((int)_workingMode));
|
||||||
set => _workingMode = (UInt32)value;
|
set => _workingMode = BitConverter.ToUInt32(BitConverter.GetBytes((float)value), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public GridSwitchMethod GridSwitchMethod
|
//
|
||||||
{
|
//public GridSwitchMethod GridSwitchMethod
|
||||||
get => (GridSwitchMethod)_methodSwitchMode;
|
//{
|
||||||
set => _methodSwitchMode = (UInt32)value;
|
// get => (GridSwitchMethod)_methodSwitchMode;
|
||||||
}
|
// //set => _methodSwitchMode = (UInt32)value;
|
||||||
|
//}
|
||||||
// ───────────────────────────────────────────────
|
//
|
||||||
// Inverter Control Configuration
|
//// ───────────────────────────────────────────────
|
||||||
// ───────────────────────────────────────────────
|
//// Inverter Control Configuration
|
||||||
public SinexcelUnbalanceCompensation EnableOnGridUnbalanceCompensation
|
//// ───────────────────────────────────────────────
|
||||||
{
|
//public SinexcelUnbalanceCompensation EnableOnGridUnbalanceCompensation
|
||||||
get => (SinexcelUnbalanceCompensation)_enableOnGridUnbalanceCompensation;
|
//{
|
||||||
set => _enableOnGridUnbalanceCompensation = (UInt32)value;
|
// get => (SinexcelUnbalanceCompensation)_enableOnGridUnbalanceCompensation;
|
||||||
}
|
// //set => _enableOnGridUnbalanceCompensation = (UInt32)value;
|
||||||
|
//}
|
||||||
public SinexcelTemperatureDrop TemperatureDrop
|
//
|
||||||
{
|
//public SinexcelTemperatureDrop TemperatureDrop
|
||||||
get => (SinexcelTemperatureDrop)ConvertBitPatternToFloat(_temperatureDrop);
|
//{
|
||||||
set => _temperatureDrop = (UInt32)value;
|
// get => (SinexcelTemperatureDrop)ConvertBitPatternToFloat(_temperatureDrop);
|
||||||
}
|
// //set => _temperatureDrop = (UInt32)value;
|
||||||
|
//}
|
||||||
public SinexcelHvrt Hvrt
|
//
|
||||||
{
|
//public SinexcelHvrt Hvrt
|
||||||
get => (SinexcelHvrt)_hvrt;
|
//{
|
||||||
set => _hvrt = (UInt32)value;
|
// get => (SinexcelHvrt)_hvrt;
|
||||||
}
|
// //set => _hvrt = (UInt32)value;
|
||||||
|
//}
|
||||||
public SinexcelLvrt Lvrt
|
//
|
||||||
{
|
//public SinexcelLvrt Lvrt
|
||||||
get => (SinexcelLvrt)_lvrt;
|
//{
|
||||||
set => _lvrt = (UInt32)value;
|
// get => (SinexcelLvrt)_lvrt;
|
||||||
}
|
// //set => _lvrt = (UInt32)value;
|
||||||
|
//}
|
||||||
// Fan Gear — numeric [0.5 ~ 1.0], default 1.0
|
//
|
||||||
public float FanGear
|
// F//an Gear — numeric [0.5 ~ 1.0], default 1.0
|
||||||
{
|
//public float FanGear
|
||||||
get => BitConverter.Int32BitsToSingle(unchecked((Int32)_fanGear));
|
//{
|
||||||
set => _fanGear = BitConverter.ToUInt32(BitConverter.GetBytes(value), 0);
|
// get => BitConverter.Int32BitsToSingle(unchecked((Int32)_fanGear));
|
||||||
}
|
// //set => _fanGear = BitConverter.ToUInt32(BitConverter.GetBytes(value), 0);
|
||||||
|
//}
|
||||||
// ───────────────────────────────────────────────
|
//
|
||||||
// Battery Configuration
|
//// ───────────────────────────────────────────────
|
||||||
// ───────────────────────────────────────────────
|
//// Battery Configuration
|
||||||
public SinexcelBatteryAccessMethod BatteryAccessMethod
|
//// ───────────────────────────────────────────────
|
||||||
{
|
//public SinexcelBatteryAccessMethod BatteryAccessMethod
|
||||||
get => (SinexcelBatteryAccessMethod)_batteryAccessMethod;
|
//{
|
||||||
set => _batteryAccessMethod = (UInt32)value;
|
// get => (SinexcelBatteryAccessMethod)_batteryAccessMethod;
|
||||||
}
|
// //set => _batteryAccessMethod = (UInt32)value;
|
||||||
|
//}
|
||||||
public SinexcelMeterAccessEnable MeterAccessEnable
|
//
|
||||||
{
|
//public SinexcelMeterAccessEnable MeterAccessEnable
|
||||||
get => (SinexcelMeterAccessEnable)ConvertBitPatternToFloat(_meterAccessEnable);
|
//{
|
||||||
set => _meterAccessEnable = (UInt32)value;
|
// get => (SinexcelMeterAccessEnable)ConvertBitPatternToFloat(_meterAccessEnable);
|
||||||
}
|
// //set => _meterAccessEnable = (UInt32)value;
|
||||||
|
//}
|
||||||
public SinexcelBatteryEnable EnableBattery1
|
//
|
||||||
{
|
//public SinexcelBatteryEnable EnableBattery1
|
||||||
get => (SinexcelBatteryEnable)ConvertBitPatternToFloat(_enableBattery1);
|
//{
|
||||||
set => _enableBattery1 = (UInt32)value;
|
// get => (SinexcelBatteryEnable)ConvertBitPatternToFloat(_enableBattery1);
|
||||||
}
|
// //set => _enableBattery1 = (UInt32)value;
|
||||||
|
//}
|
||||||
public SinexcelBatteryEnable EnableBattery2
|
//
|
||||||
{
|
//public SinexcelBatteryEnable EnableBattery2
|
||||||
get => (SinexcelBatteryEnable)ConvertBitPatternToFloat(_enableBattery2);
|
//{
|
||||||
set => _enableBattery2 = (UInt32)value;
|
// get => (SinexcelBatteryEnable)ConvertBitPatternToFloat(_enableBattery2);
|
||||||
}
|
// //set => _enableBattery2 = (UInt32)value;
|
||||||
|
//}
|
||||||
public SinexcelPvEnable EnablePv1
|
//
|
||||||
{
|
//public SinexcelPvEnable EnablePv1
|
||||||
get => (SinexcelPvEnable)ConvertBitPatternToFloat(_enablePv1);
|
//{
|
||||||
set => _enablePv1 = (UInt32)value;
|
// get => (SinexcelPvEnable)ConvertBitPatternToFloat(_enablePv1);
|
||||||
}
|
// //set => _enablePv1 = (UInt32)value;
|
||||||
|
//}
|
||||||
public SinexcelPvEnable EnablePv2
|
//
|
||||||
{
|
//public SinexcelPvEnable EnablePv2
|
||||||
get => (SinexcelPvEnable)ConvertBitPatternToFloat(_enablePv2);
|
//{
|
||||||
set => _enablePv2 = (UInt32)value;
|
// get => (SinexcelPvEnable)ConvertBitPatternToFloat(_enablePv2);
|
||||||
}
|
// //set => _enablePv2 = (UInt32)value;
|
||||||
|
//}
|
||||||
public SinexcelBatteryType BatteryType
|
//
|
||||||
{
|
//public SinexcelBatteryType BatteryType
|
||||||
get => (SinexcelBatteryType)_batteryType;
|
//{
|
||||||
set => _batteryType = (UInt32)value;
|
// get => (SinexcelBatteryType)_batteryType;
|
||||||
}
|
// //set => _batteryType = (UInt32)value;
|
||||||
|
//}
|
||||||
public float BatteryCapacity1
|
//
|
||||||
{
|
//public float BatteryCapacity1
|
||||||
get => BitConverter.Int32BitsToSingle(unchecked((Int32)_batteryCapacity1));
|
//{
|
||||||
set => _batteryCapacity1 = BitConverter.ToUInt32(BitConverter.GetBytes(value), 0);
|
// get => BitConverter.Int32BitsToSingle(unchecked((Int32)_batteryCapacity1));
|
||||||
}
|
// //set => _batteryCapacity1 = BitConverter.ToUInt32(BitConverter.GetBytes(value), 0);
|
||||||
|
//}
|
||||||
public float MaxChargingCurrentBattery1
|
//
|
||||||
{
|
//public float Battery1MaxChargingCurrent
|
||||||
get => BitConverter.Int32BitsToSingle(unchecked((Int32)_maxChargingCurrentBattery1));
|
//{
|
||||||
set => _maxChargingCurrentBattery1 = BitConverter.ToUInt32(BitConverter.GetBytes(value), 0);
|
// get => BitConverter.Int32BitsToSingle(unchecked((Int32)_maxChargingCurrentBattery1));
|
||||||
}
|
// //set => _maxChargingCurrentBattery1 = BitConverter.ToUInt32(BitConverter.GetBytes(value), 0);
|
||||||
|
//}
|
||||||
public float MaxDischargingCurrentBattery1
|
//
|
||||||
{
|
//public float Battery1MaxDischargingCurrent
|
||||||
get => BitConverter.Int32BitsToSingle(unchecked((Int32)_maxDischargingCurrentBattery1));
|
//{
|
||||||
set => _maxDischargingCurrentBattery1 = BitConverter.ToUInt32(BitConverter.GetBytes(value), 0);
|
// get => BitConverter.Int32BitsToSingle(unchecked((Int32)_maxDischargingCurrentBattery1));
|
||||||
}
|
// //set => _maxDischargingCurrentBattery1 = BitConverter.ToUInt32(BitConverter.GetBytes(value), 0);
|
||||||
|
//}
|
||||||
public float RatedBatteryVoltage1
|
//
|
||||||
{
|
//public float RatedBatteryVoltage1
|
||||||
get => BitConverter.Int32BitsToSingle(unchecked((Int32)_ratedBatteryVoltage1));
|
//{
|
||||||
set => _ratedBatteryVoltage1 = BitConverter.ToUInt32(BitConverter.GetBytes(value), 0);
|
// get => BitConverter.Int32BitsToSingle(unchecked((Int32)_ratedBatteryVoltage1));
|
||||||
}
|
// //set => _ratedBatteryVoltage1 = BitConverter.ToUInt32(BitConverter.GetBytes(value), 0);
|
||||||
|
//}
|
||||||
public float MinSocBattery1
|
//
|
||||||
{
|
//public float Battery1MinSoc
|
||||||
get => BitConverter.Int32BitsToSingle(unchecked((Int32)_minSocBattery1));
|
//{
|
||||||
set => _minSocBattery1 = BitConverter.ToUInt32(BitConverter.GetBytes(value), 0);
|
// get => BitConverter.Int32BitsToSingle(unchecked((Int32)_minSocBattery1));
|
||||||
}
|
// //set => _minSocBattery1 = BitConverter.ToUInt32(BitConverter.GetBytes(value), 0);
|
||||||
|
//}
|
||||||
public float SetValueBattery1
|
//
|
||||||
{
|
//public float SetValueBattery1
|
||||||
get => BitConverter.Int32BitsToSingle(unchecked((Int32)_setValueBattery1));
|
//{
|
||||||
set => _setValueBattery1 = BitConverter.ToUInt32(BitConverter.GetBytes(value), 0);
|
// get => BitConverter.Int32BitsToSingle(unchecked((Int32)_setValueBattery1));
|
||||||
}
|
// //set => _setValueBattery1 = BitConverter.ToUInt32(BitConverter.GetBytes(value), 0);
|
||||||
|
//}
|
||||||
public SinexcelActiveChargeDischarge ActiveChargeDischarge
|
//
|
||||||
{
|
//public SinexcelActiveChargeDischarge ActiveChargeDischarge
|
||||||
get => (SinexcelActiveChargeDischarge)ConvertBitPatternToFloat(_activeChargeDischarge);
|
//{
|
||||||
set => _activeChargeDischarge = (UInt32)value;
|
// get => (SinexcelActiveChargeDischarge)ConvertBitPatternToFloat(_activeChargeDischarge);
|
||||||
}
|
// //set => _activeChargeDischarge = (UInt32)value;
|
||||||
|
//}
|
||||||
public float ActiveChargeDischargePower
|
//
|
||||||
{
|
//public float ActiveChargeDischargePower
|
||||||
get => ConvertBitPatternToFloat(_activeChargeDischargePower);
|
//{
|
||||||
set => _activeChargeDischargePower = BitConverter.ToUInt32(BitConverter.GetBytes(value), 0);
|
// get => ConvertBitPatternToFloat(_activeChargeDischargePower) * _factorFromKwtoW;
|
||||||
}
|
// //set => _activeChargeDischargePower = BitConverter.ToUInt32(BitConverter.GetBytes(value), 0); // we should check this may need to convert from W to KW
|
||||||
|
//}
|
||||||
// ───────────────────────────────────────────────
|
//
|
||||||
// Protection & PV Mode
|
//// ───────────────────────────────────────────────
|
||||||
// ───────────────────────────────────────────────
|
//// Protection & PV Mode
|
||||||
public SinexcelIslandProtection EnableIslandProtection
|
//// ───────────────────────────────────────────────
|
||||||
{
|
//public SinexcelIslandProtection EnableIslandProtection
|
||||||
get => (SinexcelIslandProtection)_enableIslandProtection;
|
//{
|
||||||
set => _enableIslandProtection = (UInt32)value;
|
// get => (SinexcelIslandProtection)_enableIslandProtection;
|
||||||
}
|
// //set => _enableIslandProtection = (UInt32)value;
|
||||||
|
//}
|
||||||
public SinexcelPvAccessMode PvAccessMode
|
//
|
||||||
{
|
//public SinexcelPvAccessMode PvAccessMode
|
||||||
get => (SinexcelPvAccessMode)_pvAccessMode;
|
//{
|
||||||
set => _pvAccessMode = (UInt32)value;
|
// get => (SinexcelPvAccessMode)_pvAccessMode;
|
||||||
}
|
// //set => _pvAccessMode = (UInt32)value;
|
||||||
|
//}
|
||||||
// ───────────────────────────────────────────────
|
//
|
||||||
// System-Level Parameters
|
//// ───────────────────────────────────────────────
|
||||||
// ───────────────────────────────────────────────
|
//// System-Level Parameters
|
||||||
public float OutputVoltageAdjustmentFactor
|
//// ───────────────────────────────────────────────
|
||||||
{
|
//public float OutputVoltageAdjustmentFactor
|
||||||
get => BitConverter.Int32BitsToSingle(unchecked((int)_outputVoltageAdjustmentFactor));
|
//{
|
||||||
set => _outputVoltageAdjustmentFactor = BitConverter.ToUInt32(BitConverter.GetBytes(value), 0);
|
// get => BitConverter.Int32BitsToSingle(unchecked((int)_outputVoltageAdjustmentFactor));
|
||||||
}
|
// //set => _outputVoltageAdjustmentFactor = BitConverter.ToUInt32(BitConverter.GetBytes(value), 0);
|
||||||
|
//}
|
||||||
public float SetValueBatteryUndervoltage1
|
//
|
||||||
{
|
//public float SetValueBatteryUndervoltage1
|
||||||
get => BitConverter.Int32BitsToSingle(unchecked((int)_setValueBatteryUndervoltage1));
|
//{
|
||||||
set => _setValueBatteryUndervoltage1 = BitConverter.ToUInt32(BitConverter.GetBytes(value), 0);
|
// get => BitConverter.Int32BitsToSingle(unchecked((int)_setValueBatteryUndervoltage1));
|
||||||
}
|
// //set => _setValueBatteryUndervoltage1 = BitConverter.ToUInt32(BitConverter.GetBytes(value), 0);
|
||||||
|
//}
|
||||||
public float InverterPowerLimit
|
//
|
||||||
{
|
//public float InverterPowerLimit
|
||||||
get => BitConverter.Int32BitsToSingle(unchecked((int)_inverterPowerLimit));
|
//{
|
||||||
set => _inverterPowerLimit = BitConverter.ToUInt32(BitConverter.GetBytes(value), 0);
|
// get => BitConverter.Int32BitsToSingle(unchecked((int)_inverterPowerLimit));
|
||||||
}
|
// //set => _inverterPowerLimit = BitConverter.ToUInt32(BitConverter.GetBytes(value), 0);
|
||||||
|
//}
|
||||||
// ───────────────────────────────────────────────
|
//
|
||||||
// Battery 2 Parameters
|
//// ───────────────────────────────────────────────
|
||||||
// ───────────────────────────────────────────────
|
//// Battery 2 Parameters
|
||||||
public float Battery2Capacity
|
//// ───────────────────────────────────────────────
|
||||||
{
|
//public float Battery2Capacity
|
||||||
get => BitConverter.Int32BitsToSingle(unchecked((int)_battery2Capacity));
|
//{
|
||||||
set => _battery2Capacity = BitConverter.ToUInt32(BitConverter.GetBytes(value), 0);
|
// get => BitConverter.Int32BitsToSingle(unchecked((int)_battery2Capacity));
|
||||||
}
|
// //set => _battery2Capacity = BitConverter.ToUInt32(BitConverter.GetBytes(value), 0);
|
||||||
|
//}
|
||||||
public float MaxChargingCurrentBattery2
|
//
|
||||||
{
|
//public float Battery2MaxChargingCurrent
|
||||||
get => BitConverter.Int32BitsToSingle(unchecked((int)_maxChargingCurrentBattery2));
|
//{
|
||||||
set => _maxChargingCurrentBattery2 = BitConverter.ToUInt32(BitConverter.GetBytes(value), 0);
|
// get => BitConverter.Int32BitsToSingle(unchecked((int)_maxChargingCurrentBattery2));
|
||||||
}
|
// //set => _maxChargingCurrentBattery2 = BitConverter.ToUInt32(BitConverter.GetBytes(value), 0);
|
||||||
|
//}
|
||||||
public float MaxDischargingCurrentBattery2
|
//
|
||||||
{
|
//public float Battery2MaxDischargingCurrent
|
||||||
get => BitConverter.Int32BitsToSingle(unchecked((int)_maxDischargingCurrentBattery2));
|
//{
|
||||||
set => _maxDischargingCurrentBattery2 = BitConverter.ToUInt32(BitConverter.GetBytes(value), 0);
|
// get => BitConverter.Int32BitsToSingle(unchecked((int)_maxDischargingCurrentBattery2));
|
||||||
}
|
// //set => _maxDischargingCurrentBattery2 = BitConverter.ToUInt32(BitConverter.GetBytes(value), 0);
|
||||||
|
//}
|
||||||
public float Battery2RatedVoltage
|
//
|
||||||
{
|
//public float Battery2RatedVoltage
|
||||||
get => BitConverter.Int32BitsToSingle(unchecked((int)_battery2RatedVoltage));
|
//{
|
||||||
set => _battery2RatedVoltage = BitConverter.ToUInt32(BitConverter.GetBytes(value), 0);
|
// get => BitConverter.Int32BitsToSingle(unchecked((int)_battery2RatedVoltage));
|
||||||
}
|
// //set => _battery2RatedVoltage = BitConverter.ToUInt32(BitConverter.GetBytes(value), 0);
|
||||||
|
//}
|
||||||
public float Battery2MinSoc
|
//
|
||||||
{
|
//public float Battery2MinSoc
|
||||||
get => BitConverter.Int32BitsToSingle(unchecked((int)_battery2MinSoc));
|
//{
|
||||||
set => _battery2MinSoc = BitConverter.ToUInt32(BitConverter.GetBytes(value), 0);
|
// get => BitConverter.Int32BitsToSingle(unchecked((int)_battery2MinSoc));
|
||||||
}
|
// //set => _battery2MinSoc = BitConverter.ToUInt32(BitConverter.GetBytes(value), 0);
|
||||||
|
//}
|
||||||
public float Battery2OverVoltageSetting
|
//
|
||||||
{
|
//public float Battery2OverVoltageSetting
|
||||||
get => BitConverter.Int32BitsToSingle(unchecked((int)_battery2OverVoltageSetting));
|
//{
|
||||||
set => _battery2OverVoltageSetting = BitConverter.ToUInt32(BitConverter.GetBytes(value), 0);
|
// get => BitConverter.Int32BitsToSingle(unchecked((int)_battery2OverVoltageSetting));
|
||||||
}
|
// //set => _battery2OverVoltageSetting = BitConverter.ToUInt32(BitConverter.GetBytes(value), 0);
|
||||||
|
//}
|
||||||
public float Battery2UnderVoltageSetpoint
|
//
|
||||||
{
|
//public float Battery2UnderVoltageSetpoint
|
||||||
get => BitConverter.Int32BitsToSingle(unchecked((int)_battery2UnderVoltageSetpoint));
|
//{
|
||||||
set => _battery2UnderVoltageSetpoint = BitConverter.ToUInt32(BitConverter.GetBytes(value), 0);
|
// get => BitConverter.Int32BitsToSingle(unchecked((int)_battery2UnderVoltageSetpoint));
|
||||||
}
|
// //set => _battery2UnderVoltageSetpoint = BitConverter.ToUInt32(BitConverter.GetBytes(value), 0);
|
||||||
|
//}
|
||||||
// ───────────────────────────────────────────────
|
//
|
||||||
// Parallel / System Settings
|
//// ───────────────────────────────────────────────
|
||||||
// ───────────────────────────────────────────────
|
//// Parallel / System Settings
|
||||||
public SinexcelMachineMode MachineMode
|
//// ───────────────────────────────────────────────
|
||||||
{
|
//public SinexcelMachineMode MachineMode
|
||||||
get => (SinexcelMachineMode)ConvertBitPatternToFloat(_singleOrParallelMachine);
|
//{
|
||||||
set => _singleOrParallelMachine = (UInt32)value;
|
// get => (SinexcelMachineMode)ConvertBitPatternToFloat(_singleOrParallelMachine);
|
||||||
}
|
// //set => _singleOrParallelMachine = (UInt32)value;
|
||||||
|
//}
|
||||||
public UInt32 NumberOfSystemModules
|
//
|
||||||
{
|
//public UInt32 NumberOfSystemModules
|
||||||
get => (UInt32)ConvertBitPatternToFloat(_numberOfSystemModules);
|
//{
|
||||||
set => _numberOfSystemModules = value;
|
// get => (UInt32)ConvertBitPatternToFloat(_numberOfSystemModules);
|
||||||
}
|
// //set => _numberOfSystemModules = value;
|
||||||
|
//}
|
||||||
public UInt32 ParallelModuleMachineNumber
|
//
|
||||||
{
|
//public UInt32 ParallelModuleMachineNumber
|
||||||
get => (UInt32)ConvertBitPatternToFloat(_parallelModuleMachineNumber);
|
//{
|
||||||
set => _parallelModuleMachineNumber = value;
|
// get => (UInt32)ConvertBitPatternToFloat(_parallelModuleMachineNumber);
|
||||||
}
|
// //set => _parallelModuleMachineNumber = value;
|
||||||
|
//}
|
||||||
public AccreditedCountry AccreditedCountry
|
//
|
||||||
{
|
//public AccreditedCountry AccreditedCountry
|
||||||
get => (AccreditedCountry)ConvertBitPatternToFloat(_accreditedCountries);
|
//{
|
||||||
set => _accreditedCountries = (UInt32)value;
|
// get => (AccreditedCountry)ConvertBitPatternToFloat(_accreditedCountries);
|
||||||
}
|
// //set => _accreditedCountries = (UInt32)value;
|
||||||
|
//}
|
||||||
// ───────────────────────────────────────────────
|
//
|
||||||
// Control Commands
|
//// ───────────────────────────────────────────────
|
||||||
// ───────────────────────────────────────────────
|
//// Control Commands
|
||||||
|
//// ───────────────────────────────────────────────
|
||||||
public float PowerOn
|
public float PowerOn
|
||||||
{
|
{
|
||||||
get => BitConverter.Int32BitsToSingle(unchecked((Int32)_powerOn));
|
get => BitConverter.Int32BitsToSingle(unchecked((Int32)_powerOn));
|
||||||
|
|
@ -482,45 +489,39 @@ public partial class SinexcelRecord
|
||||||
get => BitConverter.Int32BitsToSingle(unchecked((Int32)_powerOff));
|
get => BitConverter.Int32BitsToSingle(unchecked((Int32)_powerOff));
|
||||||
set => _powerOff = BitConverter.ToUInt32(BitConverter.GetBytes(value), 0);
|
set => _powerOff = BitConverter.ToUInt32(BitConverter.GetBytes(value), 0);
|
||||||
}
|
}
|
||||||
|
//
|
||||||
public float FaultClearing
|
//public float FaultClearingf
|
||||||
{
|
//{
|
||||||
get => BitConverter.Int32BitsToSingle(unchecked((Int32)_faultClearing));
|
// get => BitConverter.Int32BitsToSingle(unchecked((Int32)_faultClearing));
|
||||||
set => _faultClearing = BitConverter.ToUInt32(BitConverter.GetBytes(value), 0);
|
// // //set => _faultClearing = BitConverter.ToUInt32(BitConverter.GetBytes(value), 0);
|
||||||
}
|
//}
|
||||||
|
//
|
||||||
// ───────────────────────────────────────────────
|
//// ───────────────────────────────────────────────
|
||||||
// Meter & Battery Control
|
//// Meter & Battery Control
|
||||||
// ───────────────────────────────────────────────
|
//// ───────────────────────────────────────────────
|
||||||
public float MeterReverseManualDetection
|
//public float MeterReverseManualDetection
|
||||||
{
|
//{
|
||||||
get => BitConverter.Int32BitsToSingle(unchecked((Int32)_meterReverseManualDetection));
|
// get => BitConverter.Int32BitsToSingle(unchecked((Int32)_meterReverseManualDetection));
|
||||||
set => _meterReverseManualDetection = BitConverter.ToUInt32(BitConverter.GetBytes(value), 0);
|
// //set => _meterReverseManualDetection = BitConverter.ToUInt32(BitConverter.GetBytes(value), 0);
|
||||||
}
|
//}
|
||||||
|
//
|
||||||
public Voltage BatteryVoltage
|
//public SinexcelBatteryRating BatteryVoltageRating
|
||||||
{
|
//{
|
||||||
get => (Voltage)ConvertBitPatternToFloat(_batteryVoltage);
|
// get => (SinexcelBatteryRating)ConvertBitPatternToFloat(_batteryVoltageRating);
|
||||||
set => _batteryVoltage = BitConverter.ToUInt32(BitConverter.GetBytes(value), 0);
|
// //set => _batteryVoltageRating = (UInt32)value;
|
||||||
}
|
//}
|
||||||
|
//
|
||||||
public SinexcelBatteryRating BatteryRating
|
//public float Battery1Activation
|
||||||
{
|
//{
|
||||||
get => (SinexcelBatteryRating)ConvertBitPatternToFloat(_batteryRating);
|
// get => BitConverter.Int32BitsToSingle(unchecked((Int32)_battery1Activation));
|
||||||
set => _batteryRating = (UInt32)value;
|
// //set => _battery1Activation = BitConverter.ToUInt32(BitConverter.GetBytes(value), 0);
|
||||||
}
|
//}
|
||||||
|
//
|
||||||
public float Battery1Activation
|
//public float Battery2Activation
|
||||||
{
|
//{
|
||||||
get => BitConverter.Int32BitsToSingle(unchecked((Int32)_battery1Activation));
|
// get => BitConverter.Int32BitsToSingle(unchecked((Int32)_battery2Activation));
|
||||||
set => _battery1Activation = BitConverter.ToUInt32(BitConverter.GetBytes(value), 0);
|
// //set => _battery2Activation = BitConverter.ToUInt32(BitConverter.GetBytes(value), 0);
|
||||||
}
|
//}
|
||||||
|
|
||||||
public float Battery2Activation
|
|
||||||
{
|
|
||||||
get => BitConverter.Int32BitsToSingle(unchecked((Int32)_battery2Activation));
|
|
||||||
set => _battery2Activation = BitConverter.ToUInt32(BitConverter.GetBytes(value), 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ───────────────────────────────────────────────
|
// ───────────────────────────────────────────────
|
||||||
// Electric Meter Operating State
|
// Electric Meter Operating State
|
||||||
|
|
@ -571,23 +572,149 @@ public partial class SinexcelRecord
|
||||||
// ───────────────────────────────────────────────
|
// ───────────────────────────────────────────────
|
||||||
public ActivePower ElectricMeterAPhaseActivePower
|
public ActivePower ElectricMeterAPhaseActivePower
|
||||||
{
|
{
|
||||||
get => BitConverter.Int32BitsToSingle(unchecked((Int32)_electricMeterAPhaseActivePower));
|
get => BitConverter.Int32BitsToSingle(unchecked((Int32)_electricMeterAPhaseActivePower)) * _factorFromKwtoW;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ActivePower ElectricMeterBPhaseActivePower
|
public ActivePower ElectricMeterBPhaseActivePower
|
||||||
{
|
{
|
||||||
get => BitConverter.Int32BitsToSingle(unchecked((Int32)_electricMeterBPhaseActivePower));
|
get => BitConverter.Int32BitsToSingle(unchecked((Int32)_electricMeterBPhaseActivePower)) * _factorFromKwtoW;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ActivePower ElectricMeterCPhaseActivePower
|
public ActivePower ElectricMeterCPhaseActivePower
|
||||||
{
|
{
|
||||||
get => BitConverter.Int32BitsToSingle(unchecked((Int32)_electricMeterCPhaseActivePower));
|
get => BitConverter.Int32BitsToSingle(unchecked((Int32)_electricMeterCPhaseActivePower)) * _factorFromKwtoW;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ActivePower GridPower
|
||||||
|
{
|
||||||
|
get => ElectricMeterAPhaseActivePower + ElectricMeterBPhaseActivePower + ElectricMeterCPhaseActivePower;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Energy (kW·h)
|
||||||
|
public Energy Battery1TotalChargingEnergy => BitConverter.Int32BitsToSingle(unchecked((Int32)_batteryCab1TotalChargingEnergy)); // 0xB0FC
|
||||||
|
public Energy Battery1TotalDischargedEnergy => BitConverter.Int32BitsToSingle(unchecked((Int32)_batteryCab1TotalDischargedEnergy)); // 0xB0FE
|
||||||
|
|
||||||
|
// Pack totals and status
|
||||||
|
public Voltage Battery1PackTotalVoltage => BitConverter.Int32BitsToSingle(unchecked((Int32)_batteryCab1PackTotalVoltage)); // 0xB100 (0.01 V resolution per spec)
|
||||||
|
public Current Battery1PackTotalCurrent => BitConverter.Int32BitsToSingle(unchecked((Int32)_batteryCab1PackTotalCurrent)); // 0xB102 (0.01 A resolution per spec)
|
||||||
|
public Temperature Battery1Temperature => BitConverter.Int32BitsToSingle(unchecked((Int32)_batteryCab1Temperature)); // 0xB104 (0.01 °C resolution per spec)
|
||||||
|
public Percent Battery1SocSecondvalue => BitConverter.Int32BitsToSingle(unchecked((Int32)_batteryCab1Soc)); // 0xB106 %
|
||||||
|
public Percent Battery1Soh => BitConverter.Int32BitsToSingle(unchecked((Int32)_batteryCab1Soh)); // 0xB108 %
|
||||||
|
|
||||||
|
// Energy (kW·h)
|
||||||
|
public float Battery2TotalChargingEnergy => BitConverter.Int32BitsToSingle(unchecked((Int32)_batteryCab2TotalChargingEnergy)); // 0xB1FC
|
||||||
|
public float Battery2TotalDischargedEnergy => BitConverter.Int32BitsToSingle(unchecked((Int32)_batteryCab2TotalDischargedEnergy)); // 0xB1FE
|
||||||
|
|
||||||
|
// Pack Voltage / Current / Temperature
|
||||||
|
public Voltage Battery2PackTotalVoltage => BitConverter.Int32BitsToSingle(unchecked((Int32)_batteryCab2PackTotalVoltage)); // 0xB200 (0.01 V resolution)
|
||||||
|
public Current Battery2PackTotalCurrent => BitConverter.Int32BitsToSingle(unchecked((Int32)_batteryCab2PackTotalCurrent)); // 0xB202 (0.01 A resolution)
|
||||||
|
public Temperature Battery2Socsecondvalue => BitConverter.Int32BitsToSingle(unchecked((Int32)_batteryCab2Soc)); // 0xB206 %
|
||||||
|
public Percent Battery2Soh => BitConverter.Int32BitsToSingle(unchecked((Int32)_batteryCab2Soh)); // 0xB208 %
|
||||||
|
|
||||||
|
// Repetitive-week mask (bit-mapped 0–6 = Sun–Sat)
|
||||||
|
//public float TimedChargeAndDischargeOff
|
||||||
|
//{
|
||||||
|
// get => BitConverter.Int32BitsToSingle(unchecked((Int32)_Timed_Charge_and_Discharge_Off)) ; // only 7 bits used
|
||||||
|
// //set => _Timed_Charge_and_Discharge_Off = BitConverter.ToUInt32(BitConverter.GetBytes(value), 0);
|
||||||
|
//}
|
||||||
|
// Repetitive-week mask (bit-mapped 0–6 = Sun–Sat)
|
||||||
|
/* public float OtherTimePeriodMode
|
||||||
|
{
|
||||||
|
get => _Other_time_period_mode ; // only 7 bits used
|
||||||
|
//set => _Other_time_period_mode = (UInt32)value;
|
||||||
|
}*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Repetitive-week mask (bit-mapped 0–6 = Sun–Sat)
|
||||||
|
public SinexcelWeekDays RepetitiveWeeks
|
||||||
|
{
|
||||||
|
get => (SinexcelWeekDays)(_repetitiveWeeks & 0x7F); // only 7 bits used
|
||||||
|
set => _repetitiveWeeks = (UInt32)value;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Effective start / end as UNIX timestamps
|
||||||
|
public DateTime EffectiveStartDate
|
||||||
|
{
|
||||||
|
get => DateTimeOffset.FromUnixTimeSeconds(_effectiveStartDate).DateTime;
|
||||||
|
set => _effectiveStartDate = (UInt32)new DateTimeOffset(value).ToUnixTimeSeconds();
|
||||||
|
}
|
||||||
|
//
|
||||||
|
public DateTime EffectiveEndDate
|
||||||
|
{
|
||||||
|
get => DateTimeOffset.FromUnixTimeSeconds(_effectiveEndDate).DateTime;
|
||||||
|
set => _effectiveEndDate = (UInt32)new DateTimeOffset(value).ToUnixTimeSeconds();
|
||||||
|
}
|
||||||
|
// // Charging power during time period 1 (kW)
|
||||||
|
public float ChargingPowerPeriod1
|
||||||
|
{
|
||||||
|
get => BitConverter.Int32BitsToSingle(unchecked((Int32)_chargingPowerPeriod1));
|
||||||
|
set => _chargingPowerPeriod1 = BitConverter.ToUInt32(BitConverter.GetBytes(value), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public float DishargingPowerPeriod1
|
||||||
|
{
|
||||||
|
get => BitConverter.Int32BitsToSingle(unchecked((Int32)_dischargingPowerPeriod1));
|
||||||
|
set => _dischargingPowerPeriod1 = BitConverter.ToUInt32(BitConverter.GetBytes(value), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ───────────────────────────────────────────────
|
||||||
|
// Charging period 1
|
||||||
|
// ───────────────────────────────────────────────
|
||||||
|
public TimeSpan ChargeStartTimePeriod1
|
||||||
|
{
|
||||||
|
get => ConvertToTimeSpan(_chargeStartTimePeriod1);
|
||||||
|
set => _chargeStartTimePeriod1 = ConvertFromTimeSpan(value);
|
||||||
|
}
|
||||||
|
public TimeSpan ChargeEndTimePeriod1
|
||||||
|
{
|
||||||
|
get => ConvertToTimeSpan(_chargeEndTimePeriod1);
|
||||||
|
set => _chargeEndTimePeriod1 = ConvertFromTimeSpan(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ───────────────────────────────────────────────
|
||||||
|
// Discharging period 1
|
||||||
|
// ───────────────────────────────────────────────
|
||||||
|
public TimeSpan DischargeStartTimePeriod1
|
||||||
|
{
|
||||||
|
get => ConvertToTimeSpan(_dischargeStartTimePeriod1);
|
||||||
|
set => _dischargeStartTimePeriod1 = ConvertFromTimeSpan(value);
|
||||||
|
}
|
||||||
|
//
|
||||||
|
public TimeSpan DischargeEndTimePeriod1
|
||||||
|
{
|
||||||
|
get => ConvertToTimeSpan(_dischargeEndTimePeriod1);
|
||||||
|
set => _dischargeEndTimePeriod1 = ConvertFromTimeSpan(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ───────────────────────────────────────────────
|
// ───────────────────────────────────────────────
|
||||||
// Conversion methodes
|
// Conversion methodes
|
||||||
// ───────────────────────────────────────────────
|
// ───────────────────────────────────────────────
|
||||||
|
|
||||||
|
private static TimeSpan ConvertToTimeSpan(UInt32 raw)
|
||||||
|
{
|
||||||
|
// raw is IEEE754 float bits, e.g. 0x44640000 for 912.0
|
||||||
|
float f = BitConverter.Int32BitsToSingle(unchecked((int)raw));
|
||||||
|
int hhmm = (int)Math.Round(f);
|
||||||
|
|
||||||
|
int hours = hhmm / 100;
|
||||||
|
int minutes = hhmm % 100;
|
||||||
|
|
||||||
|
return new TimeSpan(hours, minutes, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static UInt32 ConvertFromTimeSpan(TimeSpan time)
|
||||||
|
{
|
||||||
|
int hhmm = time.Hours * 100 + time.Minutes; // e.g. 9*100+12 = 912
|
||||||
|
float f = (float)hhmm; // 912.0f
|
||||||
|
// convert float to raw IEEE754 bits
|
||||||
|
return BitConverter.ToUInt32(BitConverter.GetBytes(f), 0); // e.g. 0x44640000
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private static Single IntToFloat(Int32 intValue)
|
private static Single IntToFloat(Int32 intValue)
|
||||||
{
|
{
|
||||||
byte[] intBytes = BitConverter.GetBytes(intValue);
|
byte[] intBytes = BitConverter.GetBytes(intValue);
|
||||||
|
|
|
||||||
|
|
@ -226,71 +226,70 @@ public partial class SinexcelRecord
|
||||||
// ───────────────────────────────────────────────
|
// ───────────────────────────────────────────────
|
||||||
// System configuration / operation registers
|
// System configuration / operation registers
|
||||||
// ───────────────────────────────────────────────
|
// ───────────────────────────────────────────────
|
||||||
[HoldingRegister<UInt32>(12294, writable: true)] private UInt32 _threePhaseWireSystem; // 0x3006
|
//[HoldingRegister<UInt32>(12294, writable: true)] private UInt32 _threePhaseWireSystem; // 0x3006
|
||||||
[HoldingRegister<UInt32>(12296, writable: true)] private UInt32 _remainnotused; // 0x3008
|
//[HoldingRegister<UInt32>(12296, writable: true)] private UInt32 _remainnotused; // 0x3008
|
||||||
[HoldingRegister<UInt32>(12298, writable: true)] private UInt32 _inputFrequencyClass; // 0x300A
|
//[HoldingRegister<UInt32>(12298, writable: true)] private UInt32 _inputFrequencyClass; // 0x300A
|
||||||
[HoldingRegister<UInt32>(12300, writable: true)] private UInt32 _workingMode; // 0x300C
|
[HoldingRegister<UInt32>(12300, writable: true)] private UInt32 _workingMode; // 0x300C
|
||||||
[HoldingRegister<UInt32>(12302, writable: true)] private UInt32 _methodSwitchMode; // 0x300E
|
//[HoldingRegister<UInt32>(12302, writable: true)] private UInt32 _methodSwitchMode; // 0x300E
|
||||||
// ───────────────────────────────────────────────
|
// ───────────────────────────────────────────────
|
||||||
// Inverter Control and Protection Configuration
|
// Inverter Control and Protection Configuration
|
||||||
// ───────────────────────────────────────────────
|
// ───────────────────────────────────────────────
|
||||||
[HoldingRegister<UInt32>(12304, writable: true)] private UInt32 _enableOnGridUnbalanceCompensation; // 0x3010
|
//[HoldingRegister<UInt32>(12304, writable: true)] private UInt32 _enableOnGridUnbalanceCompensation; // 0x3010
|
||||||
[HoldingRegister<UInt32>(12306, writable: true)] private UInt32 _temperatureDrop; // 0x3012
|
//[HoldingRegister<UInt32>(12306, writable: true)] private UInt32 _temperatureDrop; // 0x3012
|
||||||
[HoldingRegister<UInt32>(12308, writable: true)] private UInt32 _hvrt; // 0x3014
|
//[HoldingRegister<UInt32>(12308, writable: true)] private UInt32 _hvrt; // 0x3014
|
||||||
[HoldingRegister<UInt32>(12310, writable: true)] private UInt32 _lvrt; // 0x3016
|
//[HoldingRegister<UInt32>(12310, writable: true)] private UInt32 _lvrt; // 0x3016
|
||||||
[HoldingRegister<UInt32>(12312, writable: true)] private UInt32 _fanGear; // 0x3018
|
//[HoldingRegister<UInt32>(12312, writable: true)] private UInt32 _fanGear; // 0x3018
|
||||||
|
|
||||||
// ───────────────────────────────────────────────
|
// ───────────────────────────────────────────────
|
||||||
// Battery & PV Configuration
|
// Battery & PV Configuration
|
||||||
// ───────────────────────────────────────────────
|
// ───────────────────────────────────────────────
|
||||||
[HoldingRegister<UInt32>(12336, writable: true)] private UInt32 _batteryAccessMethod; // 0x3030
|
//[HoldingRegister<UInt32>(12336, writable: true)] private UInt32 _batteryAccessMethod; // 0x3030
|
||||||
[HoldingRegister<UInt32>(12338, writable: true)] private UInt32 _meterAccessEnable; // 0x3032
|
//[HoldingRegister<UInt32>(12338, writable: true)] private UInt32 _meterAccessEnable; // 0x3032
|
||||||
[HoldingRegister<UInt32>(12340, writable: true)] private UInt32 _enableBattery1; // 0x3034
|
//[HoldingRegister<UInt32>(12340, writable: true)] private UInt32 _enableBattery1; // 0x3034
|
||||||
[HoldingRegister<UInt32>(12342, writable: true)] private UInt32 _enableBattery2; // 0x3036
|
//[HoldingRegister<UInt32>(12342, writable: true)] private UInt32 _enableBattery2; // 0x3036
|
||||||
[HoldingRegister<UInt32>(12344, writable: true)] private UInt32 _enablePv1; // 0x3038
|
//[HoldingRegister<UInt32>(12344, writable: true)] private UInt32 _enablePv1; // 0x3038
|
||||||
[HoldingRegister<UInt32>(12346, writable: true)] private UInt32 _enablePv2; // 0x303A
|
//[HoldingRegister<UInt32>(12346, writable: true)] private UInt32 _enablePv2; // 0x303A
|
||||||
[HoldingRegister<UInt32>(12348, writable: true)] private UInt32 _batteryType; // 0x303C
|
//[HoldingRegister<UInt32>(12348, writable: true)] private UInt32 _batteryType; // 0x303C
|
||||||
[HoldingRegister<UInt32>(12350, writable: true)] private UInt32 _batteryCapacity1; // 0x303E
|
//[HoldingRegister<UInt32>(12350, writable: true)] private UInt32 _batteryCapacity1; // 0x303E
|
||||||
[HoldingRegister<UInt32>(12352, writable: true)] private UInt32 _maxChargingCurrentBattery1; // 0x3040
|
//[HoldingRegister<UInt32>(12352, writable: true)] private UInt32 _maxChargingCurrentBattery1; // 0x3040
|
||||||
[HoldingRegister<UInt32>(12354, writable: true)] private UInt32 _maxDischargingCurrentBattery1; // 0x3042
|
//[HoldingRegister<UInt32>(12354, writable: true)] private UInt32 _maxDischargingCurrentBattery1; // 0x3042
|
||||||
[HoldingRegister<UInt32>(12362, writable: true)] private UInt32 _ratedBatteryVoltage1; // 0x304A
|
//[HoldingRegister<UInt32>(12362, writable: true)] private UInt32 _ratedBatteryVoltage1; // 0x304A
|
||||||
[HoldingRegister<UInt32>(12358, writable: true)] private UInt32 _minSocBattery1; // 0x3046
|
//[HoldingRegister<UInt32>(12358, writable: true)] private UInt32 _minSocBattery1; // 0x3046
|
||||||
[HoldingRegister<UInt32>(12360, writable: true)] private UInt32 _setValueBattery1; // 0x3048
|
//[HoldingRegister<UInt32>(12360, writable: true)] private UInt32 _setValueBattery1; // 0x3048
|
||||||
[HoldingRegister<UInt32>(12364, writable: true)] private UInt32 _activeChargeDischarge; // 0x304A
|
//[HoldingRegister<UInt32>(12364, writable: true)] private UInt32 _activeChargeDischarge; // 0x304A
|
||||||
[HoldingRegister<UInt32>(12366, writable: true)] private UInt32 _activeChargeDischargePower; // 0x304C
|
//[HoldingRegister<UInt32>(12366, writable: true)] private UInt32 _activeChargeDischargePower; // 0x304C
|
||||||
[HoldingRegister<UInt32>(12380, writable: true)] private UInt32 _enableIslandProtection; // 0x305C
|
//[HoldingRegister<UInt32>(12380, writable: true)] private UInt32 _enableIslandProtection; // 0x305C
|
||||||
[HoldingRegister<UInt32>(12382, writable: true)] private UInt32 _pvAccessMode; // 0x305E
|
//[HoldingRegister<UInt32>(12382, writable: true)] private UInt32 _pvAccessMode; // 0x305E
|
||||||
|
|
||||||
// ───────────────────────────────────────────────
|
// ───────────────────────────────────────────────
|
||||||
// System & Battery-2 Configuration
|
// System & Battery-2 Configuration
|
||||||
// ───────────────────────────────────────────────
|
// ───────────────────────────────────────────────
|
||||||
[HoldingRegister<UInt32>(12384, writable: true)] private UInt32 _outputVoltageAdjustmentFactor; // 0x3060
|
//[HoldingRegister<UInt32>(12384, writable: true)] private UInt32 _outputVoltageAdjustmentFactor; // 0x3060
|
||||||
[HoldingRegister<UInt32>(12386, writable: true)] private UInt32 _setValueBatteryUndervoltage1; // 0x3062
|
//[HoldingRegister<UInt32>(12386, writable: true)] private UInt32 _setValueBatteryUndervoltage1; // 0x3062
|
||||||
[HoldingRegister<UInt32>(12388, writable: true)] private UInt32 _inverterPowerLimit; // 0x3064
|
//[HoldingRegister<UInt32>(12388, writable: true)] private UInt32 _inverterPowerLimit; // 0x3064
|
||||||
[HoldingRegister<UInt32>(12400, writable: true)] private UInt32 _battery2Capacity; // 0x30B0
|
//[HoldingRegister<UInt32>(12400, writable: true)] private UInt32 _battery2Capacity; // 0x30B0
|
||||||
[HoldingRegister<UInt32>(12402, writable: true)] private UInt32 _maxChargingCurrentBattery2; // 0x30B2
|
//[HoldingRegister<UInt32>(12402, writable: true)] private UInt32 _maxChargingCurrentBattery2; // 0x30B2
|
||||||
[HoldingRegister<UInt32>(12404, writable: true)] private UInt32 _maxDischargingCurrentBattery2; // 0x30B4
|
//[HoldingRegister<UInt32>(12404, writable: true)] private UInt32 _maxDischargingCurrentBattery2; // 0x30B4
|
||||||
[HoldingRegister<UInt32>(12406, writable: true)] private UInt32 _battery2RatedVoltage; // 0x30B6
|
//[HoldingRegister<UInt32>(12406, writable: true)] private UInt32 _battery2RatedVoltage; // 0x30B6
|
||||||
[HoldingRegister<UInt32>(12408, writable: true)] private UInt32 _battery2MinSoc; // 0x30B8
|
//[HoldingRegister<UInt32>(12408, writable: true)] private UInt32 _battery2MinSoc; // 0x30B8
|
||||||
[HoldingRegister<UInt32>(12410, writable: true)] private UInt32 _battery2OverVoltageSetting; // 0x30BA
|
//[HoldingRegister<UInt32>(12410, writable: true)] private UInt32 _battery2OverVoltageSetting; // 0x30BA
|
||||||
[HoldingRegister<UInt32>(12412, writable: true)] private UInt32 _battery2UnderVoltageSetpoint; // 0x30BC
|
//[HoldingRegister<UInt32>(12412, writable: true)] private UInt32 _battery2UnderVoltageSetpoint; // 0x30BC
|
||||||
|
//
|
||||||
[HoldingRegister<UInt32>(12414, writable: true)] private UInt32 _singleOrParallelMachine; // 0x30BE
|
//[HoldingRegister<UInt32>(12414, writable: true)] private UInt32 _singleOrParallelMachine; // 0x30BE
|
||||||
[HoldingRegister<UInt32>(12416, writable: true)] private UInt32 _numberOfSystemModules; // 0x30C0
|
//[HoldingRegister<UInt32>(12416, writable: true)] private UInt32 _numberOfSystemModules; // 0x30C0
|
||||||
[HoldingRegister<UInt32>(12418, writable: true)] private UInt32 _parallelModuleMachineNumber; // 0x30C2
|
//[HoldingRegister<UInt32>(12418, writable: true)] private UInt32 _parallelModuleMachineNumber; // 0x30C2
|
||||||
[HoldingRegister<UInt32>(12420, writable: true)] private UInt32 _accreditedCountries; // 0x30C4
|
//[HoldingRegister<UInt32>(12420, writable: true)] private UInt32 _accreditedCountries; // 0x30C4
|
||||||
|
|
||||||
// ───────────────────────────────────────────────
|
// ───────────────────────────────────────────────
|
||||||
// System Control & Diagnostic Registers
|
// System Control & Diagnostic Registers
|
||||||
// ───────────────────────────────────────────────
|
// ───────────────────────────────────────────────
|
||||||
[HoldingRegister<UInt32>(15426, writable: true)] private UInt32 _powerOn; // 0x3C42
|
[HoldingRegister<UInt32>(15426, writable: true)] private UInt32 _powerOn; // 0x3C42
|
||||||
[HoldingRegister<UInt32>(15428, writable: true)] private UInt32 _powerOff; // 0x3C44
|
[HoldingRegister<UInt32>(15428, writable: true)] private UInt32 _powerOff; // 0x3C44
|
||||||
[HoldingRegister<UInt32>(15430, writable: true)] private UInt32 _faultClearing; // 0x3C46
|
//[HoldingRegister<UInt32>(15430, writable: true)] private UInt32 _faultClearing; // 0x3C46
|
||||||
[HoldingRegister<UInt32>(15518, writable: true)] private UInt32 _meterReverseManualDetection; // 0x3C9E
|
//[HoldingRegister<UInt32>(15518, writable: true)] private UInt32 _meterReverseManualDetection; // 0x3C9E
|
||||||
[HoldingRegister<UInt32>(15520, writable: true)] private UInt32 _batteryVoltage; // 0x3CA0
|
//[HoldingRegister<UInt32>(15520, writable: true)] private UInt32 _batteryVoltageRating; // 0x3CA0
|
||||||
[HoldingRegister<UInt32>(15522, writable: true)] private UInt32 _batteryRating; // 0x3CA2
|
//[HoldingRegister<UInt32>(15524, writable: true)] private UInt32 _battery1Activation; // 0x3CA4
|
||||||
[HoldingRegister<UInt32>(15524, writable: true)] private UInt32 _battery1Activation; // 0x3CA4
|
//[HoldingRegister<UInt32>(15526, writable: true)] private UInt32 _battery2Activation; // 0x3CA6
|
||||||
[HoldingRegister<UInt32>(15526, writable: true)] private UInt32 _battery2Activation; // 0x3CA6
|
|
||||||
|
|
||||||
|
|
||||||
// ───────────────────────────────────────────────
|
// ───────────────────────────────────────────────
|
||||||
|
|
@ -310,4 +309,49 @@ public partial class SinexcelRecord
|
||||||
[HoldingRegister<UInt32>(41236)] private UInt32 _electricMeterBPhaseActivePower; // 0xA114
|
[HoldingRegister<UInt32>(41236)] private UInt32 _electricMeterBPhaseActivePower; // 0xA114
|
||||||
[HoldingRegister<UInt32>(41238)] private UInt32 _electricMeterCPhaseActivePower; // 0xA116
|
[HoldingRegister<UInt32>(41238)] private UInt32 _electricMeterCPhaseActivePower; // 0xA116
|
||||||
|
|
||||||
|
// ───────────────────────────────────────────────
|
||||||
|
// Battery Cabinet 1 — Energy / Pack measurements (read-only)
|
||||||
|
// ───────────────────────────────────────────────
|
||||||
|
[HoldingRegister<UInt32>(45308)] private UInt32 _batteryCab1TotalChargingEnergy; // 0xB0FC kW·h
|
||||||
|
[HoldingRegister<UInt32>(45310)] private UInt32 _batteryCab1TotalDischargedEnergy; // 0xB0FE kW·h
|
||||||
|
|
||||||
|
[HoldingRegister<UInt32>(45312)] private UInt32 _batteryCab1PackTotalVoltage; // 0xB100 (resolution 0.01 V)
|
||||||
|
[HoldingRegister<UInt32>(45314)] private UInt32 _batteryCab1PackTotalCurrent; // 0xB102 (resolution 0.01 A)
|
||||||
|
[HoldingRegister<UInt32>(45316)] private UInt32 _batteryCab1Temperature; // 0xB104 (resolution 0.01 °C)
|
||||||
|
[HoldingRegister<UInt32>(45318)] private UInt32 _batteryCab1Soc; // 0xB106 %
|
||||||
|
[HoldingRegister<UInt32>(45320)] private UInt32 _batteryCab1Soh; // 0xB108 %
|
||||||
|
|
||||||
|
// ───────────────────────────────────────────────
|
||||||
|
// Battery Cabinet 2 — Energy / Pack Measurements (Read-Only)
|
||||||
|
// ───────────────────────────────────────────────
|
||||||
|
[HoldingRegister<UInt32>(45564)] private UInt32 _batteryCab2TotalChargingEnergy; // 0xB1FC kW·h
|
||||||
|
[HoldingRegister<UInt32>(45566)] private UInt32 _batteryCab2TotalDischargedEnergy; // 0xB1FE kW·h
|
||||||
|
|
||||||
|
[HoldingRegister<UInt32>(45568)] private UInt32 _batteryCab2PackTotalVoltage; // 0xB200 (0.01 V)
|
||||||
|
[HoldingRegister<UInt32>(45570)] private UInt32 _batteryCab2PackTotalCurrent; // 0xB202 (0.01 A)
|
||||||
|
[HoldingRegister<UInt32>(45572)] private UInt32 _batteryCab2Temperature; // 0xB204 (0.01 °C)
|
||||||
|
[HoldingRegister<UInt32>(45574)] private UInt32 _batteryCab2Soc; // 0xB206 %
|
||||||
|
[HoldingRegister<UInt32>(45576)] private UInt32 _batteryCab2Soh; // 0xB208 %
|
||||||
|
|
||||||
|
// ───────────────────────────────────────────────
|
||||||
|
// Time-based scheduling (period 1) configuration
|
||||||
|
// ───────────────────────────────────────────────
|
||||||
|
|
||||||
|
//[HoldingRegister<UInt32>(49328, writable: true)] private UInt32 _Timed_Charge_and_Discharge_Off; // 0xC0B4, bit flags Sun–Sat
|
||||||
|
//[HoldingRegister<UInt32>(49330, writable: true)] private UInt32 _Other_time_period_mode; // 0xC0B4, bit flags Sun–Sat
|
||||||
|
[HoldingRegister<UInt32>(49332, writable: true)] private UInt32 _repetitiveWeeks; // 0xC0B4, bit flags Sun–Sat
|
||||||
|
[HoldingRegister<UInt32>(49334, writable: true)] private UInt32 _effectiveStartDate; // 0xC0B6, UNIX timestamp (UTC+offset)
|
||||||
|
[HoldingRegister<UInt32>(49336, writable: true)] private UInt32 _effectiveEndDate; // 0xC0B8, UNIX timestamp (UTC+offset)
|
||||||
|
[HoldingRegister<UInt32>(49338, writable: true)] private UInt32 _chargingPowerPeriod1; // 0xC0BA, float [0–50] kW, default 5
|
||||||
|
[HoldingRegister<UInt32>(49340, writable: true)] private UInt32 _dischargingPowerPeriod1; // 0xC0BA, float [0–50] kW, default 5
|
||||||
|
|
||||||
|
|
||||||
|
// ───────────────────────────────────────────────
|
||||||
|
// Time-based charge/discharge schedule period 1
|
||||||
|
// ───────────────────────────────────────────────
|
||||||
|
[HoldingRegister<UInt32>(49172, writable: true)] private UInt32 _chargeStartTimePeriod1; // 0xC014 [0-2359] (start)
|
||||||
|
[HoldingRegister<UInt32>(49174, writable: true)] private UInt32 _chargeEndTimePeriod1; // 0xC016 [0-2359] (end)
|
||||||
|
[HoldingRegister<UInt32>(49176, writable: true)] private UInt32 _dischargeStartTimePeriod1; // 0xC018 [0-2359] (start)
|
||||||
|
[HoldingRegister<UInt32>(49178, writable: true)] private UInt32 _dischargeEndTimePeriod1; // 0xC01A [0-2359] (end)
|
||||||
|
|
||||||
}
|
}
|
||||||
Loading…
Reference in New Issue