From fba2cc1b8bd5b1f17199d322b7801ef226e50bea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrick=20K=C3=BChnel?= Date: Sat, 23 Apr 2022 09:56:33 +0200 Subject: [PATCH 01/12] feat(chore): log carState and configService methods --- SmartTeslaAmpSetter/Server/Contracts/IConfigService.cs | 2 +- SmartTeslaAmpSetter/Server/Services/ChargingService.cs | 6 +++++- SmartTeslaAmpSetter/Server/Services/ConfigService.cs | 8 ++++++-- 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/SmartTeslaAmpSetter/Server/Contracts/IConfigService.cs b/SmartTeslaAmpSetter/Server/Contracts/IConfigService.cs index 78d10007b..3d6cc7d8b 100644 --- a/SmartTeslaAmpSetter/Server/Contracts/IConfigService.cs +++ b/SmartTeslaAmpSetter/Server/Contracts/IConfigService.cs @@ -8,7 +8,7 @@ public interface IConfigService { Task GetSettings(); ChargeMode ChangeChargeMode(int carId); - void UpdateCarConfiguration(int id, CarConfiguration carConfiguration); + void UpdateCarConfiguration(int carId, CarConfiguration carConfiguration); List GetCarBasicConfigurations(); void UpdateCarBasicConfiguration(int carId, CarBasicConfiguration carBasicConfiguration); } \ No newline at end of file diff --git a/SmartTeslaAmpSetter/Server/Services/ChargingService.cs b/SmartTeslaAmpSetter/Server/Services/ChargingService.cs index 18e399fc9..cb6cf96ec 100644 --- a/SmartTeslaAmpSetter/Server/Services/ChargingService.cs +++ b/SmartTeslaAmpSetter/Server/Services/ChargingService.cs @@ -65,6 +65,9 @@ public async Task SetNewChargingValues(bool onlyUpdateValues = false) var relevantCars = _settings.Cars.Where(c => relevantCarIds.Any(r => c.Id == r)).ToList(); + _logger.LogTrace("Relevant cars: {@relevantCars}", relevantCars); + _logger.LogTrace("Irrelevant cars: {@irrlevantCars}", irrelevantCars); + foreach (var relevantCar in relevantCars) { relevantCar.CarState.ChargingPowerAtHome = relevantCar.CarState.ChargingPower; @@ -174,7 +177,8 @@ private async Task ChangeCarAmp(Car relevantCar, int ampToRegulate) //Falls MaxPower als Charge Mode: Leistung auf maximal if (relevantCar.CarConfiguration.ChargeMode == ChargeMode.MaxPower || relevantCar.CarState.AutoFullSpeedCharge) { - _logger.LogDebug("Max Power Charging"); + _logger.LogDebug("Max Power Charging: ChargeMode: {chargeMode}, AutoFullSpeedCharge: {autofullspeedCharge}", + relevantCar.CarConfiguration.ChargeMode, relevantCar.CarState.AutoFullSpeedCharge); if (relevantCar.CarState.ChargerActualCurrent < maxAmpPerCar) { var ampToSet = maxAmpPerCar; diff --git a/SmartTeslaAmpSetter/Server/Services/ConfigService.cs b/SmartTeslaAmpSetter/Server/Services/ConfigService.cs index eeda0deb5..4d6578d79 100644 --- a/SmartTeslaAmpSetter/Server/Services/ConfigService.cs +++ b/SmartTeslaAmpSetter/Server/Services/ConfigService.cs @@ -28,20 +28,23 @@ public async Task GetSettings() public ChargeMode ChangeChargeMode(int carId) { + _logger.LogTrace("{method},({param1})", nameof(ChangeChargeMode), carId); var car = _settings.Cars.First(c => c.Id == carId); car.CarConfiguration.ChargeMode = car.CarConfiguration.ChargeMode.Next(); car.CarState.AutoFullSpeedCharge = false; return car.CarConfiguration.ChargeMode; } - public void UpdateCarConfiguration(int id, CarConfiguration carConfiguration) + public void UpdateCarConfiguration(int carId, CarConfiguration carConfiguration) { - var existingCarIndex = _settings.Cars.FindIndex(c => c.Id == id); + _logger.LogTrace("{method}({param1}, {@param2})", nameof(UpdateCarConfiguration), carId, carConfiguration); + var existingCarIndex = _settings.Cars.FindIndex(c => c.Id == carId); _settings.Cars[existingCarIndex].CarConfiguration = carConfiguration; } public List GetCarBasicConfigurations() { + _logger.LogTrace("{method}()", nameof(GetCarBasicConfigurations)); var carSettings = new List(); foreach (var car in _settings.Cars) @@ -59,6 +62,7 @@ public List GetCarBasicConfigurations() public void UpdateCarBasicConfiguration(int carId, CarBasicConfiguration carBasicConfiguration) { + _logger.LogTrace("{method}({param1}, {@param2})", carId, carBasicConfiguration); var car = _settings.Cars.First(c => c.Id == carId); car.CarConfiguration.MinimumAmpere = carBasicConfiguration.MinimumAmpere; car.CarConfiguration.MaximumAmpere = carBasicConfiguration.MaximumAmpere; From f177c00815108d0f791d565ff587dee0ad521130 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrick=20K=C3=BChnel?= Date: Sun, 24 Apr 2022 22:38:42 +0200 Subject: [PATCH 02/12] fix(ConfigService): match logging parameters --- SmartTeslaAmpSetter/Server/Services/ConfigService.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SmartTeslaAmpSetter/Server/Services/ConfigService.cs b/SmartTeslaAmpSetter/Server/Services/ConfigService.cs index 4d6578d79..debfca457 100644 --- a/SmartTeslaAmpSetter/Server/Services/ConfigService.cs +++ b/SmartTeslaAmpSetter/Server/Services/ConfigService.cs @@ -62,7 +62,7 @@ public List GetCarBasicConfigurations() public void UpdateCarBasicConfiguration(int carId, CarBasicConfiguration carBasicConfiguration) { - _logger.LogTrace("{method}({param1}, {@param2})", carId, carBasicConfiguration); + _logger.LogTrace("{method}({param1}, {@param2})", nameof(UpdateCarBasicConfiguration), carId, carBasicConfiguration); var car = _settings.Cars.First(c => c.Id == carId); car.CarConfiguration.MinimumAmpere = carBasicConfiguration.MinimumAmpere; car.CarConfiguration.MaximumAmpere = carBasicConfiguration.MaximumAmpere; From 3ee090fc0ec175e1ca817cff330ead4fd4a47bcb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrick=20K=C3=BChnel?= Date: Sun, 24 Apr 2022 23:23:33 +0200 Subject: [PATCH 03/12] fix(GridService): set inverterPower to null if no success status code --- SmartTeslaAmpSetter/Server/Services/GridService.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/SmartTeslaAmpSetter/Server/Services/GridService.cs b/SmartTeslaAmpSetter/Server/Services/GridService.cs index 57eed98ad..95d63bfef 100644 --- a/SmartTeslaAmpSetter/Server/Services/GridService.cs +++ b/SmartTeslaAmpSetter/Server/Services/GridService.cs @@ -58,7 +58,11 @@ public async Task GetCurrentOverage() var response = await httpClient.GetAsync( requestUri) .ConfigureAwait(false); - response.EnsureSuccessStatusCode(); + + if (!response.IsSuccessStatusCode) + { + return null; + } var result = await response.Content.ReadAsStringAsync().ConfigureAwait(false); if (int.TryParse(result, out var overage)) From fb1fa12bbde9c1d9bbceb9b3b3f185eb26347a57 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrick=20K=C3=BChnel?= Date: Sun, 24 Apr 2022 23:32:59 +0200 Subject: [PATCH 04/12] fix(GridService): return null if getting invertervalue unsuccessfull --- SmartTeslaAmpSetter/Server/Services/GridService.cs | 7 ++++++- SmartTeslaAmpSetter/Server/Services/TelegramService.cs | 3 +++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/SmartTeslaAmpSetter/Server/Services/GridService.cs b/SmartTeslaAmpSetter/Server/Services/GridService.cs index 95d63bfef..c81f579b5 100644 --- a/SmartTeslaAmpSetter/Server/Services/GridService.cs +++ b/SmartTeslaAmpSetter/Server/Services/GridService.cs @@ -7,11 +7,13 @@ public class GridService : IGridService { private readonly ILogger _logger; private readonly IConfiguration _configuration; + private readonly ITelegramService _telegramService; - public GridService(ILogger logger, IConfiguration configuration) + public GridService(ILogger logger, IConfiguration configuration, ITelegramService telegramService) { _logger = logger; _configuration = configuration; + _telegramService = telegramService; } public async Task GetCurrentOverage() @@ -61,6 +63,9 @@ public async Task GetCurrentOverage() if (!response.IsSuccessStatusCode) { + _logger.LogWarning("Getting current inverter power did result in statuscode {statusCode} with reason {reasonPhrase}", response.StatusCode, response.ReasonPhrase); + await _telegramService.SendMessage( + $"Getting current inverter power did result in statuscode {response.StatusCode} with reason {response.ReasonPhrase}"); return null; } var result = await response.Content.ReadAsStringAsync().ConfigureAwait(false); diff --git a/SmartTeslaAmpSetter/Server/Services/TelegramService.cs b/SmartTeslaAmpSetter/Server/Services/TelegramService.cs index 5c831da3a..2344e04a5 100644 --- a/SmartTeslaAmpSetter/Server/Services/TelegramService.cs +++ b/SmartTeslaAmpSetter/Server/Services/TelegramService.cs @@ -33,6 +33,9 @@ public async Task SendMessage(string message) } var requestUri = CreateRequestUri(message, botKey, channel); + + httpClient.Timeout = TimeSpan.FromSeconds(1); + var response = await httpClient.GetAsync( requestUri); From 8626c27d9d30d7d0403f8bede42ffd9c4a6d5ce1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrick=20K=C3=BChnel?= Date: Sun, 24 Apr 2022 23:42:05 +0200 Subject: [PATCH 05/12] fix(ChargingService): go to charging should start tree on minAmps --- SmartTeslaAmpSetter/Server/Services/ChargingService.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SmartTeslaAmpSetter/Server/Services/ChargingService.cs b/SmartTeslaAmpSetter/Server/Services/ChargingService.cs index cb6cf96ec..0d95ee0d1 100644 --- a/SmartTeslaAmpSetter/Server/Services/ChargingService.cs +++ b/SmartTeslaAmpSetter/Server/Services/ChargingService.cs @@ -238,7 +238,7 @@ private async Task ChangeCarAmp(Car relevantCar, int ampToRegulate) UpdateEarliestTimesAfterSwitch(relevantCar.Id); } //Falls nicht ladend, aber laden soll beginnen - else if (finalAmpsToSet > minAmpPerCar && relevantCar.CarState.ChargerActualCurrent == 0) + else if (finalAmpsToSet >= minAmpPerCar && relevantCar.CarState.ChargerActualCurrent == 0) { _logger.LogDebug("Charging should start"); var earliestSwitchOn = EarliestSwitchOn(relevantCar.Id); From 39ca48c8f381c93093cbebb419d608282909f97b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrick=20K=C3=BChnel?= Date: Mon, 25 Apr 2022 19:49:59 +0200 Subject: [PATCH 06/12] feat(README): Update PV only chargemode --- README.md | 2 +- SmartTeslaAmpSetter/Client/Pages/Index.razor | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 924f7bed2..c39097c47 100644 --- a/README.md +++ b/README.md @@ -123,7 +123,7 @@ The current UI can display the car's names including SOC and SOC Limit + one But ### Charge Modes Currently there are three different charge modes available: -1. **PV only**: Only PV energy is used to charge unless there is a min SOC Level set. If so the software tries to start charging with maximum power to reach the desired SOC Level in time +1. **PV only**: Only solar energy is used to charge. You can set a SOC level which should be reached at a specific date and time. If solar energy is not enough to reach the set soc level in time, the car starts charging at full speed. Note: To let this work, you have to specify `usable kWh` in the car settings section. 1. **Maximum Power**: Car charges with maximum available power 1. **Min SoC + PV**: If plugged in the car starts charging with maximum power until set Min SoC is reached. After that only PV Power is used to charge the car. diff --git a/SmartTeslaAmpSetter/Client/Pages/Index.razor b/SmartTeslaAmpSetter/Client/Pages/Index.razor index 774bf0613..26c249215 100644 --- a/SmartTeslaAmpSetter/Client/Pages/Index.razor +++ b/SmartTeslaAmpSetter/Client/Pages/Index.razor @@ -46,12 +46,12 @@ else @if (car.CarConfiguration.ChargeMode == ChargeMode.PvOnly) {

- +

- +

From 984ed3cd9328b6844bba2cc856934acfd9b20e4c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrick=20K=C3=BChnel?= Date: Tue, 26 Apr 2022 00:35:35 +0200 Subject: [PATCH 07/12] fix(CarState): Add updating car state --- SmartTeslaAmpSetter/Server/MqttHelper.cs | 3 +++ SmartTeslaAmpSetter/Shared/Enums/CarState.cs | 1 + 2 files changed, 4 insertions(+) diff --git a/SmartTeslaAmpSetter/Server/MqttHelper.cs b/SmartTeslaAmpSetter/Server/MqttHelper.cs index 50e491a51..b77cbf2c5 100644 --- a/SmartTeslaAmpSetter/Server/MqttHelper.cs +++ b/SmartTeslaAmpSetter/Server/MqttHelper.cs @@ -236,6 +236,9 @@ private void UpdateCar(TeslaMateValue value) case "driving": car.CarState.State = CarState.Driving; break; + case "updating": + car.CarState.State = CarState.Updating; + break; default: _logger.LogWarning("Unknown car state deteckted: {carState}", value.Value); car.CarState.State = CarState.Unknown; diff --git a/SmartTeslaAmpSetter/Shared/Enums/CarState.cs b/SmartTeslaAmpSetter/Shared/Enums/CarState.cs index 20e57e4a5..28dfac9b4 100644 --- a/SmartTeslaAmpSetter/Shared/Enums/CarState.cs +++ b/SmartTeslaAmpSetter/Shared/Enums/CarState.cs @@ -8,5 +8,6 @@ public enum CarState Charging, Suspended, Driving, + Updating, Unknown, } \ No newline at end of file From 12c438f9f0b54c5ab82cb649341b5844a5443f2d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrick=20K=C3=BChnel?= Date: Tue, 26 Apr 2022 20:58:45 +0200 Subject: [PATCH 08/12] feat(GridService): log requestUri and error reason phrase --- SmartTeslaAmpSetter/Server/Services/GridService.cs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/SmartTeslaAmpSetter/Server/Services/GridService.cs b/SmartTeslaAmpSetter/Server/Services/GridService.cs index c81f579b5..2bfe2bdf6 100644 --- a/SmartTeslaAmpSetter/Server/Services/GridService.cs +++ b/SmartTeslaAmpSetter/Server/Services/GridService.cs @@ -21,10 +21,17 @@ public async Task GetCurrentOverage() _logger.LogTrace("{method}()", nameof(GetCurrentOverage)); using var httpClient = new HttpClient(); var requestUri = _configuration.GetValue("CurrentPowerToGridUrl"); + _logger.LogDebug("Using {uri} to get current overage.", requestUri); var response = await httpClient.GetAsync( requestUri) .ConfigureAwait(false); - response.EnsureSuccessStatusCode(); + + if (!response.IsSuccessStatusCode) + { + _logger.LogError("Could not get current overage. {statusCode}, {reasonPhrase}", response.StatusCode, response.ReasonPhrase); + response.EnsureSuccessStatusCode(); + } + var result = await response.Content.ReadAsStringAsync().ConfigureAwait(false); var jsonPattern = _configuration.GetValue("CurrentPowerToGridJsonPattern"); From 7568c3d008d9926e025d63adb79e895e0d185ce4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrick=20K=C3=BChnel?= Date: Sun, 24 Apr 2022 23:07:07 +0200 Subject: [PATCH 09/12] fix(GridService): allow gridvalue to be float --- .../Services/GridService.cs | 26 +++++++++++++++++ .../Server/Services/GridService.cs | 28 +++++++++++++------ 2 files changed, 46 insertions(+), 8 deletions(-) create mode 100644 SmartTeslaAmpSetter.Tests/Services/GridService.cs diff --git a/SmartTeslaAmpSetter.Tests/Services/GridService.cs b/SmartTeslaAmpSetter.Tests/Services/GridService.cs new file mode 100644 index 000000000..f019e85a7 --- /dev/null +++ b/SmartTeslaAmpSetter.Tests/Services/GridService.cs @@ -0,0 +1,26 @@ +using Xunit; +using Xunit.Abstractions; + +namespace SmartTeslaAmpSetter.Tests.Services; + +public class GridService : TestBase +{ + public GridService(ITestOutputHelper outputHelper) + : base(outputHelper) + { + } + + [Theory] + [InlineData("384.8746")] + [InlineData("384")] + [InlineData("384.0")] + [InlineData("384.147")] + public void Can_extract_Integers_From_String(string value) + { + var gridService = Mock.Create(); + var intValue = gridService.GetIntegerFromString(value); + + Assert.Equal(384, intValue); + } + +} \ No newline at end of file diff --git a/SmartTeslaAmpSetter/Server/Services/GridService.cs b/SmartTeslaAmpSetter/Server/Services/GridService.cs index 2bfe2bdf6..ec9f375f6 100644 --- a/SmartTeslaAmpSetter/Server/Services/GridService.cs +++ b/SmartTeslaAmpSetter/Server/Services/GridService.cs @@ -1,4 +1,5 @@ -using Newtonsoft.Json.Linq; +using System.Globalization; +using Newtonsoft.Json.Linq; using SmartTeslaAmpSetter.Server.Contracts; namespace SmartTeslaAmpSetter.Server.Services; @@ -43,16 +44,25 @@ public async Task GetCurrentOverage() throw new InvalidOperationException("Extracted Json Value is null")).Value(); } - if (int.TryParse(result, out var overage)) + try { + var overage = GetIntegerFromString(result); if (_configuration.GetValue("CurrentPowerToGridInvertValue")) { overage = -overage; } - return overage; + return overage ; } + catch (Exception) + { + throw new InvalidCastException($"Could not parse result {result} from uri {requestUri} to integer"); + } + + } - throw new InvalidCastException($"Could not parse result {result} from uri {requestUri} to integer"); + internal int GetIntegerFromString(string? result) + { + return (int) double.Parse(result, CultureInfo.InvariantCulture); } public async Task GetCurrentInverterPower() @@ -77,11 +87,13 @@ await _telegramService.SendMessage( } var result = await response.Content.ReadAsStringAsync().ConfigureAwait(false); - if (int.TryParse(result, out var overage)) + try { - return overage; + return GetIntegerFromString(result); + } + catch (Exception) + { + throw new InvalidCastException($"Could not parse result {result} from uri {requestUri} to integer"); } - - throw new InvalidCastException($"Could not parse result {result} from uri {requestUri} to integer"); } } \ No newline at end of file From 63f90c8d6f7a64510166b7c6c4f6e3d326b33118 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrick=20K=C3=BChnel?= Date: Sun, 24 Apr 2022 23:10:42 +0200 Subject: [PATCH 10/12] feat(CICD): create tag for testing --- .github/workflows/alphaRelease.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/alphaRelease.yml b/.github/workflows/alphaRelease.yml index 362397e14..81892c769 100644 --- a/.github/workflows/alphaRelease.yml +++ b/.github/workflows/alphaRelease.yml @@ -69,4 +69,4 @@ jobs: file: ./Plugins.SmaEnergymeter/Dockerfile platforms: linux/amd64,linux/arm64,linux/arm/v7 push: true - tags: pkuehnel/smartteslaampsettersmaplugin:alpha + tags: pkuehnel/smartteslaampsettersmaplugin:gridFloat From d5f13ac8fc14e838a285330f2c4bc3a75d8c17ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrick=20K=C3=BChnel?= Date: Sun, 24 Apr 2022 23:20:40 +0200 Subject: [PATCH 11/12] feat(CICD): switch back to alpha tag --- .github/workflows/alphaRelease.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/alphaRelease.yml b/.github/workflows/alphaRelease.yml index 81892c769..362397e14 100644 --- a/.github/workflows/alphaRelease.yml +++ b/.github/workflows/alphaRelease.yml @@ -69,4 +69,4 @@ jobs: file: ./Plugins.SmaEnergymeter/Dockerfile platforms: linux/amd64,linux/arm64,linux/arm/v7 push: true - tags: pkuehnel/smartteslaampsettersmaplugin:gridFloat + tags: pkuehnel/smartteslaampsettersmaplugin:alpha From 2486893d9826188298cc6326b81da1e48fa69330 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrick=20K=C3=BChnel?= Date: Tue, 26 Apr 2022 21:03:21 +0200 Subject: [PATCH 12/12] feat(GridService): better logging in string to integer conversion --- SmartTeslaAmpSetter/Server/Services/GridService.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/SmartTeslaAmpSetter/Server/Services/GridService.cs b/SmartTeslaAmpSetter/Server/Services/GridService.cs index ec9f375f6..b94ac379f 100644 --- a/SmartTeslaAmpSetter/Server/Services/GridService.cs +++ b/SmartTeslaAmpSetter/Server/Services/GridService.cs @@ -60,9 +60,10 @@ public async Task GetCurrentOverage() } - internal int GetIntegerFromString(string? result) + internal int GetIntegerFromString(string? inputString) { - return (int) double.Parse(result, CultureInfo.InvariantCulture); + _logger.LogTrace("{method}({param})", nameof(GetIntegerFromString), inputString); + return (int) double.Parse(inputString ?? throw new ArgumentNullException(nameof(inputString)), CultureInfo.InvariantCulture); } public async Task GetCurrentInverterPower()