Motivation
BatterySystemManager._gather_optimization_data has two branches that both produce a battery plan covering tomorrow, but via separate code:
- Branch A —
if prepare_next_day: — a dedicated pass (cron at 23:55, backend/app.py:323) that builds a standalone full next-day schedule.
- Branch B —
else: (extended horizon) — the regular hourly run, which optimizes today and also extends into tomorrow when tomorrow's prices are available (192-period horizon).
Because they're parallel implementations, fixes applied to one silently miss the other. This has already bitten us twice in the same spot (both fixed in #154):
- Branch A used today's solar forecast; Branch B correctly used
get_solar_forecast_tomorrow().
- Branch A assumed min SOC; Branch B correctly used the real current SOC.
That's the classic "one branch updated, the other forgotten" failure mode.
Proposal
Consolidate the two paths so tomorrow's data (solar, consumption, prices, starting SOC) is sourced through a single shared code path. Options to evaluate:
- Make
prepare_next_day a thin special case of the extended-horizon logic (preferred if Branch B's rolling horizon already subsumes the dedicated next-day pass), or
- Extract the shared "gather tomorrow's inputs" logic into one helper both branches call.
Differences to preserve / decide on
|
Branch A (prepare_next_day) |
Branch B (extended horizon) |
| Trigger |
dedicated 23:55 pass |
every hourly run |
| Start SOC |
(now) real current SOC |
real current SOC |
| Window |
tomorrow only |
now → today (+ tomorrow if prices exist) |
| Past periods |
none (all predicted) |
uses actuals |
The open question is whether Branch A is still needed at all once Branch B reliably extends into tomorrow, or whether it should remain as an explicit "publish tomorrow's plan" trigger that simply reuses Branch B's machinery.
Acceptance
- Tomorrow's inputs (solar/consumption/price/SOC) flow through one code path; no duplicated forecast/SOC sourcing.
- Tests cover both the 23:55 next-day publish and the rolling extended-horizon case.
Related
Motivation
BatterySystemManager._gather_optimization_datahas two branches that both produce a battery plan covering tomorrow, but via separate code:if prepare_next_day:— a dedicated pass (cron at 23:55,backend/app.py:323) that builds a standalone full next-day schedule.else:(extended horizon) — the regular hourly run, which optimizes today and also extends into tomorrow when tomorrow's prices are available (192-period horizon).Because they're parallel implementations, fixes applied to one silently miss the other. This has already bitten us twice in the same spot (both fixed in #154):
get_solar_forecast_tomorrow().That's the classic "one branch updated, the other forgotten" failure mode.
Proposal
Consolidate the two paths so tomorrow's data (solar, consumption, prices, starting SOC) is sourced through a single shared code path. Options to evaluate:
prepare_next_daya thin special case of the extended-horizon logic (preferred if Branch B's rolling horizon already subsumes the dedicated next-day pass), orDifferences to preserve / decide on
prepare_next_day)The open question is whether Branch A is still needed at all once Branch B reliably extends into tomorrow, or whether it should remain as an explicit "publish tomorrow's plan" trigger that simply reuses Branch B's machinery.
Acceptance
Related