feat(planner): EV účtování v2 — headroom fix, deadline boundary, min. výkon WB, via-bat reporting
Hloubková diagnóza EV potvrdila: oportunitní ekonomika via-baterie je v LP
správně, ale okraje lhaly nebo byly nevykonatelné:
- V099 + R__039: ems.ev_session.opportunistic_value_czk_kwh (NULL = zdědit
z asset_vehicle, 0 = vypnout pro session); headroom_wh z max(target_soc,
soc_at_connect) — „nenabíjet" (nízký target) už paradoxně NEzvětšuje
oportunistickou vrstvu; vehicles JSON nese min_power_w wallboxu.
- R__015: patch klíč opportunistic_value_czk_kwh (validace >= 0).
- solver_v2: (a) deadline suma range(t_dl) — slot začínající v deadline už
nepatří „do deadline"; (b) Σ ev_direct <= gi + PV (fyzikální split);
(c) binárka ev_on → setpoint ∈ {0} ∪ [min_power_w, max] (konec 400–900 W
nevykonatelných setpointů); (d) bez session EV == 0 (stop-session i golden
fixtures — žádné pumpování při buy<0); dekompozice total == needed − unmet
+ opp i pro needed = 0; (e) battery_arbitrage_czk = via_bat kWh × oportunitní
cena (min sell exportního slotu téhož pražského dne, jinak terminal value)
místo konstantní 0. Oportunismus PO deadline zůstává POVOLENÝ (rozhodnutí:
auto často doma, odjezd řeší rolling replan).
- R__033: fn_plan_current_bundle.intervals + ev1/ev2_via_bat_w (UI nemá cenit
EV kWh z baterie slotovým buy).
Golden gate beze změny snapshotů (v1 nedotčen, fixtures bez EV sessions);
solver_v2_eval před/po identický (CELKEM −1283.5 Kč, Δ −221.9 vs v1);
tests/test_solver_v2.py +7 testů; plná sada 310 passed / 4 xfailed.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -5,6 +5,45 @@ Formát: **datum (ISO)** · stručný důvod · soubory · chování / ověřen
|
||||
|
||||
---
|
||||
|
||||
## 2026-06-12 — EV účtování v2: headroom, deadline boundary, min. výkon WB, via-bat reporting
|
||||
|
||||
**Problém (hloubková diagnóza EV):** (a) „nenabíjet" (nízký target) oportunismus
|
||||
nevypnul a paradoxně ZVĚTŠIL headroom (= 100 − target); session bez mandátu
|
||||
(nebo žádná session) při `buy < 0` pumpovala energii bez stropu; (b) off-by-one
|
||||
v deadline sumě (`range(t_dl + 1)` — slot začínající v deadline se počítal „do
|
||||
deadline"); (c) reporting lhal: `battery_arbitrage_czk` konstantně 0, via_bat se
|
||||
nepropagoval do bundle, UI cenilo EV kWh z baterie slotovým buy; (d) split
|
||||
ev_direct/via_bat byl arbitrární (direct nesvázán s gi + PV); (e) min. výkon
|
||||
wallboxu (`asset_ev_charger.min_power_w`, 1380 W = 6 A) ignorován → setpointy
|
||||
400–900 W nevykonatelné.
|
||||
|
||||
**Mechanismus:** headroom z `max(target_soc_pct, soc_at_connect_pct)` a
|
||||
opportunistic_value = `coalesce(session, vehicle)` v `fn_planning_site_context`
|
||||
(V099: `ev_session.opportunistic_value_czk_kwh`, NULL = zdědit, 0 = vypnout;
|
||||
patch přes `fn_ev_session_apply_patch`, validace ≥ 0); solver_v2: deadline suma
|
||||
`range(t_dl)`, bez session EV == 0, dekompozice `total == needed − unmet + opp`
|
||||
i pro needed = 0; binárka `ev_on` → setpoint ∈ {0} ∪ [min_power_w, max]
|
||||
(min_power_w nově ve vehicles JSON kontextu); `Σ ev_direct ≤ gi + pv_a_net +
|
||||
pv_b_eff`; `battery_arbitrage_czk` = via_bat kWh × oportunitní cena (min sell
|
||||
exportního slotu téhož pražského dne, jinak terminal value, clamp ≥ 0);
|
||||
`fn_plan_current_bundle.intervals` + `ev1/ev2_via_bat_w`. **Oportunismus PO
|
||||
deadline zůstává POVOLENÝ** (rozhodnutí: auto často doma, odjezd řeší rolling
|
||||
replan). Fixtures: `extract_fixtures.py --keep-ev` (default dál EV nuluje).
|
||||
|
||||
**Soubory:** `V099__ev_session_opportunistic.sql`, `R__039_fn_planning_site_context.sql`,
|
||||
`R__015_fn_ev_session_patch.sql`, `R__033_fn_plan_current_bundle.sql`,
|
||||
`services/planning/solver_v2.py`, `services/planning/db_io.py`,
|
||||
`scripts/harness/extract_fixtures.py` + README, `docs/04-modules/ev-charging.md`,
|
||||
`docs/04-modules/planning.md`.
|
||||
|
||||
**Ověření:** `tests/test_solver_v2.py` +7 (deadline boundary, stop-session,
|
||||
no-session při buy<0, direct ≤ gi+pv, setpoint ∈ {0}∪[1380, max], opp po
|
||||
deadline > 0, battery_arbitrage_czk > 0 u via_bat); golden gate beze změny
|
||||
snapshotů (v1 nedotčen, fixtures bez EV); `solver_v2_eval.py` před/po identický
|
||||
(CELKEM −1283.5 Kč, Δ −221.9 vs v1); plná sada 310 passed / 4 xfailed.
|
||||
|
||||
---
|
||||
|
||||
## 2026-06-12 — idle-skip telemetrie: TUV delta normalizovaná na °C/min
|
||||
|
||||
**Problém:** telemetry_collector nově přeskakuje 1min zápisy idle zařízení
|
||||
|
||||
Reference in New Issue
Block a user