Fixed bug in SodiStoreMax battery view.

This commit is contained in:
Noe 2025-04-19 13:31:24 +02:00
parent 96359fab08
commit bcde77c567
3 changed files with 140 additions and 156 deletions

View File

@ -75,14 +75,14 @@ public class AggregatedData
var s3Path = DateTime.Now.AddDays(-1).ToString("yyyy-MM-dd") + ".json"; var s3Path = DateTime.Now.AddDays(-1).ToString("yyyy-MM-dd") + ".json";
var request = _S3Config.CreatePutRequest(s3Path); var request = _S3Config.CreatePutRequest(s3Path);
// Compress CSV data to a byte array // Compress JSON data to a byte array
byte[] compressedBytes; byte[] compressedBytes;
using (var memoryStream = new MemoryStream()) using (var memoryStream = new MemoryStream())
{ {
//Create a zip directory and put the compressed file inside //Create a zip directory and put the compressed file inside
using (var archive = new ZipArchive(memoryStream, ZipArchiveMode.Create, true)) using (var archive = new ZipArchive(memoryStream, ZipArchiveMode.Create, true))
{ {
var entry = archive.CreateEntry("data.json", CompressionLevel.SmallestSize); // Add CSV data to the ZIP archive var entry = archive.CreateEntry("data.json", CompressionLevel.SmallestSize); // Add JSON data to the ZIP archive
using (var entryStream = entry.Open()) using (var entryStream = entry.Open())
using (var writer = new StreamWriter(entryStream)) using (var writer = new StreamWriter(entryStream))
{ {
@ -114,18 +114,4 @@ public class AggregatedData
return true; return true;
} }
// public static HourlyData? Load(String dataFilePath)
// {
// try
// {
// var csvString = File.ReadAllText(dataFilePath);
// return Deserialize<HourlyData>(jsonString)!;
// }
// catch (Exception e)
// {
// $"Failed to read config file {dataFilePath}, using default config\n{e}".WriteLine();
// return null;
// }
// }
} }

View File

@ -8,6 +8,9 @@ using System.Reactive.Threading.Tasks;
using System.Reflection.Metadata; using System.Reflection.Metadata;
using System.Security; using System.Security;
using System.Text; using System.Text;
using System.Text.Json;
using System.Text.Json.Serialization;
using Flurl.Http; using Flurl.Http;
using InnovEnergy.App.SodiStoreMax; using InnovEnergy.App.SodiStoreMax;
using InnovEnergy.App.SodiStoreMax.Devices; using InnovEnergy.App.SodiStoreMax.Devices;
@ -29,7 +32,6 @@ using InnovEnergy.Lib.Protocols.Modbus.Channels;
using InnovEnergy.Lib.Units; using InnovEnergy.Lib.Units;
using InnovEnergy.Lib.Utils; using InnovEnergy.Lib.Utils;
using InnovEnergy.App.SodiStoreMax.DataTypes; using InnovEnergy.App.SodiStoreMax.DataTypes;
using InnovEnergy.Lib.Utils.Net;
using Newtonsoft.Json; using Newtonsoft.Json;
using static System.Int32; using static System.Int32;
using static InnovEnergy.App.SodiStoreMax.AggregationService.Aggregator; using static InnovEnergy.App.SodiStoreMax.AggregationService.Aggregator;
@ -317,118 +319,118 @@ internal static class Program
private static StatusMessage GetSalimaxStateAlarm(StatusRecord record) private static StatusMessage GetSalimaxStateAlarm(StatusRecord record)
{ {
var alarmCondition = record.DetectAlarmStates(); // this need to be emailed to support or customer var alarmCondition = record.DetectAlarmStates(); // this need to be emailed to support or customer
var s3Bucket = Config.Load().S3?.Bucket; var s3Bucket = Config.Load().S3?.Bucket;
var alarmList = new List<AlarmOrWarning>(); var alarmList = new List<AlarmOrWarning>();
var warningList = new List<AlarmOrWarning>(); var warningList = new List<AlarmOrWarning>();
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)
{ {
var i = 0; _oneTimeFlag.WriteLine(" onetime flag");
if (record.Battery?.Voltage != null && (record.Battery?.HighestCellVoltage ?? 0) > 3.80 && !_oneTimeFlag) //this shoudld be checked the number 0
foreach (var battery in record.Battery.Devices)
{ {
var devicesBatteryNode = record.Config.Devices.BatteryNodes[i]; _oneTimeFlag = true;
warningList.Add(new AlarmOrWarning
if (battery.LimpBitMap == 0)
{ {
// "All String are Active".WriteLine(); Date = DateTime.Now.ToString("yyyy-MM-dd"),
} Time = DateTime.Now.ToString("HH:mm:ss"),
else if (IsPowerOfTwo(battery.LimpBitMap)) CreatedBy = "Charging Battery System",
{ Description = "dynCCL Active: Max Battery Charging is 10 * N"
"1 String is disabled".WriteLine(); });
Console.WriteLine(" ****************** ");
warningList.Add(new AlarmOrWarning
{
Date = DateTime.Now.ToString("yyyy-MM-dd"),
Time = DateTime.Now.ToString("HH:mm:ss"),
CreatedBy = "Battery node" + devicesBatteryNode,
Description = "1 String is disabled"
});
bWarningList.Add("/"+i+1 + "/1 String is disabled"); // battery id instead ( i +1 ) of node id: requested from the frontend
}
else
{
"2 or more string are disabled".WriteLine();
Console.WriteLine(" ****************** ");
alarmList.Add(new AlarmOrWarning
{
Date = DateTime.Now.ToString("yyyy-MM-dd"),
Time = DateTime.Now.ToString("HH:mm:ss"),
CreatedBy = "Battery node" + devicesBatteryNode,
Description = "2 or more string are disabled"
});
bAlarmList.Add(i +";2 or more string are disabled");
}
foreach (var warning in record.Battery.Warnings)
{
warningList.Add(new AlarmOrWarning
{
Date = DateTime.Now.ToString("yyyy-MM-dd"),
Time = DateTime.Now.ToString("HH:mm:ss"),
CreatedBy = "Battery node" + devicesBatteryNode,
Description = warning
});
bWarningList.Add(i +";" + warning);
}
foreach (var alarm in battery.Alarms)
{
alarmList.Add(new AlarmOrWarning
{
Date = DateTime.Now.ToString("yyyy-MM-dd"),
Time = DateTime.Now.ToString("HH:mm:ss"),
CreatedBy = "Battery node" + devicesBatteryNode,
Description = alarm
});
bWarningList.Add(i +";" + alarm);
}
i++;
} }
}*/ 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)
{
var i = 0;
foreach (var battery in record.Battery.Devices)
{
var devicesBatteryNode = record.Config.Devices.BatteryNodes[i];
if (battery.LimpBitMap == 0)
{
// "All String are Active".WriteLine();
}
else if (IsPowerOfTwo(battery.LimpBitMap))
{
"1 String is disabled".WriteLine();
Console.WriteLine(" ****************** ");
warningList.Add(new AlarmOrWarning
{
Date = DateTime.Now.ToString("yyyy-MM-dd"),
Time = DateTime.Now.ToString("HH:mm:ss"),
CreatedBy = "Battery node" + devicesBatteryNode,
Description = "1 String is disabled"
});
bWarningList.Add("/"+i+1 + "/1 String is disabled"); // battery id instead ( i +1 ) of node id: requested from the frontend
}
else
{
"2 or more string are disabled".WriteLine();
Console.WriteLine(" ****************** ");
alarmList.Add(new AlarmOrWarning
{
Date = DateTime.Now.ToString("yyyy-MM-dd"),
Time = DateTime.Now.ToString("HH:mm:ss"),
CreatedBy = "Battery node" + devicesBatteryNode,
Description = "2 or more string are disabled"
});
bAlarmList.Add(i +";2 or more string are disabled");
}
foreach (var warning in record.Battery.Warnings)
{
warningList.Add(new AlarmOrWarning
{
Date = DateTime.Now.ToString("yyyy-MM-dd"),
Time = DateTime.Now.ToString("HH:mm:ss"),
CreatedBy = "Battery node" + devicesBatteryNode,
Description = warning
});
bWarningList.Add(i +";" + warning);
}
foreach (var alarm in battery.Alarms)
{
alarmList.Add(new AlarmOrWarning
{
Date = DateTime.Now.ToString("yyyy-MM-dd"),
Time = DateTime.Now.ToString("HH:mm:ss"),
CreatedBy = "Battery node" + devicesBatteryNode,
Description = alarm
});
bWarningList.Add(i +";" + alarm);
}
i++;
}
}*/
if (alarmCondition is not null) if (alarmCondition is not null)
{ {
alarmCondition.WriteLine(); alarmCondition.WriteLine();
@ -441,7 +443,7 @@ internal static class Program
Description = alarmCondition Description = alarmCondition
}); });
} }
foreach (var alarm in record.AcDc.Alarms) foreach (var alarm in record.AcDc.Alarms)
{ {
alarmList.Add(new AlarmOrWarning alarmList.Add(new AlarmOrWarning
@ -452,7 +454,7 @@ internal static class Program
Description = alarm.ToString() Description = alarm.ToString()
}); });
} }
foreach (var alarm in record.DcDc.Alarms) foreach (var alarm in record.DcDc.Alarms)
{ {
alarmList.Add(new AlarmOrWarning alarmList.Add(new AlarmOrWarning
@ -463,7 +465,7 @@ internal static class Program
Description = alarm.ToString() Description = alarm.ToString()
}); });
} }
foreach (var warning in record.AcDc.Warnings) foreach (var warning in record.AcDc.Warnings)
{ {
warningList.Add(new AlarmOrWarning warningList.Add(new AlarmOrWarning
@ -474,7 +476,7 @@ internal static class Program
Description = warning.ToString() Description = warning.ToString()
}); });
} }
foreach (var warning in record.DcDc.Warnings) foreach (var warning in record.DcDc.Warnings)
{ {
warningList.Add(new AlarmOrWarning warningList.Add(new AlarmOrWarning
@ -486,7 +488,10 @@ internal static class Program
}); });
} }
_salimaxAlarmState = warningList.Any() //Console.WriteLine("WARNING LIST IS" + warningList[0].Description);
_salimaxAlarmState = warningList.Any()
? SalimaxAlarmState.Orange ? SalimaxAlarmState.Orange
: SalimaxAlarmState.Green; // this will be replaced by LedState : SalimaxAlarmState.Green; // this will be replaced by LedState
@ -875,28 +880,22 @@ internal static class Program
private static async Task<Boolean> UploadCsv(StatusRecord status, DateTime timeStamp) private static async Task<Boolean> UploadCsv(StatusRecord status, DateTime timeStamp)
{ {
var csv = status.ToCsv(); var csv = status.ToCsv();
Dictionary<string, object> jsonData = new Dictionary<string, object>(); Dictionary<string, object> jsonData = new Dictionary<string, object>();
//Console.WriteLine(csv); //Console.WriteLine(csv);
foreach (var line in csv.Split('\n')) foreach (var line in csv.Split('\n'))
{ {
if (string.IsNullOrWhiteSpace(line)) continue; if (string.IsNullOrWhiteSpace(line)) continue;
string[] parts = line.Split(';'); string[] parts = line.Split(';');
//if (parts.Length < 2) continue; string keyPath = parts[0];
string value = parts[1];
string keyPath = parts[0]; string unit = parts.Length > 2 ? parts[2].Trim() : "";
string value = parts[1]; //Console.WriteLine(line);
string unit = parts.Length > 2 ? parts[2].Trim() : ""; // Console.WriteLine($"Key: {keyPath}, Value: {value}, Unit: {unit}");
//Console.WriteLine(line); InsertIntoJson(jsonData, keyPath.Split('/'), value);
// Console.WriteLine($"Key: {keyPath}, Value: {value}, Unit: {unit}"); }
InsertIntoJson(jsonData, keyPath.Split('/'), value);
}
string jsonOutput = JsonConvert.SerializeObject(jsonData, Formatting.None); string jsonOutput = JsonConvert.SerializeObject(jsonData, Formatting.None);
jsonOutput.LogInfo(); jsonOutput.LogInfo();
@ -922,13 +921,12 @@ internal static class Program
var s3Path = timeStamp.ToUnixTime() + ".json"; var s3Path = timeStamp.ToUnixTime() + ".json";
s3Path.WriteLine(""); s3Path.WriteLine("");
var csvToSend = logFileConcatenator.ConcatenateFiles(NbrOfFileToConcatenate); var jsonToSend = logFileConcatenator.ConcatenateFiles(NbrOfFileToConcatenate);
var request = s3Config.CreatePutRequest(s3Path); var request = s3Config.CreatePutRequest(s3Path);
//Use this for no compression //Use this for no compression
//var response = await request.PutAsync(new StringContent(csv)); var compressedBytes = CompresseBytes(jsonToSend);
var compressedBytes = CompresseBytes(csvToSend);
// Encode the compressed byte array as a Base64 string // Encode the compressed byte array as a Base64 string
string base64String = Convert.ToBase64String(compressedBytes); string base64String = Convert.ToBase64String(compressedBytes);
@ -961,7 +959,7 @@ internal static class Program
{ {
var s3Bucket = Config.Load().S3?.Bucket; var s3Bucket = Config.Load().S3?.Bucket;
var tryParse = TryParse(s3Bucket?.Split("-")[0], out var installationId); var tryParse = TryParse(s3Bucket?.Split("-")[0], out var installationId);
var parse = TryParse(timeStamp.ToUnixTime().ToString(), out var nameOfCsvFile); var parse = TryParse(timeStamp.ToUnixTime().ToString(), out var nameOfJsonFile);
if (tryParse) if (tryParse)
{ {
@ -971,27 +969,27 @@ internal static class Program
Product = 0, // Salimax is always 0 Product = 0, // Salimax is always 0
Status = _salimaxAlarmState, Status = _salimaxAlarmState,
Type = MessageType.Heartbit, Type = MessageType.Heartbit,
Timestamp = nameOfCsvFile Timestamp = nameOfJsonFile
}; };
if (s3Bucket != null) if (s3Bucket != null)
RabbitMqManager.InformMiddleware(returnedStatus); RabbitMqManager.InformMiddleware(returnedStatus);
} }
} }
private static Byte[] CompresseBytes(String csvToSend) private static Byte[] CompresseBytes(String jsonToSend)
{ {
//Compress CSV data to a byte array //Compress JSON data to a byte array
Byte[] compressedBytes; Byte[] compressedBytes;
using (var memoryStream = new MemoryStream()) using (var memoryStream = new MemoryStream())
{ {
//Create a zip directory and put the compressed file inside //Create a zip directory and put the compressed file inside
using (var archive = new ZipArchive(memoryStream, ZipArchiveMode.Create, true)) using (var archive = new ZipArchive(memoryStream, ZipArchiveMode.Create, true))
{ {
var entry = archive.CreateEntry("data.json", CompressionLevel.SmallestSize); // Add CSV data to the ZIP archive var entry = archive.CreateEntry("data.json", CompressionLevel.SmallestSize); // Add JSON data to the ZIP archive
using (var entryStream = entry.Open()) using (var entryStream = entry.Open())
using (var writer = new StreamWriter(entryStream)) using (var writer = new StreamWriter(entryStream))
{ {
writer.Write(csvToSend); writer.Write(jsonToSend);
} }
} }

View File

@ -2,8 +2,8 @@ namespace InnovEnergy.Lib.Devices.BatteryDeligreen;
public class BatteryDeligreenRecord public class BatteryDeligreenRecord
{ {
public readonly BatteryDeligreenDataRecord BatteryDeligreenDataRecord; public BatteryDeligreenDataRecord BatteryDeligreenDataRecord { get; }
public readonly BatteryDeligreenAlarmRecord BatteryDeligreenAlarmRecord; public BatteryDeligreenAlarmRecord BatteryDeligreenAlarmRecord { get; }
public BatteryDeligreenRecord(BatteryDeligreenDataRecord batteryDeligreenDataRecord, BatteryDeligreenAlarmRecord batteryDeligreenAlarmRecord) public BatteryDeligreenRecord(BatteryDeligreenDataRecord batteryDeligreenDataRecord, BatteryDeligreenAlarmRecord batteryDeligreenAlarmRecord)
{ {