Skip to content

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
springfall2008:mainfrom
CossieRob:battery-soc-full-hysteresis
Open

Add battery_soc_full_hysteresis to work around inverters that clamp charge current at 100% SoC#4752
CossieRob wants to merge 1 commit into
springfall2008:mainfrom
CossieRob:battery-soc-full-hysteresis

Conversation

@CossieRob

Copy link
Copy Markdown

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_max below 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() in utils.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 existing predbat.status sensor (same pattern as error_count).

C++ kernel

The fast prediction kernel (prediction_kernel.cpp) mirrors this with matching logic, and PK_PARITY_REVISION/KERNEL_PARITY_REVISION are bumped so any stale prebuilt binary falls back safely to the (correct) Python engine until CI rebuilds it.

Testing

  • New tests in tests/test_battery_full_hysteresis.py: find_charge_rate clamp behaviour, the state machine (activate/hold/clear/no false-retrigger), restart persistence, and kernel-vs-Python parity for the hysteresis scenario.
  • Full --quick suite passes (273/273, one pre-existing unrelated failure in test_enphase_api.py confirmed present on a clean main too).
  • Rebuilt and ran kernel_parity (450+ randomized scenarios) and verify_kernel_binary.py against a locally compiled kernel — all bit-identical to the Python engine.
  • black --check / flake8 show no new issues versus a clean checkout.

Default is 0 (off), so this is a no-op for everyone until they opt in.

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 max charge hysterisis

1 participant