From 2c5cd8db49815fc8cac3927ee841cdd8e9edf83a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrick=20K=C3=BChnel?= Date: Sun, 30 Oct 2022 23:26:45 +0100 Subject: [PATCH 1/5] refactor(ModbusUrlCreationComponent): region for properties --- .../Client/Components/ModbusUrlCreationComponent.razor | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/TeslaSolarCharger/Client/Components/ModbusUrlCreationComponent.razor b/TeslaSolarCharger/Client/Components/ModbusUrlCreationComponent.razor index 2ce8b219a..6e6e57c00 100644 --- a/TeslaSolarCharger/Client/Components/ModbusUrlCreationComponent.razor +++ b/TeslaSolarCharger/Client/Components/ModbusUrlCreationComponent.razor @@ -53,6 +53,8 @@

@code { + + #region HelperProperties private string? ModbusUnitIdentifier { get => _modbusUnitIdentifier; @@ -143,6 +145,8 @@ } } + #endregion + private string? _modbusUnitIdentifier; private string? _startingAddress; private string? _quantity; From 340b9055ceaf9c5af59265d9cd05e592ec7b0287 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrick=20K=C3=BChnel?= Date: Sun, 30 Oct 2022 23:35:11 +0100 Subject: [PATCH 2/5] feat(ModbusService): get substring of binary result --- Plugins.Modbus/Contracts/IModbusService.cs | 2 ++ Plugins.Modbus/Controllers/ModbusController.cs | 6 ++++++ Plugins.Modbus/Services/ModbusService.cs | 13 ++++++++++++- 3 files changed, 20 insertions(+), 1 deletion(-) diff --git a/Plugins.Modbus/Contracts/IModbusService.cs b/Plugins.Modbus/Contracts/IModbusService.cs index df4ff9e33..21b736f58 100644 --- a/Plugins.Modbus/Contracts/IModbusService.cs +++ b/Plugins.Modbus/Contracts/IModbusService.cs @@ -9,4 +9,6 @@ Task ReadValue(byte unitIdentifier, ushort startingAddress, ushort qu Task GetBinaryString(byte unitIdentifier, ushort startingAddress, ushort quantity, string ipAddress, int port, int connectDelaySeconds, int timeoutSeconds, ModbusRegisterType modbusRegisterType); + + Task GetBinarySubString(byte unitIdentifier, ushort startingAddress, ushort quantity, string ipAddress, int port, int connectDelaySeconds, int timeoutSeconds, ModbusRegisterType modbusRegisterType, int startIndex, int length); } diff --git a/Plugins.Modbus/Controllers/ModbusController.cs b/Plugins.Modbus/Controllers/ModbusController.cs index fe7e79109..38e50640f 100644 --- a/Plugins.Modbus/Controllers/ModbusController.cs +++ b/Plugins.Modbus/Controllers/ModbusController.cs @@ -15,6 +15,12 @@ public ModbusController(IModbusService modbusService) _modbusService = modbusService; } + [HttpGet] + public Task GetBinarySubString(byte unitIdentifier, ushort startingAddress, ushort quantity, string ipAddress, + int port, int connectDelaySeconds, int timeoutSeconds, ModbusRegisterType modbusRegisterType, int startIndex, int length) + => _modbusService.GetBinarySubString(unitIdentifier, startingAddress, quantity, ipAddress, port, + connectDelaySeconds, timeoutSeconds, modbusRegisterType, startIndex, length); + [HttpGet] public Task GetBinaryString(byte unitIdentifier, ushort startingAddress, ushort quantity, string ipAddress, int port, int connectDelaySeconds, int timeoutSeconds, ModbusRegisterType modbusRegisterType) diff --git a/Plugins.Modbus/Services/ModbusService.cs b/Plugins.Modbus/Services/ModbusService.cs index 846524f82..c70f2969c 100644 --- a/Plugins.Modbus/Services/ModbusService.cs +++ b/Plugins.Modbus/Services/ModbusService.cs @@ -11,6 +11,8 @@ public class ModbusService : IModbusService private readonly IServiceProvider _serviceProvider; private readonly Dictionary _modbusClients = new(); + private readonly string _byteDelimiter = " "; + public ModbusService(ILogger logger, IServiceProvider serviceProvider) { _logger = logger; @@ -102,12 +104,21 @@ public async Task GetBinaryString(byte unitIdentifier, ushort startingAd foreach(var byteString in byteArray) { stringbuilder.Append(Convert.ToString(byteString, 2).PadLeft(8, '0')); - stringbuilder.Append(" "); + stringbuilder.Append(_byteDelimiter); } return stringbuilder.ToString(); } + public async Task GetBinarySubString(byte unitIdentifier, ushort startingAddress, ushort quantity, string ipAddress, int port, int connectDelaySeconds, + int timeoutSeconds, ModbusRegisterType modbusRegisterType, int startIndex, int length) + { + var binaryString = await GetBinaryString(unitIdentifier, startingAddress, quantity, ipAddress, port, connectDelaySeconds, timeoutSeconds, + modbusRegisterType).ConfigureAwait(false); + binaryString = binaryString.Replace(_byteDelimiter, string.Empty); + return binaryString.Substring(startIndex, length); + } + private IModbusClient GetModbusClient(string ipAddressString, int port) { _logger.LogTrace("{method}({ipAddress}, {port})", nameof(GetModbusClient), ipAddressString, port); From 7c80f5f491ddaaed48f0758f06cb4be30b318d4c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrick=20K=C3=BChnel?= Date: Sun, 30 Oct 2022 23:46:31 +0100 Subject: [PATCH 3/5] feat(possibleIssues): add possible solution for no inverter power available --- .../Server/Resources/PossibleIssues/PossibleIssues.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/TeslaSolarCharger/Server/Resources/PossibleIssues/PossibleIssues.cs b/TeslaSolarCharger/Server/Resources/PossibleIssues/PossibleIssues.cs index 13f18a5f7..e8969621b 100644 --- a/TeslaSolarCharger/Server/Resources/PossibleIssues/PossibleIssues.cs +++ b/TeslaSolarCharger/Server/Resources/PossibleIssues/PossibleIssues.cs @@ -47,6 +47,7 @@ public PossibleIssues(IssueKeys issueKeys) { issueKeys.InverterPowerNotAvailable, CreateIssue("Inverter power is not available", IssueType.Warning, + "Does your inverter currently produce energy? Some inverters do not return any value if solar power is not available and you can ignore this issue.", "Are all settings related to inverter power (url, extraction patterns, headers,...) correct?", "Are there any firewall related issues preventing reading the inverter power value?" ) From b3599230fc82fc90214ead18e5213dec319d2065 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrick=20K=C3=BChnel?= Date: Tue, 1 Nov 2022 22:37:11 +0100 Subject: [PATCH 4/5] refactor(Tests): remove unused package --- TeslaSolarCharger.Tests/TeslaSolarCharger.Tests.csproj | 4 ---- 1 file changed, 4 deletions(-) diff --git a/TeslaSolarCharger.Tests/TeslaSolarCharger.Tests.csproj b/TeslaSolarCharger.Tests/TeslaSolarCharger.Tests.csproj index cb00e249b..617cdbd13 100644 --- a/TeslaSolarCharger.Tests/TeslaSolarCharger.Tests.csproj +++ b/TeslaSolarCharger.Tests/TeslaSolarCharger.Tests.csproj @@ -20,10 +20,6 @@ runtime; build; native; contentfiles; analyzers; buildtransitive all - - runtime; build; native; contentfiles; analyzers; buildtransitive - all - From 24f22d6b0bc82636ff588fa563976f2430d44976 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrick=20K=C3=BChnel?= Date: Wed, 2 Nov 2022 00:01:43 +0100 Subject: [PATCH 5/5] feat(PvValueService): allow dynamic inversion of home battery power --- .../Client/Pages/BaseConfiguration.razor | 8 ++++++++ .../Server/Services/PvValueService.cs | 15 +++++++++++++++ .../Shared/Contracts/IConfigurationWrapper.cs | 2 ++ .../BaseConfiguration/BaseConfigurationBase.cs | 2 ++ .../Shared/Wrappers/ConfigurationWrapper.cs | 10 ++++++++++ 5 files changed, 37 insertions(+) diff --git a/TeslaSolarCharger/Client/Pages/BaseConfiguration.razor b/TeslaSolarCharger/Client/Pages/BaseConfiguration.razor index d3df87cb0..448ce670c 100644 --- a/TeslaSolarCharger/Client/Pages/BaseConfiguration.razor +++ b/TeslaSolarCharger/Client/Pages/BaseConfiguration.razor @@ -275,6 +275,14 @@ else +
+ + +
+ Use this if you have to dynamically invert the home battery power. Note: Only 0 and 1 are allowed as response. +
+
+
diff --git a/TeslaSolarCharger/Server/Services/PvValueService.cs b/TeslaSolarCharger/Server/Services/PvValueService.cs index 8cfcdce52..a86af2b92 100644 --- a/TeslaSolarCharger/Server/Services/PvValueService.cs +++ b/TeslaSolarCharger/Server/Services/PvValueService.cs @@ -126,6 +126,21 @@ public async Task UpdatePvValues() var homeBatteryPowerXmlPattern = _configurationWrapper.HomeBatteryPowerXmlPattern(); var homeBatteryPowerCorrectionFactor = (double)_configurationWrapper.HomeBatteryPowerCorrectionFactor(); var homeBatteryPower = await GetValueByHttpResponse(homeBatteryPowerHttpResponse, homeBatteryPowerJsonPattern, homeBatteryPowerXmlPattern, homeBatteryPowerCorrectionFactor).ConfigureAwait(false); + var homeBatteryPowerInversionRequestUrl = _configurationWrapper.HomeBatteryPowerInversionUrl(); + if (!string.IsNullOrEmpty(homeBatteryPowerInversionRequestUrl)) + { + var homeBatteryPowerInversionHeaders = _configurationWrapper.HomeBatteryPowerInversionHeaders(); + //ToDo: implement setting Headers in frontend + var homeBatteryPowerInversionRequest = GenerateHttpRequestMessage(homeBatteryPowerInversionRequestUrl, homeBatteryPowerInversionHeaders); + var homeBatteryPowerInversionHttpResponse = await GetHttpResponse(homeBatteryPowerInversionRequest).ConfigureAwait(false); + var shouldInvertHomeBatteryPowerInt = await GetValueByHttpResponse(homeBatteryPowerInversionHttpResponse, null, null, 1).ConfigureAwait(false); + var shouldInvertHomeBatteryPower = Convert.ToBoolean(shouldInvertHomeBatteryPowerInt); + if (shouldInvertHomeBatteryPower) + { + homeBatteryPower = -homeBatteryPower; + } + } + _settings.HomeBatteryPower = homeBatteryPower; } } diff --git a/TeslaSolarCharger/Shared/Contracts/IConfigurationWrapper.cs b/TeslaSolarCharger/Shared/Contracts/IConfigurationWrapper.cs index 746c1a3cd..4bbccc464 100644 --- a/TeslaSolarCharger/Shared/Contracts/IConfigurationWrapper.cs +++ b/TeslaSolarCharger/Shared/Contracts/IConfigurationWrapper.cs @@ -71,4 +71,6 @@ public interface IConfigurationWrapper Task TryAutoFillUrls(); string? SolarMqttUsername(); string? SolarMqttPassword(); + string? HomeBatteryPowerInversionUrl(); + Dictionary HomeBatteryPowerInversionHeaders(); } diff --git a/TeslaSolarCharger/Shared/Dtos/BaseConfiguration/BaseConfigurationBase.cs b/TeslaSolarCharger/Shared/Dtos/BaseConfiguration/BaseConfigurationBase.cs index 888d5db7c..be90fecbe 100644 --- a/TeslaSolarCharger/Shared/Dtos/BaseConfiguration/BaseConfigurationBase.cs +++ b/TeslaSolarCharger/Shared/Dtos/BaseConfiguration/BaseConfigurationBase.cs @@ -17,7 +17,9 @@ public class BaseConfigurationBase public Dictionary HomeBatterySocHeaders { get; set; } = new(); public string? HomeBatteryPowerMqttTopic { get; set; } public string? HomeBatteryPowerUrl { get; set; } + public string? HomeBatteryPowerInversionUrl { get; set; } public Dictionary HomeBatteryPowerHeaders { get; set; } = new(); + public Dictionary HomeBatteryPowerInversionHeaders { get; set; } = new(); public bool IsModbusGridUrl { get; set; } public bool IsModbusHomeBatterySocUrl { get; set; } public bool IsModbusHomeBatteryPowerUrl { get; set; } diff --git a/TeslaSolarCharger/Shared/Wrappers/ConfigurationWrapper.cs b/TeslaSolarCharger/Shared/Wrappers/ConfigurationWrapper.cs index 1791c8d32..53db19bd2 100644 --- a/TeslaSolarCharger/Shared/Wrappers/ConfigurationWrapper.cs +++ b/TeslaSolarCharger/Shared/Wrappers/ConfigurationWrapper.cs @@ -189,11 +189,21 @@ public Dictionary HomeBatterySocHeaders() return GetBaseConfiguration().HomeBatteryPowerUrl; } + public string? HomeBatteryPowerInversionUrl() + { + return GetBaseConfiguration().HomeBatteryPowerInversionUrl; + } + public Dictionary HomeBatteryPowerHeaders() { return GetBaseConfiguration().HomeBatteryPowerHeaders; } + public Dictionary HomeBatteryPowerInversionHeaders() + { + return GetBaseConfiguration().HomeBatteryPowerInversionHeaders; + } + public string? CurrentPowerToGridJsonPattern() { return GetBaseConfiguration().CurrentPowerToGridJsonPattern;