Update the main program.cs for Growatt : More display and comment
This commit is contained in:
parent
5e45e51357
commit
b9a7c0859a
|
|
@ -1,26 +1,32 @@
|
||||||
using System.IO.Compression;
|
using System.Diagnostics;
|
||||||
using InnovEnergy.Lib.Devices.WITGrowatt4_15K;
|
using System.IO.Compression;
|
||||||
using System.IO.Ports;
|
using System.IO.Ports;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
using System.Xml;
|
|
||||||
using Flurl.Http;
|
using Flurl.Http;
|
||||||
|
|
||||||
|
using System.Reactive.Linq;
|
||||||
|
using System.Reactive.Threading.Tasks;
|
||||||
|
|
||||||
|
using InnovEnergy.Lib.Devices.WITGrowatt4_15K;
|
||||||
using InnovEnergy.App.GrowattCommunication.DataLogging;
|
using InnovEnergy.App.GrowattCommunication.DataLogging;
|
||||||
using InnovEnergy.App.GrowattCommunication.ESS;
|
using InnovEnergy.App.GrowattCommunication.ESS;
|
||||||
using InnovEnergy.App.GrowattCommunication.MiddlewareClasses;
|
using InnovEnergy.App.GrowattCommunication.MiddlewareClasses;
|
||||||
using InnovEnergy.App.GrowattCommunication.SystemConfig;
|
using InnovEnergy.App.GrowattCommunication.SystemConfig;
|
||||||
using InnovEnergy.Lib.Protocols.Modbus.Channels;
|
using InnovEnergy.Lib.Protocols.Modbus.Channels;
|
||||||
|
using InnovEnergy.App.GrowattCommunication.DataTypes;
|
||||||
|
|
||||||
using InnovEnergy.Lib.Units;
|
using InnovEnergy.Lib.Units;
|
||||||
using InnovEnergy.Lib.Utils;
|
using InnovEnergy.Lib.Utils;
|
||||||
|
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using Formatting = Newtonsoft.Json.Formatting;
|
using Formatting = Newtonsoft.Json.Formatting;
|
||||||
using JsonSerializer = System.Text.Json.JsonSerializer;
|
using JsonSerializer = System.Text.Json.JsonSerializer;
|
||||||
using System.Diagnostics.CodeAnalysis;
|
|
||||||
using System.Reactive.Linq;
|
|
||||||
using System.Reactive.Threading.Tasks;
|
|
||||||
using InnovEnergy.App.GrowattCommunication.DataTypes;
|
|
||||||
using InnovEnergy.Lib.Devices.WITGrowatt4_15K.DataType;
|
using InnovEnergy.Lib.Devices.WITGrowatt4_15K.DataType;
|
||||||
using static InnovEnergy.App.GrowattCommunication.MiddlewareClasses.MiddlewareAgent;
|
using static InnovEnergy.App.GrowattCommunication.MiddlewareClasses.MiddlewareAgent;
|
||||||
|
using System.Diagnostics.CodeAnalysis;
|
||||||
|
#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.GrowattCommunication;
|
namespace InnovEnergy.App.GrowattCommunication;
|
||||||
|
|
||||||
|
|
@ -69,7 +75,7 @@ public static class Program
|
||||||
e.LogError();
|
e.LogError();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// ReSharper disable once FunctionNeverReturns
|
||||||
}
|
}
|
||||||
|
|
||||||
[RequiresUnreferencedCode("Calls InnovEnergy.App.GrowattCommunication.Program.SaveModbusTcpFile(StatusRecord)")]
|
[RequiresUnreferencedCode("Calls InnovEnergy.App.GrowattCommunication.Program.SaveModbusTcpFile(StatusRecord)")]
|
||||||
|
|
@ -124,16 +130,18 @@ public static class Program
|
||||||
SendSalimaxStateAlarm(GetSodiHomeStateAlarm(statusrecord),statusrecord);
|
SendSalimaxStateAlarm(GetSodiHomeStateAlarm(statusrecord),statusrecord);
|
||||||
|
|
||||||
//await DataLogging(statusrecord, timestamp); // save a csv file locally
|
//await DataLogging(statusrecord, timestamp); // save a csv file locally
|
||||||
//await SaveModbusTcpFile(statusrecord); // save the json file for modbuscTCP
|
//await SaveModbusTcpFile(statusrecord); // save the JSON file for modbuscTCP
|
||||||
|
|
||||||
|
Debug.Assert(statusrecord != null, nameof(statusrecord) + " != null");
|
||||||
statusrecord.AcDcGrowatt.RemotePowerControl.WriteLine(" = RemotePowerControl");
|
statusrecord.AcDcGrowatt.RemotePowerControl.WriteLine(" = RemotePowerControl");
|
||||||
|
statusrecord.AcDcGrowatt.EnableEmsCommunicationFailureTime.WriteLine(" = EnableEmsCommunicationFailureTime");
|
||||||
|
|
||||||
statusrecord.AcDcGrowatt.EnableCommand.WriteLine(" = EnableCommand");
|
statusrecord.AcDcGrowatt.EnableCommand.WriteLine(" = EnableCommand");
|
||||||
statusrecord.AcDcGrowatt.ControlPermession.WriteLine(" ControlPermession");
|
statusrecord.AcDcGrowatt.ControlPermession.WriteLine(" = ControlPermession");
|
||||||
statusrecord.AcDcGrowatt.MeterPower.WriteLine(" MeterPower");
|
statusrecord.AcDcGrowatt.MeterPower.WriteLine(" MeterPower");
|
||||||
statusrecord.AcDcGrowatt.GridMeterPower.WriteLine(" GridMeterPower");
|
statusrecord.AcDcGrowatt.ConsumptionPower.WriteLine(" ConsumptionPower");
|
||||||
var x = CalculateActivePower(statusrecord);
|
statusrecord.AcDcGrowatt.ExportedPowerToGridMeter.WriteLine(" ExportedPowerToGrid");
|
||||||
x.WriteLine(" Calculated Grid Power");
|
statusrecord.AcDcGrowatt.ImportedPowerFromGrid.WriteLine(" ImportedPowerFromGrid");
|
||||||
statusrecord.AcDcGrowatt.InverterActivePower.WriteLine(" InverterActivePower");
|
statusrecord.AcDcGrowatt.InverterActivePower.WriteLine(" InverterActivePower");
|
||||||
statusrecord.AcDcGrowatt.BatteryChargeCutoffVoltage.WriteLine(" BatteryChargeCutoffVoltage "); //30409 we set power here
|
statusrecord.AcDcGrowatt.BatteryChargeCutoffVoltage.WriteLine(" BatteryChargeCutoffVoltage "); //30409 we set power here
|
||||||
statusrecord.AcDcGrowatt.BatteryDischargeCutoffVoltage.WriteLine(" BatteryDishargeCutoffVoltage "); //30409 we set power here
|
statusrecord.AcDcGrowatt.BatteryDischargeCutoffVoltage.WriteLine(" BatteryDishargeCutoffVoltage "); //30409 we set power here
|
||||||
|
|
@ -144,7 +152,11 @@ public static class Program
|
||||||
statusrecord.AcDcGrowatt.Batteries[0].Voltage.WriteLine(" Battery Voltage");
|
statusrecord.AcDcGrowatt.Batteries[0].Voltage.WriteLine(" Battery Voltage");
|
||||||
statusrecord.AcDcGrowatt.BatteryMaxChargeCurrent.WriteLine(" BatteryMaxChargeCurrent "); //30409 we set power here
|
statusrecord.AcDcGrowatt.BatteryMaxChargeCurrent.WriteLine(" BatteryMaxChargeCurrent "); //30409 we set power here
|
||||||
statusrecord.AcDcGrowatt.BatteryMaxdischargeCurrent.WriteLine(" BatteryMaxDischargeCurrent "); //30409 we set power here
|
statusrecord.AcDcGrowatt.BatteryMaxdischargeCurrent.WriteLine(" BatteryMaxDischargeCurrent "); //30409 we set power here
|
||||||
|
statusrecord.AcDcGrowatt.DischargeCutoffSoc.WriteLine(" DischargeCutoffSoc "); //30409 we set power here
|
||||||
|
statusrecord.AcDcGrowatt.ChargeCutoffSoc.WriteLine(" ChargeCutoffSoc "); //30409 we set power here
|
||||||
|
|
||||||
|
statusrecord.AcDcGrowatt.TotalPvPower.WriteLine(" Pv Power "); //30409 we set power here
|
||||||
|
|
||||||
statusrecord.AcDcGrowatt.SystemOperatingMode.WriteLine(" = SystemOperatingMode");
|
statusrecord.AcDcGrowatt.SystemOperatingMode.WriteLine(" = SystemOperatingMode");
|
||||||
statusrecord.AcDcGrowatt.BatteryOperatingMode.WriteLine(" = BatteryOperatingMode");
|
statusrecord.AcDcGrowatt.BatteryOperatingMode.WriteLine(" = BatteryOperatingMode");
|
||||||
statusrecord.AcDcGrowatt.OperatingPriority.WriteLine(" = OperatingPriority"); // 30408 this the duration
|
statusrecord.AcDcGrowatt.OperatingPriority.WriteLine(" = OperatingPriority"); // 30408 this the duration
|
||||||
|
|
@ -171,38 +183,12 @@ public static class Program
|
||||||
{
|
{
|
||||||
// Handle exception and print the error
|
// Handle exception and print the error
|
||||||
Console.WriteLine(e );
|
Console.WriteLine(e );
|
||||||
// await Task.Delay(2000); // Delay in milliseconds (2000ms = 2 seconds)
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static double CalculateActivePower(this StatusRecord? status)
|
|
||||||
{
|
|
||||||
// Convert raw registers to engineering units
|
|
||||||
double Vab = status.AcDcGrowatt.GridAbLineVoltage * 0.1;
|
|
||||||
double Vbc = status.AcDcGrowatt.GridBcLineVoltage * 0.1;
|
|
||||||
double Vca = status.AcDcGrowatt.GridCaLineVoltage * 0.1;
|
|
||||||
double Ia = status.AcDcGrowatt.PhaseACurrent * 0.1;
|
|
||||||
double Ib = status.AcDcGrowatt.PhaseBCurrent * 0.1;
|
|
||||||
double Ic = status.AcDcGrowatt.PhaseCCurrent * 0.1;
|
|
||||||
|
|
||||||
// Average line-to-line voltage
|
|
||||||
double Vll = (Vab + Vbc + Vca) / 3.0;
|
|
||||||
|
|
||||||
// Average line current (absolute values, in case of signed currents)
|
|
||||||
double Il = (Math.Abs(Ia) + Math.Abs(Ib) + Math.Abs(Ic)) / 3.0;
|
|
||||||
|
|
||||||
// Apparent power (kVA)
|
|
||||||
double S_kVA = Math.Sqrt(3) * Vll * Il / 1000.0;
|
|
||||||
|
|
||||||
// Active power (kW)
|
|
||||||
double P_kW = S_kVA * 1;
|
|
||||||
|
|
||||||
return P_kW;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void ApplyConfigFile(this StatusRecord? status, Configuration? config)
|
private static void ApplyConfigFile(this StatusRecord? status, Configuration? config)
|
||||||
{
|
{
|
||||||
if (config == null) return;
|
if (config == null) return;
|
||||||
|
|
@ -212,7 +198,8 @@ public static class Program
|
||||||
status.Config.GridSetPoint = config.GridSetPoint * 1000; // converted from kW to W
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String EssModeControl(StatusRecord? statusrecord)
|
private static String EssModeControl(StatusRecord? statusrecord)
|
||||||
|
|
@ -347,11 +334,11 @@ public static class Program
|
||||||
st.AcDcGrowatt.BatteryMaxdischargeCurrent = st.Config.MaximumDischargingCurrent ;
|
st.AcDcGrowatt.BatteryMaxdischargeCurrent = st.Config.MaximumDischargingCurrent ;
|
||||||
st.AcDcGrowatt.DischargeCutoffSoc = st.Config.MinSoc;
|
st.AcDcGrowatt.DischargeCutoffSoc = st.Config.MinSoc;
|
||||||
st.AcDcGrowatt.EmsCommunicationFailureTime = 20; // 20 sec
|
st.AcDcGrowatt.EmsCommunicationFailureTime = 20; // 20 sec
|
||||||
st.AcDcGrowatt.EnableEmsCommunicationFailureTime = true;
|
st.AcDcGrowatt.EnableEmsCommunicationFailureTime = false;
|
||||||
st.AcDcGrowatt.EnableCommand = true;
|
st.AcDcGrowatt.EnableCommand = true;
|
||||||
st.AcDcGrowatt.ControlPermession = true;
|
st.AcDcGrowatt.ControlPermession = true;
|
||||||
st.AcDcGrowatt.BatteryChargeCutoffVoltage = 60; //st.Config.BatteryChargeCutoffVoltage;
|
st.AcDcGrowatt.BatteryChargeCutoffVoltage = 60; //st.Config.BatteryChargeCutoffVoltage;
|
||||||
st.AcDcGrowatt.BatteryDischargeCutoffVoltage = 20; //st.Config.BatteryDischargeCutoffVoltage;
|
st.AcDcGrowatt.BatteryDischargeCutoffVoltage = 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)
|
||||||
|
|
@ -392,12 +379,9 @@ public static class Program
|
||||||
private static async Task<Boolean> SaveModbusTcpFile(StatusRecord status)
|
private static async Task<Boolean> SaveModbusTcpFile(StatusRecord status)
|
||||||
{
|
{
|
||||||
var modbusData = new Dictionary<String, UInt16>();
|
var modbusData = new Dictionary<String, UInt16>();
|
||||||
const Double protcolNumber = 1.1; // to be communicated by yinyin maybe add this to config file
|
|
||||||
var pv1Power = status.AcDcGrowatt.Pv1Current * status.AcDcGrowatt.Pv1Voltage;
|
|
||||||
var pv2Power = status.AcDcGrowatt.Pv2Current * status.AcDcGrowatt.Pv2Voltage;
|
|
||||||
|
|
||||||
// SYSTEM DATA
|
// SYSTEM DATA
|
||||||
var result1 = ConvertToModbusRegisters((protcolNumber * 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.AcDcGrowatt.SystemDateTime.ToUnixTime(), "UInt32", 30002);
|
var result2 = ConvertToModbusRegisters(status.AcDcGrowatt.SystemDateTime.ToUnixTime(), "UInt32", 30002);
|
||||||
var result3 = ConvertToModbusRegisters(status.AcDcGrowatt.SystemOperatingMode, "UInt16", 30004);
|
var result3 = ConvertToModbusRegisters(status.AcDcGrowatt.SystemOperatingMode, "UInt16", 30004);
|
||||||
var result17 = ConvertToModbusRegisters(status.AcDcGrowatt.OperatingPriority, "UInt16", 30005);
|
var result17 = ConvertToModbusRegisters(status.AcDcGrowatt.OperatingPriority, "UInt16", 30005);
|
||||||
|
|
@ -405,33 +389,30 @@ public static class Program
|
||||||
// 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 battery = status.AcDcGrowatt.BatteriesRecords!.Batteries[0];
|
||||||
|
|
||||||
var result4 = ConvertToModbusRegisters((status.AcDcGrowatt.BatteriesRecords!.Batteries.Count ), "UInt16", 30099);
|
var result4 = ConvertToModbusRegisters((status.Config.BatteriesCount ), "UInt16", 31000);
|
||||||
var result5 = ConvertToModbusRegisters((battery.Power.Value * 10), "Int32", 31001);
|
var result8 = ConvertToModbusRegisters((status.AcDcGrowatt.BatteryOperatingMode), "UInt16", 31001);
|
||||||
var result6 = ConvertToModbusRegisters((battery.DailyChargeEnergy.Value * 10), "UInt32", 31003);
|
var result12 = ConvertToModbusRegisters((battery.Voltage.Value * 10), "Int16", 31002);
|
||||||
var result7 = ConvertToModbusRegisters((battery.AccumulatedChargeEnergy.Value * 10), "UInt32", 31005);
|
var result13 = ConvertToModbusRegisters((battery.Current.Value * 10), "Int32", 31003);
|
||||||
var result8 = ConvertToModbusRegisters((battery.DailyDischargeEnergy.Value * 10), "UInt32", 31007);
|
var result14 = ConvertToModbusRegisters((battery.Soc.Value * 100), "UInt16", 31005);
|
||||||
var result9 = ConvertToModbusRegisters((battery.AccumulatedDischargeEnergy.Value * 10), "UInt32", 31009);
|
var result5 = ConvertToModbusRegisters((battery.Power.Value * 10), "Int32", 31006);
|
||||||
var result10 = ConvertToModbusRegisters((battery.MaxAllowableDischargePower.Value * 10), "UInt32", 31011);
|
|
||||||
var result11 = ConvertToModbusRegisters((battery.MaxAllowableDischargePower.Value * 10), "UInt32", 31013);
|
|
||||||
|
|
||||||
var result12 = ConvertToModbusRegisters((battery.Voltage.Value * 10), "Int16", 31016);
|
var result7 = ConvertToModbusRegisters((status.AcDcGrowatt.DischargeCutoffSoc * 100), "UInt16", 31008);
|
||||||
var result13 = ConvertToModbusRegisters((battery.Current.Value * 10), "Int32", 31017);
|
var result20 = ConvertToModbusRegisters((status.AcDcGrowatt.ChargeCutoffSoc * 100), "UInt16", 31009);
|
||||||
var result14 = ConvertToModbusRegisters((battery.Soc.Value * 100), "UInt16", 31019);
|
var result15 = ConvertToModbusRegisters((status.AcDcGrowatt.BatteriesRecords!.AverageSoh * 100), "UInt16", 310010);
|
||||||
var result15 = ConvertToModbusRegisters((status.AcDcGrowatt.BatteriesRecords!.AverageSoh * 100), "UInt16", 31022);
|
var result16 = ConvertToModbusRegisters((battery.BatteryAmbientTemperature.Value * 100), "UInt16", 31011);
|
||||||
var result16 = ConvertToModbusRegisters((battery.BatteryAmbientTemperature.Value * 100), "UInt16", 31023);
|
var result21 = ConvertToModbusRegisters((status.AcDcGrowatt.BatteryMaxChargeCurrent * 10), "UInt16", 31012);
|
||||||
var result18 = ConvertToModbusRegisters(((pv1Power + pv2Power) * 10), "UInt32", 31999);
|
var result22 = ConvertToModbusRegisters((status.AcDcGrowatt.BatteryMaxdischargeCurrent * 10), "UInt16", 31013);
|
||||||
var result19 = ConvertToModbusRegisters((status.AcDcGrowatt.GridMeterPower.Value * 10), "Int32", 32999);
|
var result23 = ConvertToModbusRegisters((status.AcDcGrowatt.BatteryChargeCutoffVoltage * 10), "UInt16", 31014);
|
||||||
var result20 = ConvertToModbusRegisters((status.AcDcGrowatt.DischargeCutoffSoc * 100), "UInt16", 31020);
|
|
||||||
var result21 = ConvertToModbusRegisters((status.AcDcGrowatt.BatteryMaxChargeCurrent * 10), "UInt16", 31024);
|
var result18 = ConvertToModbusRegisters((status.AcDcGrowatt.TotalPvPower.Value * 10), "UInt32", 32000);
|
||||||
var result22 = ConvertToModbusRegisters((status.AcDcGrowatt.BatteryMaxdischargeCurrent * 10), "UInt16", 31025);
|
var result19 = ConvertToModbusRegisters((status.AcDcGrowatt.MeterPower * 10), "Int32", 33000);
|
||||||
var result23 = ConvertToModbusRegisters((status.AcDcGrowatt.BatteryChargeCutoffVoltage * 10), "UInt16", 31026);
|
|
||||||
|
|
||||||
|
|
||||||
// Merge all results into one dictionary
|
// Merge all results into one dictionary
|
||||||
var allResults = new[]
|
var allResults = new[]
|
||||||
{
|
{
|
||||||
result1,result2, result3, result17, result4, result5, result6, result7, result8,
|
result1,result2, result3, result17, result4, result5, result7, result8,
|
||||||
result9, result10, result11, result12, result13, result14, result15, result16, result18, result19,result20,
|
result12, result13, result14, result15, result16, result18, result19,result20,
|
||||||
result21, result22, result23
|
result21, result22, result23
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -523,6 +504,7 @@ public static class Program
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static async Task SavingLocalCsvFile(Int64 timestamp, String csv)
|
private static async Task SavingLocalCsvFile(Int64 timestamp, String csv)
|
||||||
{
|
{
|
||||||
const String directoryPath = "/home/inesco/SodiStoreHome/csvFile";
|
const String directoryPath = "/home/inesco/SodiStoreHome/csvFile";
|
||||||
|
|
@ -626,7 +608,7 @@ public static class Program
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void Heartbit()
|
private static void Heartbit()
|
||||||
{ /*
|
{
|
||||||
var s3Bucket = Config.Load().S3?.Bucket;
|
var s3Bucket = Config.Load().S3?.Bucket;
|
||||||
var tryParse = int.TryParse(s3Bucket?.Split("-")[0], out var installationId);
|
var tryParse = int.TryParse(s3Bucket?.Split("-")[0], out var installationId);
|
||||||
|
|
||||||
|
|
@ -641,10 +623,10 @@ public static class Program
|
||||||
};
|
};
|
||||||
if (s3Bucket != null)
|
if (s3Bucket != null)
|
||||||
RabbitMqManager.InformMiddleware(returnedStatus);
|
RabbitMqManager.InformMiddleware(returnedStatus);
|
||||||
}*/
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static async Task SaveToLocalCompressedFallback(Byte[] compressedData, String fileNameWithoutExtension)
|
private static async Task SaveToLocalCompressedFallback(Byte[] compressedData, String fileNameWithoutExtension)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue