Skip to content

Conversation

Copilot
Copy link

@Copilot Copilot AI commented Oct 12, 2025

Problem

When the Full-Solar-Passthrough start threshold is configured to be lower than the Battery stop threshold, the inverter continues to draw energy from the battery even after the stop threshold has been reached. This can lead to battery over-discharge and potential damage.

Example misconfiguration:

  • Full-Solar-Passthrough start threshold: 45V
  • Battery stop threshold: 48V

In this scenario, once full solar passthrough activates at 45V, it continues even when the battery voltage drops below 48V (the configured stop threshold), draining the battery beyond safe limits.

Root Cause

In the calcPowerBusUsage() function (src/PowerLimiter.cpp), the full solar passthrough check had higher priority than the battery discharge limit check. The function would return early when full solar passthrough was active, before reaching the code that checks whether battery discharge should be disabled due to the stop threshold:

// Original problematic code flow:
if (isFullSolarPassthroughActive() && solarOutputAc > powerRequested) {
    return solarOutputAc;  // Early return - never checks stop threshold!
}

auto oBatteryDischargeLimit = getBatteryDischargeLimit();  // Too late

Solution

This PR reorders the logic to check the battery discharge limit before making the full solar passthrough decision. When the stop threshold is reached (battery discharge disabled), the system now limits output to only available solar power, preventing battery discharge below the configured threshold:

// Fixed code flow:
auto oBatteryDischargeLimit = getBatteryDischargeLimit();  // Check first

if (isFullSolarPassthroughActive() && solarOutputAc > powerRequested) {
    if (oBatteryDischargeLimit && *oBatteryDischargeLimit == 0) {
        // Stop threshold reached - only use solar power
        return std::min(powerRequested, solarOutputAc);
    }
    // Normal full solar passthrough when battery discharge is allowed
    return solarOutputAc;
}

Changes

  • Modified PowerLimiterClass::calcPowerBusUsage() in src/PowerLimiter.cpp
  • Moved battery discharge limit check before full solar passthrough decision
  • Added logic to respect stop threshold even during full solar passthrough mode
  • Added diagnostic logging for the limited passthrough case

Behavior

Before this fix:

  • Full solar passthrough had absolute priority over stop threshold
  • Battery could discharge below configured stop threshold
  • Potentially dangerous for battery health

After this fix:

  • Stop threshold is always enforced, regardless of full solar passthrough state
  • When stop threshold is reached during full solar passthrough:
    • Only available solar power is used
    • Output is limited to requested power (no battery contribution)
    • Battery is protected from over-discharge
  • Full solar passthrough works normally when battery is above stop threshold
  • Systems without BMS data (nullopt case) continue to work as before

Impact

  • Minimal code changes: Only 17 lines added, 2 removed in a single function
  • No API changes: Internal logic improvement only
  • Backward compatible: Does not affect normal operation scenarios
  • Safety improvement: Protects battery from misconfiguration and over-discharge

Additional Benefits

This fix also improves safety in other scenarios:

  • Cases where SoC calibration drifts over time
  • Mixed voltage/SoC threshold configurations via MQTT
  • Inverter voltage read errors (now handled safely)

Testing

To verify this fix:

  1. Configure Full-Solar-Passthrough start threshold below Battery stop threshold
  2. Monitor battery during discharge cycle
  3. Verify that when stop threshold is reached, only solar power is used and battery discharge stops

Fixes issue where battery continues discharging during full solar passthrough despite stop threshold being reached.

Original prompt

This section details on the original issue you should resolve

<issue_title>Battery-powered inverter. Under special conditions, the inverter does not stop below the stop threshold</issue_title>
<issue_description>### What happened?

Der Inverter zieht weiter Energie aus der Batterie obwohl der Stop Schwelle unterschritten wurde.

To Reproduce Bug

Das passiert dann, wenn der Start-Schwellwert für "Full-Solar-Passthrough" niedriger ist als "Batterienutzung Stop-Schwellwert"

Expected Behavior

Die Abschaltung sollte immer erfolgen wenn der Stop-Schwellwert unterschritten wird.

Install Method

Self-Compiled

What git-hash/version of OpenDTU-OnBattery?

20bdee2

What is your inverter firmware version?

1.0.24

What firmware variant (PIO Environment)?

generic_esp32s3_usb

Relevant log/trace output

Sorry ich habe kein log.

Anything else?

Vielleicht nicht unbedingt ein Bug sondern ein Konfigurationsfehler.
Ich sehe das aber trotzdem problematisch weil:

  • Start / Stop kann in Spannung oder SoC konfiguriert werden
  • Die Werte sind über MQTT veränderbar.
  • Wenn der SoC lange nicht kalibriert wird dann kann man ebenfalls in das Problem rutschen wenn der SoC stark abweicht

Fehlerquelle: In der Funktion calcPowerBusUsage() gibt es einige fast returns und wenn einer greift dann erreicht man die Abschaltung bei auto oBatteryDischargeLimit = getBatteryDischargeLimit(); nicht mehr.

Oder mit anderen Worten: Der "Full-Solar-Passthrough" hat eine höhere Priorität als die "Stop-Schwellwert Abschaltung".

Please confirm the following

  • I believe this issue is a bug that affects all users of OpenDTU-OnBattery, not something specific to my installation.
  • I have already searched for relevant existing issues and discussions before opening this report.
  • I have updated the title field above with a concise description.
  • I have double checked that my inverter does not contain a W in the model name (like HMS-xxxW) as they are not supported.</issue_description>

Comments on the Issue (you are @copilot in this section)

Fixes #2288


💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

Copy link

coderabbitai bot commented Oct 12, 2025

Important

Review skipped

Bot user detected.

To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch copilot/fix-inverter-stop-threshold

Comment @coderabbitai help to get the list of available commands and usage tips.

Copilot AI and others added 2 commits October 12, 2025 07:27
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>
…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>
@Copilot Copilot AI changed the title [WIP] Fix inverter not stopping below the stop threshold Fix: Enforce battery stop threshold during full solar passthrough mode Oct 12, 2025
@Copilot Copilot AI requested a review from AndreasBoehm October 12, 2025 07:34
Copilot finished work on behalf of AndreasBoehm October 12, 2025 07:34
@AndreasBoehm
Copy link
Member

@SW-Niko i did not look into this but do you think that this will fix the issue that you reported?

@SW-Niko
Copy link

SW-Niko commented Oct 12, 2025

@AndreasBoehm I thought I understood how the stop-threshold, solar-passthrough, and full-solar-passthrough work together. Now I'm not sure if I didn't understand the principle or if I didn't understand the code.

The amplifiers are only switched to standby when the function calcPowerBusUsage() delivers 0W.
The fix will now limit the full-solar-passthrough power to the solarpower to avoid drawing energy from the battery.
However, this isn't true if we fall below the stop-threshold.

  • If no solar energy is available at that time, the inverter will shut down
  • But if solar energy is available, the inverter will be limited to solar energy.

I thought we definitely wanted to shut down the inverter when the voltage fell below the stop-threshold, right?

@SW-Niko
Copy link

SW-Niko commented Oct 13, 2025

No, I was wrong ... 😞

I thought we definitely wanted to shut down the inverter when the voltage fell below the stop-threshold, right?

We do not switch off if the solar-passthrough is enabled and we have sufficient solar power. Got it.

Okay, I think I've found a very simple solution. I'll do some testing. Stay tuned.

@SW-Niko
Copy link

SW-Niko commented Oct 17, 2025

Use #2299 and delete this PR

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Battery-powered inverter. Under special conditions, waste of solar energy below the battery start theshold

3 participants