feat(battery): plan a periodic full charge of the stationary battery (#1486)

LFP batteries can only recalibrate their state of charge close to full
charge, so many systems expect a full charge every few weeks and some
start one on their own at an arbitrary, possibly expensive time. EOS can
now plan it instead (GENETIC only, off by default).

New battery settings: full_charge_interval_days (unset = off),
full_charge_soc_percentage, full_charge_detect_percentage,
full_charge_allow_grid and the informational cell_chemistry. The last
full charge is read from the measured SoC history; nothing is stored.
When the next one is due within the horizon (or overdue), the maximum
SoC is raised to the target. With full_charge_allow_grid the optimizer
must reach the target once before the deadline, which is at least 24 h
away (penalty battery_full_charge_miss on the best SoC reached), so it
picks the cheapest time itself. Without it, PV surplus may fill the
battery but the target is not enforced.

Signed-off-by: SchaafAlexander <86607129+SchaafAlexander@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
SchaafAlexander
2026-11-08 07:40:13 +01:00
committed by GitHub
co-authored by Claude Opus 5.5
parent b33953d445
commit a06473b6d6
12 changed files with 1085 additions and 6 deletions
+4
View File
@@ -46,6 +46,10 @@ compatibility changes and a short test procedure. These changes are not yet a ta
- Optional size limit for the GENETIC fitness cache: `optimization.genetic.fitness_cache_max_entries`
(`null` = unbounded, the default; `0` = off; N = at most N keys). Bounding it lowers peak memory of
a run by up to ~150 MB on small devices without changing the plan.
- Optional periodic full charge of a stationary battery for GENETIC, e.g. to recalibrate an LFP
battery: `full_charge_interval_days` (unset = off, the default), `full_charge_soc_percentage`,
`full_charge_detect_percentage`, `full_charge_allow_grid` and the informational
`cell_chemistry`. The last full charge is taken from the measured state of charge.
- Optional `general.timezone_override`: an IANA timezone name used as `general.timezone`
instead of the lookup from latitude/longitude. Unset (default), the lookup is unchanged.
- `GET /v1/health` reports `started_at`, the start time of the server process, so a client