make 48TL use updated Modbus Lib
This commit is contained in:
parent
faa1dd2af8
commit
21b49a1339
|
@ -1,14 +1,12 @@
|
||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
<PropertyGroup>
|
|
||||||
<Configurations>Debug;Release;Release-Server</Configurations>
|
|
||||||
<Platforms>AnyCPU;linux-arm</Platforms>
|
|
||||||
</PropertyGroup>
|
|
||||||
<Import Project="../../InnovEnergy.Lib.props" />
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<ProjectReference Include="../../Utils/Utils.csproj" />
|
|
||||||
<ProjectReference Include="../../Protocols/Modbus/Modbus.csproj" />
|
|
||||||
<ProjectReference Include="../../StatusApi/StatusApi.csproj" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
</Project>
|
<!-- <Import Project="../../InnovEnergy.Lib.props" />-->
|
||||||
|
<Import Project="../../../App/InnovEnergy.App.props" />
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="../../Protocols/Modbus/Modbus.csproj" />
|
||||||
|
<ProjectReference Include="../../StatusApi/StatusApi.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</Project>
|
|
@ -1,48 +1,47 @@
|
||||||
|
using System.IO.Ports;
|
||||||
|
using InnovEnergy.Lib.Protocols.Modbus.Channels;
|
||||||
using InnovEnergy.Lib.Protocols.Modbus.Clients;
|
using InnovEnergy.Lib.Protocols.Modbus.Clients;
|
||||||
using InnovEnergy.Lib.Protocols.Modbus.Connections;
|
using InnovEnergy.Lib.Protocols.Modbus.Slaves;
|
||||||
using static InnovEnergy.Lib.Devices.Battery48TL.Constants;
|
using InnovEnergy.Lib.Utils;
|
||||||
|
using static System.IO.Ports.Parity;
|
||||||
|
|
||||||
namespace InnovEnergy.Lib.Devices.Battery48TL;
|
namespace InnovEnergy.Lib.Devices.Battery48TL;
|
||||||
|
|
||||||
public class Battery48TlDevice
|
|
||||||
|
public class Battery48TlDevice: ModbusDevice<Battery48TlRegisters>
|
||||||
{
|
{
|
||||||
private ModbusClient Modbus { get; }
|
public const Parity Parity = Odd;
|
||||||
|
public const Int32 StopBits = 1;
|
||||||
|
public const Int32 BaudRate = 115200;
|
||||||
|
public const Int32 DataBits = 8;
|
||||||
|
|
||||||
|
|
||||||
|
public Battery48TlDevice(String tty, Byte slaveId, SshHost host) : this
|
||||||
|
(
|
||||||
|
channel: new RemoteSerialChannel(host, tty, BaudRate, Parity, StopBits, DataBits),
|
||||||
|
slaveId
|
||||||
|
)
|
||||||
|
{}
|
||||||
|
|
||||||
public Battery48TlDevice(String device, Byte nodeId)
|
public Battery48TlDevice(String tty, Byte slaveId, String? host = null) : this
|
||||||
|
(
|
||||||
|
channel: host switch
|
||||||
|
{
|
||||||
|
null => new SerialPortChannel ( tty, BaudRate, Parity, StopBits, DataBits),
|
||||||
|
_ => new RemoteSerialChannel(host, tty, BaudRate, Parity, StopBits, DataBits)
|
||||||
|
},
|
||||||
|
slaveId
|
||||||
|
)
|
||||||
|
{}
|
||||||
|
|
||||||
|
public Battery48TlDevice(Channel channel, Byte slaveId) : this
|
||||||
|
(
|
||||||
|
client: new ModbusRtuClient(channel, slaveId)
|
||||||
|
)
|
||||||
|
{}
|
||||||
|
|
||||||
|
public Battery48TlDevice(ModbusClient client): base(client)
|
||||||
{
|
{
|
||||||
var serialConnection = new ModbusSerialConnection(device,
|
|
||||||
BaudRate,
|
|
||||||
Parity,
|
|
||||||
DataBits,
|
|
||||||
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
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
return Modbus
|
|
||||||
.ReadInputRegisters(BaseAddress, NoOfRegisters)
|
|
||||||
.ParseBatteryStatus();
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
Console.WriteLine(e.Message + " Battery ");
|
|
||||||
Modbus.CloseConnection();
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
|
@ -1,49 +0,0 @@
|
||||||
using System.Diagnostics.CodeAnalysis;
|
|
||||||
using InnovEnergy.Lib.StatusApi;
|
|
||||||
using InnovEnergy.Lib.Units;
|
|
||||||
|
|
||||||
namespace InnovEnergy.Lib.Devices.Battery48TL;
|
|
||||||
|
|
||||||
using T = Battery48TLStatus;
|
|
||||||
|
|
||||||
[SuppressMessage("ReSharper", "InconsistentNaming")]
|
|
||||||
public record Battery48TLStatus : BatteryStatus
|
|
||||||
{
|
|
||||||
public Voltage CellsVoltage { get; init; }
|
|
||||||
|
|
||||||
public Power MaxChargingPower { get; init; }
|
|
||||||
public Power MaxDischargingPower { get; init; }
|
|
||||||
|
|
||||||
public LedState GreenLed { get; init; }
|
|
||||||
public LedState AmberLed { get; init; }
|
|
||||||
public LedState BlueLed { get; init; }
|
|
||||||
public LedState RedLed { get; init; }
|
|
||||||
|
|
||||||
public IReadOnlyList<String> Warnings { get; init; } = Array.Empty<String>();
|
|
||||||
public IReadOnlyList<String> Alarms { get; init; } = Array.Empty<String>();
|
|
||||||
|
|
||||||
public Boolean EocReached { get; init; }
|
|
||||||
public Boolean ConnectedToDc { get; init; }
|
|
||||||
public Boolean Heating { get; init; }
|
|
||||||
public TemperatureState TemperatureState { get; init; } // cold | operating temperature | overheated
|
|
||||||
|
|
||||||
public Current TotalCurrent { get; init; }
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// TODO: strings
|
|
||||||
// TODO
|
|
||||||
// public State LimitedBy { get; init; }
|
|
||||||
|
|
||||||
// TODO
|
|
||||||
// public Boolean AlarmOutActive { get; init; }
|
|
||||||
// public Boolean InternalFanActive { get; init; }
|
|
||||||
// public Boolean VoltMeasurementAllowed { get; init; }
|
|
||||||
// public Boolean AuxRelay { get; init; }
|
|
||||||
// public Boolean RemoteState { get; init; }
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,55 @@
|
||||||
|
using System.Diagnostics.CodeAnalysis;
|
||||||
|
using InnovEnergy.Lib.Devices.Battery48TL.DataTypes;
|
||||||
|
using InnovEnergy.Lib.Protocols.Modbus.Reflection.Attributes;
|
||||||
|
using InnovEnergy.Lib.StatusApi.DeviceTypes;
|
||||||
|
using InnovEnergy.Lib.Units;
|
||||||
|
using InnovEnergy.Lib.Units.Composite;
|
||||||
|
|
||||||
|
namespace InnovEnergy.Lib.Devices.Battery48TL;
|
||||||
|
|
||||||
|
|
||||||
|
#pragma warning disable CS0169, CS0649
|
||||||
|
|
||||||
|
[SuppressMessage("ReSharper", "InconsistentNaming")]
|
||||||
|
[SuppressMessage("ReSharper", "UnusedMember.Global")]
|
||||||
|
[BigEndian] // alarm/warning flags
|
||||||
|
public record Battery48TlRegisters : IBattery
|
||||||
|
{
|
||||||
|
[InputRegister(1004)] internal UInt16 _LedStates;
|
||||||
|
|
||||||
|
[InputRegister<UInt64>(1005)] internal UInt64 _WarningFlags;
|
||||||
|
[InputRegister<UInt64>(1009)] internal UInt64 _AlarmFlags;
|
||||||
|
|
||||||
|
[InputRegister(1013)] internal UInt16 _IoStates;
|
||||||
|
|
||||||
|
[InputRegister(999, Scale = 0.01)] internal Double _Voltage ;
|
||||||
|
[InputRegister(1000, Scale = 0.01, Offset = -10000)] internal Double _Current ;
|
||||||
|
[InputRegister(1053, Scale = 0.1)] internal Double _Soc;
|
||||||
|
|
||||||
|
[InputRegister(1014, Scale = 0.1, Offset = -400)] internal Double _TemperatureBoard ;
|
||||||
|
[InputRegister(1015, Scale = 0.1, Offset = -400)] internal Double _TemperatureCellsCenter ;
|
||||||
|
[InputRegister(1016, Scale = 0.1, Offset = -400)] internal Double _TemperatureCellsLeft ;
|
||||||
|
[InputRegister(1017, Scale = 0.1, Offset = -400)] internal Double _TemperatureCellsRight ;
|
||||||
|
|
||||||
|
|
||||||
|
public DcBus Dc => DcBus.FromVoltageCurrent(_Voltage, _Current);
|
||||||
|
public Percent Soc => _Soc;
|
||||||
|
|
||||||
|
public Leds Leds => this.ParseLeds();
|
||||||
|
public Temperatures Temperature => this.ParseBatteryTemperatures();
|
||||||
|
|
||||||
|
public Boolean ConnectedToDcBus => this.ParseConnectedToDcBus();
|
||||||
|
public Boolean Heating => this.ParseHeating();
|
||||||
|
public Boolean Eoc => this.ParseEoc();
|
||||||
|
|
||||||
|
|
||||||
|
public IReadOnlyList<String> Warnings => this.ParseWarnings().ToList() ;
|
||||||
|
public IReadOnlyList<String> Alarms => this.ParseAlarms().ToList() ;
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
// public Decimal CellsVoltage { get; init; }
|
||||||
|
//
|
||||||
|
// public Decimal MaxChargingPower { get; init; }
|
||||||
|
// public Decimal MaxDischargingPower { get; init; }
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
using InnovEnergy.Lib.Units;
|
||||||
|
|
||||||
|
namespace InnovEnergy.Lib.Devices.Battery48TL.DataTypes;
|
||||||
|
|
||||||
|
public readonly struct CellTemperatures
|
||||||
|
{
|
||||||
|
public Temperature Center { get; internal init; }
|
||||||
|
public Temperature Left { get; internal init; }
|
||||||
|
public Temperature Right { get; internal init; }
|
||||||
|
}
|
||||||
|
|
|
@ -1,9 +1,8 @@
|
||||||
using System.Diagnostics.CodeAnalysis;
|
using System.Diagnostics.CodeAnalysis;
|
||||||
using System.IO.Ports;
|
using System.IO.Ports;
|
||||||
using static System.IO.Ports.Parity;
|
using static System.IO.Ports.Parity;
|
||||||
using static System.IO.Ports.StopBits;
|
|
||||||
|
|
||||||
namespace InnovEnergy.Lib.Devices.Battery48TL;
|
namespace InnovEnergy.Lib.Devices.Battery48TL.DataTypes;
|
||||||
|
|
||||||
[SuppressMessage("ReSharper", "InconsistentNaming")]
|
[SuppressMessage("ReSharper", "InconsistentNaming")]
|
||||||
public static class Constants
|
public static class Constants
|
||||||
|
@ -12,7 +11,7 @@ public static class Constants
|
||||||
public const Int32 NoOfRegisters = 56;
|
public const Int32 NoOfRegisters = 56;
|
||||||
|
|
||||||
public const Parity Parity = Odd;
|
public const Parity Parity = Odd;
|
||||||
public const StopBits StopBits = One;
|
public const Int32 StopBits = 1;
|
||||||
public const Int32 BaudRate = 115200;
|
public const Int32 BaudRate = 115200;
|
||||||
public const Int32 DataBits = 8;
|
public const Int32 DataBits = 8;
|
||||||
public static TimeSpan Timeout { get; } = TimeSpan.FromMilliseconds(100);
|
public static TimeSpan Timeout { get; } = TimeSpan.FromMilliseconds(100);
|
|
@ -0,0 +1,9 @@
|
||||||
|
namespace InnovEnergy.Lib.Devices.Battery48TL.DataTypes;
|
||||||
|
|
||||||
|
public enum LedColor
|
||||||
|
{
|
||||||
|
Green = 0, // don't change: numbers are important
|
||||||
|
Amber = 2,
|
||||||
|
Blue = 4,
|
||||||
|
Red = 6,
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
namespace InnovEnergy.Lib.Devices.Battery48TL.DataTypes;
|
||||||
|
|
||||||
|
public enum LedState
|
||||||
|
{
|
||||||
|
Off = 0,
|
||||||
|
On = 1,
|
||||||
|
Blinking = 2,
|
||||||
|
BlinkingFast = 3
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
namespace InnovEnergy.Lib.Devices.Battery48TL.DataTypes;
|
||||||
|
|
||||||
|
public readonly struct Leds
|
||||||
|
{
|
||||||
|
public LedState Blue { get; internal init; }
|
||||||
|
public LedState Green { get; internal init; }
|
||||||
|
public LedState Amber { get; internal init; }
|
||||||
|
public LedState Red { get; internal init; }
|
||||||
|
}
|
|
@ -0,0 +1,8 @@
|
||||||
|
namespace InnovEnergy.Lib.Devices.Battery48TL.DataTypes;
|
||||||
|
|
||||||
|
public enum TemperatureState
|
||||||
|
{
|
||||||
|
Cold = 0,
|
||||||
|
Operation = 1,
|
||||||
|
Overheated = 2,
|
||||||
|
}
|
|
@ -0,0 +1,23 @@
|
||||||
|
using InnovEnergy.Lib.Units;
|
||||||
|
using static InnovEnergy.Lib.Devices.Battery48TL.DataTypes.LedState;
|
||||||
|
|
||||||
|
namespace InnovEnergy.Lib.Devices.Battery48TL.DataTypes;
|
||||||
|
|
||||||
|
public readonly struct Temperatures
|
||||||
|
{
|
||||||
|
public CellTemperatures Cells { get; internal init; }
|
||||||
|
public Temperature Board { get; internal init; }
|
||||||
|
public TemperatureState State { get; internal init; }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// public abstract record Result
|
||||||
|
// {
|
||||||
|
// private Result() { }
|
||||||
|
//
|
||||||
|
// public sealed record Ok(object result) : Result;
|
||||||
|
// public sealed record Error(string message) : Result;
|
||||||
|
// }
|
|
@ -0,0 +1,2 @@
|
||||||
|
|
||||||
|
stty -F /dev/ttyUSB0 <<< '0:0:1bb2:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0'
|
|
@ -1,9 +0,0 @@
|
||||||
namespace InnovEnergy.Lib.Devices.Battery48TL;
|
|
||||||
|
|
||||||
public enum LedColor
|
|
||||||
{
|
|
||||||
Green = 0,
|
|
||||||
Amber = 1,
|
|
||||||
Blue = 2,
|
|
||||||
Red = 3,
|
|
||||||
}
|
|
|
@ -1,9 +0,0 @@
|
||||||
namespace InnovEnergy.Lib.Devices.Battery48TL;
|
|
||||||
|
|
||||||
public enum LedState
|
|
||||||
{
|
|
||||||
Off = 0,
|
|
||||||
On = 1,
|
|
||||||
BlinkingSlow = 2,
|
|
||||||
BlinkingFast = 3
|
|
||||||
}
|
|
|
@ -1,274 +1,183 @@
|
||||||
using System.Diagnostics.CodeAnalysis;
|
// using System.Diagnostics.CodeAnalysis;
|
||||||
using System.Text;
|
// using InnovEnergy.Lib.Devices.Battery48TL.DataTypes;
|
||||||
using InnovEnergy.Lib.Protocols.Modbus.Conversions;
|
// using InnovEnergy.Lib.Protocols.Modbus.Conversions;
|
||||||
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;
|
// public static class ModbusParser
|
||||||
|
// {
|
||||||
public static class ModbusParser
|
// public static Decimal ParseDecimal(this ModbusRegisters data, Int32 register, Decimal scaleFactor = 1.0m, Double offset = 0.0)
|
||||||
{
|
// {
|
||||||
internal static Battery48TLStatus ParseBatteryStatus(this ModbusRegisters data)
|
// var value = data[register].ConvertTo<Int32>(); // widen to 32bit signed
|
||||||
{
|
//
|
||||||
var greenLed = data.ParseLedState(register: 1005, led: LedColor.Green);
|
// if (value >= 0x8000)
|
||||||
var amberLed = data.ParseLedState(register: 1005, led: LedColor.Amber);
|
// value -= 0x10000; // Fiamm stores their integers signed AND with sign-offset @#%^&!
|
||||||
var blueLed = data.ParseLedState(register: 1005, led: LedColor.Blue);
|
//
|
||||||
var redLed = data.ParseLedState(register: 1005, led: LedColor.Red);
|
// return (Decimal)(value + offset) * scaleFactor;
|
||||||
|
// }
|
||||||
var soc = data.ParseSoc();
|
//
|
||||||
|
// internal static Decimal ParseCurrent(this ModbusRegisters data)
|
||||||
// var eoc = greenLed is On
|
// {
|
||||||
// && amberLed is Off
|
// return data.ParseDecimal(register: 1001, scaleFactor: 0.01m, offset: -10000);
|
||||||
// && blueLed is Off;
|
// }
|
||||||
|
//
|
||||||
var eoc = data.ParseEocReached();
|
// internal static Decimal ParseBusVoltage(this ModbusRegisters data)
|
||||||
|
// {
|
||||||
var maxSoc = eoc ? 100m : 99.9m;
|
// return data.ParseDecimal(register: 1002, scaleFactor: 0.01m);
|
||||||
|
// }
|
||||||
var batteryCold = greenLed >= BlinkingSlow
|
//
|
||||||
&& blueLed >= BlinkingSlow;
|
// internal static Boolean ParseBool(this ModbusRegisters data, Int32 baseRegister, Int16 bit)
|
||||||
|
// {
|
||||||
var temperatureState = batteryCold
|
// var x = bit / 16;
|
||||||
? TemperatureState.Cold
|
// var y = bit % 16;
|
||||||
: TemperatureState.OperatingTemperature; // TODO: overheated
|
//
|
||||||
|
// var value = (UInt32)data[baseRegister + x];
|
||||||
|
//
|
||||||
return new Battery48TLStatus
|
// return (value & (1 << y)) > 0;
|
||||||
{
|
// }
|
||||||
Dc = data.ParseDcBus(),
|
//
|
||||||
Alarms = data.ParseAlarms().ToList(),
|
//
|
||||||
Warnings = data.ParseWarnings().ToList(),
|
// internal static LedState ParseLed(this UInt16 ledStates, LedColor led)
|
||||||
Soc = Math.Min(soc, maxSoc),
|
// {
|
||||||
Temperature = data.ParseDecimal(register: 1004, scaleFactor: 0.1m, offset: -400),
|
// return (LedState)((ledStates >> (Int32)led * 2) & 3);
|
||||||
GreenLed = greenLed,
|
// }
|
||||||
AmberLed = amberLed,
|
//
|
||||||
BlueLed = blueLed,
|
//
|
||||||
RedLed = redLed,
|
// private static Decimal CalcPowerLimitImposedByVoltageLimit(Decimal v, Decimal i, Decimal vLimit, Decimal rInt)
|
||||||
Heating = data.ParseBool(baseRegister: 1014, bit: 6),
|
// {
|
||||||
ConnectedToDc = data.ParseBool(baseRegister: 1014, bit: 0),
|
// var dv = vLimit - v;
|
||||||
TemperatureState = temperatureState,
|
// var di = dv / rInt;
|
||||||
MaxChargingPower = data.CalcMaxChargePower(),
|
// var pLimit = vLimit * (i + di);
|
||||||
MaxDischargingPower = data.CalcMaxDischargePower(),
|
//
|
||||||
CellsVoltage = data.ParseDecimal(register: 1000, scaleFactor: 0.01m),
|
// return pLimit;
|
||||||
TotalCurrent = data.ReadTotalCurrent(),
|
// }
|
||||||
EocReached = eoc
|
//
|
||||||
};
|
// private static Decimal CalcPowerLimitImposedByCurrentLimit(Decimal v, Decimal i, Decimal iLimit, Decimal rInt)
|
||||||
}
|
// {
|
||||||
|
// var di = iLimit - i;
|
||||||
|
// var dv = di * rInt;
|
||||||
public static Decimal ParseDecimal(this ModbusRegisters data, Int32 register, Decimal scaleFactor = 1.0m, Double offset = 0.0)
|
// var pLimit = iLimit * (v + dv);
|
||||||
{
|
//
|
||||||
var value = data[register].ConvertTo<Int32>(); // widen to 32bit signed
|
// return pLimit;
|
||||||
|
// }
|
||||||
if (value >= 0x8000)
|
//
|
||||||
value -= 0x10000; // Fiamm stores their integers signed AND with sign-offset @#%^&!
|
//
|
||||||
|
// private static Decimal CalcPowerLimitImposedByTempLimit(Decimal t, Decimal maxAllowedTemp, Decimal power , Decimal setpoint)
|
||||||
return (Decimal)(value + offset) * scaleFactor;
|
// {
|
||||||
}
|
// // const Int32 holdZone = 300;
|
||||||
|
// // const Int32 maxAllowedTemp = 315;
|
||||||
internal static Decimal ParseCurrent(this ModbusRegisters data)
|
//
|
||||||
{
|
// var kp = 0.05m;
|
||||||
return data.ParseDecimal(register: 1001, scaleFactor: 0.01m, offset: -10000);
|
// var error = setpoint - power;
|
||||||
}
|
// var controlOutput = (kp * error) *(1 - Math.Abs((t-307.5m)/7.5m));
|
||||||
|
//
|
||||||
internal static Decimal ParseBusVoltage(this ModbusRegisters data)
|
// return controlOutput;
|
||||||
{
|
//
|
||||||
return data.ParseDecimal(register: 1002, scaleFactor: 0.01m);
|
// // var a = holdZone - maxAllowedTemp;
|
||||||
}
|
// // var b = -a * maxAllowedTemp;
|
||||||
|
// }
|
||||||
internal static Decimal ReadTotalCurrent(this ModbusRegisters data)
|
//
|
||||||
{
|
// internal static Decimal CalcMaxChargePower(this ModbusRegisters data)
|
||||||
try
|
// {
|
||||||
{
|
// var v = data.ParseDecimal(register: 1000, scaleFactor: 0.01m);
|
||||||
return ParseDecimal(data, register: 1063, scaleFactor: 0.01m, offset: -100);
|
// var i = ParseCurrent(data);
|
||||||
}
|
//
|
||||||
catch (Exception e)
|
// var pLimits = new[]
|
||||||
{
|
// {
|
||||||
Console.WriteLine(e + " Read Total current fail ");
|
// // TODO: review
|
||||||
throw;
|
// CalcPowerLimitImposedByVoltageLimit(v, i, Constants.VMax, Constants.RIntMin),
|
||||||
}
|
// CalcPowerLimitImposedByVoltageLimit(v, i, Constants.VMax, Constants.RIntMax),
|
||||||
}
|
// CalcPowerLimitImposedByCurrentLimit(v, i, Constants.IMax, Constants.RIntMin),
|
||||||
|
// CalcPowerLimitImposedByCurrentLimit(v, i, Constants.IMax, Constants.RIntMax)
|
||||||
internal static Boolean ParseBool(this ModbusRegisters data, Int32 baseRegister, Int16 bit)
|
// };
|
||||||
{
|
//
|
||||||
var x = bit / 16;
|
// var pLimit = pLimits.Min();
|
||||||
var y = bit % 16;
|
//
|
||||||
|
// return Math.Max(pLimit, 0);
|
||||||
var value = (UInt32)data[baseRegister + x];
|
// }
|
||||||
|
//
|
||||||
return (value & (1 << y)) > 0;
|
// internal static DcBus ParseDcBus(this ModbusRegisters data) => new()
|
||||||
}
|
// {
|
||||||
|
// Current = data.ParseCurrent(),
|
||||||
internal static LedState ParseLedState(this ModbusRegisters data, Int32 register, LedColor led)
|
// Voltage = data.ParseBusVoltage(),
|
||||||
{
|
// };
|
||||||
var lo = data.ParseBool(register, (led.ConvertTo<Int16>() * 2 ).ConvertTo<Int16>());
|
//
|
||||||
var hi = data.ParseBool(register, (led.ConvertTo<Int16>() * 2 + 1).ConvertTo<Int16>());
|
// internal static Decimal CalcMaxDischargePower(this ModbusRegisters data)
|
||||||
|
// {
|
||||||
return (hi, lo) switch
|
// var v = data.ParseDecimal(register: 1000, scaleFactor: 0.01m);
|
||||||
{
|
// var i = ParseCurrent(data);
|
||||||
(false, false) => Off,
|
//
|
||||||
(false, true) => On,
|
// var pLimits = new[]
|
||||||
(true, false) => BlinkingSlow,
|
// {
|
||||||
(true, true) => BlinkingFast,
|
// // TODO: review
|
||||||
};
|
// CalcPowerLimitImposedByVoltageLimit(v, i, Constants.VMin, Constants.RIntMin),
|
||||||
}
|
// CalcPowerLimitImposedByVoltageLimit(v, i, Constants.VMin, Constants.RIntMax),
|
||||||
|
// CalcPowerLimitImposedByCurrentLimit(v, i, -Constants.IMax, Constants.RIntMin),
|
||||||
internal static String ParseString(this ModbusRegisters data, Int32 register, Int16 count)
|
// CalcPowerLimitImposedByCurrentLimit(v, i, -Constants.IMax, Constants.RIntMax),
|
||||||
{
|
// // CalcPowerLimitImposedByTempLimit(t,315,300)
|
||||||
return Enumerable
|
// };
|
||||||
.Range(register, count)
|
//
|
||||||
.Select(i => data[i])
|
// var pLimit = pLimits.Max();
|
||||||
.Select(BitConverter.GetBytes)
|
//
|
||||||
.Select(Encoding.ASCII.GetString)
|
// return Math.Min(pLimit, 0);
|
||||||
.Aggregate("", (a, b) => a + b[1] + b[0]); // endian swap
|
// }
|
||||||
}
|
//
|
||||||
|
//
|
||||||
internal static Boolean ParseEocReached(this ModbusRegisters data)
|
// [SuppressMessage("ReSharper", "StringLiteralTypo")]
|
||||||
{
|
// internal static IEnumerable<String> ParseAlarms(this ModbusRegisters data)
|
||||||
var s = ParseString(data, 1061, 2);
|
// {
|
||||||
return "EOC_" == s;
|
// if (data.ParseBool(1010, 0)) yield return "Tam : BMS temperature too low";
|
||||||
}
|
// if (data.ParseBool(1010, 2)) yield return "TaM2 : BMS temperature too high";
|
||||||
|
// if (data.ParseBool(1010, 3)) yield return "Tbm : Battery temperature too low";
|
||||||
internal static Decimal ParseSoc(this ModbusRegisters data)
|
// if (data.ParseBool(1010, 5)) yield return "TbM2 : Battery temperature too high";
|
||||||
{
|
// if (data.ParseBool(1010, 7)) yield return "VBm2 : Bus voltage too low";
|
||||||
return data.ParseDecimal(register: 1054, scaleFactor: 0.1m);
|
// if (data.ParseBool(1010, 9)) yield return "VBM2 : Bus voltage too high";
|
||||||
}
|
// if (data.ParseBool(1010, 11)) yield return "IDM2 : Discharge current too high";
|
||||||
|
// if (data.ParseBool(1010, 12)) yield return "ISOB : Electrical insulation failure";
|
||||||
private static Decimal CalcPowerLimitImposedByVoltageLimit(Decimal v,Decimal i,Decimal vLimit,Decimal rInt)
|
// if (data.ParseBool(1010, 13)) yield return "MSWE : Main switch failure";
|
||||||
{
|
// if (data.ParseBool(1010, 14)) yield return "FUSE : Main fuse blown";
|
||||||
var dv = vLimit - v;
|
// if (data.ParseBool(1010, 15)) yield return "HTRE : Battery failed to warm up";
|
||||||
var di = dv / rInt;
|
// if (data.ParseBool(1010, 16)) yield return "TCPE : Temperature sensor failure";
|
||||||
var pLimit = vLimit * (i + di);
|
// if (data.ParseBool(1010, 17)) yield return "STRE :";
|
||||||
|
// if (data.ParseBool(1010, 18)) yield return "CME : Current sensor failure";
|
||||||
return pLimit;
|
// if (data.ParseBool(1010, 19)) yield return "HWFL : BMS hardware failure";
|
||||||
}
|
// if (data.ParseBool(1010, 20)) yield return "HWEM : Hardware protection tripped";
|
||||||
|
// if (data.ParseBool(1010, 21)) yield return "ThM : Heatsink temperature too high";
|
||||||
private static Decimal CalcPowerLimitImposedByCurrentLimit(Decimal v, Decimal i, Decimal iLimit, Decimal rInt)
|
// if (data.ParseBool(1010, 22)) yield return "vsm1 : String voltage too low";
|
||||||
{
|
// if (data.ParseBool(1010, 23)) yield return "vsm2 : Low string voltage failure";
|
||||||
var di = iLimit - i;
|
// if (data.ParseBool(1010, 25)) yield return "vsM2 : String voltage too high";
|
||||||
var dv = di * rInt;
|
// if (data.ParseBool(1010, 27)) yield return "iCM2 : Charge current too high";
|
||||||
var pLimit = iLimit * (v + dv);
|
// if (data.ParseBool(1010, 29)) yield return "iDM2 : Discharge current too high";
|
||||||
|
// if (data.ParseBool(1010, 31)) yield return "MID2 : String voltage unbalance too high";
|
||||||
return pLimit;
|
// if (data.ParseBool(1010, 33)) yield return "CCBF : Internal charger hardware failure";
|
||||||
}
|
// if (data.ParseBool(1010, 34)) yield return "AhFL :";
|
||||||
|
// if (data.ParseBool(1010, 36)) yield return "TbCM :";
|
||||||
|
// if (data.ParseBool(1010, 37)) yield return "BRNF :";
|
||||||
private static Decimal CalcPowerLimitImposedByTempLimit(Decimal t, Decimal maxAllowedTemp, Decimal power , Decimal setpoint)
|
// if (data.ParseBool(1010, 42)) yield return "HTFS : If Heaters Fuse Blown";
|
||||||
{
|
// if (data.ParseBool(1010, 43)) yield return "DATA : Parameters out of range";
|
||||||
// const Int32 holdZone = 300;
|
// if (data.ParseBool(1010, 45)) yield return "CELL2:";
|
||||||
// const Int32 maxAllowedTemp = 315;
|
// }
|
||||||
|
//
|
||||||
var kp = 0.05m;
|
// [SuppressMessage("ReSharper", "StringLiteralTypo")]
|
||||||
var error = setpoint - power;
|
// internal static IEnumerable<String> ParseWarnings(this ModbusRegisters data)
|
||||||
var controlOutput = (kp * error) *(1 - Math.Abs((t-307.5m)/7.5m));
|
// {
|
||||||
|
// if (data.ParseBool(1006, 1)) yield return "TaM1: BMS temperature high";
|
||||||
return controlOutput;
|
// if (data.ParseBool(1006, 4)) yield return "TbM1: Battery temperature high";
|
||||||
|
// if (data.ParseBool(1006, 6)) yield return "VBm1: Bus voltage low";
|
||||||
// var a = holdZone - maxAllowedTemp;
|
// if (data.ParseBool(1006, 8)) yield return "VBM1: Bus voltage high";
|
||||||
// var b = -a * maxAllowedTemp;
|
// if (data.ParseBool(1006, 10)) yield return "IDM1: Discharge current high";
|
||||||
}
|
// if (data.ParseBool(1006, 24)) yield return "vsM1: String voltage high";
|
||||||
|
// if (data.ParseBool(1006, 26)) yield return "iCM1: Charge current high";
|
||||||
internal static Decimal CalcMaxChargePower(this ModbusRegisters data)
|
// if (data.ParseBool(1006, 28)) yield return "iDM1: Discharge current high";
|
||||||
{
|
// if (data.ParseBool(1006, 30)) yield return "MID1: String voltages unbalanced";
|
||||||
var v = data.ParseDecimal(register: 1000, scaleFactor: 0.01m);
|
// if (data.ParseBool(1006, 32)) yield return "BLPW: Not enough charging power on bus";
|
||||||
var i = ParseCurrent(data);
|
// if (data.ParseBool(1006, 35)) yield return "Ah_W: String SOC low";
|
||||||
|
// if (data.ParseBool(1006, 38)) yield return "MPMM: Midpoint wiring problem";
|
||||||
var pLimits = new[]
|
// if (data.ParseBool(1006, 39)) yield return "TCMM:";
|
||||||
{
|
// if (data.ParseBool(1006, 40)) yield return "TCdi: Temperature difference between strings high";
|
||||||
// TODO: review
|
// if (data.ParseBool(1006, 41)) yield return "WMTO:";
|
||||||
CalcPowerLimitImposedByVoltageLimit(v, i, Constants.VMax, Constants.RIntMin),
|
// if (data.ParseBool(1006, 44)) yield return "bit44:";
|
||||||
CalcPowerLimitImposedByVoltageLimit(v, i, Constants.VMax, Constants.RIntMax),
|
// if (data.ParseBool(1006, 46)) yield return "CELL1:";
|
||||||
CalcPowerLimitImposedByCurrentLimit(v, i, Constants.IMax, Constants.RIntMin),
|
// }
|
||||||
CalcPowerLimitImposedByCurrentLimit(v, i, Constants.IMax, Constants.RIntMax)
|
// }
|
||||||
};
|
|
||||||
|
|
||||||
var pLimit = pLimits.Min();
|
|
||||||
|
|
||||||
return Math.Max(pLimit, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
internal static DcBus ParseDcBus(this ModbusRegisters data) => new()
|
|
||||||
{
|
|
||||||
Current = data.ParseCurrent(),
|
|
||||||
Voltage = data.ParseBusVoltage(),
|
|
||||||
};
|
|
||||||
|
|
||||||
internal static Decimal CalcMaxDischargePower(this ModbusRegisters data)
|
|
||||||
{
|
|
||||||
var v = data.ParseDecimal(register: 1000, scaleFactor: 0.01m);
|
|
||||||
var i = ParseCurrent(data);
|
|
||||||
|
|
||||||
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),
|
|
||||||
CalcPowerLimitImposedByCurrentLimit(v, i, -Constants.IMax, Constants.RIntMax),
|
|
||||||
// CalcPowerLimitImposedByTempLimit(t,315,300)
|
|
||||||
};
|
|
||||||
|
|
||||||
var pLimit = pLimits.Max();
|
|
||||||
|
|
||||||
return Math.Min(pLimit, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
[SuppressMessage("ReSharper", "StringLiteralTypo")]
|
|
||||||
internal static IEnumerable<String> ParseAlarms(this ModbusRegisters data)
|
|
||||||
{
|
|
||||||
if (data.ParseBool(1010, 0)) yield return "Tam : BMS temperature too low";
|
|
||||||
if (data.ParseBool(1010, 2)) yield return "TaM2 : BMS temperature too high";
|
|
||||||
if (data.ParseBool(1010, 3)) yield return "Tbm : Battery temperature too low";
|
|
||||||
if (data.ParseBool(1010, 5)) yield return "TbM2 : Battery temperature too high";
|
|
||||||
if (data.ParseBool(1010, 7)) yield return "VBm2 : Bus voltage too low";
|
|
||||||
if (data.ParseBool(1010, 9)) yield return "VBM2 : Bus voltage too high";
|
|
||||||
if (data.ParseBool(1010, 11)) yield return "IDM2 : Discharge current too high";
|
|
||||||
if (data.ParseBool(1010, 12)) yield return "ISOB : Electrical insulation failure";
|
|
||||||
if (data.ParseBool(1010, 13)) yield return "MSWE : Main switch failure";
|
|
||||||
if (data.ParseBool(1010, 14)) yield return "FUSE : Main fuse blown";
|
|
||||||
if (data.ParseBool(1010, 15)) yield return "HTRE : Battery failed to warm up";
|
|
||||||
if (data.ParseBool(1010, 16)) yield return "TCPE : Temperature sensor failure";
|
|
||||||
if (data.ParseBool(1010, 17)) yield return "STRE :";
|
|
||||||
if (data.ParseBool(1010, 18)) yield return "CME : Current sensor failure";
|
|
||||||
if (data.ParseBool(1010, 19)) yield return "HWFL : BMS hardware failure";
|
|
||||||
if (data.ParseBool(1010, 20)) yield return "HWEM : Hardware protection tripped";
|
|
||||||
if (data.ParseBool(1010, 21)) yield return "ThM : Heatsink temperature too high";
|
|
||||||
if (data.ParseBool(1010, 22)) yield return "vsm1 : String voltage too low";
|
|
||||||
if (data.ParseBool(1010, 23)) yield return "vsm2 : Low string voltage failure";
|
|
||||||
if (data.ParseBool(1010, 25)) yield return "vsM2 : String voltage too high";
|
|
||||||
if (data.ParseBool(1010, 27)) yield return "iCM2 : Charge current too high";
|
|
||||||
if (data.ParseBool(1010, 29)) yield return "iDM2 : Discharge current too high";
|
|
||||||
if (data.ParseBool(1010, 31)) yield return "MID2 : String voltage unbalance too high";
|
|
||||||
if (data.ParseBool(1010, 33)) yield return "CCBF : Internal charger hardware failure";
|
|
||||||
if (data.ParseBool(1010, 34)) yield return "AhFL :";
|
|
||||||
if (data.ParseBool(1010, 36)) yield return "TbCM :";
|
|
||||||
if (data.ParseBool(1010, 37)) yield return "BRNF :";
|
|
||||||
if (data.ParseBool(1010, 42)) yield return "HTFS : If Heaters Fuse Blown";
|
|
||||||
if (data.ParseBool(1010, 43)) yield return "DATA : Parameters out of range";
|
|
||||||
if (data.ParseBool(1010, 45)) yield return "CELL2:";
|
|
||||||
}
|
|
||||||
|
|
||||||
[SuppressMessage("ReSharper", "StringLiteralTypo")]
|
|
||||||
internal static IEnumerable<String> ParseWarnings(this ModbusRegisters data)
|
|
||||||
{
|
|
||||||
if (data.ParseBool(1006, 1)) yield return "TaM1: BMS temperature high";
|
|
||||||
if (data.ParseBool(1006, 4)) yield return "TbM1: Battery temperature high";
|
|
||||||
if (data.ParseBool(1006, 6)) yield return "VBm1: Bus voltage low";
|
|
||||||
if (data.ParseBool(1006, 8)) yield return "VBM1: Bus voltage high";
|
|
||||||
if (data.ParseBool(1006, 10)) yield return "IDM1: Discharge current high";
|
|
||||||
if (data.ParseBool(1006, 24)) yield return "vsM1: String voltage high";
|
|
||||||
if (data.ParseBool(1006, 26)) yield return "iCM1: Charge current high";
|
|
||||||
if (data.ParseBool(1006, 28)) yield return "iDM1: Discharge current high";
|
|
||||||
if (data.ParseBool(1006, 30)) yield return "MID1: String voltages unbalanced";
|
|
||||||
if (data.ParseBool(1006, 32)) yield return "BLPW: Not enough charging power on bus";
|
|
||||||
if (data.ParseBool(1006, 35)) yield return "Ah_W: String SOC low";
|
|
||||||
if (data.ParseBool(1006, 38)) yield return "MPMM: Midpoint wiring problem";
|
|
||||||
if (data.ParseBool(1006, 39)) yield return "TCMM:";
|
|
||||||
if (data.ParseBool(1006, 40)) yield return "TCdi: Temperature difference between strings high";
|
|
||||||
if (data.ParseBool(1006, 41)) yield return "WMTO:";
|
|
||||||
if (data.ParseBool(1006, 44)) yield return "bit44:";
|
|
||||||
if (data.ParseBool(1006, 46)) yield return "CELL1:";
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,122 @@
|
||||||
|
using System.Diagnostics.CodeAnalysis;
|
||||||
|
using InnovEnergy.Lib.Devices.Battery48TL.DataTypes;
|
||||||
|
using InnovEnergy.Lib.Protocols.Modbus.Conversions;
|
||||||
|
using static InnovEnergy.Lib.Devices.Battery48TL.DataTypes.LedState;
|
||||||
|
using static InnovEnergy.Lib.Devices.Battery48TL.DataTypes.TemperatureState;
|
||||||
|
|
||||||
|
namespace InnovEnergy.Lib.Devices.Battery48TL;
|
||||||
|
|
||||||
|
using R = Battery48TlRegisters;
|
||||||
|
|
||||||
|
internal static class Parser
|
||||||
|
{
|
||||||
|
internal static Boolean ParseEoc(this R r)
|
||||||
|
{
|
||||||
|
return r.Leds is
|
||||||
|
{
|
||||||
|
Green: On,
|
||||||
|
Amber: Off,
|
||||||
|
Blue : Off
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static Leds ParseLeds(this R r)
|
||||||
|
{
|
||||||
|
LedState ParseLed(LedColor led) => (LedState)((r._LedStates >> (Int32)led) & 3);
|
||||||
|
|
||||||
|
return new()
|
||||||
|
{
|
||||||
|
Blue = ParseLed(LedColor.Blue),
|
||||||
|
Green = ParseLed(LedColor.Green),
|
||||||
|
Amber = ParseLed(LedColor.Amber),
|
||||||
|
Red = ParseLed(LedColor.Red),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static Temperatures ParseBatteryTemperatures(this R r) => new()
|
||||||
|
{
|
||||||
|
Board = r._TemperatureBoard,
|
||||||
|
Cells = r.ParseCells(),
|
||||||
|
State = r.ParseTemperatureState()
|
||||||
|
};
|
||||||
|
|
||||||
|
private static TemperatureState ParseTemperatureState(this R r) => r.Leds switch
|
||||||
|
{
|
||||||
|
{ Green: >= Blinking, Blue: >= Blinking } => Cold,
|
||||||
|
_ => Operation,
|
||||||
|
// TODO: overheated
|
||||||
|
};
|
||||||
|
|
||||||
|
private static CellTemperatures ParseCells(this R r) => new()
|
||||||
|
{
|
||||||
|
Left = r._TemperatureCellsLeft,
|
||||||
|
Right = r._TemperatureCellsRight,
|
||||||
|
Center = r._TemperatureCellsCenter
|
||||||
|
};
|
||||||
|
|
||||||
|
internal static Boolean ParseConnectedToDcBus(this R r) => (r._IoStates & 1) == 0; // inverted
|
||||||
|
internal static Boolean ParseHeating (this R r) => (r._IoStates & 64) != 0;
|
||||||
|
|
||||||
|
|
||||||
|
[SuppressMessage("ReSharper", "StringLiteralTypo")]
|
||||||
|
internal static IEnumerable<String> ParseAlarms(this R data)
|
||||||
|
{
|
||||||
|
Boolean HasBit(Int16 bit) => (data._AlarmFlags & 1uL << bit) > 0;
|
||||||
|
|
||||||
|
if (HasBit(0) ) yield return "Tam : BMS temperature too low";
|
||||||
|
if (HasBit(2) ) yield return "TaM2 : BMS temperature too high";
|
||||||
|
if (HasBit(3) ) yield return "Tbm : Battery temperature too low";
|
||||||
|
if (HasBit(5) ) yield return "TbM2 : Battery temperature too high";
|
||||||
|
if (HasBit(7) ) yield return "VBm2 : Bus voltage too low";
|
||||||
|
if (HasBit(9) ) yield return "VBM2 : Bus voltage too high";
|
||||||
|
if (HasBit(11)) yield return "IDM2 : Discharge current too high";
|
||||||
|
if (HasBit(12)) yield return "ISOB : Electrical insulation failure";
|
||||||
|
if (HasBit(13)) yield return "MSWE : Main switch failure";
|
||||||
|
if (HasBit(14)) yield return "FUSE : Main fuse blown";
|
||||||
|
if (HasBit(15)) yield return "HTRE : Battery failed to warm up";
|
||||||
|
if (HasBit(16)) yield return "TCPE : Temperature sensor failure";
|
||||||
|
if (HasBit(17)) yield return "STRE :";
|
||||||
|
if (HasBit(18)) yield return "CME : Current sensor failure";
|
||||||
|
if (HasBit(19)) yield return "HWFL : BMS hardware failure";
|
||||||
|
if (HasBit(20)) yield return "HWEM : Hardware protection tripped";
|
||||||
|
if (HasBit(21)) yield return "ThM : Heatsink temperature too high";
|
||||||
|
if (HasBit(22)) yield return "vsm1 : String voltage too low";
|
||||||
|
if (HasBit(23)) yield return "vsm2 : Low string voltage failure";
|
||||||
|
if (HasBit(25)) yield return "vsM2 : String voltage too high";
|
||||||
|
if (HasBit(27)) yield return "iCM2 : Charge current too high";
|
||||||
|
if (HasBit(29)) yield return "iDM2 : Discharge current too high";
|
||||||
|
if (HasBit(31)) yield return "MID2 : String voltage unbalance too high";
|
||||||
|
if (HasBit(33)) yield return "CCBF : Internal charger hardware failure";
|
||||||
|
if (HasBit(34)) yield return "AhFL :";
|
||||||
|
if (HasBit(36)) yield return "TbCM :";
|
||||||
|
if (HasBit(37)) yield return "BRNF :";
|
||||||
|
if (HasBit(42)) yield return "HTFS : If Heaters Fuse Blown";
|
||||||
|
if (HasBit(43)) yield return "DATA : Parameters out of range";
|
||||||
|
if (HasBit(45)) yield return "CELL2:";
|
||||||
|
}
|
||||||
|
|
||||||
|
[SuppressMessage("ReSharper", "StringLiteralTypo")]
|
||||||
|
internal static IEnumerable<String> ParseWarnings(this R data)
|
||||||
|
{
|
||||||
|
Boolean HasBit(Int16 bit) => (data._WarningFlags & 1uL << bit) > 0;
|
||||||
|
|
||||||
|
if (HasBit(1) ) yield return "TaM1: BMS temperature high";
|
||||||
|
if (HasBit(4) ) yield return "TbM1: Battery temperature high";
|
||||||
|
if (HasBit(6) ) yield return "VBm1: Bus voltage low";
|
||||||
|
if (HasBit(8) ) yield return "VBM1: Bus voltage high";
|
||||||
|
if (HasBit(10)) yield return "IDM1: Discharge current high";
|
||||||
|
if (HasBit(24)) yield return "vsM1: String voltage high";
|
||||||
|
if (HasBit(26)) yield return "iCM1: Charge current high";
|
||||||
|
if (HasBit(28)) yield return "iDM1: Discharge current high";
|
||||||
|
if (HasBit(30)) yield return "MID1: String voltages unbalanced";
|
||||||
|
if (HasBit(32)) yield return "BLPW: Not enough charging power on bus";
|
||||||
|
if (HasBit(35)) yield return "Ah_W: String SOC low";
|
||||||
|
if (HasBit(38)) yield return "MPMM: Midpoint wiring problem";
|
||||||
|
if (HasBit(39)) yield return "TCMM:";
|
||||||
|
if (HasBit(40)) yield return "TCdi: Temperature difference between strings high";
|
||||||
|
if (HasBit(41)) yield return "WMTO:";
|
||||||
|
if (HasBit(44)) yield return "bit44:";
|
||||||
|
if (HasBit(46)) yield return "CELL1:";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,22 @@
|
||||||
|
|
||||||
|
using System.Text.Json;
|
||||||
|
using System.Text.Json.Serialization;
|
||||||
|
using InnovEnergy.Lib.Utils;
|
||||||
|
|
||||||
|
namespace InnovEnergy.Lib.Devices.Battery48TL;
|
||||||
|
|
||||||
|
public static class Program
|
||||||
|
{
|
||||||
|
public static Task Main(string[] args)
|
||||||
|
{
|
||||||
|
var d = new Battery48TlDevice("ttyUSB0", 2, "10.2.3.47");
|
||||||
|
|
||||||
|
var options = new JsonSerializerOptions { WriteIndented = true, Converters = { new JsonStringEnumConverter() }};
|
||||||
|
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
var x = d.Read();
|
||||||
|
(x, options).Apply(JsonSerializer.Serialize).WriteLine();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,8 +0,0 @@
|
||||||
namespace InnovEnergy.Lib.Devices.Battery48TL;
|
|
||||||
|
|
||||||
public enum TemperatureState
|
|
||||||
{
|
|
||||||
Cold = 0,
|
|
||||||
OperatingTemperature = 1,
|
|
||||||
Overheated = 2,
|
|
||||||
}
|
|
Loading…
Reference in New Issue