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) 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); _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, 0),
new BatteryDeligreenDevice(Port, 1) new BatteryDeligreenDevice(Port, 1)
}; };
var batteryDevices = new BatteryDeligreenDevices(listOfBatteries);*/ var batteryDevices = new BatteryDeligreenDevices(listOfBatteries);
Console.WriteLine("Starting Battery Communication"); Console.WriteLine("Starting Battery Communication");
@ -47,51 +45,17 @@ internal static class Program
{ {
var startTime = DateTime.Now; var startTime = DateTime.Now;
Console.WriteLine("***************************** Reading Battery Data *********************************************"); Console.WriteLine("***************************** Reading Battery Data *********************************************");
// Console.WriteLine($"Start Reading all Batteries: {startTime}"); Console.WriteLine($"Start Reading all Batteries: {startTime}");
//var batteriesRecord = batteryDevices.Read(); var batteriesRecord = batteryDevices.Read();
var stopTime = DateTime.Now; var stopTime = DateTime.Now;
//Console.WriteLine($"Finish Reading all Batteries: {stopTime}"); Console.WriteLine($"Finish Reading all Batteries: {stopTime}");
var relays = saliMaxRelaysDevice.Read();
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("Time used for reading all batteries:" + (stopTime - startTime));
Console.WriteLine("Average SOC " + batteriesRecord?.Soc); 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 Alarm 2 : " + batteriesRecord?.Devices[0].BatteryDeligreenAlarmRecord.CellAlarmList[1]);
Console.WriteLine("Cell Temperature Alarm 1 : " + batteriesRecord?.Devices[0].BatteryDeligreenAlarmRecord.CellTemperatureAlarm[0]); 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("TotalVoltage Alarm : " + batteriesRecord?.Devices[0].BatteryDeligreenAlarmRecord.TotalVoltageAlarm);
Console.WriteLine("PowerTemp Alarm : " + batteriesRecord?.Devices[0].BatteryDeligreenAlarmRecord.PowerTempAlarm);*/ 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 // Wait for 2 seconds before the next reading
await Task.Delay(2000); // Delay in milliseconds (2000ms = 2 seconds) await Task.Delay(2000); // Delay in milliseconds (2000ms = 2 seconds)
} }

View File

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

View File

@ -63,10 +63,10 @@ internal static class Program
private static Boolean _subscribeToQueueForTheFirstTime = false; private static Boolean _subscribeToQueueForTheFirstTime = false;
private static SalimaxAlarmState _prevSalimaxState = SalimaxAlarmState.Green; private static SalimaxAlarmState _prevSalimaxState = SalimaxAlarmState.Green;
private const UInt16 NbrOfFileToConcatenate = 30; private const UInt16 NbrOfFileToConcatenate = 30;
private static UInt16 _counterOfFile = 0; private static UInt16 _fileCounter = 0;
private static SalimaxAlarmState _salimaxAlarmState = SalimaxAlarmState.Green; private static SalimaxAlarmState _salimaxAlarmState = SalimaxAlarmState.Green;
private const String Port = "/dev/ttyUSB0"; private const String Port = "/dev/ttyUSB0";
private static Boolean _oneTimeFlag = false;
static Program() static Program()
{ {
@ -324,6 +324,41 @@ internal static class Program
var bAlarmList = new List<String>(); var bAlarmList = new List<String>();
var bWarningList = 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) if (record.Battery != null)
{ {
@ -491,8 +526,10 @@ internal static class Program
Double maxBatteryChargingCurrentLive ; //used with deligreenBattery for limiting charging Double maxBatteryChargingCurrentLive ; //used with deligreenBattery for limiting charging
Double maxBatteryDischargingCurrentLive; //used with deligreenBattery for limiting discharging 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 //var maxBatteryDischargingCurrentLive = 0.0; //never used with deligreenBattery
/* /*
// This adapting the max discharging current to the current Active Strings // 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 // TODO The discharging current is well calculated but not communicated to live. But Written in S3
// Deligreen upper current limitation dynCCL // 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); maxBatteryChargingCurrentLive.WriteLine("dynCCL Active: Max Battery Charging is "+ maxBatteryChargingCurrentLive);
} }
else else
@ -536,15 +573,18 @@ internal static class Program
} }
// Deligreen lower current limitation dynDCL // Deligreen lower current limitation dynDCL
if (r.Battery?.Soc != null && (r.Battery?.Soc ?? 100) < r.Config.MinSoc ) // if (r.Battery?.Voltage != null && (r.Battery?.LowestCellVoltage ?? 10) < 2.0 ) // this 10 comparison need to be checked
{ // {
maxBatteryDischargingCurrentLive = 0; // Max charging current is 10 A * Number of batteries // 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); // maxBatteryDischargingCurrentLive.WriteLine("dynDCL Active: Max Battery disCharging is "+ maxBatteryDischargingCurrentLive);
} // }
else // else
{ // {
maxBatteryDischargingCurrentLive = devicesConfig.DcDc.MaxBatteryDischargingCurrent; // 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.MaxVoltage = devicesConfig.AcDc.MaxDcLinkVoltage);
inverters.ForEach(d => d.Control.Dc.MinVoltage = devicesConfig.AcDc.MinDcLinkVoltage); 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) private static async Task<Boolean> ConcatinatingAndCompressingFiles(DateTime timeStamp, S3Config s3Config)
{ {
if (_counterOfFile >= NbrOfFileToConcatenate) if (_fileCounter >= NbrOfFileToConcatenate)
{ {
_counterOfFile = 0; _fileCounter = 0;
var logFileConcatenator = new LogFileConcatenator(); var logFileConcatenator = new LogFileConcatenator();
@ -912,7 +952,7 @@ internal static class Program
Heartbit(timeStamp); Heartbit(timeStamp);
} }
_counterOfFile++; _fileCounter++;
return true; return true;
} }

View File

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

View File

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

View File

@ -1,17 +1,36 @@
using static InnovEnergy.Lib.Devices.BatteryDeligreen.AlarmBitMessage;
namespace InnovEnergy.Lib.Devices.BatteryDeligreen; namespace InnovEnergy.Lib.Devices.BatteryDeligreen;
public class BatteryDeligreenAlarmRecord public class BatteryDeligreenAlarmRecord
{ {
public List<String> CellAlarmList { get; set; } public List<String> CellAlarmList { get; set; }
public List<String> CellTemperatureAlarm { get; set; } public List<String> CellTemperatureAlarm { get; set; }
public String EnviTempAlarm { get; set; } public String EnviTempAlarm { get; set; }
public String PowerTempAlarm { get; set; } public String PowerTempAlarm { get; set; }
public String CurrentAlarm { get; set; } public String CurrentAlarm { get; set; }
public String TotalVoltageAlarm { get; set; } public String TotalVoltageAlarm { get; set; }
public AlarmEvent1_ AlarmEvent1 { get; set; }
/* public AlarmBitMessage.AlarmEvent2 AlarmEvent2 { get; set; }
public BatteryDeligreenAlarmRecord( List<String> cellAlarmList, List<String> cellTemperatureAlarm, String enviTempAlarm1, String powerTempAlarm1, String currentAlarm1, String totalVoltageAlarm1) 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; CellAlarmList = cellAlarmList;
CellTemperatureAlarm = cellTemperatureAlarm; CellTemperatureAlarm = cellTemperatureAlarm;
@ -19,5 +38,6 @@ public class BatteryDeligreenAlarmRecord
PowerTempAlarm = powerTempAlarm1; PowerTempAlarm = powerTempAlarm1;
CurrentAlarm = currentAlarm1; CurrentAlarm = currentAlarm1;
TotalVoltageAlarm = totalVoltageAlarm1; TotalVoltageAlarm = totalVoltageAlarm1;
AlarmEvent1 = new AlarmEvent1_(alarmEvent1);
} }
} }

View File

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

View File

@ -1,6 +1,4 @@
using InnovEnergy.Lib.Units; using InnovEnergy.Lib.Units;
using InnovEnergy.Lib.Units.Composite;
using InnovEnergy.Lib.Units.Power;
namespace InnovEnergy.Lib.Devices.BatteryDeligreen; namespace InnovEnergy.Lib.Devices.BatteryDeligreen;
@ -14,6 +12,9 @@ public class BatteryDeligreenRecords
public required Percent CurrentMinSoc { get; init; } public required Percent CurrentMinSoc { get; init; }
public required Temperature TemperatureCell1 { get; init; } public required Temperature TemperatureCell1 { get; init; }
public required Double Power { 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 TemperatureCell2 { get; init; }
// public required Temperature TemperatureCell3 { get; init; } // public required Temperature TemperatureCell3 { get; init; }
@ -40,7 +41,8 @@ public class BatteryDeligreenRecords
Current = records.Sum(r =>r.BatteryDeligreenDataRecord.BusCurrent), Current = records.Sum(r =>r.BatteryDeligreenDataRecord.BusCurrent),
Voltage = records.Average(r =>r.BatteryDeligreenDataRecord.BusVoltage), Voltage = records.Average(r =>r.BatteryDeligreenDataRecord.BusVoltage),
Power = records.Sum(r => r.BatteryDeligreenDataRecord.Power), 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 powerTempAlarm = ParseAndPrintField(response, "Power Temperature Alarm" );
var currentAlarm = ParseAndPrintField(response, "Charge/Discharge Current Alarm" ); var currentAlarm = ParseAndPrintField(response, "Charge/Discharge Current Alarm" );
var totalVoltageAlarm = ParseAndPrintField(response, "Total Battery Voltage Alarm" ); var totalVoltageAlarm = ParseAndPrintField(response, "Total Battery Voltage Alarm" );
var alarmEvent1 = ParseByteAlarm(response, "Alarm Event 1");
var batteryAlarmRecord = new BatteryDeligreenAlarmRecord(cellAlarmList, cellTemperatureAlarm, enviTempAlarm, powerTempAlarm,currentAlarm, totalVoltageAlarm);
var batteryAlarmRecord = new BatteryDeligreenAlarmRecord(cellAlarmList, cellTemperatureAlarm, enviTempAlarm, powerTempAlarm,currentAlarm, totalVoltageAlarm, alarmEvent1);
return batteryAlarmRecord; return batteryAlarmRecord;
} }
@ -151,6 +152,23 @@ public class TelecommandFrameParser
_currentIndex += length; _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) private static String ParseAndPrintField(String response, String fieldName)
{ {
var fieldBytes = response.Substring(_currentIndex, 4); var fieldBytes = response.Substring(_currentIndex, 4);