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:
@@ -819,4 +819,30 @@ Plánovač má dvě implementace, přepínané env proměnnými (`backend/app/co
|
||||
front-load v sell<0 (`planner_pv_risk_frontload_czk_kwh`, V090), denní SoC
|
||||
rampa (`safety_soc_target_wh` × `planner_safety_soc_risk_factor`, V091).
|
||||
Detail: hlavička `solver_v2.py` + changelog 2026-06-12.
|
||||
- **EV ve v2 — účtování, headroom, min. výkon (2026-06-12):**
|
||||
- **Deadline boundary:** tvrdý cíl sčítá energii jen ve slotech `t < t_deadline`
|
||||
(první slot s `interval_start >= deadline` už energii dodává po odjezdu —
|
||||
dřívější off-by-one `range(t_dl + 1)` opraven).
|
||||
- **Měkký cíl (oportunismus):** dekompozice `Σ(EV energie) == needed − unmet + opp`;
|
||||
`opp ∈ [0, headroom_wh]`. **Headroom** = `(100 − max(target_soc_pct,
|
||||
soc_at_connect_pct)) % kapacity` (R__039) — „nenabíjet" (nízký target) už
|
||||
paradoxně NEzvětšuje oportunistickou vrstvu; auto fyzicky bere jen nad svým
|
||||
SoC. Hodnota kWh = `coalesce(ev_session.opportunistic_value_czk_kwh,
|
||||
asset_vehicle.opportunistic_value_czk_kwh)` (V099: session override; NULL =
|
||||
zdědit, 0 = vypnout pro session → `headroom_wh = 0`); patch klíčem
|
||||
`opportunistic_value_czk_kwh` v `fn_ev_session_apply_patch` (validace ≥ 0).
|
||||
**Oportunistická vrstva NENÍ omezená deadline** (rozhodnutí 2026-06-12:
|
||||
auto bývá doma dál, odjezd řeší rolling replan). **Bez session je EV == 0**
|
||||
i při `buy < 0` (stop-session; dřív neomezené „pumpování").
|
||||
- **Min. výkon wallboxu:** `asset_ev_charger.min_power_w` (6 A ≈ 1380 W) jde
|
||||
přes `fn_planning_site_context` (vehicles JSON) do binárky `ev_on[e][t]` —
|
||||
setpoint ∈ {0} ∪ [min, max]; konec nevykonatelných 400–900 W setpointů.
|
||||
- **Fyzikální split:** `Σ_e ev_direct[e][t] ≤ gi[t] + pv_a_net + pv_b_eff`
|
||||
(direct jen ze sítě + PV; via_bat kryje `bd`). Ekonomiku nemění, ale split
|
||||
direct/via_bat už není arbitrární.
|
||||
- **Reporting via_bat:** kWh do EV z baterie neplatí slotový buy — solver_v2
|
||||
plní `battery_arbitrage_czk` oportunitní cenou (min `sell` exportního slotu
|
||||
téhož pražského dne, jinak terminal value; clamp ≥ 0) × via_bat energie
|
||||
(dřív konstantní 0). `fn_plan_current_bundle` nese `ev1/ev2_via_bat_w`
|
||||
v `intervals`, aby UI necenilo EV kWh z baterie slotovým buy.
|
||||
- Regresní brána a měření: `scripts/harness/README.md` (golden replay, economics report, penalty audit, `solver_v2_eval.py`); plán refaktoru: `docs/refactor-clean-planner.md`.
|
||||
|
||||
Reference in New Issue
Block a user