diff --git a/csharp/App/SodiStoreMax/src/Program.cs b/csharp/App/SodiStoreMax/src/Program.cs index 10e3ca99e..ec9f2e542 100644 --- a/csharp/App/SodiStoreMax/src/Program.cs +++ b/csharp/App/SodiStoreMax/src/Program.cs @@ -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) {