From 1a3abf1e046161feb2db42a3f827039ff6efffa4 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 12 Oct 2025 07:22:29 +0000 Subject: [PATCH 1/3] Initial plan From bd1d25239a31238ce501d57bb318aeb0ae12bf89 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 12 Oct 2025 07:27:45 +0000 Subject: [PATCH 2/3] Fix: Respect battery stop threshold during full solar passthrough Move battery discharge limit check before full solar passthrough logic to ensure stop threshold is always respected. When battery discharge is disabled due to stop threshold, limit full solar passthrough to requested power only, preventing battery discharge below threshold. Fixes issue where full solar passthrough had higher priority than stop threshold, causing battery to discharge below configured limit. Co-authored-by: AndreasBoehm <1270749+AndreasBoehm@users.noreply.github.com> --- src/PowerLimiter.cpp | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/src/PowerLimiter.cpp b/src/PowerLimiter.cpp index 6a2ccc8d3..87ff67db4 100644 --- a/src/PowerLimiter.cpp +++ b/src/PowerLimiter.cpp @@ -706,14 +706,29 @@ uint16_t PowerLimiterClass::calcPowerBusUsage(uint16_t powerRequested) const auto solarOutputDc = getSolarPassthroughPower(); auto solarOutputAc = dcPowerBusToInverterAc(solarOutputDc); + + auto oBatteryDischargeLimit = getBatteryDischargeLimit(); + if (isFullSolarPassthroughActive() && solarOutputAc > powerRequested) { + // Full solar passthrough is active and solar power exceeds request. + // However, we must still respect the battery discharge limit (stop threshold). + // If battery discharge is disabled, we can only use solar power. + if (!oBatteryDischargeLimit || *oBatteryDischargeLimit == 0) { + // Battery discharge is disabled (stop threshold reached). + // Only use solar power, not more than requested. + uint16_t allowedPower = std::min(powerRequested, solarOutputAc); + DTU_LOGD("using %u W AC from DC power bus (full solar-passthrough, " + "limited by stop threshold), solar power is %u/%u W DC/AC", + allowedPower, solarOutputDc, solarOutputAc); + return allowedPower; + } + DTU_LOGD("using %u/%u W DC/AC from DC power bus (full solar-passthrough)", solarOutputDc, solarOutputAc); return solarOutputAc; } - - auto oBatteryDischargeLimit = getBatteryDischargeLimit(); + if (!oBatteryDischargeLimit) { DTU_LOGD("granting %d W from DC power bus (no battery discharge " "limit), solar power is %u/%u W DC/AC", From 956fb5c4e1ee385f364514de12fed6cc30c4d5a9 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 12 Oct 2025 07:31:02 +0000 Subject: [PATCH 3/3] Refine fix: Only limit full solar passthrough when battery discharge is explicitly disabled Corrected the condition to check if battery discharge limit exists AND is zero, rather than treating nullopt (no BMS data) the same as disabled. When no BMS data is available (nullopt), full solar passthrough behaves normally. Co-authored-by: AndreasBoehm <1270749+AndreasBoehm@users.noreply.github.com> --- src/PowerLimiter.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/PowerLimiter.cpp b/src/PowerLimiter.cpp index 87ff67db4..b7809cb2e 100644 --- a/src/PowerLimiter.cpp +++ b/src/PowerLimiter.cpp @@ -713,7 +713,7 @@ uint16_t PowerLimiterClass::calcPowerBusUsage(uint16_t powerRequested) const // Full solar passthrough is active and solar power exceeds request. // However, we must still respect the battery discharge limit (stop threshold). // If battery discharge is disabled, we can only use solar power. - if (!oBatteryDischargeLimit || *oBatteryDischargeLimit == 0) { + if (oBatteryDischargeLimit && *oBatteryDischargeLimit == 0) { // Battery discharge is disabled (stop threshold reached). // Only use solar power, not more than requested. uint16_t allowedPower = std::min(powerRequested, solarOutputAc);