Repository navigation
Predbat learns your battery's charge and discharge rates (SoC × temperature rate grids), Predheat Climate Scheduler, Solis and GivTCP fixes
Latest⭐ The big change: Predbat now learns how fast your battery really charges and discharges
Batteries rarely charge or discharge at their full rated rate all the time. Most slow down near full (charging) and near empty (discharging), and many charge more slowly when cold. Cold batteries also start slowing down at a lower SoC: on one install charging began to taper at about 80% SoC at 28°C, about 60% at 20°C, and almost straight away at 12°C. A single charge curve plus a temperature cap cannot describe that.
Predbat now learns two rate grids from your own battery's history, one for charging and one for discharging. Each grid gives the rate your battery actually reaches at each SoC (0-100%) and each battery temperature. The plan then uses the grid row that matches each step's forecast battery temperature. That makes overnight charge plans more accurate, especially in winter: Predbat no longer expects a full charge that the battery won't take, and doesn't buy extra slots it doesn't need.
You can see what was learned on the new Curves page in the web interface (Charts → Curves). It shows each grid in 3D with the last 90 days of evidence as dots, a short table, and a status table. Two new sensors report the same status: binary_sensor.predbat_battery_charge_rate_grid and binary_sensor.predbat_battery_discharge_rate_grid. Each is on while a grid learned from your battery's history is in use.
Full details: Battery rate grids.
How this affects your defaults
Learning is now on for everyone, by default. The new setting battery_rate_grid_auto defaults to True. Before this release the charge curve was only learned and kept up to date if you set battery_charge_power_curve: auto, and the discharge curve was opt-in. Both grids are now learned automatically, and the temperature is part of what is learned.
Your apps.yaml curves become the fallback, not the final word. Setting battery_charge_power_curve, battery_discharge_power_curve (or their _default), battery_temperature_charge_curve or battery_temperature_discharge_curve no longer turns learning off. Where Predbat has evidence from your battery, the learned grid is used. Where it doesn't, your curves still apply. In the cold, below any evidence it has, your temperature curve still caps the rate, and Predbat never assumes a slower rate than it has seen.
- To keep planning only from your own curves, set
battery_rate_grid_auto: Falseinapps.yaml. Evidence is still gathered, so you can compare your curves against it on the Curves page. battery_charge_power_curve: auto/battery_discharge_power_curve: autonow just mean "no manual curve". You can leave them in place or remove them.- Nothing changes straight away. A learned grid is used only once it has at least 20 SoC × temperature cells from at least 3 different days. Until then Predbat plans exactly as before, from your curves or the default.
- At startup Predbat scans up to 28 days of history (
battery_rate_grid_history_days), then rescans the last 2 days once a day (battery_rate_grid_scan_days). - Home Assistant's recorder keeps only 10 days by default (
purge_keep_days), so most installs start from 10 days of history. - Evidence is kept in Predbat's cache for a year, so last winter's cold-weather data is still there for the next cold spell.
- At startup Predbat scans up to 28 days of history (
- It learns only from full-rate charging and forced exports (runs of 15 minutes or more at the maximum rate):
- If you always charge in low-power mode, or rarely export at full rate, there may be little evidence. Your curves then keep being used, as before.
- In Read Only mode no new evidence is gathered.
- Grids need the right history. Learning needs history for
status,charge_rate/discharge_rate,battery_powerandsoc_percentorsoc_kw.- For the temperature part, set
battery_temperature_history. Without it, Predbat learns a single SoC curve with no temperature. - Set
grid_powertoo, so that a forced export that never reached the grid isn't learned as a slow battery.
- For the temperature part, set
- GivTCP users: GivTCP 3.6.13 renamed the battery stack temperature sensor. The old
sensor.givtcp_battery_stack_1_bms_temperaturenow reads 0, and Predbat treats a reading of exactly 0 as missing. Updatebattery_temperatureandbattery_temperature_historytosensor.givtcp_battery_stack_1_battery_temperature(#6203). Predbat now warns when the temperature history has read 0 for 24 hours. - Multi-inverter sites learn from the combined battery, the same way the plan models it.
battery_rate_max_scalingis divided out of what is learned, so changing it later doesn't spoil the grid.
Small planning changes you may notice, even with learning off
- Charge curves now cap a rate in kW, not a share of each path's maximum. On AC charging and forced export (any path at or below your rated rate), the ceiling is the same kW whichever path is used, so a cold battery limited to 1 kW plans at 1 kW on both. On a hybrid inverter's DC charging from PV, whose maximum can be above the rated rate, a learned grid scales with the path, but a manual temperature curve stays an absolute limit. Previously a curve was always a fraction of whichever path's maximum applied, so DC charge plans on hybrids can shift slightly.
battery_temperature_charge_curve/_discharge_curvecan now set degrees up to 30 (previously 20). A curve with no entries above 20 behaves exactly as before.- Cold readings with no 0 entry in your curve: a reading below 1° whose degree isn't set now uses the coldest degree your curve sets. Before, it got no cap at all. A reading of exactly 0 is still treated as possibly missing.
- Plans built from manual curves are unchanged on all our golden debug cases.
There's no need to copy a logged curve into apps.yaml any more. If you tried battery_temperature_charge_curve_auto from a main-branch build, remove it: the rate grids replace it.
What's Changed
New features
- feat(battery): learn charge and discharge rate grids (SoC x battery temperature) by @springfall2008 in #6212
- feat(battery): learn the temperature charge curve, keep auto SoC curves in storage and out of the cold (the groundwork for the rate grids, which replaced its learners) by @springfall2008 in #6189
- Add Climate Scheduler support to Predheat by @graememorgan in #6042
Bug fixes
- fix(balance): keep zero-rate holds, learn a derated peer's real rate, latch cross-charge holds, add a balance sensor and a closed-loop simulator by @springfall2008 in #6194
- fix(solis): don't let an early-armed window cut off the one running in TOU V2 slot 1 (#6210) by @springfall2008 in #6213
- fix(givtcp): GivTCP 3.6.13 renamed the battery stack temperature sensor - update templates/docs and warn on a dead sensor (#6193) by @chalfontchubby in #6203
- fix(givtcp): point battery_temperature_history at the sensor battery_temperature reads (#6193) by @springfall2008 in #6201
Docs
- docs(debug-journal): record the GH#4013 reserve-ratchet fix in PR #6137 by @springfall2008 in #6197
Maintenance
- fix(triage): give deepseek-v4.1-flash:cloud its 1M context window by @springfall2008 in #6215
Full Changelog: v9.7.11...v9.8.0