From e538f6dd7e3bf35f8a60948002b20da1f10d9404 Mon Sep 17 00:00:00 2001 From: ig Date: Mon, 11 Sep 2023 11:31:02 +0200 Subject: [PATCH 1/8] set Root Namespace for EmuMeterDriver --- csharp/App/EmuMeterDriver/EmuMeterDriver.csproj | 7 +++++++ csharp/App/EmuMeterDriver/Nic.cs | 12 ++++++------ 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/csharp/App/EmuMeterDriver/EmuMeterDriver.csproj b/csharp/App/EmuMeterDriver/EmuMeterDriver.csproj index 97bfb0569..5afaaff4a 100644 --- a/csharp/App/EmuMeterDriver/EmuMeterDriver.csproj +++ b/csharp/App/EmuMeterDriver/EmuMeterDriver.csproj @@ -1,5 +1,10 @@ + + + InnovEnergy.App.EmuMeterDriver + + @@ -13,5 +18,7 @@ + + diff --git a/csharp/App/EmuMeterDriver/Nic.cs b/csharp/App/EmuMeterDriver/Nic.cs index 0b81b0843..2c507cb8d 100644 --- a/csharp/App/EmuMeterDriver/Nic.cs +++ b/csharp/App/EmuMeterDriver/Nic.cs @@ -12,7 +12,7 @@ public readonly struct Nic private readonly JsonNode _Node; - public Nic(JsonNode node) + private Nic(JsonNode node) { _Node = node; } @@ -134,11 +134,11 @@ public readonly struct Nic .ExecuteBufferedAsync(); return JsonNode - .Parse(result.StandardOutput)! - .AsArray() - .Where(n=>n != null) - .Select(n=> new Nic(n!)) - .ToList(); + .Parse(result.StandardOutput)! + .AsArray() + .Where(n => n != null) + .Select(n => new Nic(n!)) + .ToList(); } catch { From 3a61b1e80b84d6dfc631c5ea675e68fd53ede030 Mon Sep 17 00:00:00 2001 From: ig Date: Mon, 11 Sep 2023 11:31:41 +0200 Subject: [PATCH 2/8] Add Zero --- csharp/Lib/Units/Composite/AcPower.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/csharp/Lib/Units/Composite/AcPower.cs b/csharp/Lib/Units/Composite/AcPower.cs index 38a83c742..bc345445c 100644 --- a/csharp/Lib/Units/Composite/AcPower.cs +++ b/csharp/Lib/Units/Composite/AcPower.cs @@ -3,7 +3,6 @@ using static System.Math; namespace InnovEnergy.Lib.Units.Composite; - public record AcPower { public required ActivePower Active { get; init; } @@ -31,4 +30,6 @@ public record AcPower public static implicit operator AcPower(Double p) => new AcPower { Active = p, Reactive = 0 }; public static implicit operator AcPower(Int32 p) => new AcPower { Active = p, Reactive = 0 }; + + public static AcPower Zero => new AcPower { Active = 0, Reactive = 0, }; } \ No newline at end of file From b213d9753784dedfdac24739c6ad8b72d1d4ca63 Mon Sep 17 00:00:00 2001 From: ig Date: Mon, 11 Sep 2023 11:32:53 +0200 Subject: [PATCH 3/8] resharper ignore "typo" --- csharp/App/SaliMax/src/Watchdog.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/csharp/App/SaliMax/src/Watchdog.cs b/csharp/App/SaliMax/src/Watchdog.cs index c738badaf..d2713ad8f 100644 --- a/csharp/App/SaliMax/src/Watchdog.cs +++ b/csharp/App/SaliMax/src/Watchdog.cs @@ -7,6 +7,7 @@ namespace InnovEnergy.App.SaliMax; public static class Watchdog { // "it is generally recommended to ignore the return value of this call. " + // ReSharper disable once StringLiteralTypo [DllImport("libsystemd.so.0")] private static extern Int32 sd_notify(Int32 unsetEnvironment, String state); From c51250a380cc06590e9db5944f8789072c78c78a Mon Sep 17 00:00:00 2001 From: atef Date: Tue, 12 Sep 2023 19:31:39 +0200 Subject: [PATCH 4/8] One try catch instead of two for DcDcDeviceRecord Read() --- .../Devices/Battery48TL/Battery48TlRecords.cs | 18 +++++++++--------- .../TruConvertDc/TruConvertDcDcDevices.cs | 16 +++------------- 2 files changed, 12 insertions(+), 22 deletions(-) diff --git a/csharp/Lib/Devices/Battery48TL/Battery48TlRecords.cs b/csharp/Lib/Devices/Battery48TL/Battery48TlRecords.cs index 445a78452..84129e61e 100644 --- a/csharp/Lib/Devices/Battery48TL/Battery48TlRecords.cs +++ b/csharp/Lib/Devices/Battery48TL/Battery48TlRecords.cs @@ -6,15 +6,15 @@ namespace InnovEnergy.Lib.Devices.Battery48TL; public class Battery48TlRecords { - public required DcBus Dc { get; init; } - public required Boolean Eoc { get; init; } - public required IReadOnlyList Warnings { get; init; } - public required IReadOnlyList Alarms { get; init; } - public required Percent Soc { get; init; } - public required Percent CurrentMinSoc { get; init; } - public required Temperature Temperature { get; init; } - public required DcPower HeatingPower { get; init; } - public required UInt16 TimeSinceToc { get; init; } + public required DcBus Dc { get; init; } + public required Boolean Eoc { get; init; } + public required IReadOnlyList Warnings { get; init; } + public required IReadOnlyList Alarms { get; init; } + public required Percent Soc { get; init; } + public required Percent CurrentMinSoc { get; init; } + public required Temperature Temperature { get; init; } + public required DcPower HeatingPower { get; init; } + public required UInt16 TimeSinceToc { get; init; } public required Boolean CalibrationChargeRequested { get; init; } public required IReadOnlyList Devices { get; init; } diff --git a/csharp/Lib/Devices/Trumpf/TruConvertDc/TruConvertDcDcDevices.cs b/csharp/Lib/Devices/Trumpf/TruConvertDc/TruConvertDcDcDevices.cs index edd7a8bdf..742578db9 100644 --- a/csharp/Lib/Devices/Trumpf/TruConvertDc/TruConvertDcDcDevices.cs +++ b/csharp/Lib/Devices/Trumpf/TruConvertDc/TruConvertDcDcDevices.cs @@ -35,22 +35,12 @@ public class TruConvertDcDcDevices public DcDcDevicesRecord Read() { - SystemControlRegisters? scStatus; try { - scStatus = _SystemControl.Read(); - } - catch (Exception e) - { - Console.WriteLine(e); - return DcDcDevicesRecord.Null; - } + var scStatus = _SystemControl.Read(); + var n = scStatus.NumberOfConnectedSlaves; - var n = scStatus.NumberOfConnectedSlaves; - - try - { var dcDcRecords = _DcDcs .Take(n) .Select(dcdc => dcdc.Read()) @@ -61,7 +51,7 @@ public class TruConvertDcDcDevices catch { "Failed to read DCDC data".WriteLine(); - return new DcDcDevicesRecord(scStatus, Array.Empty()); + return new DcDcDevicesRecord(null, Array.Empty()); } } From 3b77c4a5b291c656a19ee35ee3449c35f880aad3 Mon Sep 17 00:00:00 2001 From: atef Date: Wed, 13 Sep 2023 10:57:12 +0200 Subject: [PATCH 5/8] Added the feature of the forceCalibrationCharge in the config file. --- csharp/App/SaliMax/src/Ess/Controller.cs | 8 +++++++- csharp/App/SaliMax/src/SystemConfig/Config.cs | 6 +++--- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/csharp/App/SaliMax/src/Ess/Controller.cs b/csharp/App/SaliMax/src/Ess/Controller.cs index 4f991d58e..15adb1590 100644 --- a/csharp/App/SaliMax/src/Ess/Controller.cs +++ b/csharp/App/SaliMax/src/Ess/Controller.cs @@ -188,7 +188,13 @@ public static class Controller private static Boolean MustDoCalibrationCharge(this StatusRecord statusRecord) { - return statusRecord.Battery?.CalibrationChargeRequested ?? false; + var calibrationChargeForced = statusRecord.Config.ForceCalibrationCharge; + + var batteryCalibrationChargeRequested = statusRecord.Battery?.CalibrationChargeRequested?? false ; + + var mustDoCalibrationCharge = batteryCalibrationChargeRequested || calibrationChargeForced; + + return mustDoCalibrationCharge; } diff --git a/csharp/App/SaliMax/src/SystemConfig/Config.cs b/csharp/App/SaliMax/src/SystemConfig/Config.cs index e57a3d5dd..452935375 100644 --- a/csharp/App/SaliMax/src/SystemConfig/Config.cs +++ b/csharp/App/SaliMax/src/SystemConfig/Config.cs @@ -15,7 +15,7 @@ public class Config //TODO: let IE choose from config files (Json) and connect t private static readonly JsonSerializerOptions JsonOptions = new() { WriteIndented = true }; public required Double MinSoc { get; set; } - public required UnixTime LastEoc { get; set; } + public required Boolean ForceCalibrationCharge { get; set; } public required Double PConstant { get; set; } public required Double GridSetPoint { get; set; } public required Double BatterySelfDischargePower { get; set; } @@ -40,7 +40,7 @@ public class Config //TODO: let IE choose from config files (Json) and connect t public static Config Default => new() { MinSoc = 20, - LastEoc = UnixTime.Epoch, // TODO: remove, use new LastEoc feature from BMS + ForceCalibrationCharge = false, PConstant = .5, GridSetPoint = 0, BatterySelfDischargePower = 200, @@ -102,7 +102,7 @@ public class Config //TODO: let IE choose from config files (Json) and connect t public static Config Default => new() { MinSoc = 20, - LastEoc = UnixTime.Epoch, // TODO: remove, use new LastEoc feature from BMS + ForceCalibrationCharge = false, PConstant = .5, GridSetPoint = 0, BatterySelfDischargePower = 200, From 3ae8a97d156b9c0c6f901116e6d526344f214e95 Mon Sep 17 00:00:00 2001 From: atef Date: Fri, 15 Sep 2023 09:23:09 +0200 Subject: [PATCH 6/8] Delete to do log --- csharp/App/SaliMax/src/SaliMaxRelays/RelaysDevice.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/csharp/App/SaliMax/src/SaliMaxRelays/RelaysDevice.cs b/csharp/App/SaliMax/src/SaliMaxRelays/RelaysDevice.cs index 118d1ed54..5413d0690 100644 --- a/csharp/App/SaliMax/src/SaliMaxRelays/RelaysDevice.cs +++ b/csharp/App/SaliMax/src/SaliMaxRelays/RelaysDevice.cs @@ -19,8 +19,6 @@ public class RelaysDevice catch (Exception e) { $"Failed to read from {nameof(RelaysDevice)}\n{e}".LogError(); - - // TODO: log return null; } } From 0d400a0eead304e92e03e53f88341bc513fa824c Mon Sep 17 00:00:00 2001 From: atef Date: Fri, 15 Sep 2023 09:38:21 +0200 Subject: [PATCH 7/8] Add Control Special Error. --- csharp/App/SaliMax/src/Program.cs | 42 ++++++++++++++++++++++++++++++- 1 file changed, 41 insertions(+), 1 deletion(-) diff --git a/csharp/App/SaliMax/src/Program.cs b/csharp/App/SaliMax/src/Program.cs index 8a857c7db..fd63b0882 100644 --- a/csharp/App/SaliMax/src/Program.cs +++ b/csharp/App/SaliMax/src/Program.cs @@ -170,6 +170,16 @@ internal static class Program Watchdog.NotifyAlive(); var record = ReadStatus(); + + // If control Special Error return true, we must stop the system.(break;) + var specialErrorOccured = record.ControlSpecialError(); + + if (specialErrorOccured.Item1) + { + //stop the system + //return + specialErrorOccured.Item2.WriteLine(); + } record.ControlConstants(); record.ControlSystemState(); @@ -202,6 +212,36 @@ internal static class Program // ReSharper disable once FunctionNeverReturns } + private static (Boolean, String) ControlSpecialError (this StatusRecord r) // to find a better name + { + // Those errors must not occurs. Stop the system in case this is happen. + var isSpecialErrorOccured = false; + var errorMessage = "No Error"; + + // 1. relay0 is open and K2 Close. + if (r.Relays is { K2ConnectIslandBusToGridBus: false, K2IslandBusIsConnectedToGridBus: true } ) + { + isSpecialErrorOccured = true; + errorMessage = " Contradiction: R0 is opening the K2 but the K2 is still close "; + } + + // 2. If K1 is open, K2 must be open . + if (r.Relays is { K1GridBusIsConnectedToGrid: false, K2IslandBusIsConnectedToGridBus: true } ) + { + isSpecialErrorOccured = true; + errorMessage = " Contradiction: K1 is open but the K2 is still close "; + } + + // 3. If FI error is occured, K2 must be open. + if (r.Relays is { FiError: true, K2IslandBusIsConnectedToGridBus: true } ) + { + isSpecialErrorOccured = true; + errorMessage = " Contradiction: Fi error occured but the K2 is still close "; + } + + + return (isSpecialErrorOccured, errorMessage); + } private static void ControlConstants(this StatusRecord r) { @@ -228,7 +268,7 @@ internal static class Program dcDevices.ForEach(d => d.Control.VoltageLimits.MaxBatteryVoltage = configFile.MaxChargeBatteryVoltage); dcDevices.ForEach(d => d.Control.VoltageLimits.MinBatteryVoltage = configFile.MinDischargeBatteryVoltage); dcDevices.ForEach(d => d.Control.ControlMode = DcControlMode.VoltageDroop); - + r.DcDc.ResetAlarms(); r.AcDc.ResetAlarms(); } From 9928e732ffd2bb8e4ef36af913fb510ec3e18d8b Mon Sep 17 00:00:00 2001 From: atef Date: Mon, 18 Sep 2023 11:15:18 +0200 Subject: [PATCH 8/8] Change TimeSinceTOC from Uint16 to TimeSpan --- .../Lib/Devices/Battery48TL/Battery48TlRecord.Api.cs | 11 +++++------ csharp/Lib/Devices/Battery48TL/Battery48TlRecords.cs | 2 +- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/csharp/Lib/Devices/Battery48TL/Battery48TlRecord.Api.cs b/csharp/Lib/Devices/Battery48TL/Battery48TlRecord.Api.cs index e1bbe7d92..56e43bc9a 100644 --- a/csharp/Lib/Devices/Battery48TL/Battery48TlRecord.Api.cs +++ b/csharp/Lib/Devices/Battery48TL/Battery48TlRecord.Api.cs @@ -12,7 +12,6 @@ using Strings = IReadOnlyList; [SuppressMessage("ReSharper", "ConvertToAutoProperty")] public partial class Battery48TlRecord { - private UInt16 OneWeekInMinutes => 10080; public Dc_ Dc => new Dc_(this); public Leds_ Leds => new Leds_(this); public Temperatures_ Temperatures => new Temperatures_(this); @@ -31,12 +30,12 @@ public partial class Battery48TlRecord // Time since TOC is a counter from the last moment when the battery reached EOC // When The battery is full charged (reached EOC) the Time Since TOC is set to 0 - public UInt16 TimeSinceTOC => _TimeSinceToc; - public Current BusCurrent => _BusCurrent; - public Current HeatingCurrent => _BusCurrent - _CellsCurrent; - public DcPower HeatingPower => HeatingCurrent * Dc.Voltage; + public TimeSpan TimeSinceTOC => TimeSpan.FromMinutes(_TimeSinceToc); + public Current BusCurrent => _BusCurrent; + public Current HeatingCurrent => _BusCurrent - _CellsCurrent; + public DcPower HeatingPower => HeatingCurrent * Dc.Voltage; - public Boolean CalibrationChargeRequested => TimeSinceTOC > OneWeekInMinutes; + public Boolean CalibrationChargeRequested => TimeSinceTOC > TimeSpan.FromDays(7); public readonly struct Leds_ { diff --git a/csharp/Lib/Devices/Battery48TL/Battery48TlRecords.cs b/csharp/Lib/Devices/Battery48TL/Battery48TlRecords.cs index 84129e61e..7053f295e 100644 --- a/csharp/Lib/Devices/Battery48TL/Battery48TlRecords.cs +++ b/csharp/Lib/Devices/Battery48TL/Battery48TlRecords.cs @@ -14,7 +14,7 @@ public class Battery48TlRecords public required Percent CurrentMinSoc { get; init; } public required Temperature Temperature { get; init; } public required DcPower HeatingPower { get; init; } - public required UInt16 TimeSinceToc { get; init; } + public required TimeSpan TimeSinceToc { get; init; } public required Boolean CalibrationChargeRequested { get; init; } public required IReadOnlyList Devices { get; init; }