diff --git a/csharp/Lib/Devices/Battery48TL/Battery48TLStatusRecord.cs b/csharp/Lib/Devices/Battery48TL/Battery48TLStatusRecord.cs index b9feb07d0..c42532fc6 100644 --- a/csharp/Lib/Devices/Battery48TL/Battery48TLStatusRecord.cs +++ b/csharp/Lib/Devices/Battery48TL/Battery48TLStatusRecord.cs @@ -1,7 +1,6 @@ using System.Diagnostics.CodeAnalysis; using InnovEnergy.Lib.StatusApi; using InnovEnergy.Lib.Units; -using InnovEnergy.Lib.Utils; namespace InnovEnergy.Lib.Devices.Battery48TL; @@ -15,22 +14,17 @@ public record Battery48TLStatus : BatteryStatus public Power MaxChargingPower { get; init; } public Power MaxDischargingPower { get; init; } - public State GreenLed { get; init; } - public State AmberLed { get; init; } - public State BlueLed { get; init; } - public State RedLed { get; init; } - - public State Warnings { get; init; } - public State Alarms { get; init; } - - public State MainSwitchState { get; init; } // connected to bus | disconnected from bus - public State HeaterState { get; init; } // heating | not heating - public State EocState { get; init; } // EOC reached | EOC not reached - public State TemperatureState { get; init; } // cold | operating temperature | overheated + public LedState GreenLed { get; init; } + public LedState AmberLed { get; init; } + public LedState BlueLed { get; init; } + public LedState RedLed { get; init; } + public IReadOnlyList Warnings { get; init; } = Array.Empty(); + public IReadOnlyList Alarms { get; init; } = Array.Empty(); - public static T operator |(T left, T right) => OpParallel(left, right); - private static readonly Func OpParallel = "|".CreateBinaryOpForProps(); + public Boolean ConnectedToDc { get; init; } + public Boolean Heating { get; init; } + public TemperatureState TemperatureState { get; init; } // cold | operating temperature | overheated diff --git a/csharp/Lib/Devices/Battery48TL/Constants.cs b/csharp/Lib/Devices/Battery48TL/Constants.cs index 44234a09c..ea2e7501e 100644 --- a/csharp/Lib/Devices/Battery48TL/Constants.cs +++ b/csharp/Lib/Devices/Battery48TL/Constants.cs @@ -24,7 +24,7 @@ public static class Constants private const Decimal RStringMin = 0.125m; private const Decimal RStringMax = 0.250m; private const Decimal IMaxPerString = 20.0m; - private const UInt16 NumberOfStrings = 5; + private const UInt16 NumberOfStrings = 5; public const Decimal RIntMin = RStringMin / NumberOfStrings; public const Decimal RIntMax = RStringMax / NumberOfStrings; diff --git a/csharp/Lib/Devices/Battery48TL/ModbusParser.cs b/csharp/Lib/Devices/Battery48TL/ModbusParser.cs index d16c3dc5d..af2c3568a 100644 --- a/csharp/Lib/Devices/Battery48TL/ModbusParser.cs +++ b/csharp/Lib/Devices/Battery48TL/ModbusParser.cs @@ -1,8 +1,8 @@ using System.Diagnostics.CodeAnalysis; using InnovEnergy.Lib.Protocols.Modbus.Conversions; -using InnovEnergy.Lib.Units; using InnovEnergy.Lib.Units.Composite; using InnovEnergy.Lib.Utils; +using static InnovEnergy.Lib.Devices.Battery48TL.LedState; namespace InnovEnergy.Lib.Devices.Battery48TL; @@ -10,24 +10,44 @@ public static class ModbusParser { internal static Battery48TLStatus ParseBatteryStatus(this ModbusRegisters data) { + var greenLed = data.ParseLedState(register: 1005, led: LedColor.Green); + var amberLed = data.ParseLedState(register: 1005, led: LedColor.Amber); + var blueLed = data.ParseLedState(register: 1005, led: LedColor.Blue); + var redLed = data.ParseLedState(register: 1005, led: LedColor.Red); + + var soc = data.ParseSoc(); + + var eoc = greenLed is On + && amberLed is Off + && blueLed is Off; + + var maxSoc = eoc ? 100m : 99.9m; + + var batteryCold = greenLed >= BlinkingSlow + && blueLed >= BlinkingSlow; + + var temperatureState = batteryCold + ? TemperatureState.Cold + : TemperatureState.OperatingTemperature; // TODO: overheated + + return new Battery48TLStatus { Dc = data.ParseDcBus(), Alarms = data.ParseAlarms().ToList(), Warnings = data.ParseWarnings().ToList(), - Soc = data.ParseSoc(), - Temperature = data.ParseTemperature(), - GreenLed = data.ParseGreenLed(), - AmberLed = data.ParseAmberLed(), - BlueLed = data.ParseBlueLed(), - RedLed = data.ParseRedLed(), - MainSwitchState = data.ParseMainSwitchState(), - HeaterState = data.ParseHeaterState(), - EocState = data.ParseEocState(), - TemperatureState = data.ParseTemperatureState(), + Soc = Math.Min(soc, maxSoc), + Temperature = data.ParseDecimal(register: 1004, scaleFactor: 0.1m, offset: -400), + GreenLed = greenLed, + AmberLed = amberLed, + BlueLed = blueLed, + RedLed = redLed, + Heating = data.ParseBool(baseRegister: 1014, bit: 6), + ConnectedToDc = data.ParseBool(baseRegister: 1014, bit: 0), + TemperatureState = temperatureState, MaxChargingPower = data.CalcMaxChargePower(), MaxDischargingPower = data.CalcMaxDischargePower(), - CellsVoltage = data.ParseCellsVoltage(), + CellsVoltage = data.ParseDecimal(register: 1000, scaleFactor: 0.01m), }; } @@ -47,11 +67,6 @@ public static class ModbusParser return data.ParseDecimal(register: 1001, scaleFactor: 0.01m, offset: -10000); } - internal static Decimal ParseCellsVoltage(this ModbusRegisters data) - { - return data.ParseDecimal(register: 1000, scaleFactor: 0.01m); - } - internal static Decimal ParseBusVoltage(this ModbusRegisters data) { return data.ParseDecimal(register: 1002, scaleFactor: 0.01m); @@ -74,57 +89,19 @@ public static class ModbusParser return (hi, lo) switch { - (false, false) => LedState.Off, - (false, true) => LedState.On, - (true, false) => LedState.BlinkingSlow, - (true, true) => LedState.BlinkingFast, + (false, false) => Off, + (false, true) => On, + (true, false) => BlinkingSlow, + (true, true) => BlinkingFast, }; } - private static Boolean ParseEocReached(this ModbusRegisters data) - { - return ParseLedState(data, 1005, LedColor.Green) == LedState.On && - ParseLedState(data, 1005, LedColor.Amber) == LedState.Off && - ParseLedState(data, 1005, LedColor.Blue) == LedState.Off; - } - - internal static State ParseTemperatureState(this ModbusRegisters data) - { - return data.ParseBatteryCold() ? "cold" : "operating temperature"; // TODO: overheated, - } - - internal static Decimal ParseTemperature(this ModbusRegisters data) - { - return data.ParseDecimal(register: 1004, scaleFactor: 0.1m, offset: -400); - } - internal static Decimal ParseSoc(this ModbusRegisters data) { return data.ParseDecimal(register: 1054, scaleFactor: 0.1m); } - internal static State ParseEocState(this ModbusRegisters data) - { - return data.ParseEocReached() ? "EOC reached" : "EOC not reached"; - } - - internal static State ParseHeaterState(this ModbusRegisters data) - { - return data.ParseBool(baseRegister: 1014, bit: 6) ? "heating" : "not heating"; - } - - internal static State ParseMainSwitchState(this ModbusRegisters data) - { - return data.ParseBool(baseRegister: 1014, bit: 0) ? "connected to bus" : "disconnected from bus"; - } - - internal static Boolean ParseBatteryCold(this ModbusRegisters data) - { - return ParseLedState(data, 1005, LedColor.Green) >= LedState.BlinkingSlow && - ParseLedState(data, 1005, LedColor.Blue) >= LedState.BlinkingSlow; - } - private static Decimal CalcPowerLimitImposedByVoltageLimit(Decimal v,Decimal i,Decimal vLimit,Decimal rInt) { var dv = vLimit - v; @@ -161,11 +138,12 @@ public static class ModbusParser internal static Decimal CalcMaxChargePower(this ModbusRegisters data) { - var v = ParseCellsVoltage(data); + var v = data.ParseDecimal(register: 1000, scaleFactor: 0.01m); var i = ParseCurrent(data); var pLimits = new[] { + // TODO: review CalcPowerLimitImposedByVoltageLimit(v, i, Constants.VMax, Constants.RIntMin), CalcPowerLimitImposedByVoltageLimit(v, i, Constants.VMax, Constants.RIntMax), CalcPowerLimitImposedByCurrentLimit(v, i, Constants.IMax, Constants.RIntMin), @@ -177,23 +155,20 @@ public static class ModbusParser return Math.Max(pLimit, 0); } - internal static DcBus ParseDcBus(this ModbusRegisters data) + internal static DcBus ParseDcBus(this ModbusRegisters data) => new() { - return new() - { - Current = data.ParseCurrent(), - Voltage = data.ParseBusVoltage(), - }; - } + Current = data.ParseCurrent(), + Voltage = data.ParseBusVoltage(), + }; internal static Decimal CalcMaxDischargePower(this ModbusRegisters data) { - var v = ParseCellsVoltage(data); + var v = data.ParseDecimal(register: 1000, scaleFactor: 0.01m); var i = ParseCurrent(data); - var t = data.ParseDecimal(register: 1004, scaleFactor: 0.1m, offset: -400); var pLimits = new[] { + // TODO: review CalcPowerLimitImposedByVoltageLimit(v, i, Constants.VMin, Constants.RIntMin), CalcPowerLimitImposedByVoltageLimit(v, i, Constants.VMin, Constants.RIntMax), CalcPowerLimitImposedByCurrentLimit(v, i, -Constants.IMax, Constants.RIntMin), @@ -207,12 +182,6 @@ public static class ModbusParser } - internal static LedState ParseGreenLed(this ModbusRegisters data) => data.ParseLedState(register: 1005, led: LedColor.Green); - internal static LedState ParseAmberLed(this ModbusRegisters data) => data.ParseLedState(register: 1006, led: LedColor.Amber); - internal static LedState ParseBlueLed (this ModbusRegisters data) => data.ParseLedState(register: 1005, led: LedColor.Blue); - internal static LedState ParseRedLed (this ModbusRegisters data) => data.ParseLedState(register: 1005, led: LedColor.Red); - - [SuppressMessage("ReSharper", "StringLiteralTypo")] internal static IEnumerable ParseAlarms(this ModbusRegisters data) { diff --git a/csharp/Lib/Devices/Battery48TL/TemperatureState.cs b/csharp/Lib/Devices/Battery48TL/TemperatureState.cs new file mode 100644 index 000000000..da34812e0 --- /dev/null +++ b/csharp/Lib/Devices/Battery48TL/TemperatureState.cs @@ -0,0 +1,8 @@ +namespace InnovEnergy.Lib.Devices.Battery48TL; + +public enum TemperatureState +{ + Cold = 0, + OperatingTemperature = 1, + Overheated =2, +} \ No newline at end of file