using System.Diagnostics.CodeAnalysis; using InnovEnergy.Lib.Protocols.Modbus.Conversions; namespace InnovEnergy.Lib.Devices.Battery48TL; [SuppressMessage("ReSharper", "InconsistentNaming")] public class Battery48TLStatus { public Decimal Soc { get; } public Decimal Current { get; } public Decimal Voltage { get; } public Decimal Power => Current * Voltage; // TODO do we have to invert the sign here? public Decimal BusVoltage { get; } public Decimal BatteryTemperature { get; } public LedState GreenLed { get; } public LedState AmberLed { get; } public LedState BlueLed { get; } public LedState RedLed { get; } public IReadOnlyList Warnings { get; } public IReadOnlyList Alarms { get; } public Boolean MainSwitchClosed { get; } public Boolean AlarmOutActive { get; } public Boolean InternalFanActive { get; } public Boolean VoltMeasurementAllowed { get; } public Boolean AuxRelay { get; } public Boolean RemoteState { get; } public Boolean HeaterOn { get; } public Boolean EocReached { get; } public Boolean BatteryCold { get; } public Decimal MaxChargingPower { get; } public Decimal MaxDischargingPower { get; } public Battery48TLStatus(ModbusRegisters data) { var soc = data.ParseDecimal(register: 1054, scaleFactor: 0.1m); var eocReached = data.ParseEocReached(); var warnings = new List(); if (data.ParseBool(1006, 1)) warnings.Add("TaM1: BMS temperature high"); if (data.ParseBool(1006, 4)) warnings.Add("TbM1: Battery temperature high"); if (data.ParseBool(1006, 6)) warnings.Add("VBm1: Bus voltage low"); if (data.ParseBool(1006, 8)) warnings.Add("VBM1: Bus voltage high"); if (data.ParseBool(1006, 10)) warnings.Add("IDM1: Discharge current high"); if (data.ParseBool(1006, 24)) warnings.Add("vsM1: String voltage high"); if (data.ParseBool(1006, 26)) warnings.Add("iCM1: Charge current high"); if (data.ParseBool(1006, 28)) warnings.Add("iDM1: Discharge current high"); if (data.ParseBool(1006, 30)) warnings.Add("MID1: String voltages unbalanced"); if (data.ParseBool(1006, 32)) warnings.Add("BLPW: Not enough charging power on bus"); if (data.ParseBool(1006, 35)) warnings.Add("Ah_W: String SOC low"); if (data.ParseBool(1006, 38)) warnings.Add("MPMM: Midpoint wiring problem"); if (data.ParseBool(1006, 39)) warnings.Add("TCMM:"); if (data.ParseBool(1006, 40)) warnings.Add("TCdi: Temperature difference between strings high"); if (data.ParseBool(1006, 41)) warnings.Add("WMTO:"); if (data.ParseBool(1006, 44)) warnings.Add("bit44:"); if (data.ParseBool(1006, 46)) warnings.Add("CELL1:"); var alarms = new List(); if (data.ParseBool(1010, 0)) alarms.Add("Tam : BMS temperature too low"); if (data.ParseBool(1010, 2)) alarms.Add("TaM2 : BMS temperature too high"); if (data.ParseBool(1010, 3)) alarms.Add("Tbm : Battery temperature too low"); if (data.ParseBool(1010, 5)) alarms.Add("TbM2 : Battery temperature too high"); if (data.ParseBool(1010, 7)) alarms.Add("VBm2 : Bus voltage too low"); if (data.ParseBool(1010, 9)) alarms.Add("VBM2 : Bus voltage too high"); if (data.ParseBool(1010, 11)) alarms.Add("IDM2 : Discharge current too high"); if (data.ParseBool(1010, 12)) alarms.Add("ISOB : Electrical insulation failure"); if (data.ParseBool(1010, 13)) alarms.Add("MSWE : Main switch failure"); if (data.ParseBool(1010, 14)) alarms.Add("FUSE : Main fuse blown"); if (data.ParseBool(1010, 15)) alarms.Add("HTRE : Battery failed to warm up"); if (data.ParseBool(1010, 16)) alarms.Add("TCPE : Temperature sensor failure"); if (data.ParseBool(1010, 17)) alarms.Add("STRE :"); if (data.ParseBool(1010, 18)) alarms.Add("CME : Current sensor failure"); if (data.ParseBool(1010, 19)) alarms.Add("HWFL : BMS hardware failure"); if (data.ParseBool(1010, 20)) alarms.Add("HWEM : Hardware protection tripped"); if (data.ParseBool(1010, 21)) alarms.Add("ThM : Heatsink temperature too high"); if (data.ParseBool(1010, 22)) alarms.Add("vsm1 : String voltage too low"); if (data.ParseBool(1010, 23)) alarms.Add("vsm2 : Low string voltage failure"); if (data.ParseBool(1010, 25)) alarms.Add("vsM2 : String voltage too high"); if (data.ParseBool(1010, 27)) alarms.Add("iCM2 : Charge current too high"); if (data.ParseBool(1010, 29)) alarms.Add("iDM2 : Discharge current too high"); if (data.ParseBool(1010, 31)) alarms.Add("MID2 : String voltage unbalance too high"); if (data.ParseBool(1010, 33)) alarms.Add("CCBF : Internal charger hardware failure"); if (data.ParseBool(1010, 34)) alarms.Add("AhFL :"); if (data.ParseBool(1010, 36)) alarms.Add("TbCM :"); if (data.ParseBool(1010, 37)) alarms.Add("BRNF :"); if (data.ParseBool(1010, 42)) alarms.Add("HTFS : If Heaters Fuse Blown"); if (data.ParseBool(1010, 43)) alarms.Add("DATA : Parameters out of range"); if (data.ParseBool(1010, 45)) alarms.Add("CELL2:"); Voltage = data.ReadVoltage(); Current = data.ReadCurrent(); Soc = !eocReached && soc >= 100m ? 99.9m : soc; BusVoltage = data.ParseDecimal(register: 1002, scaleFactor: 0.01m); BatteryTemperature = data.ParseDecimal(register: 1004, scaleFactor: 0.1m, offset: -400); GreenLed = data.ParseLedState(register: 1005, led: LedColor.Green); AmberLed = data.ParseLedState(register: 1006, led: LedColor.Amber); BlueLed = data.ParseLedState(register: 1005, led: LedColor.Blue); RedLed = data.ParseLedState(register: 1005, led: LedColor.Red); Warnings = warnings; Alarms = alarms; MainSwitchClosed = data.ParseBool(baseRegister: 1014, bit: 0); AlarmOutActive = data.ParseBool(baseRegister: 1014, bit: 1); InternalFanActive = data.ParseBool(baseRegister: 1014, bit: 2); VoltMeasurementAllowed = data.ParseBool(baseRegister: 1014, bit: 3); AuxRelay = data.ParseBool(baseRegister: 1014, bit: 4); RemoteState = data.ParseBool(baseRegister: 1014, bit: 5); HeaterOn = data.ParseBool(baseRegister: 1014, bit: 6); EocReached = eocReached; BatteryCold = data.ParseBatteryCold(); MaxChargingPower = data.CalcMaxChargePower(); MaxDischargingPower = data.CalcMaxDischargePower(); } }