2023-02-16 12:57:06 +00:00
|
|
|
using InnovEnergy.Lib.Protocols.Modbus.Clients;
|
|
|
|
using InnovEnergy.Lib.Protocols.Modbus.Connections;
|
2023-02-23 12:45:09 +00:00
|
|
|
using InnovEnergy.Lib.Protocols.Modbus.Conversions;
|
|
|
|
using InnovEnergy.Lib.StatusApi.Connections;
|
2023-02-16 12:57:06 +00:00
|
|
|
|
|
|
|
namespace InnovEnergy.Lib.Devices.Battery48TL;
|
|
|
|
|
|
|
|
public class Battery48TlDevice
|
|
|
|
{
|
|
|
|
private ModbusClient Modbus { get; }
|
|
|
|
|
|
|
|
public Battery48TlDevice(String device, Byte nodeId)
|
|
|
|
{
|
|
|
|
var serialConnection = new ModbusSerialConnection(device,
|
|
|
|
Constants.BaudRate,
|
|
|
|
Constants.Parity,
|
|
|
|
Constants.DataBits,
|
|
|
|
Constants.StopBits,
|
|
|
|
Constants.Timeout);
|
|
|
|
|
|
|
|
Modbus = new ModbusRtuClient(serialConnection, nodeId);
|
|
|
|
}
|
|
|
|
|
|
|
|
private Battery48TlDevice(ModbusClient modbus) // TODO : remove nullable
|
|
|
|
{
|
|
|
|
Modbus = modbus;
|
|
|
|
}
|
|
|
|
|
|
|
|
public static Battery48TlDevice Fake() // TODO : remove nullable
|
|
|
|
{
|
|
|
|
return new Battery48TlDevice(null!);
|
|
|
|
}
|
|
|
|
|
|
|
|
public Battery48TLStatus? ReadStatus() //Already try catch is implemented
|
|
|
|
{
|
|
|
|
if (Modbus is null) // TODO : remove fake
|
|
|
|
{
|
2023-02-23 12:45:09 +00:00
|
|
|
Console.WriteLine("Battery is null");
|
2023-02-16 12:57:06 +00:00
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Console.WriteLine("Reading Battery Data");
|
|
|
|
|
|
|
|
try
|
|
|
|
{
|
|
|
|
var registers = Modbus.ReadInputRegisters(Constants.BaseAddress, Constants.NoOfRegisters);
|
2023-02-23 12:45:09 +00:00
|
|
|
return TryReadStatus(registers);
|
2023-02-16 12:57:06 +00:00
|
|
|
}
|
|
|
|
catch (Exception e)
|
|
|
|
{
|
2023-02-23 12:45:09 +00:00
|
|
|
Console.WriteLine(e.Message + " Battery ");
|
2023-02-16 12:57:06 +00:00
|
|
|
Modbus.CloseConnection();
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
}
|
2023-02-23 12:45:09 +00:00
|
|
|
|
|
|
|
private Battery48TLStatus? TryReadStatus(ModbusRegisters data)
|
|
|
|
{
|
|
|
|
var soc = data.ParseDecimal(register: 1054, scaleFactor: 0.1m);
|
|
|
|
var eocReached = data.ParseEocReached();
|
|
|
|
|
|
|
|
var warnings = new List<String>();
|
|
|
|
|
|
|
|
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<String>();
|
|
|
|
|
|
|
|
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:");
|
|
|
|
|
|
|
|
|
|
|
|
return new Battery48TLStatus(
|
|
|
|
Dc: new DcConnection
|
|
|
|
(
|
|
|
|
Voltage : data.ReadVoltage(),
|
|
|
|
Current : data.ReadCurrent()),
|
|
|
|
|
|
|
|
Soc : !eocReached && soc >= 100m ? 99.9m : soc,
|
|
|
|
Temperature : data.ParseDecimal(register: 1004, scaleFactor: 0.1m, offset: -400),
|
|
|
|
BusVoltage : data.ParseDecimal(register: 1002, scaleFactor: 0.01m),
|
|
|
|
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()
|
|
|
|
);
|
|
|
|
}
|
2023-02-16 12:57:06 +00:00
|
|
|
}
|