diff --git a/Plugins.SmaEnergymeter/Controllers/CurrentPowerController.cs b/Plugins.SmaEnergymeter/Controllers/CurrentPowerController.cs index 14cb814d6..3fba57740 100644 --- a/Plugins.SmaEnergymeter/Controllers/CurrentPowerController.cs +++ b/Plugins.SmaEnergymeter/Controllers/CurrentPowerController.cs @@ -14,10 +14,18 @@ public CurrentPowerController(CurrentPowerService currentPowerService) _currentPowerService = currentPowerService; } + [Obsolete] [HttpGet] - public int GetCurrentPower(int lastXSeconds) + public int GetCurrentPower(int lastXSeconds = 0) { - return _currentPowerService.GetCurrentPower(lastXSeconds); + return _currentPowerService.GetCurrentPower(); + } + + [Route("[action]")] + [HttpGet] + public int GetPower() + { + return _currentPowerService.GetCurrentPower(); } } } diff --git a/Plugins.SmaEnergymeter/Services/CurrentPowerService.cs b/Plugins.SmaEnergymeter/Services/CurrentPowerService.cs index e50bcaaba..0fe5c8ce6 100644 --- a/Plugins.SmaEnergymeter/Services/CurrentPowerService.cs +++ b/Plugins.SmaEnergymeter/Services/CurrentPowerService.cs @@ -11,26 +11,9 @@ public CurrentPowerService(ILogger logger, SharedValues sha _sharedValues = sharedValues; } - public int GetCurrentPower(int lastXSeconds) + public int GetCurrentPower() { - _logger.LogTrace("{method}({param1})", nameof(GetCurrentPower), lastXSeconds); - var orderedValues = _sharedValues.LastValues - .Where(v => v.Timestamp >= DateTime.UtcNow.AddSeconds(-lastXSeconds)) - .OrderBy(v => v.Timestamp) - .ToList(); - - long weightedSum = 0; - for (var i = 0; i < orderedValues.Count; i++) - { - _logger.LogTrace("Power Value: {value}", orderedValues[i].Power); - weightedSum += orderedValues[i].Power * (i + 1); - _logger.LogTrace("weightedSum: {value}", weightedSum); - } - var weightedCount = orderedValues.Count * (orderedValues.Count + 1) / 2; - if (weightedCount == 0) - { - throw new InvalidOperationException("There are no power values available"); - } - return (int) (weightedSum / weightedCount); + _logger.LogTrace("{method}()", nameof(GetCurrentPower)); + return _sharedValues.Overage; } } \ No newline at end of file diff --git a/Plugins.SmaEnergymeter/Services/EnergyMeterService.cs b/Plugins.SmaEnergymeter/Services/EnergyMeterService.cs index 2d6fa889b..b5a6f428a 100644 --- a/Plugins.SmaEnergymeter/Services/EnergyMeterService.cs +++ b/Plugins.SmaEnergymeter/Services/EnergyMeterService.cs @@ -62,27 +62,14 @@ public void StartLogging() _logger.LogTrace("current supply: {currentSupply}", currentSupply); _logger.LogTrace("current overage: {currentOverage}", currentOverage); + if (currentSupply > 0) { - _sharedValues.LastValues.Add(new() - { - Timestamp = DateTime.UtcNow, - Power = (int)-currentSupply, - }); + _sharedValues.Overage = (int)-currentSupply; } else { - _sharedValues.LastValues.Add(new() - { - Timestamp = DateTime.UtcNow, - Power = (int)currentOverage, - }); - } - - var maxValuesInList = _configuration.GetValue("MaxValuesInLastValuesList"); - if (_sharedValues.LastValues.Count > maxValuesInList) - { - _sharedValues.LastValues.RemoveRange(0, _sharedValues.LastValues.Count - maxValuesInList); + _sharedValues.Overage = (int)currentOverage; } } } diff --git a/Plugins.SmaEnergymeter/SharedValues.cs b/Plugins.SmaEnergymeter/SharedValues.cs index 69a7bc3ae..c035a9a04 100644 --- a/Plugins.SmaEnergymeter/SharedValues.cs +++ b/Plugins.SmaEnergymeter/SharedValues.cs @@ -4,5 +4,5 @@ namespace Plugins.SmaEnergymeter; public class SharedValues { - public List LastValues = new (); + public int Overage { get; set; } } \ No newline at end of file diff --git a/Plugins.SmaEnergymeter/appsettings.json b/Plugins.SmaEnergymeter/appsettings.json index abf4744cc..5f46c4f23 100644 --- a/Plugins.SmaEnergymeter/appsettings.json +++ b/Plugins.SmaEnergymeter/appsettings.json @@ -22,6 +22,5 @@ }, "AllowedHosts": "*", "EnergyMeterPort": 9522, - "EnergyMeterMulticastAddress": "239.12.255.254", - "MaxValuesInLastValuesList": 30 + "EnergyMeterMulticastAddress": "239.12.255.254" } diff --git a/README.md b/README.md index c39097c47..06b897a35 100644 --- a/README.md +++ b/README.md @@ -30,7 +30,7 @@ You can either use it in a Docker container or go download the code and deploy i ### Docker-compose -If you run the simple Docker deployment of TeslaMate, then adding this will do the trick. You'll have the frontend available on port 7190 then. +If you run the simple Docker deployment of TeslaMate, then adding this will do the trick. You'll have the frontend available on port 7190 then. Note: you have to change the CurrentPowerToGridUrl based on your environment. If you use the SMA Plugin you only have to update the IP address. ```yaml services: @@ -45,9 +45,9 @@ services: depends_on: - teslamateapi environment: - - CurrentPowerToGridUrl=http://192.168.1.50/api/CurrentPower + - CurrentPowerToGridUrl=http://192.168.1.50/api/CurrentPower/GetPower - TeslaMateApiBaseUrl=http://teslamateapi:8080 - - UpdateIntervalSeconds=30 + - UpdateIntervalSeconds=20 - CarPriorities=1 - GeoFence=Home - MinutesUntilSwitchOn=5 @@ -154,5 +154,4 @@ services: network_mode: host environment: - ASPNETCORE_URLS=http://+:8453 - - MaxValuesInLastValuesList=120 ``` diff --git a/SmartTeslaAmpSetter.Tests/Services/ChargingService.cs b/SmartTeslaAmpSetter.Tests/Services/ChargingService.cs index a0fc7d6fd..66eb1d306 100644 --- a/SmartTeslaAmpSetter.Tests/Services/ChargingService.cs +++ b/SmartTeslaAmpSetter.Tests/Services/ChargingService.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Linq; using Autofac; +using SmartTeslaAmpSetter.Shared.Dtos.Contracts; using SmartTeslaAmpSetter.Shared.Dtos.Settings; using SmartTeslaAmpSetter.Shared.Enums; using SmartTeslaAmpSetter.Shared.TimeProviding; diff --git a/SmartTeslaAmpSetter.Tests/Services/MqttService.cs b/SmartTeslaAmpSetter.Tests/Services/MqttService.cs index c588f52ce..9e472c167 100644 --- a/SmartTeslaAmpSetter.Tests/Services/MqttService.cs +++ b/SmartTeslaAmpSetter.Tests/Services/MqttService.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Linq; using SmartTeslaAmpSetter.Server.Services; +using SmartTeslaAmpSetter.Shared.Dtos.Contracts; using SmartTeslaAmpSetter.Shared.Dtos.Settings; using Xunit; using Xunit.Abstractions; diff --git a/SmartTeslaAmpSetter/Client/Pages/Index.razor b/SmartTeslaAmpSetter/Client/Pages/Index.razor index aaf996a15..6131cd954 100644 --- a/SmartTeslaAmpSetter/Client/Pages/Index.razor +++ b/SmartTeslaAmpSetter/Client/Pages/Index.razor @@ -4,9 +4,8 @@ @using SmartTeslaAmpSetter.Shared @using SmartTeslaAmpSetter.Shared.Dtos.Settings @using SmartTeslaAmpSetter.Shared.Enums -@inject HttpClient _httpClient -@inject IToastService _toastService -@inject IConfiguration _configuration +@inject HttpClient HttpClient +@inject IToastService ToastService Index @@ -19,12 +18,16 @@ else
@if (_settings.InverterPower != null) { -
@_settings.InverterPower W
-
@(_settings.InverterPower - _settings.Overage - _settings.Cars.Sum(c => c.CarState.ChargingPowerAtHome)) W
+
@_settings.InverterPower W
+
@(_settings.InverterPower - _settings.Overage - _settings.Cars.Sum(c => c.CarState.ChargingPowerAtHome)) W
} -
@(Math.Abs(_settings.Overage)) W
-
@_settings.Cars.Sum(c => c.CarState.ChargingPowerAtHome) W
- +
+ @if (_settings.Overage != null) + { + @Math.Abs((int)_settings.Overage) + } + W
+
@_settings.Cars.Sum(c => c.CarState.ChargingPowerAtHome) W
@foreach (var car in _settings.Cars) { @@ -219,7 +222,7 @@ else protected override async Task OnInitializedAsync() { - var handler = _httpClient.GetFromJsonAsync("api/Config/GetSettings"); + var handler = HttpClient.GetFromJsonAsync("api/Config/GetSettings"); _settings = await handler; foreach (var car in _settings!.Cars) { @@ -236,17 +239,17 @@ else private async Task ChangeChargeMode(int carId) { _chargemodeChangeButtonTexts[carId] = _buttonLoadingText; - var updateBackend = _httpClient.PostAsync($"api/Config/ChangeChargeMode?carId={carId}", new StringContent(string.Empty)); + var updateBackend = HttpClient.PostAsync($"api/Config/ChangeChargeMode?carId={carId}", new StringContent(string.Empty)); var car = _settings?.Cars.First(c => c.Id == carId); var result = await updateBackend; if (result.IsSuccessStatusCode) { - _toastService.ShowSuccess("ChargeMode Changed"); + ToastService.ShowSuccess("ChargeMode Changed"); car!.CarConfiguration.ChargeMode = car.CarConfiguration.ChargeMode.Next(); } else { - _toastService.ShowError("Error changing ChargeMode"); + ToastService.ShowError("Error changing ChargeMode"); } _chargemodeChangeButtonTexts[carId] = _chargeModeChangeButtonDefaultText; } @@ -254,21 +257,21 @@ else private async Task UpdateCarConfiguration(int carId, CarConfiguration carConfiguration) { _saveButtonTexts[carId] = _buttonLoadingText; - var result = await _httpClient.PutAsJsonAsync($"api/Config/UpdateCarConfiguration?carId={carId}", carConfiguration); + var result = await HttpClient.PutAsJsonAsync($"api/Config/UpdateCarConfiguration?carId={carId}", carConfiguration); if (result.IsSuccessStatusCode) { - _toastService.ShowSuccess("Car Configuration updated"); + ToastService.ShowSuccess("Car Configuration updated"); } else { - _toastService.ShowError("Error updating car configuration"); + ToastService.ShowError("Error updating car configuration"); } _saveButtonTexts[carId] = _saveButtonDefaultText; } private async void RefreshStates(object? sender, ElapsedEventArgs elapsedEventArgs) { - var tmpSettings = await _httpClient.GetFromJsonAsync("api/Config/GetSettings"); + var tmpSettings = await HttpClient.GetFromJsonAsync("api/Config/GetSettings"); _settings!.InverterPower = tmpSettings!.InverterPower; _settings.Overage = tmpSettings.Overage; foreach (var tmpCar in tmpSettings.Cars) @@ -282,9 +285,9 @@ else private async void RefreshSettings() { _refreshButtonText = _buttonLoadingText; - _settings = await _httpClient.GetFromJsonAsync("api/Config/GetSettings"); + _settings = await HttpClient.GetFromJsonAsync("api/Config/GetSettings"); this.StateHasChanged(); - _toastService.ShowSuccess("Refreshed"); + ToastService.ShowSuccess("Refreshed"); _refreshButtonText = _refreshButtonDefaultText; this.StateHasChanged(); } diff --git a/SmartTeslaAmpSetter/Server/Contracts/IChargingService.cs b/SmartTeslaAmpSetter/Server/Contracts/IChargingService.cs index 7f7883603..1e0b2bf36 100644 --- a/SmartTeslaAmpSetter/Server/Contracts/IChargingService.cs +++ b/SmartTeslaAmpSetter/Server/Contracts/IChargingService.cs @@ -2,5 +2,5 @@ public interface IChargingService { - Task SetNewChargingValues(bool onlyUpdateValues = false); + Task SetNewChargingValues(); } \ No newline at end of file diff --git a/SmartTeslaAmpSetter/Server/Contracts/IConfigService.cs b/SmartTeslaAmpSetter/Server/Contracts/IConfigService.cs index 3d6cc7d8b..3d8b285b0 100644 --- a/SmartTeslaAmpSetter/Server/Contracts/IConfigService.cs +++ b/SmartTeslaAmpSetter/Server/Contracts/IConfigService.cs @@ -1,4 +1,5 @@ using SmartTeslaAmpSetter.Shared.Dtos; +using SmartTeslaAmpSetter.Shared.Dtos.Contracts; using SmartTeslaAmpSetter.Shared.Dtos.Settings; using SmartTeslaAmpSetter.Shared.Enums; @@ -6,7 +7,7 @@ namespace SmartTeslaAmpSetter.Server.Contracts; public interface IConfigService { - Task GetSettings(); + ISettings GetSettings(); ChargeMode ChangeChargeMode(int carId); void UpdateCarConfiguration(int carId, CarConfiguration carConfiguration); List GetCarBasicConfigurations(); diff --git a/SmartTeslaAmpSetter/Server/Contracts/IConfigurationWrapper.cs b/SmartTeslaAmpSetter/Server/Contracts/IConfigurationWrapper.cs index f926c859c..677a9fde2 100644 --- a/SmartTeslaAmpSetter/Server/Contracts/IConfigurationWrapper.cs +++ b/SmartTeslaAmpSetter/Server/Contracts/IConfigurationWrapper.cs @@ -3,7 +3,8 @@ public interface IConfigurationWrapper { string ConfigFileLocation(); - TimeSpan UpdateIntervall(); + TimeSpan ChargingValueJobUpdateIntervall(); + TimeSpan PvValueJobUpdateIntervall(); string MqqtClientId(); string MosquitoServer(); string CurrentPowerToGridUrl(); diff --git a/SmartTeslaAmpSetter/Server/Contracts/IGridService.cs b/SmartTeslaAmpSetter/Server/Contracts/IGridService.cs index ebcbadfc6..a732193ee 100644 --- a/SmartTeslaAmpSetter/Server/Contracts/IGridService.cs +++ b/SmartTeslaAmpSetter/Server/Contracts/IGridService.cs @@ -2,6 +2,6 @@ public interface IGridService { - Task GetCurrentOverage(); + Task GetCurrentOverage(); Task GetCurrentInverterPower(); } \ No newline at end of file diff --git a/SmartTeslaAmpSetter/Server/Contracts/IPvValueService.cs b/SmartTeslaAmpSetter/Server/Contracts/IPvValueService.cs new file mode 100644 index 000000000..bb1f6d266 --- /dev/null +++ b/SmartTeslaAmpSetter/Server/Contracts/IPvValueService.cs @@ -0,0 +1,7 @@ +namespace SmartTeslaAmpSetter.Server.Contracts; + +public interface IPvValueService +{ + Task UpdatePvValues(); + int GetAveragedOverage(); +} \ No newline at end of file diff --git a/SmartTeslaAmpSetter/Server/Controllers/ConfigController.cs b/SmartTeslaAmpSetter/Server/Controllers/ConfigController.cs index 375d00f33..cd862d6e8 100644 --- a/SmartTeslaAmpSetter/Server/Controllers/ConfigController.cs +++ b/SmartTeslaAmpSetter/Server/Controllers/ConfigController.cs @@ -1,6 +1,7 @@ using Microsoft.AspNetCore.Mvc; using SmartTeslaAmpSetter.Server.Contracts; using SmartTeslaAmpSetter.Shared.Dtos; +using SmartTeslaAmpSetter.Shared.Dtos.Contracts; using SmartTeslaAmpSetter.Shared.Dtos.Settings; using SmartTeslaAmpSetter.Shared.Enums; @@ -21,7 +22,7 @@ public ConfigController(IConfigService service) /// Get all settings and status of all cars /// [HttpGet] - public Task GetSettings() => _service.GetSettings(); + public ISettings GetSettings() => _service.GetSettings(); /// /// Change Chargemode of car diff --git a/SmartTeslaAmpSetter/Server/Program.cs b/SmartTeslaAmpSetter/Server/Program.cs index 36eea3dd1..d30583115 100644 --- a/SmartTeslaAmpSetter/Server/Program.cs +++ b/SmartTeslaAmpSetter/Server/Program.cs @@ -7,6 +7,8 @@ using SmartTeslaAmpSetter.Server.Scheduling; using SmartTeslaAmpSetter.Server.Services; using SmartTeslaAmpSetter.Server.Wrappers; +using SmartTeslaAmpSetter.Shared.Dtos; +using SmartTeslaAmpSetter.Shared.Dtos.Contracts; using SmartTeslaAmpSetter.Shared.Dtos.Settings; using SmartTeslaAmpSetter.Shared.TimeProviding; @@ -27,9 +29,10 @@ builder.Services .AddTransient() - .AddTransient() + .AddTransient() .AddTransient() .AddTransient() + .AddTransient() .AddTransient() .AddTransient() .AddTransient() @@ -42,10 +45,12 @@ .AddTransient() .AddTransient() .AddSingleton() + .AddSingleton() .AddSingleton() .AddSingleton(mqttClient) .AddTransient() .AddTransient() + .AddTransient() ; builder.Host.UseSerilog((context, configuration) => configuration @@ -68,9 +73,6 @@ var telegramService = app.Services.GetRequiredService(); await telegramService.SendMessage("Application starting up"); -var configurationWrapper = app.Services.GetRequiredService(); -var jobIntervall = configurationWrapper.UpdateIntervall(); - var configJsonService = app.Services.GetRequiredService(); await configJsonService.AddCarIdsToSettings().ConfigureAwait(false); @@ -80,7 +82,7 @@ await mqttHelper.ConfigureMqttClient().ConfigureAwait(false); var jobManager = app.Services.GetRequiredService(); -jobManager.StartJobs(jobIntervall); +jobManager.StartJobs(); // Configure the HTTP request pipeline. if (app.Environment.IsDevelopment()) diff --git a/SmartTeslaAmpSetter/Server/Scheduling/Job.cs b/SmartTeslaAmpSetter/Server/Scheduling/ChargingValueJob.cs similarity index 72% rename from SmartTeslaAmpSetter/Server/Scheduling/Job.cs rename to SmartTeslaAmpSetter/Server/Scheduling/ChargingValueJob.cs index 4593793c9..85dd595a1 100644 --- a/SmartTeslaAmpSetter/Server/Scheduling/Job.cs +++ b/SmartTeslaAmpSetter/Server/Scheduling/ChargingValueJob.cs @@ -4,12 +4,12 @@ namespace SmartTeslaAmpSetter.Server.Scheduling; [DisallowConcurrentExecution] -public class Job : IJob +public class ChargingValueJob : IJob { - private readonly ILogger _logger; + private readonly ILogger _logger; private readonly IChargingService _chargingService; - public Job(ILogger logger, IChargingService chargingService) + public ChargingValueJob(ILogger logger, IChargingService chargingService) { _logger = logger; _chargingService = chargingService; diff --git a/SmartTeslaAmpSetter/Server/Scheduling/JobManager.cs b/SmartTeslaAmpSetter/Server/Scheduling/JobManager.cs index 2c76f6dc1..852bfd39e 100644 --- a/SmartTeslaAmpSetter/Server/Scheduling/JobManager.cs +++ b/SmartTeslaAmpSetter/Server/Scheduling/JobManager.cs @@ -1,5 +1,6 @@ using Quartz; using Quartz.Spi; +using SmartTeslaAmpSetter.Server.Contracts; namespace SmartTeslaAmpSetter.Server.Scheduling; @@ -8,28 +9,33 @@ public class JobManager private readonly ILogger _logger; private readonly IJobFactory _jobFactory; private readonly ISchedulerFactory _schedulerFactory; + private readonly IConfigurationWrapper _configurationWrapper; private IScheduler _scheduler; #pragma warning disable CS8618 - public JobManager(ILogger logger, IJobFactory jobFactory, ISchedulerFactory schedulerFactory) + public JobManager(ILogger logger, IJobFactory jobFactory, ISchedulerFactory schedulerFactory, IConfigurationWrapper configurationWrapper) #pragma warning restore CS8618 { _logger = logger; _jobFactory = jobFactory; _schedulerFactory = schedulerFactory; + _configurationWrapper = configurationWrapper; } - public async void StartJobs(TimeSpan jobIntervall) + public async void StartJobs() { - _logger.LogTrace("{class}.{Method}()", nameof(JobManager), nameof(StartJobs)); + _logger.LogTrace("{Method}()", nameof(StartJobs)); _scheduler = _schedulerFactory.GetScheduler().GetAwaiter().GetResult(); _scheduler.JobFactory = _jobFactory; - var chargeLogJob = JobBuilder.Create().Build(); + var chargingValueJob = JobBuilder.Create().Build(); var configJsonUpdateJob = JobBuilder.Create().Build(); var chargeTimeUpdateJob = JobBuilder.Create().Build(); + var pvValueJob = JobBuilder.Create().Build(); + + var jobIntervall = _configurationWrapper.ChargingValueJobUpdateIntervall(); var defaultTrigger = TriggerBuilder.Create().WithSchedule(SimpleScheduleBuilder.RepeatSecondlyForever((int)jobIntervall.TotalSeconds)).Build(); @@ -40,11 +46,18 @@ public async void StartJobs(TimeSpan jobIntervall) var chargeTimeUpdateTrigger = TriggerBuilder.Create() .WithSchedule(SimpleScheduleBuilder.RepeatSecondlyForever(30)).Build(); + var pvValueJobIntervall = _configurationWrapper.PvValueJobUpdateIntervall(); + _logger.LogTrace("PvValue Job intervall is {pvValueJobIntervall}", pvValueJobIntervall); + + var pvValueTrigger = TriggerBuilder.Create() + .WithSchedule(SimpleScheduleBuilder.RepeatSecondlyForever((int)pvValueJobIntervall.TotalSeconds)).Build(); + var triggersAndJobs = new Dictionary> { - {chargeLogJob, new HashSet { defaultTrigger }}, + {chargingValueJob, new HashSet { defaultTrigger }}, {configJsonUpdateJob, new HashSet {updateJsonTrigger}}, {chargeTimeUpdateJob, new HashSet {chargeTimeUpdateTrigger}}, + {pvValueJob, new HashSet {pvValueTrigger}}, }; await _scheduler.ScheduleJobs(triggersAndJobs, false).ConfigureAwait(false); diff --git a/SmartTeslaAmpSetter/Server/Scheduling/PvValueJob.cs b/SmartTeslaAmpSetter/Server/Scheduling/PvValueJob.cs new file mode 100644 index 000000000..3c0a736f7 --- /dev/null +++ b/SmartTeslaAmpSetter/Server/Scheduling/PvValueJob.cs @@ -0,0 +1,22 @@ +using Quartz; +using SmartTeslaAmpSetter.Server.Contracts; + +namespace SmartTeslaAmpSetter.Server.Scheduling; + +[DisallowConcurrentExecution] +public class PvValueJob : IJob +{ + private readonly ILogger _logger; + private readonly IPvValueService _service; + + public PvValueJob(ILogger logger, IPvValueService service) + { + _logger = logger; + _service = service; + } + public async Task Execute(IJobExecutionContext context) + { + _logger.LogTrace("Executing Job to get PV values"); + await _service.UpdatePvValues().ConfigureAwait(false); + } +} \ No newline at end of file diff --git a/SmartTeslaAmpSetter/Server/Services/ChargeTimeUpdateService.cs b/SmartTeslaAmpSetter/Server/Services/ChargeTimeUpdateService.cs index f5b4c84b9..b06ce3b4f 100644 --- a/SmartTeslaAmpSetter/Server/Services/ChargeTimeUpdateService.cs +++ b/SmartTeslaAmpSetter/Server/Services/ChargeTimeUpdateService.cs @@ -1,5 +1,6 @@ using System.Runtime.CompilerServices; using SmartTeslaAmpSetter.Server.Contracts; +using SmartTeslaAmpSetter.Shared.Dtos.Contracts; using SmartTeslaAmpSetter.Shared.Dtos.Settings; using SmartTeslaAmpSetter.Shared.TimeProviding; diff --git a/SmartTeslaAmpSetter/Server/Services/ChargingService.cs b/SmartTeslaAmpSetter/Server/Services/ChargingService.cs index e137aa051..38328567a 100644 --- a/SmartTeslaAmpSetter/Server/Services/ChargingService.cs +++ b/SmartTeslaAmpSetter/Server/Services/ChargingService.cs @@ -1,5 +1,6 @@ using System.Runtime.CompilerServices; using SmartTeslaAmpSetter.Server.Contracts; +using SmartTeslaAmpSetter.Shared.Dtos.Contracts; using SmartTeslaAmpSetter.Shared.Dtos.Settings; using SmartTeslaAmpSetter.Shared.Enums; using SmartTeslaAmpSetter.Shared.TimeProviding; @@ -17,10 +18,11 @@ public class ChargingService : IChargingService private readonly ITelegramService _telegramService; private readonly ITeslaService _teslaService; private readonly IConfigurationWrapper _configurationWrapper; + private readonly IPvValueService _pvValueService; public ChargingService(ILogger logger, IGridService gridService, ISettings settings, IDateTimeProvider dateTimeProvider, ITelegramService telegramService, - ITeslaService teslaService, IConfigurationWrapper configurationWrapper) + ITeslaService teslaService, IConfigurationWrapper configurationWrapper, IPvValueService pvValueService) { _logger = logger; _gridService = gridService; @@ -29,28 +31,14 @@ public ChargingService(ILogger logger, IGridService gridService _telegramService = telegramService; _teslaService = teslaService; _configurationWrapper = configurationWrapper; + _pvValueService = pvValueService; } - public async Task SetNewChargingValues(bool onlyUpdateValues = false) + public async Task SetNewChargingValues() { - _logger.LogTrace("{method}({param})", nameof(SetNewChargingValues), onlyUpdateValues); + _logger.LogTrace("{method}()", nameof(SetNewChargingValues)); - var overage = await _gridService.GetCurrentOverage().ConfigureAwait(false); - - _settings.Overage = overage; - - _logger.LogDebug($"Current overage is {overage} Watt."); - - var inverterPower = await _gridService.GetCurrentInverterPower().ConfigureAwait(false); - - _settings.InverterPower = inverterPower; - - _logger.LogDebug($"Current overage is {overage} Watt."); - - var buffer = _configurationWrapper.PowerBuffer(); - _logger.LogDebug("Adding powerbuffer {powerbuffer}", buffer); - - overage -= buffer; + _logger.LogDebug("Current overage is {overage} Watt.", _settings.Overage); var geofence = _configurationWrapper.GeoFence(); _logger.LogDebug("Relevant Geofence: {geofence}", geofence); @@ -59,7 +47,7 @@ public async Task SetNewChargingValues(bool onlyUpdateValues = false) var relevantCarIds = GetRelevantCarIds(geofence); _logger.LogDebug("Relevant car ids: {@ids}", relevantCarIds); - + var irrelevantCars = GetIrrelevantCars(relevantCarIds); _logger.LogDebug("Irrelevant car ids: {@ids}", irrelevantCars.Select(c => c.Id)); @@ -70,27 +58,35 @@ public async Task SetNewChargingValues(bool onlyUpdateValues = false) UpdateChargingPowerAtHome(geofence); - if (onlyUpdateValues) - { - return; - } - if (relevantCarIds.Count < 1) { return; } - var currentRegulatedPower = relevantCars + var currentControledPower = relevantCars .Sum(c => c.CarState.ChargingPower); - _logger.LogDebug("Current regulated Power: {power}", currentRegulatedPower); + _logger.LogDebug("Current control Power: {power}", currentControledPower); - var powerToRegulate = overage; - _logger.LogDebug("Power to regulate: {power}", powerToRegulate); + var buffer = _configurationWrapper.PowerBuffer(); + _logger.LogDebug("Adding powerbuffer {powerbuffer}", buffer); - var ampToRegulate = Convert.ToInt32(Math.Floor(powerToRegulate / ((double)230 * 3))); - _logger.LogDebug("Amp to regulate: {amp}", ampToRegulate); + var averagedOverage = _pvValueService.GetAveragedOverage(); + _logger.LogDebug("Averaged overage {averagedOverage}", averagedOverage); + + if (_settings.Overage != null) + { + _logger.LogWarning("Can not control power as overage is unknown"); + //ToDo: add return + //return; + } + + var overage = averagedOverage - buffer; + + var powerToControl = overage; - if (ampToRegulate < 0) + _logger.LogDebug("Power to control: {power}", powerToControl); + + if (powerToControl < 0) { _logger.LogDebug("Reversing car order"); relevantCars.Reverse(); @@ -98,8 +94,10 @@ public async Task SetNewChargingValues(bool onlyUpdateValues = false) foreach (var relevantCar in relevantCars) { + var ampToControl = Convert.ToInt32(Math.Floor(powerToControl / ((double)230 * (relevantCar.CarState.ActualPhases ?? 3)))); + _logger.LogDebug("Amp to control: {amp}", ampToControl); _logger.LogDebug("Update Car amp for car {carname}", relevantCar.CarState.Name); - ampToRegulate -= await ChangeCarAmp(relevantCar, ampToRegulate).ConfigureAwait(false); + powerToControl -= await ChangeCarAmp(relevantCar, ampToControl).ConfigureAwait(false); } } @@ -167,125 +165,131 @@ internal List GetRelevantCarIds(string geofence) return relevantIds; } - - private async Task ChangeCarAmp(Car relevantCar, int ampToRegulate) + + /// + /// Changes ampere of car + /// + /// car whose Ampere should be changed + /// Needed amp difference + /// Power difference + private async Task ChangeCarAmp(Car car, int ampToChange) { - _logger.LogTrace("{method}({param1}, {param2})", nameof(ChangeCarAmp), relevantCar.CarState.Name, ampToRegulate); - var finalAmpsToSet = (relevantCar.CarState.ChargerActualCurrent?? 0) + ampToRegulate; + _logger.LogTrace("{method}({param1}, {param2})", nameof(ChangeCarAmp), car.CarState.Name, ampToChange); + var finalAmpsToSet = (car.CarState.ChargerActualCurrent ?? 0) + ampToChange; _logger.LogDebug("Amps to set: {amps}", finalAmpsToSet); var ampChange = 0; - var minAmpPerCar = relevantCar.CarConfiguration.MinimumAmpere; - var maxAmpPerCar = relevantCar.CarConfiguration.MaximumAmpere; + var minAmpPerCar = car.CarConfiguration.MinimumAmpere; + var maxAmpPerCar = car.CarConfiguration.MaximumAmpere; _logger.LogDebug("Min amp for car: {amp}", minAmpPerCar); _logger.LogDebug("Max amp for car: {amp}", maxAmpPerCar); - - EnableFullSpeedChargeIfMinimumSocNotReachable(relevantCar); - DisableFullSpeedChargeIfMinimumSocReachedOrMinimumSocReachable(relevantCar); + + EnableFullSpeedChargeIfMinimumSocNotReachable(car); + DisableFullSpeedChargeIfMinimumSocReachedOrMinimumSocReachable(car); //Falls MaxPower als Charge Mode: Leistung auf maximal - if (relevantCar.CarConfiguration.ChargeMode == ChargeMode.MaxPower || relevantCar.CarState.AutoFullSpeedCharge) + if (car.CarConfiguration.ChargeMode == ChargeMode.MaxPower || car.CarState.AutoFullSpeedCharge) { - _logger.LogDebug("Max Power Charging: ChargeMode: {chargeMode}, AutoFullSpeedCharge: {autofullspeedCharge}", - relevantCar.CarConfiguration.ChargeMode, relevantCar.CarState.AutoFullSpeedCharge); - if (relevantCar.CarState.ChargerActualCurrent < maxAmpPerCar) + _logger.LogDebug("Max Power Charging: ChargeMode: {chargeMode}, AutoFullSpeedCharge: {autofullspeedCharge}", + car.CarConfiguration.ChargeMode, car.CarState.AutoFullSpeedCharge); + if (car.CarState.ChargerActualCurrent < maxAmpPerCar) { var ampToSet = maxAmpPerCar; - if (relevantCar.CarState.ChargerActualCurrent < 1) + if (car.CarState.ChargerActualCurrent < 1) { //Do not start charging when battery level near charge limit - if (relevantCar.CarState.SoC >= - relevantCar.CarState.SocLimit - 2) + if (car.CarState.SoC >= + car.CarState.SocLimit - 2) { - return ampChange; + return 0; } - await _teslaService.StartCharging(relevantCar.Id, ampToSet, relevantCar.CarState.State).ConfigureAwait(false); - ampChange += ampToSet - (relevantCar.CarState.ChargerActualCurrent?? 0); - UpdateEarliestTimesAfterSwitch(relevantCar.Id); + await _teslaService.StartCharging(car.Id, ampToSet, car.CarState.State).ConfigureAwait(false); + ampChange += ampToSet - (car.CarState.ChargerActualCurrent ?? 0); + UpdateEarliestTimesAfterSwitch(car.Id); } else { - await _teslaService.SetAmp(relevantCar.Id, ampToSet).ConfigureAwait(false); - ampChange += ampToSet - (relevantCar.CarState.ChargerActualCurrent?? 0); - UpdateEarliestTimesAfterSwitch(relevantCar.Id); + await _teslaService.SetAmp(car.Id, ampToSet).ConfigureAwait(false); + ampChange += ampToSet - (car.CarState.ChargerActualCurrent ?? 0); + UpdateEarliestTimesAfterSwitch(car.Id); } } } //Falls Laden beendet werden soll, aber noch ladend - else if (finalAmpsToSet < minAmpPerCar && relevantCar.CarState.ChargerActualCurrent > 0) + else if (finalAmpsToSet < minAmpPerCar && car.CarState.ChargerActualCurrent > 0) { _logger.LogDebug("Charging should stop"); - var earliestSwitchOff = EarliestSwitchOff(relevantCar.Id); + var earliestSwitchOff = EarliestSwitchOff(car.Id); //Falls Klima an (Laden nicht deaktivierbar), oder Ausschaltbefehl erst seit Kurzem - if (relevantCar.CarState.ClimateOn == true || earliestSwitchOff > DateTime.Now) + if (car.CarState.ClimateOn == true || earliestSwitchOff > DateTime.Now) { _logger.LogDebug("Can not stop charing: Climate on: {climateState}, earliest Switch Off: {earliestSwitchOff}", - relevantCar.CarState.ClimateOn, + car.CarState.ClimateOn, earliestSwitchOff); - if (relevantCar.CarState.ChargerActualCurrent != minAmpPerCar) + if (car.CarState.ChargerActualCurrent != minAmpPerCar) { - await _teslaService.SetAmp(relevantCar.Id, minAmpPerCar).ConfigureAwait(false); + await _teslaService.SetAmp(car.Id, minAmpPerCar).ConfigureAwait(false); } - ampChange += minAmpPerCar - (relevantCar.CarState.ChargerActualCurrent?? 0); + ampChange += minAmpPerCar - (car.CarState.ChargerActualCurrent ?? 0); } //Laden Stoppen else { _logger.LogDebug("Stop Charging"); - await _teslaService.StopCharging(relevantCar.Id).ConfigureAwait(false); - ampChange -= relevantCar.CarState.ChargerActualCurrent ?? 0; - UpdateEarliestTimesAfterSwitch(relevantCar.Id); + await _teslaService.StopCharging(car.Id).ConfigureAwait(false); + ampChange -= car.CarState.ChargerActualCurrent ?? 0; + UpdateEarliestTimesAfterSwitch(car.Id); } } //Falls Laden beendet ist und beendet bleiben soll else if (finalAmpsToSet < minAmpPerCar) { _logger.LogDebug("Charging should stay stopped"); - UpdateEarliestTimesAfterSwitch(relevantCar.Id); + UpdateEarliestTimesAfterSwitch(car.Id); } //Falls nicht ladend, aber laden soll beginnen - else if (finalAmpsToSet >= minAmpPerCar && relevantCar.CarState.ChargerActualCurrent == 0) + else if (finalAmpsToSet >= minAmpPerCar && car.CarState.ChargerActualCurrent == 0) { _logger.LogDebug("Charging should start"); - var earliestSwitchOn = EarliestSwitchOn(relevantCar.Id); + var earliestSwitchOn = EarliestSwitchOn(car.Id); if (earliestSwitchOn <= DateTime.Now) { _logger.LogDebug("Charging should start"); var startAmp = finalAmpsToSet > maxAmpPerCar ? maxAmpPerCar : finalAmpsToSet; - await _teslaService.StartCharging(relevantCar.Id, startAmp, relevantCar.CarState.State).ConfigureAwait(false); + await _teslaService.StartCharging(car.Id, startAmp, car.CarState.State).ConfigureAwait(false); ampChange += startAmp; - UpdateEarliestTimesAfterSwitch(relevantCar.Id); + UpdateEarliestTimesAfterSwitch(car.Id); } } //Normal Ampere setzen else { _logger.LogDebug("Normal amp set"); - UpdateEarliestTimesAfterSwitch(relevantCar.Id); + UpdateEarliestTimesAfterSwitch(car.Id); var ampToSet = finalAmpsToSet > maxAmpPerCar ? maxAmpPerCar : finalAmpsToSet; - if (ampToSet != relevantCar.CarState.ChargerActualCurrent) + if (ampToSet != car.CarState.ChargerActualCurrent) { - await _teslaService.SetAmp(relevantCar.Id, ampToSet).ConfigureAwait(false); - ampChange += ampToSet - (relevantCar.CarState.ChargerActualCurrent ?? 0); + await _teslaService.SetAmp(car.Id, ampToSet).ConfigureAwait(false); + ampChange += ampToSet - (car.CarState.ChargerActualCurrent ?? 0); } else { _logger.LogDebug("Current actual amp: {currentActualAmp} same as amp to set: {ampToSet} Do not change anything", - relevantCar.CarState.ChargerActualCurrent, ampToSet); + car.CarState.ChargerActualCurrent, ampToSet); } } - return ampChange; + return ampChange * (car.CarState.ChargerVoltage ?? 230) * (car.CarState.ActualPhases ?? 3); } internal void DisableFullSpeedChargeIfMinimumSocReachedOrMinimumSocReachable(Car car) { if (car.CarState.ReachingMinSocAtFullSpeedCharge == null - || car.CarState.SoC >= car.CarConfiguration.MinimumSoC - || car.CarState.ReachingMinSocAtFullSpeedCharge < car.CarConfiguration.LatestTimeToReachSoC.AddMinutes(-30) + || car.CarState.SoC >= car.CarConfiguration.MinimumSoC + || car.CarState.ReachingMinSocAtFullSpeedCharge < car.CarConfiguration.LatestTimeToReachSoC.AddMinutes(-30) && car.CarConfiguration.ChargeMode != ChargeMode.PvAndMinSoc) { car.CarState.AutoFullSpeedCharge = false; diff --git a/SmartTeslaAmpSetter/Server/Services/ConfigJsonService.cs b/SmartTeslaAmpSetter/Server/Services/ConfigJsonService.cs index e69404f49..5ae4b600c 100644 --- a/SmartTeslaAmpSetter/Server/Services/ConfigJsonService.cs +++ b/SmartTeslaAmpSetter/Server/Services/ConfigJsonService.cs @@ -3,6 +3,7 @@ using Newtonsoft.Json; using SmartTeslaAmpSetter.Server.Contracts; using SmartTeslaAmpSetter.Shared; +using SmartTeslaAmpSetter.Shared.Dtos.Contracts; using SmartTeslaAmpSetter.Shared.Dtos.Settings; using SmartTeslaAmpSetter.Shared.Enums; diff --git a/SmartTeslaAmpSetter/Server/Services/ConfigService.cs b/SmartTeslaAmpSetter/Server/Services/ConfigService.cs index 75e85877c..e372b394f 100644 --- a/SmartTeslaAmpSetter/Server/Services/ConfigService.cs +++ b/SmartTeslaAmpSetter/Server/Services/ConfigService.cs @@ -1,6 +1,7 @@ using SmartTeslaAmpSetter.Server.Contracts; using SmartTeslaAmpSetter.Shared; using SmartTeslaAmpSetter.Shared.Dtos; +using SmartTeslaAmpSetter.Shared.Dtos.Contracts; using SmartTeslaAmpSetter.Shared.Dtos.Settings; using SmartTeslaAmpSetter.Shared.Enums; @@ -19,10 +20,9 @@ public ConfigService(ILogger logger, ISettings settings, IChargin _chargingService = chargingService; } - public async Task GetSettings() + public ISettings GetSettings() { _logger.LogTrace("{method}()", nameof(GetSettings)); - await _chargingService.SetNewChargingValues(true); return _settings; } diff --git a/SmartTeslaAmpSetter/Server/Services/GridService.cs b/SmartTeslaAmpSetter/Server/Services/GridService.cs index 898810c8c..6185b921f 100644 --- a/SmartTeslaAmpSetter/Server/Services/GridService.cs +++ b/SmartTeslaAmpSetter/Server/Services/GridService.cs @@ -17,7 +17,7 @@ public GridService(ILogger logger, ITelegramService telegramService _configurationWrapper = configurationWrapper; } - public async Task GetCurrentOverage() + public async Task GetCurrentOverage() { _logger.LogTrace("{method}()", nameof(GetCurrentOverage)); using var httpClient = new HttpClient(); @@ -30,7 +30,7 @@ public async Task GetCurrentOverage() if (!response.IsSuccessStatusCode) { _logger.LogError("Could not get current overage. {statusCode}, {reasonPhrase}", response.StatusCode, response.ReasonPhrase); - response.EnsureSuccessStatusCode(); + return null; } var result = await response.Content.ReadAsStringAsync().ConfigureAwait(false); diff --git a/SmartTeslaAmpSetter/Server/Services/MqttService.cs b/SmartTeslaAmpSetter/Server/Services/MqttService.cs index d57915512..de647112c 100644 --- a/SmartTeslaAmpSetter/Server/Services/MqttService.cs +++ b/SmartTeslaAmpSetter/Server/Services/MqttService.cs @@ -1,6 +1,7 @@ using MQTTnet; using MQTTnet.Client; using SmartTeslaAmpSetter.Server.Contracts; +using SmartTeslaAmpSetter.Shared.Dtos.Contracts; using SmartTeslaAmpSetter.Shared.Dtos.Settings; using CarState = SmartTeslaAmpSetter.Shared.Enums.CarState; diff --git a/SmartTeslaAmpSetter/Server/Services/PvValueService.cs b/SmartTeslaAmpSetter/Server/Services/PvValueService.cs new file mode 100644 index 000000000..43cc2c16c --- /dev/null +++ b/SmartTeslaAmpSetter/Server/Services/PvValueService.cs @@ -0,0 +1,71 @@ +using SmartTeslaAmpSetter.Server.Contracts; +using SmartTeslaAmpSetter.Shared.Dtos.Contracts; +using SmartTeslaAmpSetter.Shared.Dtos.Settings; + +namespace SmartTeslaAmpSetter.Server.Services; + +public class PvValueService : IPvValueService +{ + private readonly ILogger _logger; + private readonly ISettings _settings; + private readonly IGridService _gridService; + private readonly IInMemoryValues _inMemoryValues; + private readonly IConfigurationWrapper _configurationWrapper; + + public PvValueService(ILogger logger, ISettings settings, IGridService gridService, + IInMemoryValues inMemoryValues, IConfigurationWrapper configurationWrapper) + { + _logger = logger; + _settings = settings; + _gridService = gridService; + _inMemoryValues = inMemoryValues; + _configurationWrapper = configurationWrapper; + } + + public async Task UpdatePvValues() + { + _logger.LogTrace("{method}()", nameof(UpdatePvValues)); + + var overage = await _gridService.GetCurrentOverage().ConfigureAwait(false); + _logger.LogDebug("Overage is {overage}", overage); + _settings.Overage = overage; + if (overage != null) + { + AddOverageValueToInMemoryList((int)overage); + } + _settings.InverterPower = await _gridService.GetCurrentInverterPower().ConfigureAwait(false); + } + + public int GetAveragedOverage() + { + _logger.LogTrace("{method}()", nameof(GetAveragedOverage)); + long weightedSum = 0; + _logger.LogDebug("Build weighted average of {count} values", _inMemoryValues.OverageValues.Count); + for (var i = 0; i < _inMemoryValues.OverageValues.Count; i++) + { + _logger.LogTrace("Power Value: {value}", _inMemoryValues.OverageValues[i]); + weightedSum += _inMemoryValues.OverageValues[i] * (i + 1); + _logger.LogTrace("weightedSum: {value}", weightedSum); + } + var weightedCount = _inMemoryValues.OverageValues.Count * (_inMemoryValues.OverageValues.Count + 1) / 2; + if (weightedCount == 0) + { + throw new InvalidOperationException("There are no power values available"); + } + return (int)(weightedSum / weightedCount); + } + + private void AddOverageValueToInMemoryList(int overage) + { + _logger.LogTrace("{method}({overage})", nameof(AddOverageValueToInMemoryList), overage); + _inMemoryValues.OverageValues.Add(overage); + + var valuesToSave = (int)(_configurationWrapper.ChargingValueJobUpdateIntervall().TotalSeconds / + _configurationWrapper.PvValueJobUpdateIntervall().TotalSeconds); + + if (_inMemoryValues.OverageValues.Count > valuesToSave) + { + _inMemoryValues.OverageValues.RemoveRange(0, _inMemoryValues.OverageValues.Count - valuesToSave); + } + } +} \ No newline at end of file diff --git a/SmartTeslaAmpSetter/Server/Services/TeslamateApiService.cs b/SmartTeslaAmpSetter/Server/Services/TeslamateApiService.cs index 05483aed5..a365456f9 100644 --- a/SmartTeslaAmpSetter/Server/Services/TeslamateApiService.cs +++ b/SmartTeslaAmpSetter/Server/Services/TeslamateApiService.cs @@ -1,6 +1,7 @@ using System.Text; using Newtonsoft.Json; using SmartTeslaAmpSetter.Server.Contracts; +using SmartTeslaAmpSetter.Shared.Dtos.Contracts; using SmartTeslaAmpSetter.Shared.Dtos.Settings; using CarState = SmartTeslaAmpSetter.Shared.Enums.CarState; diff --git a/SmartTeslaAmpSetter/Server/Wrappers/ConfigurationWrapper.cs b/SmartTeslaAmpSetter/Server/Wrappers/ConfigurationWrapper.cs index 891975f4c..88975e77e 100644 --- a/SmartTeslaAmpSetter/Server/Wrappers/ConfigurationWrapper.cs +++ b/SmartTeslaAmpSetter/Server/Wrappers/ConfigurationWrapper.cs @@ -23,7 +23,7 @@ public string ConfigFileLocation() return value; } - public TimeSpan UpdateIntervall() + public TimeSpan ChargingValueJobUpdateIntervall() { var environmentVariableName = "UpdateIntervallSeconds"; var minimum = TimeSpan.FromSeconds(20); @@ -31,7 +31,26 @@ public TimeSpan UpdateIntervall() _logger.LogDebug("Config value extracted: [{key}]: {value}", environmentVariableName, value); return value; } - + + public TimeSpan PvValueJobUpdateIntervall() + { + var environmentVariableName = "PvValueUpdateIntervalSeconds"; + var maximum = ChargingValueJobUpdateIntervall(); + var minimum = TimeSpan.FromSeconds(1); + var value = TimeSpan.FromSeconds(_configuration.GetValue(environmentVariableName)); + + if (value > maximum) + { + value = maximum; + } + else if (value < minimum) + { + value = minimum; + } + _logger.LogDebug("Config value extracted: [{key}]: {value}", environmentVariableName, value); + return value; + } + public string MqqtClientId() { var environmentVariableName = "MqqtClientId"; diff --git a/SmartTeslaAmpSetter/Server/appsettings.Development.json b/SmartTeslaAmpSetter/Server/appsettings.Development.json index c7770e9a3..ae4ad1e96 100644 --- a/SmartTeslaAmpSetter/Server/appsettings.Development.json +++ b/SmartTeslaAmpSetter/Server/appsettings.Development.json @@ -32,6 +32,7 @@ "CurrentInverterPowerUrl": "http://192.168.1.50:5007/api/ChargingLog/GetAverageInverterPowerOfLastXseconds", "TeslaMateApiBaseUrl": "http://192.168.1.50:8097", "UpdateIntervalSeconds": 30, + "PvValueUpdateIntervalSeconds": 1, "CarPriorities": "1|2", "GeoFence": "asdf", "MinutesUntilSwitchOn": 5, diff --git a/SmartTeslaAmpSetter/Server/appsettings.json b/SmartTeslaAmpSetter/Server/appsettings.json index 2d33667f9..cb1da4fb5 100644 --- a/SmartTeslaAmpSetter/Server/appsettings.json +++ b/SmartTeslaAmpSetter/Server/appsettings.json @@ -29,6 +29,7 @@ "AllowedHosts": "*", "ConfigFileLocation": "configs/carConfig.json", "UpdateIntervalSeconds": 30, + "PvValueUpdateIntervalSeconds": 1, "MqqtClientId": "SmartTeslaAmpSetter", "MosquitoServer": "mosquitto" //"CurrentPowerToGridUrl": "http://192.168.1.50:5007/api/ChargingLog/GetAverageGridPowerOfLastXseconds", diff --git a/SmartTeslaAmpSetter/Shared/Dtos/Contracts/IInMemoryValues.cs b/SmartTeslaAmpSetter/Shared/Dtos/Contracts/IInMemoryValues.cs new file mode 100644 index 000000000..ce1feb31e --- /dev/null +++ b/SmartTeslaAmpSetter/Shared/Dtos/Contracts/IInMemoryValues.cs @@ -0,0 +1,6 @@ +namespace SmartTeslaAmpSetter.Shared.Dtos.Contracts; + +public interface IInMemoryValues +{ + List OverageValues { get; set; } +} \ No newline at end of file diff --git a/SmartTeslaAmpSetter/Shared/Dtos/Contracts/ISettings.cs b/SmartTeslaAmpSetter/Shared/Dtos/Contracts/ISettings.cs new file mode 100644 index 000000000..f30d368df --- /dev/null +++ b/SmartTeslaAmpSetter/Shared/Dtos/Contracts/ISettings.cs @@ -0,0 +1,10 @@ +using SmartTeslaAmpSetter.Shared.Dtos.Settings; + +namespace SmartTeslaAmpSetter.Shared.Dtos.Contracts; + +public interface ISettings +{ + int? InverterPower { get; set; } + int? Overage { get; set; } + List Cars { get; set; } +} \ No newline at end of file diff --git a/SmartTeslaAmpSetter/Shared/Dtos/InMemoryValues.cs b/SmartTeslaAmpSetter/Shared/Dtos/InMemoryValues.cs new file mode 100644 index 000000000..984ee16e1 --- /dev/null +++ b/SmartTeslaAmpSetter/Shared/Dtos/InMemoryValues.cs @@ -0,0 +1,13 @@ +using SmartTeslaAmpSetter.Shared.Dtos.Contracts; + +namespace SmartTeslaAmpSetter.Shared.Dtos; + +public class InMemoryValues : IInMemoryValues +{ + public List OverageValues { get; set; } + + public InMemoryValues() + { + OverageValues = new List(); + } +} \ No newline at end of file diff --git a/SmartTeslaAmpSetter/Shared/Dtos/Settings/CarState.cs b/SmartTeslaAmpSetter/Shared/Dtos/Settings/CarState.cs index 0fab92b40..cd7c51a53 100644 --- a/SmartTeslaAmpSetter/Shared/Dtos/Settings/CarState.cs +++ b/SmartTeslaAmpSetter/Shared/Dtos/Settings/CarState.cs @@ -13,6 +13,9 @@ public class CarState public bool AutoFullSpeedCharge { get; set; } public int LastSetAmp { get; set; } public int? ChargerPhases { get; set; } + + public int? ActualPhases => ChargerPhases > 1 ? 3 : 1; + public int? ChargerVoltage { get; set; } public int? ChargerActualCurrent { get; set; } public bool? PluggedIn { get; set; } @@ -22,8 +25,7 @@ public int? ChargingPower { get { - var phases = ChargerPhases > 1 ? 3 : 1; - var power = ChargerActualCurrent * ChargerVoltage * phases; + var power = ChargerActualCurrent * ChargerVoltage * ActualPhases; return power; } } diff --git a/SmartTeslaAmpSetter/Shared/Dtos/Settings/ISettings.cs b/SmartTeslaAmpSetter/Shared/Dtos/Settings/ISettings.cs deleted file mode 100644 index a9151b940..000000000 --- a/SmartTeslaAmpSetter/Shared/Dtos/Settings/ISettings.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace SmartTeslaAmpSetter.Shared.Dtos.Settings; - -public interface ISettings -{ - int? InverterPower { get; set; } - int Overage { get; set; } - List Cars { get; set; } -} \ No newline at end of file diff --git a/SmartTeslaAmpSetter/Shared/Dtos/Settings/Settings.cs b/SmartTeslaAmpSetter/Shared/Dtos/Settings/Settings.cs index bac09a510..d496a942a 100644 --- a/SmartTeslaAmpSetter/Shared/Dtos/Settings/Settings.cs +++ b/SmartTeslaAmpSetter/Shared/Dtos/Settings/Settings.cs @@ -1,4 +1,6 @@ -namespace SmartTeslaAmpSetter.Shared.Dtos.Settings; +using SmartTeslaAmpSetter.Shared.Dtos.Contracts; + +namespace SmartTeslaAmpSetter.Shared.Dtos.Settings; public class Settings : ISettings { @@ -10,7 +12,7 @@ public Settings() } public int? InverterPower { get; set; } - public int Overage { get; set; } + public int? Overage { get; set; } public List Cars {