a minimum of 5 A are applied on DcDc to avoid ossiclation problem
This commit is contained in:
parent
e1a5aa3b2f
commit
2513187d89
|
|
@ -1,17 +1,11 @@
|
|||
#define Amax
|
||||
#undef Amax
|
||||
#undef GridLimit
|
||||
|
||||
using System.Diagnostics;
|
||||
using System.IO.Compression;
|
||||
using System.Reactive.Linq;
|
||||
using System.Reactive.Threading.Tasks;
|
||||
using System.Reflection.Metadata;
|
||||
using System.Security;
|
||||
using System.Text;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
using Flurl.Http;
|
||||
using InnovEnergy.App.SodiStoreMax;
|
||||
using InnovEnergy.App.SodiStoreMax.Devices;
|
||||
using InnovEnergy.App.SodiStoreMax.Ess;
|
||||
using InnovEnergy.App.SodiStoreMax.MiddlewareClasses;
|
||||
|
|
@ -32,13 +26,11 @@ using InnovEnergy.Lib.Protocols.Modbus.Channels;
|
|||
using InnovEnergy.Lib.Units;
|
||||
using InnovEnergy.Lib.Utils;
|
||||
using InnovEnergy.App.SodiStoreMax.DataTypes;
|
||||
using InnovEnergy.Lib.Devices.Doepke;
|
||||
using Newtonsoft.Json;
|
||||
using static InnovEnergy.App.SodiStoreMax.AggregationService.Aggregator;
|
||||
using static InnovEnergy.App.SodiStoreMax.MiddlewareClasses.MiddlewareAgent;
|
||||
using static InnovEnergy.Lib.Devices.Trumpf.SystemControl.DataTypes.SystemConfig;
|
||||
|
||||
using Controller = InnovEnergy.App.SodiStoreMax.System.Controller;
|
||||
using DeviceState = InnovEnergy.App.SodiStoreMax.Devices.DeviceState;
|
||||
// ReSharper disable PossibleLossOfFraction
|
||||
|
||||
|
|
@ -481,8 +473,8 @@ internal static class Program
|
|||
maxBatteryDischargingCurrentLivebyDcDc = devicesConfig.DcDc.MaxBatteryDischargingCurrent/r.Battery.Devices.Count;
|
||||
}
|
||||
|
||||
maxBatteryChargingCurrentLiveByDcDc = 5 + (maxBatteryChargingCurrentLiveByDcDc * r.Battery.AvailableChBatteries); // Adapt the current to the number of available battery
|
||||
maxBatteryDischargingCurrentLivebyDcDc = 5 + (maxBatteryDischargingCurrentLivebyDcDc * r.Battery.AvailableDischBatteries); // Adapt the current to the number of available battery
|
||||
maxBatteryChargingCurrentLiveByDcDc = (maxBatteryChargingCurrentLiveByDcDc * r.Battery.AvailableChBatteries); // Adapt the current to the amount of available battery
|
||||
maxBatteryDischargingCurrentLivebyDcDc = (maxBatteryDischargingCurrentLivebyDcDc * r.Battery.AvailableDischBatteries); // Adapt the current to the amount of available battery
|
||||
|
||||
(r.Battery?.AvailableChBatteries)?.WriteLine(" Available Charging Batteries");
|
||||
(r.Battery?.AvailableDischBatteries)?.WriteLine(" Available Discharging Batteries");
|
||||
|
|
@ -499,6 +491,17 @@ internal static class Program
|
|||
maxBatteryChargingCurrentLiveByDcDc = 0;
|
||||
maxBatteryDischargingCurrentLivebyDcDc = 0;
|
||||
}
|
||||
|
||||
// This random value 5 is applied when the current is limited to 0. This will create an oscillation between discharging and charging
|
||||
if (maxBatteryChargingCurrentLiveByDcDc == 0)
|
||||
{
|
||||
maxBatteryChargingCurrentLiveByDcDc = 5 / dcCount;
|
||||
}
|
||||
else if (maxBatteryDischargingCurrentLivebyDcDc == 0)
|
||||
{
|
||||
maxBatteryDischargingCurrentLivebyDcDc = 5 / dcCount;
|
||||
}
|
||||
|
||||
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.ReferenceVoltage = devicesConfig.AcDc.ReferenceDcLinkVoltage);
|
||||
|
|
@ -775,16 +778,6 @@ internal static class Program
|
|||
}
|
||||
else
|
||||
{
|
||||
// var values = value.Split(','); //in case it is a list
|
||||
// Console.WriteLine("len is ",values.Length);
|
||||
// if (values.Length > 4)
|
||||
// {
|
||||
// foreach (var val in values)
|
||||
// {
|
||||
// Console.WriteLine("value from list is ", val);
|
||||
// }
|
||||
// }
|
||||
|
||||
currentDict[key] = value; // Store as string if not a number
|
||||
}
|
||||
}
|
||||
|
|
@ -793,13 +786,12 @@ internal static class Program
|
|||
currentDict = (Dictionary<String, Object>)currentDict[key];
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static async Task<Boolean> UploadCsv(StatusRecord status, DateTime timeStamp)
|
||||
{
|
||||
var csv = status.ToCsv();
|
||||
Dictionary<string, object> jsonData = new Dictionary<string, object>();
|
||||
var jsonData = new Dictionary<String, Object>();
|
||||
|
||||
foreach (var line in csv.Split('\n'))
|
||||
{
|
||||
|
|
@ -828,7 +820,7 @@ internal static class Program
|
|||
return await ConcatinatingAndCompressingFiles(timeStamp, s3Config);
|
||||
}
|
||||
|
||||
private static async Task<Boolean> ConcatinatingAndCompressingFiles(DateTime timeStamp, S3Config s3Config)
|
||||
/* private static async Task<Boolean> ConcatinatingAndCompressingFiles(DateTime timeStamp, S3Config s3Config)
|
||||
{
|
||||
if (_fileCounter >= NbrOfFileToConcatenate)
|
||||
{
|
||||
|
|
@ -837,9 +829,7 @@ internal static class Program
|
|||
var logFileConcatenator = new LogFileConcatenator();
|
||||
|
||||
var s3Path = timeStamp.ToUnixTime() + ".json";
|
||||
s3Path.WriteLine("");
|
||||
var jsonToSend = logFileConcatenator.ConcatenateFiles(NbrOfFileToConcatenate);
|
||||
|
||||
var jsonToSend = logFileConcatenator.ConcatenateFiles(NbrOfFileToConcatenate);
|
||||
var request = s3Config.CreatePutRequest(s3Path);
|
||||
|
||||
//Use this for no compression
|
||||
|
|
@ -870,6 +860,126 @@ internal static class Program
|
|||
_fileCounter++;
|
||||
|
||||
return true;
|
||||
}*/
|
||||
|
||||
private static async Task<Boolean> ConcatinatingAndCompressingFiles(DateTime timeStamp, S3Config s3Config)
|
||||
{
|
||||
if (_fileCounter >= NbrOfFileToConcatenate)
|
||||
{
|
||||
_fileCounter = 0;
|
||||
|
||||
var logFileConcatenator = new LogFileConcatenator();
|
||||
var jsontoSend = logFileConcatenator.ConcatenateFiles(NbrOfFileToConcatenate);
|
||||
|
||||
var fileNameWithoutExtension = timeStamp.ToUnixTime().ToString(); // used for both S3 and local
|
||||
var s3Path = fileNameWithoutExtension + ".json";
|
||||
|
||||
var request = s3Config.CreatePutRequest(s3Path);
|
||||
|
||||
var compressedBytes = CompresseBytes(jsontoSend);
|
||||
var base64String = Convert.ToBase64String(compressedBytes);
|
||||
var stringContent = new StringContent(base64String, Encoding.UTF8, "application/base64");
|
||||
|
||||
var uploadSucceeded = false;
|
||||
|
||||
try
|
||||
{
|
||||
var response = await request.PutAsync(stringContent);
|
||||
|
||||
if (response.StatusCode != 200)
|
||||
{
|
||||
Console.WriteLine("ERROR: PUT");
|
||||
var error = await response.GetStringAsync();
|
||||
Console.WriteLine(error);
|
||||
|
||||
await SaveToLocalCompressedFallback(compressedBytes, fileNameWithoutExtension);
|
||||
Heartbit();
|
||||
return false;
|
||||
}
|
||||
|
||||
uploadSucceeded = true;
|
||||
Console.WriteLine("✅ File uploaded to S3 successfully.");
|
||||
|
||||
Console.WriteLine("----------------------------------------Sending Heartbit----------------------------------------");
|
||||
Heartbit();
|
||||
|
||||
await ResendLocalFailedFilesAsync(s3Config); // retry any pending failed files
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine("Upload exception: " + ex.Message);
|
||||
|
||||
if (!uploadSucceeded)
|
||||
{
|
||||
await SaveToLocalCompressedFallback(compressedBytes, fileNameWithoutExtension);
|
||||
}
|
||||
|
||||
Heartbit();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
_fileCounter++;
|
||||
return true;
|
||||
}
|
||||
|
||||
private static async Task SaveToLocalCompressedFallback(Byte[] compressedData, String fileNameWithoutExtension)
|
||||
{
|
||||
try
|
||||
{
|
||||
var fallbackDir = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "FailedUploads");
|
||||
Directory.CreateDirectory(fallbackDir);
|
||||
|
||||
var fileName = fileNameWithoutExtension + ".json"; // Save as .json, but still compressed
|
||||
var fullPath = Path.Combine(fallbackDir, fileName);
|
||||
|
||||
await File.WriteAllBytesAsync(fullPath, compressedData); // Compressed data
|
||||
Console.WriteLine($"Saved compressed failed upload to: {fullPath}");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine("Failed to save compressed file locally: " + ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
private static async Task ResendLocalFailedFilesAsync(S3Config s3Config)
|
||||
{
|
||||
var fallbackDir = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "FailedUploads");
|
||||
|
||||
if (!Directory.Exists(fallbackDir))
|
||||
return;
|
||||
|
||||
var files = Directory.GetFiles(fallbackDir, "*.json");
|
||||
|
||||
foreach (var filePath in files)
|
||||
{
|
||||
var fileName = Path.GetFileName(filePath); // e.g., "1720023600.json"
|
||||
var s3Key = fileName; // same name for S3
|
||||
|
||||
try
|
||||
{
|
||||
byte[] compressedBytes = await File.ReadAllBytesAsync(filePath);
|
||||
var base64String = Convert.ToBase64String(compressedBytes);
|
||||
var stringContent = new StringContent(base64String, Encoding.UTF8, "application/base64");
|
||||
|
||||
var request = s3Config.CreatePutRequest(s3Key);
|
||||
var response = await request.PutAsync(stringContent);
|
||||
|
||||
if (response.StatusCode == 200)
|
||||
{
|
||||
File.Delete(filePath);
|
||||
Console.WriteLine($"✅ Successfully resent and deleted: {fileName}");
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine($"❌ Failed to resend {fileName}, status: {response.StatusCode}");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"⚠️ Exception while resending {fileName}: {ex.Message}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void Heartbit()
|
||||
|
|
|
|||
Loading…
Reference in New Issue