Add battery_soc_full_hysteresis to work around inverters that clamp charge current at 100% SoC - #4752
Open
CossieRob wants to merge 1 commit into
Open
Conversation
…harge current at 100% SoC
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Some inverters (reported on Fox and others) drop max charge current to 0A once the battery reaches 100% SoC, and won't accept charge current again until SoC has dropped a few percent (e.g. below 97%). Predbat isn't aware of this, so it can plan and command charging that the inverter silently won't deliver — wasting charge windows and producing an inaccurate forecast. The only current workaround is capping
best_soc_maxbelow 100%, which sacrifices usable capacity.Closes #2513
Fix
Adds
input_number.predbat_battery_soc_full_hysteresis(0–20%, default 0/off, expert mode). When set to match your inverter's behaviour (e.g. 3 for a 97% resume threshold), Predbat tracks whether the battery is within that band below 100% and, while so, both plans and live-controls as if charge current is unavailable — via a single shared choke point,find_charge_rate()inutils.py, used by the simulation, live control, and dashboard display.State is tracked in
PredBat.update_battery_full_hysteresis(), called each cycle, and persists across restarts as an attribute on the existingpredbat.statussensor (same pattern aserror_count).C++ kernel
The fast prediction kernel (
prediction_kernel.cpp) mirrors this with matching logic, andPK_PARITY_REVISION/KERNEL_PARITY_REVISIONare bumped so any stale prebuilt binary falls back safely to the (correct) Python engine until CI rebuilds it.Testing
tests/test_battery_full_hysteresis.py:find_charge_rateclamp behaviour, the state machine (activate/hold/clear/no false-retrigger), restart persistence, and kernel-vs-Python parity for the hysteresis scenario.--quicksuite passes (273/273, one pre-existing unrelated failure intest_enphase_api.pyconfirmed present on a cleanmaintoo).kernel_parity(450+ randomized scenarios) andverify_kernel_binary.pyagainst a locally compiled kernel — all bit-identical to the Python engine.black --check/flake8show no new issues versus a clean checkout.Default is 0 (off), so this is a no-op for everyone until they opt in.