update Sodistoremax application

This commit is contained in:
atef 2025-03-14 13:26:38 +01:00
parent 37a8831585
commit 34849dde17
1 changed files with 44 additions and 61 deletions

View File

@ -1,4 +1,4 @@
#undef Amax #define Amax
#undef GridLimit #undef GridLimit
using System.Diagnostics; using System.Diagnostics;
@ -54,7 +54,6 @@ internal static class Program
private static readonly Channel PvOnAcGrid; private static readonly Channel PvOnAcGrid;
private static readonly Channel PvOnAcIsland; private static readonly Channel PvOnAcIsland;
private static readonly Channel RelaysChannel; private static readonly Channel RelaysChannel;
private static readonly Channel RelaysTsChannel;
private static readonly Channel BatteriesChannel; private static readonly Channel BatteriesChannel;
private static Boolean _curtailFlag = false; private static Boolean _curtailFlag = false;
@ -86,7 +85,6 @@ internal static class Program
PvOnAcGrid = CreateChannel(d.PvOnAcGrid); PvOnAcGrid = CreateChannel(d.PvOnAcGrid);
PvOnAcIsland = CreateChannel(d.PvOnAcIsland); PvOnAcIsland = CreateChannel(d.PvOnAcIsland);
RelaysChannel = CreateChannel(d.RelaysIp); RelaysChannel = CreateChannel(d.RelaysIp);
RelaysTsChannel = CreateChannel(d.TsRelaysIp);
BatteriesChannel = CreateChannel(d.BatteryIp); BatteriesChannel = CreateChannel(d.BatteryIp);
BatteryNodes = config BatteryNodes = config
@ -140,29 +138,25 @@ internal static class Program
var pvOnDcDevice = new AmptDevices(PvOnDc); var pvOnDcDevice = new AmptDevices(PvOnDc);
var pvOnAcGridDevice = new AmptDevices(PvOnAcGrid); var pvOnAcGridDevice = new AmptDevices(PvOnAcGrid);
var pvOnAcIslandDevice = new AmptDevices(PvOnAcIsland); var pvOnAcIslandDevice = new AmptDevices(PvOnAcIsland);
var saliMaxTsRelaysDevice = new RelaysDeviceAdam6060(RelaysTsChannel);
#if Amax #if Amax
var saliMaxRelaysDevice = new RelaysDeviceAmax(RelaysChannel); var saliMaxRelaysDevice = new RelaysDeviceAmax(RelaysChannel);
#else #else
var saliMaxRelaysDevice = new RelaysDeviceAdam6360(RelaysChannel); var saliMaxRelaysDevice = new RelaysDevice(RelaysChannel);
#endif #endif
StatusRecord ReadStatus() StatusRecord ReadStatus()
{ {
var config = Config.Load(); var config = Config.Load();
var devices = config.Devices; var devices = config.Devices;
var acDc = acDcDevices.Read(); var acDc = acDcDevices.Read();
var dcDc = dcDcDevices.Read(); var dcDc = dcDcDevices.Read();
var relays = saliMaxRelaysDevice.Read(); var relays = saliMaxRelaysDevice.Read();
var tsRelays = saliMaxTsRelaysDevice.Read();
var loadOnAcIsland = acIslandLoadMeter.Read(); var loadOnAcIsland = acIslandLoadMeter.Read();
var gridMeter = gridMeterDevice.Read(); var gridMeter = gridMeterDevice.Read();
var pvOnDc = pvOnDcDevice.Read(); var pvOnDc = pvOnDcDevice.Read();
var battery = batteryDevices.Read(); var battery = batteryDevices.Read();
var pvOnAcGrid = pvOnAcGridDevice.Read(); var pvOnAcGrid = pvOnAcGridDevice.Read();
var pvOnAcIsland = pvOnAcIslandDevice.Read(); var pvOnAcIsland = pvOnAcIslandDevice.Read();
@ -180,18 +174,13 @@ internal static class Program
Topology.CalculateAcDcToDcLink(pvOnDc, dcDc, acDc) Topology.CalculateAcDcToDcLink(pvOnDc, dcDc, acDc)
: new DcPowerDevice{ Power = acDc.Dc.Power}; : new DcPowerDevice{ Power = acDc.Dc.Power};
#if Amax
var combinedRelays = relays;
#else
var combinedRelays = new CombinedAdamRelaysRecord(tsRelays, relays);
#endif
return new StatusRecord return new StatusRecord
{ {
AcDc = acDc, AcDc = acDc,
DcDc = dcDc, DcDc = dcDc,
Battery = battery, Battery = battery,
Relays = combinedRelays, Relays = relays,
GridMeter = gridMeter, GridMeter = gridMeter,
PvOnAcGrid = pvOnAcGrid, PvOnAcGrid = pvOnAcGrid,
PvOnAcIsland = pvOnAcIsland, PvOnAcIsland = pvOnAcIsland,
@ -215,13 +204,9 @@ internal static class Program
#if Amax #if Amax
saliMaxRelaysDevice.Write((RelaysRecordAmax)r.Relays); saliMaxRelaysDevice.Write((RelaysRecordAmax)r.Relays);
#else #else
((RelaysDevice)saliMaxRelaysDevice).Write((RelaysRecord)r.Relays);
if (r.Relays is CombinedAdamRelaysRecord adamRelays)
{
saliMaxRelaysDevice.Write(adamRelays.GetAdam6360DRecord() ?? throw new InvalidOperationException());
saliMaxTsRelaysDevice.Write(adamRelays.GetAdam6060Record() ?? throw new InvalidOperationException());
}
#endif #endif
} }
acDcDevices.Write(r.AcDc); acDcDevices.Write(r.AcDc);
@ -246,41 +231,13 @@ internal static class Program
Watchdog.NotifyAlive(); Watchdog.NotifyAlive();
var record = ReadStatus(); var record = ReadStatus();
/*
if (record.Relays != null)
{
record.Relays.Do0StartPulse = true;
record.Relays.PulseOut0HighTime = 20000;
record.Relays.PulseOut0LowTime = 20000;
record.Relays.DigitalOutput0Mode = 2;
record.Relays.LedGreen = false;
record.Relays.Do0StartPulse.WriteLine(" = start pulse 0");
record.Relays.PulseOut0HighTime.WriteLine(" = PulseOut0HighTime");
record.Relays.PulseOut0LowTime.WriteLine(" = PulseOut0LowTime");
record.Relays.DigitalOutput0Mode.WriteLine(" = DigitalOutput0Mode");
record.Relays.LedGreen.WriteLine(" = LedGreen");
record.Relays.LedRed.WriteLine(" = LedRed");
}
else
{
" Relays are null".WriteLine();
}*/
SendSalimaxStateAlarm(GetSalimaxStateAlarm(record), record); // to improve SendSalimaxStateAlarm(GetSalimaxStateAlarm(record), record); // to improve
record.ControlConstants(); record.ControlConstants();
record.ControlSystemState(); record.ControlSystemState();
record.ControlPvPower(record.Config.CurtailP, record.Config.PvInstalledPower); //record.ControlPvPower(record.Config.CurtailP, record.Config.PvInstalledPower);
var essControl = record.ControlEss().WriteLine(); var essControl = record.ControlEss().WriteLine();
@ -291,10 +248,10 @@ internal static class Program
DistributePower(record, essControl); DistributePower(record, essControl);
record.PerformLed(); //record.PerformLed();
WriteControl(record); WriteControl(record);
$"{DateTime.Now.Round(UpdateInterval).ToUnixTime()} : {record.StateMachine.State}: {record.StateMachine.Message}".WriteLine(); $"{DateTime.Now.Round(UpdateInterval).ToUnixTime()} : {record.StateMachine.State}: {record.StateMachine.Message}".WriteLine();
record.CreateTopologyTextBlock().WriteLine(); record.CreateTopologyTextBlock().WriteLine();
@ -529,8 +486,13 @@ internal static class Program
var inverters = r.AcDc.Devices; var inverters = r.AcDc.Devices;
var dcDevices = r.DcDc.Devices; var dcDevices = r.DcDc.Devices;
var configFile = r.Config; var configFile = r.Config;
//var maxBatteryDischargingCurrentLive = 0.0; //never used with deligreenBattery
var devicesConfig = r.AcDc.Devices.All(d => d.Control.Ac.GridType == GridType.GridTied400V50Hz) ? configFile.GridTie : configFile.IslandMode; // TODO if any of the grid tie mode var devicesConfig = r.AcDc.Devices.All(d => d.Control.Ac.GridType == GridType.GridTied400V50Hz) ? configFile.GridTie : configFile.IslandMode; // TODO if any of the grid tie mode
Double maxBatteryChargingCurrentLive ; //used with deligreenBattery for limiting charging
Double maxBatteryDischargingCurrentLive; //used with deligreenBattery for limiting discharging
//var maxBatteryDischargingCurrentLive = 0.0; //never used with deligreenBattery
/* /*
// This adapting the max discharging current to the current Active Strings // This adapting the max discharging current to the current Active Strings
if (r.Battery != null) if (r.Battery != null)
@ -560,7 +522,28 @@ internal static class Program
} }
*/ */
// TODO The discharging current is well calculated but not communicated to live. But Written in S3 // TODO The discharging current is well calculated but not communicated to live. But Written in S3
// Deligreen upper current limitation dynCCL
if (r.Battery?.Voltage != null && (r.Battery?.Voltage ?? 0) > 61.0 )
{
maxBatteryChargingCurrentLive = r.Battery.Devices.Count * 10; // Max charging current is 10 A * Number of batteries
maxBatteryChargingCurrentLive.WriteLine("dynCCL Active: Max Battery Charging is "+ maxBatteryChargingCurrentLive);
}
else
{
maxBatteryChargingCurrentLive = devicesConfig.DcDc.MaxBatteryChargingCurrent;
}
// Deligreen lower current limitation dynDCL
if (r.Battery?.Soc != null && (r.Battery?.Soc ?? 100) < r.Config.MinSoc )
{
maxBatteryDischargingCurrentLive = 0; // Max charging current is 10 A * Number of batteries
maxBatteryDischargingCurrentLive.WriteLine("dynDCL Active: Max Battery disCharging is "+ maxBatteryDischargingCurrentLive);
}
else
{
maxBatteryDischargingCurrentLive = devicesConfig.DcDc.MaxBatteryDischargingCurrent;
}
inverters.ForEach(d => d.Control.Dc.MaxVoltage = devicesConfig.AcDc.MaxDcLinkVoltage); inverters.ForEach(d => d.Control.Dc.MaxVoltage = devicesConfig.AcDc.MaxDcLinkVoltage);
inverters.ForEach(d => d.Control.Dc.MinVoltage = devicesConfig.AcDc.MinDcLinkVoltage); inverters.ForEach(d => d.Control.Dc.MinVoltage = devicesConfig.AcDc.MinDcLinkVoltage);
@ -572,8 +555,8 @@ internal static class Program
dcDevices.ForEach(d => d.Control.DroopControl.LowerVoltage = devicesConfig.DcDc.LowerDcLinkVoltage); dcDevices.ForEach(d => d.Control.DroopControl.LowerVoltage = devicesConfig.DcDc.LowerDcLinkVoltage);
dcDevices.ForEach(d => d.Control.DroopControl.ReferenceVoltage = devicesConfig.DcDc.ReferenceDcLinkVoltage); dcDevices.ForEach(d => d.Control.DroopControl.ReferenceVoltage = devicesConfig.DcDc.ReferenceDcLinkVoltage);
dcDevices.ForEach(d => d.Control.CurrentControl.MaxBatteryChargingCurrent = devicesConfig.DcDc.MaxBatteryChargingCurrent); dcDevices.ForEach(d => d.Control.CurrentControl.MaxBatteryChargingCurrent = maxBatteryChargingCurrentLive);
dcDevices.ForEach(d => d.Control.CurrentControl.MaxBatteryDischargingCurrent = devicesConfig.DcDc.MaxBatteryDischargingCurrent); dcDevices.ForEach(d => d.Control.CurrentControl.MaxBatteryDischargingCurrent = maxBatteryDischargingCurrentLive);
dcDevices.ForEach(d => d.Control.MaxDcPower = devicesConfig.DcDc.MaxDcPower); dcDevices.ForEach(d => d.Control.MaxDcPower = devicesConfig.DcDc.MaxDcPower);
dcDevices.ForEach(d => d.Control.VoltageLimits.MaxBatteryVoltage = devicesConfig.DcDc.MaxChargeBatteryVoltage); dcDevices.ForEach(d => d.Control.VoltageLimits.MaxBatteryVoltage = devicesConfig.DcDc.MaxChargeBatteryVoltage);
@ -699,7 +682,7 @@ internal static class Program
} }
// To test, most probably the curtailing flag will not work // To test, most probably the curtailing flag will not work
private static void PerformLed(this StatusRecord record) /*private static void PerformLed(this StatusRecord record)
{ {
if (record.StateMachine.State == 23) if (record.StateMachine.State == 23)
{ {
@ -751,7 +734,7 @@ internal static class Program
{ {
record.Relays?.PerformFastFlashingRedLed(); record.Relays?.PerformFastFlashingRedLed();
} }
} }*/
private static Double IncreaseInverterUpperLimit(Double upperLimit, Double stepSize) private static Double IncreaseInverterUpperLimit(Double upperLimit, Double stepSize)
{ {