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