Compare commits

...

9 Commits

9 changed files with 161 additions and 92 deletions

View File

@ -25,19 +25,17 @@ internal static class Program
public static async Task Main(String[] args)
{
var device1 = new SalimaxDevice { Host = "10.0.1.3" , Port = 502, DeviceState = DeviceState.Measured };
/*var device1 = new SalimaxDevice { Host = "10.0.1.3" , Port = 502, DeviceState = DeviceState.Measured };
_relaysChannel = CreateChannel(device1);
var saliMaxRelaysDevice = new RelaysDeviceAmax(_relaysChannel);
var saliMaxRelaysDevice = new RelaysDeviceAmax(_relaysChannel);*/
/* var listOfBatteries = new List<BatteryDeligreenDevice>
var listOfBatteries = new List<BatteryDeligreenDevice>
{
new BatteryDeligreenDevice(Port, 0),
new BatteryDeligreenDevice(Port, 1)
};
var batteryDevices = new BatteryDeligreenDevices(listOfBatteries);*/
var batteryDevices = new BatteryDeligreenDevices(listOfBatteries);
Console.WriteLine("Starting Battery Communication");
@ -47,51 +45,17 @@ internal static class Program
{
var startTime = DateTime.Now;
Console.WriteLine("***************************** Reading Battery Data *********************************************");
// Console.WriteLine($"Start Reading all Batteries: {startTime}");
//var batteriesRecord = batteryDevices.Read();
Console.WriteLine($"Start Reading all Batteries: {startTime}");
var batteriesRecord = batteryDevices.Read();
var stopTime = DateTime.Now;
//Console.WriteLine($"Finish Reading all Batteries: {stopTime}");
var relays = saliMaxRelaysDevice.Read();
Console.WriteLine($"Finish Reading all Batteries: {stopTime}");
Console.WriteLine("***************************** Writing register 27 to true Amax *********************************************");
relays.K0 = true;
relays.K1 = true;
relays.R0 = true;
relays.R1 = true;
relays.R2 = true;
relays.R3 = true;
// relays.K0Input.WriteLine(" : K0input");
saliMaxRelaysDevice.Write(relays);
Console.WriteLine("***************************** Reading Amax *********************************************");
// relays.K1GridBusIsConnectedToGrid.WriteLine(" : K1");
await Task.Delay(2000);
Console.WriteLine("***************************** Writing register 27 to false Amax *********************************************");
relays.K0 = false;
relays.K1 = false;
relays.R0 = false;
relays.R1 = false;
relays.R2 = false;
relays.R3 = false;
// relays.K0Input.WriteLine(" : K0input");
saliMaxRelaysDevice.Write(relays);
Console.WriteLine("***************************** Reading Amax *********************************************");
/*
Console.WriteLine("Time used for reading all batteries:" + (stopTime - startTime));
Console.WriteLine("Average SOC " + batteriesRecord?.Soc);
Console.WriteLine("Cell Alarm 1 : " + batteriesRecord?.Devices[0].BatteryDeligreenAlarmRecord.CellAlarmList[0]);
/* Console.WriteLine("Cell Alarm 1 : " + batteriesRecord?.Devices[0].BatteryDeligreenAlarmRecord.CellAlarmList[0]);
Console.WriteLine("Cell Alarm 2 : " + batteriesRecord?.Devices[0].BatteryDeligreenAlarmRecord.CellAlarmList[1]);
Console.WriteLine("Cell Temperature Alarm 1 : " + batteriesRecord?.Devices[0].BatteryDeligreenAlarmRecord.CellTemperatureAlarm[0]);
@ -105,8 +69,15 @@ internal static class Program
Console.WriteLine("TotalVoltage Alarm : " + batteriesRecord?.Devices[0].BatteryDeligreenAlarmRecord.TotalVoltageAlarm);
Console.WriteLine("PowerTemp Alarm : " + batteriesRecord?.Devices[0].BatteryDeligreenAlarmRecord.PowerTempAlarm);*/
Console.WriteLine("CellVoltageDropoutFault : " + batteriesRecord?.Devices[0].BatteryDeligreenAlarmRecord.AlarmEvent1.CellVoltageDropoutFault);
Console.WriteLine("ChargeSwitchFault : " + batteriesRecord?.Devices[0].BatteryDeligreenAlarmRecord.AlarmEvent1.ChargeSwitchFault);
Console.WriteLine("CurrentSensorFault : " + batteriesRecord?.Devices[0].BatteryDeligreenAlarmRecord.AlarmEvent1.CurrentSensorFault);
Console.WriteLine("DischargeSwitchFault : " + batteriesRecord?.Devices[0].BatteryDeligreenAlarmRecord.AlarmEvent1.DischargeSwitchFault);
Console.WriteLine("KeySwitchFault : " + batteriesRecord?.Devices[0].BatteryDeligreenAlarmRecord.AlarmEvent1.KeySwitchFault);
Console.WriteLine("TemperatureSensorFault : " + batteriesRecord?.Devices[0].BatteryDeligreenAlarmRecord.AlarmEvent1.TemperatureSensorFault);
Console.WriteLine("VoltageSensorFault : " + batteriesRecord?.Devices[0].BatteryDeligreenAlarmRecord.AlarmEvent1.VoltageSensorFault);
Console.WriteLine("CurrentLimitSwitchFault : " + batteriesRecord?.Devices[0].BatteryDeligreenAlarmRecord.AlarmEvent1.CurrentLimitSwitchFault);
// Wait for 2 seconds before the next reading
await Task.Delay(2000); // Delay in milliseconds (2000ms = 2 seconds)
}

View File

@ -12,7 +12,7 @@ public class RelaysRecordAmax
//{
// get => _regs.DigitalInput;
//}
/*
public Boolean K0
{

View File

@ -63,10 +63,10 @@ internal static class Program
private static Boolean _subscribeToQueueForTheFirstTime = false;
private static SalimaxAlarmState _prevSalimaxState = SalimaxAlarmState.Green;
private const UInt16 NbrOfFileToConcatenate = 30;
private static UInt16 _counterOfFile = 0;
private static UInt16 _fileCounter = 0;
private static SalimaxAlarmState _salimaxAlarmState = SalimaxAlarmState.Green;
private const String Port = "/dev/ttyUSB0";
private static Boolean _oneTimeFlag = false;
static Program()
{
@ -324,6 +324,41 @@ internal static class Program
var bAlarmList = new List<String>();
var bWarningList = new List<String>();
if (record.Battery != null)
{
_oneTimeFlag.WriteLine(" onetime flag");
if (record.Battery?.Voltage != null && (record.Battery?.HighestCellVoltage ?? 0) > 3.80 && !_oneTimeFlag) //this shoudld be checked the number 0
{
_oneTimeFlag = true;
warningList.Add(new AlarmOrWarning
{
Date = DateTime.Now.ToString("yyyy-MM-dd"),
Time = DateTime.Now.ToString("HH:mm:ss"),
CreatedBy = "Charging Battery System",
Description = "dynCCL Active: Max Battery Charging is 10 * N"
});
}
else
{
_oneTimeFlag = false;
}
if (record.Battery?.Voltage != null && (record.Battery?.LowestCellVoltage ?? 10) < 2.0 && !_oneTimeFlag) //this should be checked the number 10
{
_oneTimeFlag = true;
warningList.Add(new AlarmOrWarning
{
Date = DateTime.Now.ToString("yyyy-MM-dd"),
Time = DateTime.Now.ToString("HH:mm:ss"),
CreatedBy = "Battery System",
Description = "dynDCL Active: Max Battery Discharging is 10 * N"
});
}
else
{
_oneTimeFlag = false;
}
}
/*
if (record.Battery != null)
{
@ -491,8 +526,10 @@ internal static class Program
Double maxBatteryChargingCurrentLive ; //used with deligreenBattery for limiting charging
Double maxBatteryDischargingCurrentLive; //used with deligreenBattery for limiting discharging
r.Battery?.HighestCellVoltage.WriteLine(" HighestCellVoltage");
r.Battery?.LowestCellVoltage.WriteLine(" LowestCellVoltage");
//var maxBatteryDischargingCurrentLive = 0.0; //never used with deligreenBattery
/*
// This adapting the max discharging current to the current Active Strings
@ -525,9 +562,9 @@ internal static class Program
// TODO The discharging current is well calculated but not communicated to live. But Written in S3
// Deligreen upper current limitation dynCCL
if (r.Battery?.Voltage != null && (r.Battery?.Voltage ?? 0) > 61.0 )
if (r.Battery?.Voltage != null && (r.Battery?.HighestCellVoltage ?? 0) > 3.80 )
{
maxBatteryChargingCurrentLive = r.Battery.Devices.Count * 10; // Max charging current is 10 A * Number of batteries
maxBatteryChargingCurrentLive = (r.Battery.Devices.Count * 10)/ r.DcDc.Devices.Count ; // Max charging current is 10 A * Number of batteries
maxBatteryChargingCurrentLive.WriteLine("dynCCL Active: Max Battery Charging is "+ maxBatteryChargingCurrentLive);
}
else
@ -536,15 +573,18 @@ internal static class Program
}
// Deligreen lower current limitation dynDCL
if (r.Battery?.Soc != null && (r.Battery?.Soc ?? 100) < r.Config.MinSoc )
{
maxBatteryDischargingCurrentLive = 0; // Max charging current is 10 A * Number of batteries
maxBatteryDischargingCurrentLive.WriteLine("dynDCL Active: Max Battery disCharging is "+ maxBatteryDischargingCurrentLive);
}
else
{
maxBatteryDischargingCurrentLive = devicesConfig.DcDc.MaxBatteryDischargingCurrent;
}
// if (r.Battery?.Voltage != null && (r.Battery?.LowestCellVoltage ?? 10) < 2.0 ) // this 10 comparison need to be checked
// {
// maxBatteryDischargingCurrentLive =(r.Battery.Devices.Count * 10)/ r.DcDc.Devices.Count ; // Max discharging current is 10 A * Number of batteries
// maxBatteryDischargingCurrentLive.WriteLine("dynDCL Active: Max Battery disCharging is "+ maxBatteryDischargingCurrentLive);
// }
// else
// {
// maxBatteryDischargingCurrentLive = devicesConfig.DcDc.MaxBatteryDischargingCurrent;
// }
maxBatteryChargingCurrentLive.WriteLine(" maxBatteryChargingCurrentLive by DcDC");
maxBatteryDischargingCurrentLive.WriteLine(" maxBatteryDischargingCurrentLive by DcD");
inverters.ForEach(d => d.Control.Dc.MaxVoltage = devicesConfig.AcDc.MaxDcLinkVoltage);
inverters.ForEach(d => d.Control.Dc.MinVoltage = devicesConfig.AcDc.MinDcLinkVoltage);
@ -874,9 +914,9 @@ internal static class Program
private static async Task<Boolean> ConcatinatingAndCompressingFiles(DateTime timeStamp, S3Config s3Config)
{
if (_counterOfFile >= NbrOfFileToConcatenate)
if (_fileCounter >= NbrOfFileToConcatenate)
{
_counterOfFile = 0;
_fileCounter = 0;
var logFileConcatenator = new LogFileConcatenator();
@ -912,7 +952,7 @@ internal static class Program
Heartbit(timeStamp);
}
_counterOfFile++;
_fileCounter++;
return true;
}

View File

@ -8,7 +8,7 @@ namespace InnovEnergy.Lib.Devices.Amax5070
[AddressOffset(-1)]
public class Amax5070Registers
{
[Coil(1)] public Boolean DigitalOutput0 { get; private set; }
[Coil(1)] public Boolean DigitalOutput0 { get; set; }
[Coil(2)] public Boolean DigitalOutput1 { get; private set; }
[Coil(3)] public Boolean DigitalOutput2 { get; private set; }
[Coil(4)] public Boolean DigitalOutput3 { get; private set; }

View File

@ -1,20 +1,38 @@
namespace InnovEnergy.Lib.Devices.BatteryDeligreen;
public class AlarmMessage
public class AlarmBitMessage
{
// Enum for Alarm Event 1
public enum AlarmEvent1
public readonly struct AlarmEvent1_
{
VoltageSensorFault,
TemperatureSensorFault,
CurrentSensorFault,
KeySwitchFault,
CellVoltageDropoutFault,
ChargeSwitchFault,
DischargeSwitchFault,
CurrentLimitSwitchFault
private readonly Byte _record;
public Boolean VoltageSensorFault => (_record & (1 << 0)) == 1;
public Boolean TemperatureSensorFault => (_record & (1 << 1)) == 1;
public Boolean CurrentSensorFault => (_record & (1 << 2)) == 1;
public Boolean KeySwitchFault => (_record & (1 << 3)) == 1;
public Boolean CellVoltageDropoutFault => (_record & (1 << 4)) == 1;
public Boolean ChargeSwitchFault => (_record & (1 << 5)) == 1;
public Boolean DischargeSwitchFault => (_record & (1 << 6)) == 1;
public Boolean CurrentLimitSwitchFault => (_record & (1 << 7)) == 1;
public AlarmEvent1_(Byte record) => _record = record;
}
// Enum for Alarm Event 1
//public enum AlarmEvent1
//{
// VoltageSensorFault,
// TemperatureSensorFault,
// CurrentSensorFault,
// KeySwitchFault,
// CellVoltageDropoutFault,
// ChargeSwitchFault,
// DischargeSwitchFault,
// CurrentLimitSwitchFault
//}
// Enum for Alarm Event 2
public enum AlarmEvent2
{

View File

@ -1,17 +1,36 @@
using static InnovEnergy.Lib.Devices.BatteryDeligreen.AlarmBitMessage;
namespace InnovEnergy.Lib.Devices.BatteryDeligreen;
public class BatteryDeligreenAlarmRecord
{
public List<String> CellAlarmList { get; set; }
public List<String> CellTemperatureAlarm { get; set; }
public String EnviTempAlarm { get; set; }
public String PowerTempAlarm { get; set; }
public String CurrentAlarm { get; set; }
public String TotalVoltageAlarm { get; set; }
public BatteryDeligreenAlarmRecord( List<String> cellAlarmList, List<String> cellTemperatureAlarm, String enviTempAlarm1, String powerTempAlarm1, String currentAlarm1, String totalVoltageAlarm1)
public List<String> CellAlarmList { get; set; }
public List<String> CellTemperatureAlarm { get; set; }
public String EnviTempAlarm { get; set; }
public String PowerTempAlarm { get; set; }
public String CurrentAlarm { get; set; }
public String TotalVoltageAlarm { get; set; }
public AlarmEvent1_ AlarmEvent1 { get; set; }
/* public AlarmBitMessage.AlarmEvent2 AlarmEvent2 { get; set; }
public AlarmBitMessage.AlarmEvent3 AlarmEvent3 { get; set; }
public AlarmBitMessage.AlarmEvent4 AlarmEvent4 { get; set; }
public AlarmBitMessage.AlarmEvent5 AlarmEvent5 { get; set; }
public AlarmBitMessage.AlarmEvent6 AlarmEvent6 { get; set; }
public AlarmBitMessage.AlarmEvent7 AlarmEvent7 { get; set; }
public AlarmBitMessage.AlarmEvent8 AlarmEvent8 { get; set; }
public AlarmBitMessage.DisconnectionState1 DisconnectionState1 { get; set; }
public AlarmBitMessage.DisconnectionState2 DisconnectionState2 { get; set; }
public AlarmBitMessage.EquilibriumState1 EquilibriumState1 { get; set; }
public AlarmBitMessage.EquilibriumState2 EquilibriumState2 { get; set; }
public AlarmBitMessage.OnOffState OnOffState { get; set; }
public AlarmBitMessage.SystemState SystemState { get; set; }*/
public BatteryDeligreenAlarmRecord( List<String> cellAlarmList, List<String> cellTemperatureAlarm, String enviTempAlarm1, String powerTempAlarm1,
String currentAlarm1, String totalVoltageAlarm1, Byte alarmEvent1/*, Enum alarmEvent2, Enum alarmEvent3,
Enum alarmEvent4, Enum alarmEvent5, Enum alarmEvent6, Enum alarmEvent7, Enum alarmEvent8, Enum disconnectionState1,
Enum disconnectionState2, Enum equilibriumState1, Enum equilibriumState2, Enum onOffState, Enum systemState*/)
{
CellAlarmList = cellAlarmList;
CellTemperatureAlarm = cellTemperatureAlarm;
@ -19,5 +38,6 @@ public class BatteryDeligreenAlarmRecord
PowerTempAlarm = powerTempAlarm1;
CurrentAlarm = currentAlarm1;
TotalVoltageAlarm = totalVoltageAlarm1;
AlarmEvent1 = new AlarmEvent1_(alarmEvent1);
}
}

View File

@ -201,7 +201,7 @@ public class BatteryDeligreenDevice
private async Task<BatteryDeligreenAlarmRecord?> ReadTelecomandData(UInt16 batteryId)
{
var frameToSend = batteryId switch
var frameToSend = batteryId switch // this should be calculated
{
0 => "7E3230303034363434453030323030464433350D",
1 => "7E3230303134363434453030323031464433330D",

View File

@ -1,6 +1,4 @@
using InnovEnergy.Lib.Units;
using InnovEnergy.Lib.Units.Composite;
using InnovEnergy.Lib.Units.Power;
namespace InnovEnergy.Lib.Devices.BatteryDeligreen;
@ -14,6 +12,9 @@ public class BatteryDeligreenRecords
public required Percent CurrentMinSoc { get; init; }
public required Temperature TemperatureCell1 { get; init; }
public required Double Power { get; init; }
public required Voltage LowestCellVoltage { get; init; }
public required Voltage HighestCellVoltage { get; init; }
// public required Temperature TemperatureCell2 { get; init; }
// public required Temperature TemperatureCell3 { get; init; }
@ -40,7 +41,8 @@ public class BatteryDeligreenRecords
Current = records.Sum(r =>r.BatteryDeligreenDataRecord.BusCurrent),
Voltage = records.Average(r =>r.BatteryDeligreenDataRecord.BusVoltage),
Power = records.Sum(r => r.BatteryDeligreenDataRecord.Power),
LowestCellVoltage = records.Min(r => r.BatteryDeligreenDataRecord.CellVoltage.Min()),
HighestCellVoltage = records.Max(r => r.BatteryDeligreenDataRecord.CellVoltage.Max())
};
}
}

View File

@ -80,8 +80,9 @@ public class TelecommandFrameParser
var powerTempAlarm = ParseAndPrintField(response, "Power Temperature Alarm" );
var currentAlarm = ParseAndPrintField(response, "Charge/Discharge Current Alarm" );
var totalVoltageAlarm = ParseAndPrintField(response, "Total Battery Voltage Alarm" );
var batteryAlarmRecord = new BatteryDeligreenAlarmRecord(cellAlarmList, cellTemperatureAlarm, enviTempAlarm, powerTempAlarm,currentAlarm, totalVoltageAlarm);
var alarmEvent1 = ParseByteAlarm(response, "Alarm Event 1");
var batteryAlarmRecord = new BatteryDeligreenAlarmRecord(cellAlarmList, cellTemperatureAlarm, enviTempAlarm, powerTempAlarm,currentAlarm, totalVoltageAlarm, alarmEvent1);
return batteryAlarmRecord;
}
@ -151,6 +152,23 @@ public class TelecommandFrameParser
_currentIndex += length;
}
private static Byte ParseByteAlarm(String response, String fieldName)
{
var fieldBytes = response.Substring(_currentIndex, 4);
Byte byteValue = 0;
try
{
var tempAscii = HexToAscii(fieldBytes);
byteValue = byte.Parse(tempAscii, NumberStyles.HexNumber);
}
catch (Exception)
{
Console.WriteLine($"Failed to decode : {fieldName}" + " Alarm");
}
_currentIndex += 4;
return byteValue;
}
private static String ParseAndPrintField(String response, String fieldName)
{
var fieldBytes = response.Substring(_currentIndex, 4);