From 90a4257bbf63ead90a6455ce356ee6e44c2f7f3d Mon Sep 17 00:00:00 2001 From: atef <sarraj@innov.energy> Date: Fri, 14 Mar 2025 13:26:52 +0100 Subject: [PATCH] update telemetry and telecommad frame reading --- .../TelecommandFrameParser.cs | 114 ++++++++++++------ .../BatteryDeligreen/TelemetryFrameParser.cs | 18 +-- 2 files changed, 87 insertions(+), 45 deletions(-) diff --git a/csharp/Lib/Devices/BatteryDeligreen/TelecommandFrameParser.cs b/csharp/Lib/Devices/BatteryDeligreen/TelecommandFrameParser.cs index 56f32c610..214486f41 100644 --- a/csharp/Lib/Devices/BatteryDeligreen/TelecommandFrameParser.cs +++ b/csharp/Lib/Devices/BatteryDeligreen/TelecommandFrameParser.cs @@ -10,7 +10,15 @@ public class TelecommandFrameParser private static Int32 _currentIndex; private const Int32 FrameLength = 232; - public Boolean ParsingTelecommandFrame(String response) + private static readonly Dictionary<String, String> ByteAlarmCodes = new() + { + { "00", "Normal, no alarm" }, + { "01", "Alarm that analog quantity reaches the lower limit" }, + { "02", "Alarm that analog quantity reaches the upper limit" }, + { "F0", "Other alarms" } + }; + + public BatteryDeligreenAlarmRecord? ParsingTelecommandFrame(String response) { _currentIndex = 0; // Reset currentIndex to the start @@ -19,7 +27,7 @@ public class TelecommandFrameParser Console.WriteLine("Response is too short to contain valid data."); Console.WriteLine(" Fixed Length" + FrameLength); Console.WriteLine(" response Length" + response.Length); - return false; + return null; } // Check starting byte @@ -31,7 +39,7 @@ public class TelecommandFrameParser else { Console.WriteLine($"Incorrect starting byte: {startingByte}"); - return false; + return null; } _currentIndex += 2; @@ -46,36 +54,66 @@ public class TelecommandFrameParser catch (Exception) { Console.WriteLine($"Failed to decode firmware version from bytes: {versionBytes}"); - return false; + return null; } _currentIndex += 4; // Extract and parse other fields - ParseAndPrintHexField(response, "Device Address", 4); - ParseAndPrintHexField(response, "Device Code (CID1)", 4); - ParseAndPrintHexField(response, "Function Code", 4); - ParseAndPrintHexField(response, "Length Code", 8); - ParseAndPrintHexField(response, "Data Flag", 4); - ParseAndPrintHexField(response, "Command Group", 4); - ParseAndPrintHexField(response, "Number of Cells", 4); - ExtractCellAlarm(response); - return true; + ParseAndPrintHexField(response, "Device Address", 4); // this is not added to the Alarm record + ParseAndPrintHexField(response, "Device Code (CID1)", 4); // this is not added to the Alarm record + ParseAndPrintHexField(response, "Function Code", 4); // this is not added to the Alarm record + ParseAndPrintHexField(response, "Length Code", 8); // this is not added to the Alarm record + ParseAndPrintHexField(response, "Data Flag", 4); // this is not added to the Alarm record + ParseAndPrintHexField(response, "Command Group", 4); // this is not added to the Alarm record + ParseAndPrintHexField(response, "Number of Cells", 4); // this is not added to the Alarm record + + // Parse Cell Temperature Alarm fields + var cellAlarmList = ExtractCellAlarm(response); + + // Parse Number of Temperature Alarm + ParseAndPrintHexField(response, "Number of Temperature ", 4); // this is not added to the Alarm record + + // Parse Cell Temperature Alarm fields + var cellTemperatureAlarm = ExtractCellTempAlarm(response); + var enviTempAlarm = ParseAndPrintField(response, "Environment Temperature Alarm" ); + 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); + + return batteryAlarmRecord; } - - - private static void ExtractCellAlarm(String response) + private static List<String> ExtractCellTempAlarm(String response) { + var cellTempAlarmList = new List<String>(); - Dictionary<string, string> byteAlarmCodes = new Dictionary<string, string> + var tempCellAlarm = response.Substring(_currentIndex, 4); + for (var i = 0; i < 4; i++) { - { "00", "Normal, no alarm" }, - { "01", "Alarm that analog quantity reaches the lower limit" }, - { "02", "Alarm that analog quantity reaches the upper limit" }, - { "F0", "Other alarms" } - }; - + try + { + var tempAscii = HexToAscii(tempCellAlarm); + var alarmMessage = ByteAlarmCodes.ContainsKey(tempAscii) ? ByteAlarmCodes[tempAscii] : "Unknown alarm code"; + cellTempAlarmList.Add(alarmMessage); + } + catch (Exception) + { + Console.WriteLine($"Failed to decode Cell Temp Alarm {i + 1} from bytes: {tempCellAlarm}"); + } + _currentIndex += 4; + } + + return cellTempAlarmList; + } + + + private static List<String> ExtractCellAlarm(String response) + { + var cellAlarmList = new List<String>(); + // Process Alarms for all 16 cells for (var i = 0; i < 16; i++) { @@ -83,28 +121,28 @@ public class TelecommandFrameParser try { var alarmAscii = HexToAscii(cellAlarm); - var cellVoltageDecimal = HexToDecimal(alarmAscii); - string alarmMessage = byteAlarmCodes.ContainsKey(alarmAscii) ? byteAlarmCodes[alarmAscii] : "Unknown alarm code"; + var alarmMessage = ByteAlarmCodes.ContainsKey(alarmAscii) ? ByteAlarmCodes[alarmAscii] : "Unknown alarm code"; + cellAlarmList.Add(alarmMessage); // Console.WriteLine($"Cell {i + 1}: Alarm Code {cellAlarm}, Status: {alarmMessage}"); - } catch (Exception) { - Console.WriteLine($"Failed to decode Voltage of Cell {i + 1} from bytes: {cellAlarm}"); + Console.WriteLine($"Failed to decode Cell Alarm {i + 1} from bytes: {cellAlarm}"); } _currentIndex += 4; } + return cellAlarmList; } - private static void ParseAndPrintHexField(String response, String fieldName, int length) + private static void ParseAndPrintHexField(String response, String fieldName, Int32 length) { var hexBytes = response.Substring(_currentIndex, length); try { var asciiValue = HexToAscii(hexBytes); var decimalValue = int.Parse(asciiValue, NumberStyles.HexNumber); - // Console.WriteLine($"{fieldName}: {hexBytes} (Hex), ASCII: {asciiValue}, Decimal: {decimalValue}"); + //Console.WriteLine($"{fieldName}: {hexBytes} (Hex), ASCII: {asciiValue}, Decimal: {decimalValue}"); } catch (Exception) { @@ -112,20 +150,24 @@ public class TelecommandFrameParser } _currentIndex += length; } - private static void ParseAndPrintField(String response, String fieldName, Int32 length, Func<Double, Double> conversion, String unit) + + private static String ParseAndPrintField(String response, String fieldName) { - var fieldBytes = response.Substring(_currentIndex, length); + var fieldBytes = response.Substring(_currentIndex, 4); + var alarmMessage = "Failed to read alarm"; + try { - var fieldAscii = HexToAscii(fieldBytes); - var fieldDecimal = conversion(HexToDecimal(fieldAscii)); - Console.WriteLine($"{fieldName}: {fieldBytes} (Hex), ASCII: {fieldAscii}, {fieldName}: {fieldDecimal:F3} {unit}"); + var tempAscii = HexToAscii(fieldBytes); + alarmMessage = ByteAlarmCodes.ContainsKey(tempAscii) ? ByteAlarmCodes[tempAscii] : "Unknown alarm code"; } catch (Exception) { - Console.WriteLine($"Failed to decode {fieldName} from bytes: {fieldBytes}"); + Console.WriteLine($"Failed to decode : {fieldName}" + " Alarm"); } - _currentIndex += length; + _currentIndex += 4; + + return alarmMessage; } private static String HexToAscii(String hex) diff --git a/csharp/Lib/Devices/BatteryDeligreen/TelemetryFrameParser.cs b/csharp/Lib/Devices/BatteryDeligreen/TelemetryFrameParser.cs index bdd2e4218..bc3ebc220 100644 --- a/csharp/Lib/Devices/BatteryDeligreen/TelemetryFrameParser.cs +++ b/csharp/Lib/Devices/BatteryDeligreen/TelemetryFrameParser.cs @@ -52,18 +52,18 @@ public class TelemetryFrameParser _currentIndex += 4; // Extract and parse other fields - ParseAndPrintHexField(response, "Device Address", 4); - ParseAndPrintHexField(response, "Device Code (CID1)", 4); - ParseAndPrintHexField(response, "Function Code", 4); - ParseAndPrintHexField(response, "Length Code", 8); - ParseAndPrintHexField(response, "Data Flag", 4); - ParseAndPrintHexField(response, "Command Group", 4); - ParseAndPrintHexField(response, "Number of Cells", 4); - + ParseAndPrintHexField(response, "Device Address", 4); // this is not added to the Data record + ParseAndPrintHexField(response, "Device Code (CID1)", 4); // this is not added to the Data record + ParseAndPrintHexField(response, "Function Code", 4); // this is not added to the Data record + ParseAndPrintHexField(response, "Length Code", 8); // this is not added to the Data record + ParseAndPrintHexField(response, "Data Flag", 4); // this is not added to the Data record + ParseAndPrintHexField(response, "Command Group", 4); // this is not added to the Data record + ParseAndPrintHexField(response, "Number of Cells", 4); // this is not added to the Data record + var cellVoltages = ExtractCellVoltage(response); // Parse other fields - ParseAndPrintHexField(response, "Number of Temperature Sensors", 4); + ParseAndPrintHexField(response, "Number of Temperature Sensors", 4); // this is not added to the Data record var cellTemperature = new List<Double>(); // Parse cell temperatures