From a1da3f98420bd7e4fc5bae818a9226cc25c0a606 Mon Sep 17 00:00:00 2001 From: qubeck Date: Sun, 2 Apr 2023 22:13:43 +0200 Subject: [PATCH 1/4] producing DC channel aware artificial increase of applied power limit to mitigate fixed distribution of applied power limit across all channels --- src/PowerLimiter.cpp | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/PowerLimiter.cpp b/src/PowerLimiter.cpp index b9b5b171..93decf9f 100644 --- a/src/PowerLimiter.cpp +++ b/src/PowerLimiter.cpp @@ -223,7 +223,18 @@ void PowerLimiterClass::setNewPowerLimit(std::shared_ptr inver _lastCommandSent = millis(); } MessageOutput.printf("[PowerLimiterClass::loop] Limit Non-Persistent: %d W\r\n", newPowerLimit); - inverter->sendActivePowerControlRequest(Hoymiles.getRadio(), newPowerLimit, PowerLimitControlType::AbsolutNonPersistent); + + std::list dcChnls = inverter->Statistics()->getChannelsByType(TYPE_DC); + int dcProdChnls = 0, dcTotalChnls = dcChnls.size(); + for (auto& c : dcChnls){ + if (inverter->Statistics()->getChannelFieldValue(TYPE_DC, c, FLD_PDC) > 0) + dcProdChnls++; + } + int32_t effPowerLimit = round(newPowerLimit * (float)dcTotalChnls / dcProdChnls); + if (effPowerLimit > config.PowerLimiter_UpperPowerLimit) + effPowerLimit = config.PowerLimiter_UpperPowerLimit; + + inverter->sendActivePowerControlRequest(Hoymiles.getRadio(), effPowerLimit, PowerLimitControlType::AbsolutNonPersistent); _lastRequestedPowerLimit = newPowerLimit; } } From bd57d0f19ae3ec550a7061e901265ec696edf41a Mon Sep 17 00:00:00 2001 From: qubeck Date: Sun, 2 Apr 2023 22:26:44 +0200 Subject: [PATCH 2/4] fixed casting issues --- src/PowerLimiter.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/PowerLimiter.cpp b/src/PowerLimiter.cpp index 93decf9f..54447e66 100644 --- a/src/PowerLimiter.cpp +++ b/src/PowerLimiter.cpp @@ -230,7 +230,7 @@ void PowerLimiterClass::setNewPowerLimit(std::shared_ptr inver if (inverter->Statistics()->getChannelFieldValue(TYPE_DC, c, FLD_PDC) > 0) dcProdChnls++; } - int32_t effPowerLimit = round(newPowerLimit * (float)dcTotalChnls / dcProdChnls); + int32_t effPowerLimit = round(newPowerLimit * static_cast(dcTotalChnls) / dcProdChnls); if (effPowerLimit > config.PowerLimiter_UpperPowerLimit) effPowerLimit = config.PowerLimiter_UpperPowerLimit; From cd4a327671c98971799a1cb5005e09842c82ea9e Mon Sep 17 00:00:00 2001 From: qubeck Date: Tue, 4 Apr 2023 17:11:59 +0200 Subject: [PATCH 3/4] limiting the artificialy increased power limit to inverter maximum power --- src/PowerLimiter.cpp | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/PowerLimiter.cpp b/src/PowerLimiter.cpp index 54447e66..9fd7944b 100644 --- a/src/PowerLimiter.cpp +++ b/src/PowerLimiter.cpp @@ -226,13 +226,16 @@ void PowerLimiterClass::setNewPowerLimit(std::shared_ptr inver std::list dcChnls = inverter->Statistics()->getChannelsByType(TYPE_DC); int dcProdChnls = 0, dcTotalChnls = dcChnls.size(); - for (auto& c : dcChnls){ - if (inverter->Statistics()->getChannelFieldValue(TYPE_DC, c, FLD_PDC) > 0) + for (auto& c : dcChnls) { + if (inverter->Statistics()->getChannelFieldValue(TYPE_DC, c, FLD_PDC) > 0) { dcProdChnls++; + } } int32_t effPowerLimit = round(newPowerLimit * static_cast(dcTotalChnls) / dcProdChnls); - if (effPowerLimit > config.PowerLimiter_UpperPowerLimit) - effPowerLimit = config.PowerLimiter_UpperPowerLimit; + uint16_t inverterMaxPower = inverter->DevInfo()->getMaxPower(); + if (effPowerLimit > inverterMaxPower) { + effPowerLimit = inverterMaxPower; + } inverter->sendActivePowerControlRequest(Hoymiles.getRadio(), effPowerLimit, PowerLimitControlType::AbsolutNonPersistent); _lastRequestedPowerLimit = newPowerLimit; From b79619bf8b05cc11f9ff1fa536e4471e2a839a3a Mon Sep 17 00:00:00 2001 From: qubeck Date: Wed, 12 Apr 2023 20:44:38 +0200 Subject: [PATCH 4/4] add explicit checks to avoid potential div. by zero on application of artificially increased power limit if channel power becomes zero --- src/PowerLimiter.cpp | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/PowerLimiter.cpp b/src/PowerLimiter.cpp index 9fd7944b..b22e7b4a 100644 --- a/src/PowerLimiter.cpp +++ b/src/PowerLimiter.cpp @@ -224,17 +224,20 @@ void PowerLimiterClass::setNewPowerLimit(std::shared_ptr inver } MessageOutput.printf("[PowerLimiterClass::loop] Limit Non-Persistent: %d W\r\n", newPowerLimit); + int32_t effPowerLimit = newPowerLimit; std::list dcChnls = inverter->Statistics()->getChannelsByType(TYPE_DC); int dcProdChnls = 0, dcTotalChnls = dcChnls.size(); for (auto& c : dcChnls) { - if (inverter->Statistics()->getChannelFieldValue(TYPE_DC, c, FLD_PDC) > 0) { + if (inverter->Statistics()->getChannelFieldValue(TYPE_DC, c, FLD_PDC) > 1.0) { dcProdChnls++; } } - int32_t effPowerLimit = round(newPowerLimit * static_cast(dcTotalChnls) / dcProdChnls); - uint16_t inverterMaxPower = inverter->DevInfo()->getMaxPower(); - if (effPowerLimit > inverterMaxPower) { - effPowerLimit = inverterMaxPower; + if (dcProdChnls > 0) { + effPowerLimit = round(newPowerLimit * static_cast(dcTotalChnls) / dcProdChnls); + uint16_t inverterMaxPower = inverter->DevInfo()->getMaxPower(); + if (effPowerLimit > inverterMaxPower) { + effPowerLimit = inverterMaxPower; + } } inverter->sendActivePowerControlRequest(Hoymiles.getRadio(), effPowerLimit, PowerLimitControlType::AbsolutNonPersistent);