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
csharp/App/SodiStoreMax/src

View File

@ -1,4 +1,4 @@
#undef Amax
#define Amax
#undef GridLimit
using System.Diagnostics;
@ -54,7 +54,6 @@ internal static class Program
private static readonly Channel PvOnAcGrid;
private static readonly Channel PvOnAcIsland;
private static readonly Channel RelaysChannel;
private static readonly Channel RelaysTsChannel;
private static readonly Channel BatteriesChannel;
private static Boolean _curtailFlag = false;
@ -86,7 +85,6 @@ internal static class Program
PvOnAcGrid = CreateChannel(d.PvOnAcGrid);
PvOnAcIsland = CreateChannel(d.PvOnAcIsland);
RelaysChannel = CreateChannel(d.RelaysIp);
RelaysTsChannel = CreateChannel(d.TsRelaysIp);
BatteriesChannel = CreateChannel(d.BatteryIp);
BatteryNodes = config
@ -140,29 +138,25 @@ internal static class Program
var pvOnDcDevice = new AmptDevices(PvOnDc);
var pvOnAcGridDevice = new AmptDevices(PvOnAcGrid);
var pvOnAcIslandDevice = new AmptDevices(PvOnAcIsland);
var saliMaxTsRelaysDevice = new RelaysDeviceAdam6060(RelaysTsChannel);
#if Amax
var saliMaxRelaysDevice = new RelaysDeviceAmax(RelaysChannel);
var saliMaxRelaysDevice = new RelaysDeviceAmax(RelaysChannel);
#else
var saliMaxRelaysDevice = new RelaysDeviceAdam6360(RelaysChannel);
#endif
var saliMaxRelaysDevice = new RelaysDevice(RelaysChannel);
#endif
StatusRecord ReadStatus()
{
{
var config = Config.Load();
var devices = config.Devices;
var acDc = acDcDevices.Read();
var dcDc = dcDcDevices.Read();
var relays = saliMaxRelaysDevice.Read();
var tsRelays = saliMaxTsRelaysDevice.Read();
var loadOnAcIsland = acIslandLoadMeter.Read();
var gridMeter = gridMeterDevice.Read();
var pvOnDc = pvOnDcDevice.Read();
var battery = batteryDevices.Read();
var pvOnAcGrid = pvOnAcGridDevice.Read();
var pvOnAcIsland = pvOnAcIslandDevice.Read();
@ -180,18 +174,13 @@ internal static class Program
Topology.CalculateAcDcToDcLink(pvOnDc, dcDc, acDc)
: new DcPowerDevice{ Power = acDc.Dc.Power};
#if Amax
var combinedRelays = relays;
#else
var combinedRelays = new CombinedAdamRelaysRecord(tsRelays, relays);
#endif
return new StatusRecord
{
AcDc = acDc,
DcDc = dcDc,
Battery = battery,
Relays = combinedRelays,
Relays = relays,
GridMeter = gridMeter,
PvOnAcGrid = pvOnAcGrid,
PvOnAcIsland = pvOnAcIsland,
@ -215,13 +204,9 @@ internal static class Program
#if Amax
saliMaxRelaysDevice.Write((RelaysRecordAmax)r.Relays);
#else
if (r.Relays is CombinedAdamRelaysRecord adamRelays)
{
saliMaxRelaysDevice.Write(adamRelays.GetAdam6360DRecord() ?? throw new InvalidOperationException());
saliMaxTsRelaysDevice.Write(adamRelays.GetAdam6060Record() ?? throw new InvalidOperationException());
}
((RelaysDevice)saliMaxRelaysDevice).Write((RelaysRecord)r.Relays);
#endif
}
acDcDevices.Write(r.AcDc);
@ -246,41 +231,13 @@ internal static class Program
Watchdog.NotifyAlive();
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
record.ControlConstants();
record.ControlSystemState();
record.ControlPvPower(record.Config.CurtailP, record.Config.PvInstalledPower);
//record.ControlPvPower(record.Config.CurtailP, record.Config.PvInstalledPower);
var essControl = record.ControlEss().WriteLine();
@ -291,10 +248,10 @@ internal static class Program
DistributePower(record, essControl);
record.PerformLed();
//record.PerformLed();
WriteControl(record);
$"{DateTime.Now.Round(UpdateInterval).ToUnixTime()} : {record.StateMachine.State}: {record.StateMachine.Message}".WriteLine();
record.CreateTopologyTextBlock().WriteLine();
@ -529,8 +486,13 @@ internal static class Program
var inverters = r.AcDc.Devices;
var dcDevices = r.DcDc.Devices;
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
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
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
// 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.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.ReferenceVoltage = devicesConfig.DcDc.ReferenceDcLinkVoltage);
dcDevices.ForEach(d => d.Control.CurrentControl.MaxBatteryChargingCurrent = devicesConfig.DcDc.MaxBatteryChargingCurrent);
dcDevices.ForEach(d => d.Control.CurrentControl.MaxBatteryDischargingCurrent = devicesConfig.DcDc.MaxBatteryDischargingCurrent);
dcDevices.ForEach(d => d.Control.CurrentControl.MaxBatteryChargingCurrent = maxBatteryChargingCurrentLive);
dcDevices.ForEach(d => d.Control.CurrentControl.MaxBatteryDischargingCurrent = maxBatteryDischargingCurrentLive);
dcDevices.ForEach(d => d.Control.MaxDcPower = devicesConfig.DcDc.MaxDcPower);
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
private static void PerformLed(this StatusRecord record)
/*private static void PerformLed(this StatusRecord record)
{
if (record.StateMachine.State == 23)
{
@ -751,7 +734,7 @@ internal static class Program
{
record.Relays?.PerformFastFlashingRedLed();
}
}
}*/
private static Double IncreaseInverterUpperLimit(Double upperLimit, Double stepSize)
{