Make Battery48TL use new StatusLog lib

This commit is contained in:
ig 2023-04-04 13:16:10 +02:00
parent 005da7fbcb
commit 4e6588192f
4 changed files with 62 additions and 91 deletions

View File

@ -1,7 +1,6 @@
using System.Diagnostics.CodeAnalysis; using System.Diagnostics.CodeAnalysis;
using InnovEnergy.Lib.StatusApi; using InnovEnergy.Lib.StatusApi;
using InnovEnergy.Lib.Units; using InnovEnergy.Lib.Units;
using InnovEnergy.Lib.Utils;
namespace InnovEnergy.Lib.Devices.Battery48TL; namespace InnovEnergy.Lib.Devices.Battery48TL;
@ -15,22 +14,17 @@ public record Battery48TLStatus : BatteryStatus
public Power MaxChargingPower { get; init; } public Power MaxChargingPower { get; init; }
public Power MaxDischargingPower { get; init; } public Power MaxDischargingPower { get; init; }
public State GreenLed { get; init; } public LedState GreenLed { get; init; }
public State AmberLed { get; init; } public LedState AmberLed { get; init; }
public State BlueLed { get; init; } public LedState BlueLed { get; init; }
public State RedLed { get; init; } public LedState 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 IReadOnlyList<String> Warnings { get; init; } = Array.Empty<String>();
public IReadOnlyList<String> Alarms { get; init; } = Array.Empty<String>();
public static T operator |(T left, T right) => OpParallel(left, right); public Boolean ConnectedToDc { get; init; }
private static readonly Func<T, T, T> OpParallel = "|".CreateBinaryOpForProps<T>(); public Boolean Heating { get; init; }
public TemperatureState TemperatureState { get; init; } // cold | operating temperature | overheated

View File

@ -24,7 +24,7 @@ public static class Constants
private const Decimal RStringMin = 0.125m; private const Decimal RStringMin = 0.125m;
private const Decimal RStringMax = 0.250m; private const Decimal RStringMax = 0.250m;
private const Decimal IMaxPerString = 20.0m; 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 RIntMin = RStringMin / NumberOfStrings;
public const Decimal RIntMax = RStringMax / NumberOfStrings; public const Decimal RIntMax = RStringMax / NumberOfStrings;

View File

@ -1,8 +1,8 @@
using System.Diagnostics.CodeAnalysis; using System.Diagnostics.CodeAnalysis;
using InnovEnergy.Lib.Protocols.Modbus.Conversions; using InnovEnergy.Lib.Protocols.Modbus.Conversions;
using InnovEnergy.Lib.Units;
using InnovEnergy.Lib.Units.Composite; using InnovEnergy.Lib.Units.Composite;
using InnovEnergy.Lib.Utils; using InnovEnergy.Lib.Utils;
using static InnovEnergy.Lib.Devices.Battery48TL.LedState;
namespace InnovEnergy.Lib.Devices.Battery48TL; namespace InnovEnergy.Lib.Devices.Battery48TL;
@ -10,24 +10,44 @@ public static class ModbusParser
{ {
internal static Battery48TLStatus ParseBatteryStatus(this ModbusRegisters data) 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 return new Battery48TLStatus
{ {
Dc = data.ParseDcBus(), Dc = data.ParseDcBus(),
Alarms = data.ParseAlarms().ToList(), Alarms = data.ParseAlarms().ToList(),
Warnings = data.ParseWarnings().ToList(), Warnings = data.ParseWarnings().ToList(),
Soc = data.ParseSoc(), Soc = Math.Min(soc, maxSoc),
Temperature = data.ParseTemperature(), Temperature = data.ParseDecimal(register: 1004, scaleFactor: 0.1m, offset: -400),
GreenLed = data.ParseGreenLed(), GreenLed = greenLed,
AmberLed = data.ParseAmberLed(), AmberLed = amberLed,
BlueLed = data.ParseBlueLed(), BlueLed = blueLed,
RedLed = data.ParseRedLed(), RedLed = redLed,
MainSwitchState = data.ParseMainSwitchState(), Heating = data.ParseBool(baseRegister: 1014, bit: 6),
HeaterState = data.ParseHeaterState(), ConnectedToDc = data.ParseBool(baseRegister: 1014, bit: 0),
EocState = data.ParseEocState(), TemperatureState = temperatureState,
TemperatureState = data.ParseTemperatureState(),
MaxChargingPower = data.CalcMaxChargePower(), MaxChargingPower = data.CalcMaxChargePower(),
MaxDischargingPower = data.CalcMaxDischargePower(), 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); 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) internal static Decimal ParseBusVoltage(this ModbusRegisters data)
{ {
return data.ParseDecimal(register: 1002, scaleFactor: 0.01m); return data.ParseDecimal(register: 1002, scaleFactor: 0.01m);
@ -74,57 +89,19 @@ public static class ModbusParser
return (hi, lo) switch return (hi, lo) switch
{ {
(false, false) => LedState.Off, (false, false) => Off,
(false, true) => LedState.On, (false, true) => On,
(true, false) => LedState.BlinkingSlow, (true, false) => BlinkingSlow,
(true, true) => LedState.BlinkingFast, (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) internal static Decimal ParseSoc(this ModbusRegisters data)
{ {
return data.ParseDecimal(register: 1054, scaleFactor: 0.1m); 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) private static Decimal CalcPowerLimitImposedByVoltageLimit(Decimal v,Decimal i,Decimal vLimit,Decimal rInt)
{ {
var dv = vLimit - v; var dv = vLimit - v;
@ -161,11 +138,12 @@ public static class ModbusParser
internal static Decimal CalcMaxChargePower(this ModbusRegisters data) 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 i = ParseCurrent(data);
var pLimits = new[] var pLimits = new[]
{ {
// TODO: review
CalcPowerLimitImposedByVoltageLimit(v, i, Constants.VMax, Constants.RIntMin), CalcPowerLimitImposedByVoltageLimit(v, i, Constants.VMax, Constants.RIntMin),
CalcPowerLimitImposedByVoltageLimit(v, i, Constants.VMax, Constants.RIntMax), CalcPowerLimitImposedByVoltageLimit(v, i, Constants.VMax, Constants.RIntMax),
CalcPowerLimitImposedByCurrentLimit(v, i, Constants.IMax, Constants.RIntMin), CalcPowerLimitImposedByCurrentLimit(v, i, Constants.IMax, Constants.RIntMin),
@ -177,23 +155,20 @@ public static class ModbusParser
return Math.Max(pLimit, 0); 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) 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 i = ParseCurrent(data);
var t = data.ParseDecimal(register: 1004, scaleFactor: 0.1m, offset: -400);
var pLimits = new[] var pLimits = new[]
{ {
// TODO: review
CalcPowerLimitImposedByVoltageLimit(v, i, Constants.VMin, Constants.RIntMin), CalcPowerLimitImposedByVoltageLimit(v, i, Constants.VMin, Constants.RIntMin),
CalcPowerLimitImposedByVoltageLimit(v, i, Constants.VMin, Constants.RIntMax), CalcPowerLimitImposedByVoltageLimit(v, i, Constants.VMin, Constants.RIntMax),
CalcPowerLimitImposedByCurrentLimit(v, i, -Constants.IMax, Constants.RIntMin), 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")] [SuppressMessage("ReSharper", "StringLiteralTypo")]
internal static IEnumerable<String> ParseAlarms(this ModbusRegisters data) internal static IEnumerable<String> ParseAlarms(this ModbusRegisters data)
{ {

View File

@ -0,0 +1,8 @@
namespace InnovEnergy.Lib.Devices.Battery48TL;
public enum TemperatureState
{
Cold = 0,
OperatingTemperature = 1,
Overheated =2,
}