From ef7fff730219bc669dbbf1145979f02d8db482c7 Mon Sep 17 00:00:00 2001 From: djnitehawk Date: Wed, 12 Mar 2025 21:21:13 +0530 Subject: [PATCH] set settings --- src/Client/Pages/BMS.razor | 32 ++++---- src/Client/Pages/Settings.razor | 41 +++++----- src/Server/Endpoints/GetStatus/Endpoint.cs | 32 ++++---- .../Endpoints/PVLog/GetPVForDay/Endpoint.cs | 9 ++- .../Endpoints/PVLog/GetPVForDay/Request.cs | 6 -- .../Settings/GetSettingValues/Endpoint.cs | 69 +++++++++++------ .../Settings/SetSettingValue/Endpoint.cs | 27 +++++-- src/Server/InverterService/CurrentStatus.cs | 8 -- .../InverterService/FelicityInverter.cs | 75 ++++++++----------- src/Server/InverterService/StatusRetriever.cs | 23 +++++- src/Server/Program.cs | 1 + src/Shared/Models/ChargePriority.cs | 8 +- src/Shared/Models/CurrentSettings.cs | 59 +++++++++------ src/Shared/Models/OutputPriority.cs | 6 +- src/Shared/Models/SetSetting.cs | 4 +- 15 files changed, 226 insertions(+), 174 deletions(-) delete mode 100644 src/Server/Endpoints/PVLog/GetPVForDay/Request.cs delete mode 100644 src/Server/InverterService/CurrentStatus.cs diff --git a/src/Client/Pages/BMS.razor b/src/Client/Pages/BMS.razor index 8d29bc8..419baeb 100644 --- a/src/Client/Pages/BMS.razor +++ b/src/Client/Pages/BMS.razor @@ -7,7 +7,7 @@ JK BMS Status - + @if (status is not null) { @@ -50,7 +50,7 @@ @if (status.AvgCurrentAmps == 0) {
- Holding
Voltage + Holding
Voltage
} @if (status.IsWarning) @@ -134,13 +134,14 @@ protected override void OnInitialized() { onStatusUpdated += UpdateState; - onStatusRetrievalError += NullifyStatus; + onStatusRetrievalError += NullifyStatus; } protected override async Task OnInitializedAsync() { var st = await Js.LoadStateAsync(); - if(st is null) + + if (st is null) { await Js.SaveStateAsync(state); } @@ -168,6 +169,7 @@ { return status!.GetTimeString(); } + return $"{status!.TimeHrs} Hrs {status.TimeMins} Mins"; } @@ -175,10 +177,12 @@ { if (state.ShowCapacityKwh) { - var avlCap = Math.Round((status!.AvailableCapacity * status.PackNominalVoltage) / 1000, 1); - var packCap = Math.Round((status!.PackCapacity * status.PackNominalVoltage) / 1000, 1); + var avlCap = Math.Round(status!.AvailableCapacity * status.PackNominalVoltage / 1000, 1); + var packCap = Math.Round(status!.PackCapacity * status.PackNominalVoltage / 1000, 1); + return $"{avlCap} kWh / {packCap} kWh"; } + return $"{Math.Round(status!.AvailableCapacity, 1)} Ah / {status!.PackCapacity} Ah"; } @@ -207,11 +211,9 @@ // and it leads to a new stream download being created everytime a page is initialized. // which leads to a memory leak/ connection exhaustion. - using var client = new HttpClient - { - BaseAddress = new(basePath), - Timeout = TimeSpan.FromSeconds(5) - }; + using var client = new HttpClient(); + client.BaseAddress = new(basePath); + client.Timeout = TimeSpan.FromSeconds(5); var retryDelay = 1000; @@ -231,10 +233,10 @@ JsonSerializer.DeserializeAsyncEnumerable( stream, new JsonSerializerOptions - { - PropertyNameCaseInsensitive = true, - DefaultBufferSize = 64 - })) + { + PropertyNameCaseInsensitive = true, + DefaultBufferSize = 64 + })) { onStatusUpdated?.Invoke(s); retryDelay = 1000; diff --git a/src/Client/Pages/Settings.razor b/src/Client/Pages/Settings.razor index 563f879..1cf9594 100644 --- a/src/Client/Pages/Settings.razor +++ b/src/Client/Pages/Settings.razor @@ -265,7 +265,7 @@ @code{ private CurrentSettings? settings; - private Button currentButton = Button.None; + private Button? currentButton; private bool isSuccess; protected override async Task OnInitializedAsync() @@ -274,7 +274,7 @@ StateHasChanged(); } - private async Task SetChargePriority(string priority) + private async Task SetChargePriority(byte priority) { isSuccess = false; @@ -297,7 +297,7 @@ break; default: - currentButton = Button.None; + currentButton = null; break; } @@ -310,7 +310,7 @@ } } - private async Task SetOutputPriority(string priority) + private async Task SetOutputPriority(byte priority) { isSuccess = false; @@ -319,7 +319,7 @@ OutputPriority.SolarFirst => Button.OpSolarFirst, OutputPriority.SolarBatteryUtility => Button.OpSolarBatteryUtility, OutputPriority.UtilityFirst => Button.OpUtilityFirst, - _ => Button.None + _ => null }; if (await Http.GetStringAsync($"api/settings/set-setting/{Setting.OutputPriority}/{priority}") == "true") @@ -332,7 +332,7 @@ private async Task SetVoltage(Setting setting) { isSuccess = false; - decimal value = 0; + double value = 0; switch (setting) { @@ -362,19 +362,19 @@ break; default: - currentButton = Button.None; + currentButton = null; break; } ; - if (await Http.GetStringAsync($"api/settings/set-setting/{setting}/{value:00.0}") == "true") + if (await Http.GetStringAsync($"api/settings/set-setting/{setting}/{value}") == "true") { isSuccess = true; } } - private async Task SetSetting(Setting settingName, string value) + private async Task SetSetting(Setting settingName, byte value) { if (await Http.GetStringAsync($"api/settings/set-setting/{settingName}/{value}") == "true") { @@ -382,7 +382,7 @@ } } - private void UpdateLocalSetting(Setting settingName, string value) + private void UpdateLocalSetting(Setting settingName, byte value) { switch (settingName) { @@ -411,7 +411,7 @@ isSuccess = false; await Http.PostAsJsonAsync("api/settings/set-system-spec", settings!.SystemSpec); isSuccess = true; - currentButton = Button.None; + currentButton = null; } private string Spinner(Button button) @@ -424,7 +424,7 @@ ? "visually-hidden" : ""; - private string Success(Button button, string currentValue, string settingValue) + private string Success(Button button, byte currentValue, byte settingValue) => (currentButton == button && isSuccess) || currentValue == settingValue ? "oi oi-circle-check text-success" : ""; @@ -432,16 +432,15 @@ private string Sanitize(string value) => value.StartsWith("0") ? value[1..] : value; - private enum Button + private enum Button : byte { - None = 0, - ChOnlySolar = 1, - ChSolarFirst = 2, - ChSolarAndUtility = 3, - ChUtilityFirst = 4, - OpUtilityFirst = 5, - OpSolarFirst = 6, - OpSolarBatteryUtility = 7, + OpUtilityFirst = 1, //never change this value + OpSolarFirst = 2, //never change this value + OpSolarBatteryUtility = 3, //never change this value + ChOnlySolar = 4, + ChSolarFirst = 5, + ChSolarAndUtility = 6, + ChUtilityFirst = 7, UpdateUserSettings = 8, BackToGridVoltage = 9, BackToBattery = 10, diff --git a/src/Server/Endpoints/GetStatus/Endpoint.cs b/src/Server/Endpoints/GetStatus/Endpoint.cs index d395650..f9a0ff2 100644 --- a/src/Server/Endpoints/GetStatus/Endpoint.cs +++ b/src/Server/Endpoints/GetStatus/Endpoint.cs @@ -6,7 +6,7 @@ namespace InverterMon.Server.Endpoints.GetStatus; public class Endpoint : EndpointWithoutRequest { - public FelicitySolarInverter Inverter { get; set; } + public FelicitySolarInverter Inverter { get; set; } = null!; public override void Configure() { @@ -28,25 +28,25 @@ public class Endpoint : EndpointWithoutRequest async IAsyncEnumerable GetDataStream([EnumeratorCancellation] CancellationToken c) { - var blank = new InverterStatus(); - while (!c.IsCancellationRequested) { if (Env.IsDevelopment()) { - var status = new InverterStatus(); - status.OutputVoltage = Random.Shared.Next(240); - status.LoadWatts = Random.Shared.Next(3500); - status.LoadPercentage = Random.Shared.Next(100); - status.BatteryVoltage = Random.Shared.Next(24); - status.BatteryChargeCurrent = Random.Shared.Next(20); - status.BatteryDischargeCurrent = Random.Shared.Next(300); - status.HeatSinkTemperature = Random.Shared.Next(300); - status.PVInputCurrent = Random.Shared.Next(300); - status.PVInputVoltage = Random.Shared.Next(300); - status.PVInputWatt = Random.Shared.Next(1000); - status.PV_MaxCapacity = 1000; - status.BatteryCapacity = 100; + var status = new InverterStatus + { + OutputVoltage = Random.Shared.Next(240), + LoadWatts = Random.Shared.Next(3500), + LoadPercentage = Random.Shared.Next(100), + BatteryVoltage = Random.Shared.Next(24), + BatteryChargeCurrent = Random.Shared.Next(20), + BatteryDischargeCurrent = Random.Shared.Next(300), + HeatSinkTemperature = Random.Shared.Next(300), + PVInputCurrent = Random.Shared.Next(300), + PVInputVoltage = Random.Shared.Next(300), + PVInputWatt = Random.Shared.Next(1000), + PV_MaxCapacity = 1000, + BatteryCapacity = 100 + }; yield return status; } diff --git a/src/Server/Endpoints/PVLog/GetPVForDay/Endpoint.cs b/src/Server/Endpoints/PVLog/GetPVForDay/Endpoint.cs index e24b94f..8ecd030 100644 --- a/src/Server/Endpoints/PVLog/GetPVForDay/Endpoint.cs +++ b/src/Server/Endpoints/PVLog/GetPVForDay/Endpoint.cs @@ -4,6 +4,11 @@ using InverterMon.Shared.Models; namespace InverterMon.Server.Endpoints.PVLog.GetPVForDay; +public class Request +{ + public int DayNumber { get; set; } +} + public class Endpoint : Endpoint { public Database Db { get; set; } @@ -21,7 +26,7 @@ public class Endpoint : Endpoint if (pvDay is null) { - await SendNotFoundAsync(); + await SendNotFoundAsync(c); return; } @@ -34,8 +39,6 @@ public class Endpoint : Endpoint TotalWattHours = Random.Shared.Next(3000) }; - //pvDay.AllocateBuckets(6, 18); - for (var i = 0; i < 97; i++) pvDay.WattPeaks.Add(i.ToString(), Random.Shared.Next(2000)); } diff --git a/src/Server/Endpoints/PVLog/GetPVForDay/Request.cs b/src/Server/Endpoints/PVLog/GetPVForDay/Request.cs deleted file mode 100644 index 63889cd..0000000 --- a/src/Server/Endpoints/PVLog/GetPVForDay/Request.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace InverterMon.Server.Endpoints.PVLog.GetPVForDay; - -public class Request -{ - public int DayNumber { get; set; } -} \ No newline at end of file diff --git a/src/Server/Endpoints/Settings/GetSettingValues/Endpoint.cs b/src/Server/Endpoints/Settings/GetSettingValues/Endpoint.cs index 0a1171f..dbfa4c0 100644 --- a/src/Server/Endpoints/Settings/GetSettingValues/Endpoint.cs +++ b/src/Server/Endpoints/Settings/GetSettingValues/Endpoint.cs @@ -1,4 +1,5 @@ -using InverterMon.Server.Persistence.Settings; +using InverterMon.Server.InverterService; +using InverterMon.Server.Persistence.Settings; using InverterMon.Shared.Models; namespace InverterMon.Server.Endpoints.Settings.GetSettingValues; @@ -6,6 +7,7 @@ namespace InverterMon.Server.Endpoints.Settings.GetSettingValues; public class Endpoint : EndpointWithoutRequest { public UserSettings UserSettings { get; set; } + public FelicitySolarInverter Inverter { get; set; } public override void Configure() { @@ -15,29 +17,48 @@ public class Endpoint : EndpointWithoutRequest public override async Task HandleAsync(CancellationToken c) { - //todo: get values from inverter and send to client + if (Env.IsDevelopment()) + { + var res = new CurrentSettings + { + BackToBatteryVoltage = 48.1, + BackToGridVoltage = 48.2, + FloatChargeVoltage = 48.3, + ChargePriority = ChargePriority.OnlySolar, + DischargeCuttOffVoltage = 48.4, + BulkChargeVoltage = 48.5, + MaxACChargeCurrent = 10, + MaxCombinedChargeCurrent = 20, + OutputPriority = OutputPriority.SolarFirst, + SystemSpec = UserSettings.ToSystemSpec() + }; + await SendAsync(res, cancellation: c); - // var cmd = new GetSettings(); - // cmd.Result.SystemSpec = UserSettings.ToSystemSpec(); - // - // if (Env.IsDevelopment()) - // { - // cmd.Result.ChargePriority = "03"; - // cmd.Result.MaxACChargeCurrent = "10"; - // cmd.Result.MaxCombinedChargeCurrent = "020"; - // cmd.Result.OutputPriority = "02"; - // cmd.Result.BulkChargeVoltage = 27.1m; - // await SendAsync(cmd.Result); - // return; - // } - // - // Queue.AddCommands(cmd); - // - // await cmd.WhileProcessing(c); - // - // if (cmd.IsComplete) - // await SendAsync(cmd.Result); - // else - // ThrowError("Unable to read settings in a timely manner!"); + return; + } + + try + { + var data = Inverter.ReadSettings(); + var res = new CurrentSettings + { + BackToBatteryVoltage = data.BatteryBackToDischargeVoltage, + BackToGridVoltage = data.BatteryBackToChargeVoltage, + BulkChargeVoltage = data.BatteryCvChargingVoltage, + ChargePriority = data.ChargingSourcePriority, + DischargeCuttOffVoltage = data.BatteryCutOffVoltage, + FloatChargeVoltage = data.BatteryFloatingChargingVoltage, + MaxACChargeCurrent = data.MaxAcChargingCurrent, + MaxCombinedChargeCurrent = data.MaxChargingCurrent, + OutputPriority = data.OutputSourcePriority, + SystemSpec = UserSettings.ToSystemSpec() + }; + await SendAsync(res, cancellation: c); + } + catch (Exception e) + { + Logger.LogError("Unable to read settings from inverter. Details: [{msg}]", e.Message); + ThrowError("Unable to read settings from inverter!"); + } } } \ No newline at end of file diff --git a/src/Server/Endpoints/Settings/SetSettingValue/Endpoint.cs b/src/Server/Endpoints/Settings/SetSettingValue/Endpoint.cs index 7a941d9..2f113b2 100644 --- a/src/Server/Endpoints/Settings/SetSettingValue/Endpoint.cs +++ b/src/Server/Endpoints/Settings/SetSettingValue/Endpoint.cs @@ -1,20 +1,33 @@ -namespace InverterMon.Server.Endpoints.Settings.SetSettingValue; +using InverterMon.Server.InverterService; + +namespace InverterMon.Server.Endpoints.Settings.SetSettingValue; public class Endpoint : Endpoint { + public FelicitySolarInverter Inverter { get; set; } + public override void Configure() { - Get("settings/set-setting/{Command}/{Value}"); + Get("settings/set-setting/{Setting}/{Value}"); AllowAnonymous(); } public override async Task HandleAsync(Shared.Models.SetSetting r, CancellationToken c) { - //todo: set settings using inveter + if (Env.IsDevelopment()) + { + await SendAsync(true, cancellation: c); - // var cmd = new InverterService.Commands.SetSetting(r.Command, r.Value); - // Queue.AddCommands(cmd); - // await cmd.WhileProcessing(c); - // await SendAsync(cmd.Result); + return; + } + + try + { + Inverter.SetSetting(r.Setting, r.Value); + } + catch + { + await SendAsync(false, cancellation: c); + } } } \ No newline at end of file diff --git a/src/Server/InverterService/CurrentStatus.cs b/src/Server/InverterService/CurrentStatus.cs deleted file mode 100644 index 8829d67..0000000 --- a/src/Server/InverterService/CurrentStatus.cs +++ /dev/null @@ -1,8 +0,0 @@ -// using InverterMon.Shared.Models; -// -// namespace InverterMon.Server.InverterService; -// -// public class CurrentStatus -// { -// public InverterStatus Result { get; set; } -// } \ No newline at end of file diff --git a/src/Server/InverterService/FelicityInverter.cs b/src/Server/InverterService/FelicityInverter.cs index 2a0b9f1..e3f192c 100644 --- a/src/Server/InverterService/FelicityInverter.cs +++ b/src/Server/InverterService/FelicityInverter.cs @@ -5,20 +5,6 @@ using InverterMon.Shared.Models; namespace InverterMon.Server.InverterService; -// sealed class StatusData -// { -// public int WorkingMode { get; set; } -// public int BatteryChargingStage { get; set; } -// public double BatteryVoltage { get; set; } -// public int BatteryCurrent { get; set; } -// public int BatteryPower { get; set; } -// public double AcOutputVoltage { get; set; } -// public int AcOutputActivePower { get; set; } -// public int LoadPercentage { get; set; } -// public double PvInputVoltage { get; set; } -// public int PvInputPower { get; set; } -// } - sealed class SettingsData { public double BatteryCutOffVoltage { get; set; } @@ -32,21 +18,32 @@ sealed class SettingsData public byte MaxAcChargingCurrent { get; set; } } -[SuppressMessage("Performance", "CA1822:Mark members as static")] +[SuppressMessage("Performance", "CA1822:Mark members as static"), + SuppressMessage("ReSharper", "MemberCanBeMadeStatic.Global")] public sealed class FelicitySolarInverter { - public InverterStatus Status { get; private set; } + public InverterStatus Status { get; } = new(); const byte SlaveAddress = 0x01; static SerialPort _serialPort = null!; - internal void Connect(string portName) + internal bool Connect(string portName) { lock (_lock) { _serialPort = new(portName, 2400, Parity.None, 8, StopBits.One); - _serialPort.Open(); + + try + { + _serialPort.Open(); + } + catch + { + return false; + } } + + return true; } static byte[]? _cachedStatusFrame; @@ -60,11 +57,8 @@ public sealed class FelicitySolarInverter { var regs = ReadRegisters(StatusStartAddress, StatusRegisterCount); - // var status = new StatusData - // { // WorkingMode = regs[0], // 0x1101: Working mode (offset 0) // BatteryChargingStage = regs[1], // 0x1102: Battery charging stage (offset 1) - // }; Status.BatteryVoltage = regs[7] / 100.0; // 0x1108: Battery voltage (offset 0x1108 - 0x1101 = 7) Status.BatteryDischargeCurrent = regs[8]; // 0x1109: Battery current (offset 8) -- signed value @@ -103,7 +97,7 @@ public sealed class FelicitySolarInverter return settings; } - internal void SetSetting(Setting setting, float value) + internal void SetSetting(Setting setting, double value) { ushort registerAddress; @@ -154,7 +148,23 @@ public sealed class FelicitySolarInverter throw new ArgumentException("Invalid setting!"); } - WriteSingleRegister(registerAddress, (ushort)value); + var settingValue = (ushort)value; + + // Build request frame: + // [Slave Address][Function Code 0x06][Register Address Hi][Register Address Lo] + // [Value Hi][Value Lo][CRC Lo][CRC Hi] + var frame = new byte[8]; + frame[0] = SlaveAddress; + frame[1] = 0x06; + frame[2] = (byte)(registerAddress >> 8); + frame[3] = (byte)(registerAddress & 0xFF); + frame[4] = (byte)(settingValue >> 8); + frame[5] = (byte)(settingValue & 0xFF); + var crc = CalculateCrc(frame, 6); + frame[6] = (byte)(crc & 0xFF); + frame[7] = (byte)(crc >> 8); + + SendModbusRequest(frame); } internal void Close() @@ -212,25 +222,6 @@ public sealed class FelicitySolarInverter return registers; } - static void WriteSingleRegister(ushort registerAddress, ushort value) - { - // Build request frame: - // [Slave Address][Function Code 0x06][Register Address Hi][Register Address Lo] - // [Value Hi][Value Lo][CRC Lo][CRC Hi] - var frame = new byte[8]; - frame[0] = SlaveAddress; - frame[1] = 0x06; - frame[2] = (byte)(registerAddress >> 8); - frame[3] = (byte)(registerAddress & 0xFF); - frame[4] = (byte)(value >> 8); - frame[5] = (byte)(value & 0xFF); - var crc = CalculateCrc(frame, 6); - frame[6] = (byte)(crc & 0xFF); - frame[7] = (byte)(crc >> 8); - - SendModbusRequest(frame); - } - static readonly object _lock = new(); static byte[] SendModbusRequest(byte[] request) diff --git a/src/Server/InverterService/StatusRetriever.cs b/src/Server/InverterService/StatusRetriever.cs index 757fef8..d44f692 100644 --- a/src/Server/InverterService/StatusRetriever.cs +++ b/src/Server/InverterService/StatusRetriever.cs @@ -3,16 +3,35 @@ using InverterMon.Server.Persistence.Settings; namespace InverterMon.Server.InverterService; -class StatusRetriever(Database db, FelicitySolarInverter inverter, UserSettings userSettings) : BackgroundService +class StatusRetriever(Database db, FelicitySolarInverter inverter, UserSettings userSettings, IConfiguration config, ILogger log) + : BackgroundService { protected override async Task ExecuteAsync(CancellationToken c) { + var port = config["LaunchSettings:DeviceAddress"] ?? throw new ArgumentException("Device address not specified in appsettings.json file!"); + + while (!inverter.Connect(port)) + { + log.LogCritical("Unable to connect to the inverter at [{port}]. Retrying in 5 seconds...", port); + await Task.Delay(5000); + } + while (!c.IsCancellationRequested) { inverter.Status.BatteryCapacity = userSettings.BatteryCapacity; inverter.Status.PV_MaxCapacity = userSettings.PV_MaxCapacity; - //todo: get data from inverter and map to CurrentStatus.Result + try + { + inverter.UpdateStatus(); + } + catch (Exception e) + { + log.LogError("Error while reading inverter status data! Details: [{msg}]", e.Message); + await Task.Delay(2000); + + continue; + } db.UpdateTodaysPvGeneration(c); diff --git a/src/Server/Program.cs b/src/Server/Program.cs index 516ca48..50a79d5 100644 --- a/src/Server/Program.cs +++ b/src/Server/Program.cs @@ -20,6 +20,7 @@ bld.WebHost.ConfigureKestrel(o => o.Listen(IPAddress.Any, port)); bld.Services .AddSingleton() .AddSingleton() + .AddSingleton() .AddSingleton(); if (!bld.Environment.IsDevelopment()) diff --git a/src/Shared/Models/ChargePriority.cs b/src/Shared/Models/ChargePriority.cs index af10e82..5d46c70 100644 --- a/src/Shared/Models/ChargePriority.cs +++ b/src/Shared/Models/ChargePriority.cs @@ -2,8 +2,8 @@ public static class ChargePriority { - public const string SolarFirst = "1"; - public const string SolarAndUtility = "2"; - public const string OnlySolar = "3"; - public const string UtilityFirst = "0"; + public const byte SolarFirst = 1; + public const byte SolarAndUtility = 2; + public const byte OnlySolar = 3; + public const byte UtilityFirst = 0; } \ No newline at end of file diff --git a/src/Shared/Models/CurrentSettings.cs b/src/Shared/Models/CurrentSettings.cs index 90d3afc..12ddeb7 100644 --- a/src/Shared/Models/CurrentSettings.cs +++ b/src/Shared/Models/CurrentSettings.cs @@ -2,39 +2,56 @@ public class CurrentSettings { - public string ChargePriority { get; set; } = "000"; - public string OutputPriority { get; set; } = "000"; - public string MaxACChargeCurrent { get; set; } = "000"; - public string MaxCombinedChargeCurrent { get; set; } = "000"; + public byte ChargePriority { get; set; } + public byte OutputPriority { get; set; } + public byte MaxACChargeCurrent { get; set; } + public byte MaxCombinedChargeCurrent { get; set; } - decimal _backToGrid; - public decimal BackToGridVoltage { get => _backToGrid; set => _backToGrid = RoundToHalfPoints(value); } + double _backToGrid; - decimal _dischargeCuttOff; - public decimal DischargeCuttOffVoltage { get => _dischargeCuttOff; set => _dischargeCuttOff = RoundToOneDecimalPoint(value); } + public double BackToGridVoltage + { + get => _backToGrid; + set => _backToGrid = value; //RoundToHalfPoints(value); + } - decimal _bulkVoltage; - public decimal BulkChargeVoltage + double _dischargeCuttOff; + + public double DischargeCuttOffVoltage + { + get => _dischargeCuttOff; + set => _dischargeCuttOff = value; // RoundToOneDecimalPoint(value); + } + + double _bulkVoltage; + + public double BulkChargeVoltage { get => _bulkVoltage; - set => _bulkVoltage = RoundToOneDecimalPoint(value < _floatVoltage ? _floatVoltage : value); + set => _bulkVoltage = value; // RoundToOneDecimalPoint(value < _floatVoltage ? _floatVoltage : value); } - decimal _floatVoltage; - public decimal FloatChargeVoltage + double _floatVoltage; + + public double FloatChargeVoltage { get => _floatVoltage; - set => _floatVoltage = RoundToOneDecimalPoint(value > _bulkVoltage ? _bulkVoltage : value); + set => _floatVoltage = value; // RoundToOneDecimalPoint(value > _bulkVoltage ? _bulkVoltage : value); } - decimal _backToBattery; - public decimal BackToBatteryVoltage { get => _backToBattery; set => _backToBattery = RoundToHalfPoints(value); } + double _backToBattery; + + public double BackToBatteryVoltage + { + get => _backToBattery; + set => _backToBattery = value; //RoundToHalfPoints(value); + } public SystemSpec SystemSpec { get; set; } = new(); - static decimal RoundToHalfPoints(decimal value) - => Math.Round(value * 2, MidpointRounding.AwayFromZero) / 2; + // static double RoundToHalfPoints(double value) + // => Math.Round(value * 2, MidpointRounding.AwayFromZero) / 2; - static decimal RoundToOneDecimalPoint(decimal value) - => Math.Round(value, 1, MidpointRounding.AwayFromZero); -} + // static double RoundToOneDecimalPoint(double value) + // => Math.Round(value, 1, MidpointRounding.AwayFromZero); +} \ No newline at end of file diff --git a/src/Shared/Models/OutputPriority.cs b/src/Shared/Models/OutputPriority.cs index 677db81..e34cb5e 100644 --- a/src/Shared/Models/OutputPriority.cs +++ b/src/Shared/Models/OutputPriority.cs @@ -2,7 +2,7 @@ public static class OutputPriority { - public const string SolarFirst = "1"; - public const string SolarBatteryUtility = "2"; - public const string UtilityFirst = "0"; + public const byte SolarFirst = 1; + public const byte SolarBatteryUtility = 2; + public const byte UtilityFirst = 0; } \ No newline at end of file diff --git a/src/Shared/Models/SetSetting.cs b/src/Shared/Models/SetSetting.cs index 8a6efcd..8890d2e 100644 --- a/src/Shared/Models/SetSetting.cs +++ b/src/Shared/Models/SetSetting.cs @@ -2,6 +2,6 @@ public class SetSetting { - public string Command { get; set; } - public string Value { get; set; } + public Setting Setting { get; set; } + public double Value { get; set; } } \ No newline at end of file