Innovenergy_trunk/csharp/App/SinexcelCommunication/SystemConfig/Config.cs

165 lines
7.4 KiB
C#

using System.Diagnostics.CodeAnalysis;
using System.Text.Json;
using InnovEnergy.App.SinexcelCommunication.DataTypes;
using InnovEnergy.Lib.Devices.Sinexcel_12K_TL.DataType;
using InnovEnergy.Lib.Utils;
using static System.Text.Json.JsonSerializer;
namespace InnovEnergy.App.SinexcelCommunication.SystemConfig;
[SuppressMessage("Trimming", "IL2026:Members annotated with \'RequiresUnreferencedCodeAttribute\' require dynamic access otherwise can break functionality when trimming application code")]
public class Config
{
private static String DefaultConfigFilePath => Path.Combine(Environment.CurrentDirectory, "config.json");
private static DateTime DefaultDatetime => new(2025, 01, 01, 09, 00, 00);
private static readonly JsonSerializerOptions JsonOptions = new() { WriteIndented = true };
public required DeviceConfig Devices { get; set; }
//public required Boolean DynamicPricingEnabled { get; set; }
//public required DynamicPricingMode DynamicPricingMode { get; set; }
//public required Decimal CheapPrice { get; set; }
//public required Decimal HighPrice { get; set; }
public required Double MinSoc { get; set; }
public required Double GridSetPoint { get; set; }
public required Double MaximumDischargingCurrent { get; set; }
public required Double MaximumChargingCurrent { get; set; }
public required OperatingPriority OperatingPriority { get; set; }
public required Int16 BatteriesCount { get; set; }
public required Int16 ClusterNumber { get; set; }
public required Int16 PvNumber { get; set; }
public required Double ModbusProtcolNumber { get; set; }
public required DateTime StartTimeChargeandDischargeDayandTime { get; set; }
public required DateTime StopTimeChargeandDischargeDayandTime { get; set; }
public required Single TimeChargeandDischargePower { get; set; }
public required Boolean ControlPermission { get; set; }
public required S3Config? S3 { get; set; }
private static String? LastSavedData { get; set; }
private static DateTime? LoadedWriteTimeUtc { get; set; }
public static Config Default => new()
{
Devices = new ()
{
Serial = new() {BaudRate = 115200, Parity = 0, StopBits = 1, DataBits = 8},
Inverter1 = new() {DeviceState = DeviceState.Measured, Port = "/dev/ttyUSB0", SlaveId = 1},
Inverter2 = new() {DeviceState = DeviceState.Measured, Port = "/dev/ttyUSB1", SlaveId = 1},
Inverter3 = new() {DeviceState = DeviceState.Measured, Port = "/dev/ttyUSB3", SlaveId = 1},
Inverter4 = new() {DeviceState = DeviceState.Measured, Port = "/dev/ttyUSB4", SlaveId = 1},
},
//DynamicPricingEnabled = false,
//DynamicPricingMode = DynamicPricingMode.Disabled,
MinSoc = 20,
GridSetPoint = 0,
MaximumChargingCurrent = 180,
MaximumDischargingCurrent = 180,
OperatingPriority = OperatingPriority.LoadPriority,
BatteriesCount = 0,
ClusterNumber = 0,
PvNumber = 0,
ModbusProtcolNumber = 1.2,
StartTimeChargeandDischargeDayandTime = DefaultDatetime,
StopTimeChargeandDischargeDayandTime = DefaultDatetime,
TimeChargeandDischargePower = 3,
ControlPermission = false,
S3 = new()
{
Bucket = "1-3e5b3069-214a-43ee-8d85-57d72000c19d",
Region = "sos-ch-dk-2",
Provider = "exo.io",
Key = "EXObb5a49acb1061781761895e7",
Secret = "sKhln0w8ii3ezZ1SJFF33yeDo8NWR1V4w2H0D4-350I",
ContentType = "text/plain; charset=utf-8"
}
};
public void Save(String? path = null)
{
var configFilePath = path ?? DefaultConfigFilePath;
var currentWriteTime = File.GetLastWriteTimeUtc(configFilePath);
if (currentWriteTime != LoadedWriteTimeUtc)
throw new IOException("Config file changed on disk since it was loaded; refusing to overwrite."); // to prevent an overwriting while an external changes happended in the meantime
try
{
var jsonString = Serialize(this, JsonOptions);
if (LastSavedData == jsonString)
return;
LastSavedData = jsonString;
File.WriteAllText(configFilePath, jsonString);
}
catch (Exception e)
{
$"Failed to write config file {configFilePath}\n{e}".WriteLine();
throw;
}
}
/*
public static Config Load(String? path = null)
{
var configFilePath = path ?? DefaultConfigFilePath;
try
{
var jsonString = File.ReadAllText(configFilePath);
// LoadedWriteTimeUtc = File.GetLastWriteTimeUtc(configFilePath);
return Deserialize<Config>(jsonString)!;
}
catch (Exception e)
{
$"Failed to read config file {configFilePath}, using default config\n{e}".WriteLine();
return Default;
}
}*/
public static Config Load(string? path = null)
{
var configFilePath = path ?? DefaultConfigFilePath; // ✅ handle null first
try
{
// Now safe to call any File/Path API
var json = File.ReadAllText(configFilePath);
var cfg = Deserialize<Config>(json, JsonOptions)
?? throw new InvalidOperationException("Config deserialized to null.");
// Optional: store last write time / last saved json
LoadedWriteTimeUtc = File.GetLastWriteTimeUtc(configFilePath);
LastSavedData = Serialize(cfg, JsonOptions); // if you use the save-skip logic
return cfg;
}
catch (Exception e)
{
$"Failed to read config file {configFilePath}\n{e}".WriteLine();
throw;
}
}
public static async Task<Config> LoadAsync(String? path = null)
{
var configFilePath = path ?? DefaultConfigFilePath;
try
{
var jsonString = await File.ReadAllTextAsync(configFilePath);
return Deserialize<Config>(jsonString)!;
}
catch (Exception e)
{
Console.WriteLine($"Couldn't read config file {configFilePath}, using default config");
e.Message.WriteLine();
return Default;
}
}
}