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:
@@ -347,12 +347,33 @@ stav baterie auta → cíl (+kWh), deadline, plánovaná nabíjecí okna s ø ce
|
||||
|
||||
Tvrdý cíl (deadline) = „bez tohohle neodjedu"; měkký cíl = „klidně doplň
|
||||
do 100 %, když je energie skoro zadarmo". Implementace: dekompozice
|
||||
Σ(EV energie) == needed − unmet + opp; `opp ∈ [0, headroom]`
|
||||
(headroom = (100 − target) % kapacity, jen když `asset_vehicle.
|
||||
opportunistic_value_czk_kwh > 0`; default 1 Kč/kWh, 0 = vypnuto).
|
||||
Σ(EV energie) == needed − unmet + opp; `opp ∈ [0, headroom]`.
|
||||
**Headroom = (100 − max(target, soc_at_connect)) % kapacity** (fix paradoxu
|
||||
„nižší target → větší headroom": auto fyzicky bere jen energii nad svým
|
||||
aktuálním SoC). **Hodnota kWh:** `coalesce(ev_session.opportunistic_value_czk_kwh,
|
||||
asset_vehicle.opportunistic_value_czk_kwh)` — V099 přidal per-session override
|
||||
(NULL = zdědit z vozidla, 0 = vypnout pro session ⇒ headroom_wh = 0; patch
|
||||
klíčem `opportunistic_value_czk_kwh` ve `fn_ev_session_apply_patch`, validace ≥ 0).
|
||||
Default vozidla 1 Kč/kWh, 0 = vypnuto.
|
||||
Hodnota = ušetřené BUDOUCÍ nabíjení (auto neumí zpět — žádný noční prodej),
|
||||
proto nízká → uplatní se při záporných cenách / plné domácí baterce
|
||||
(lepší než curtail), běžné ceny ji nezaplatí. Víkendový vzor „pátek
|
||||
nemusím do plna, víkend doplní zadarmo" z toho plyne sám. Dekompozice
|
||||
zároveň stropuje celkovou energii do auta (dřív při buy<0 chyběl strop).
|
||||
Session zůstává v plánu i po dosažení targetu, dokud má headroom.
|
||||
zároveň stropuje celkovou energii do auta (dřív při buy<0 chyběl strop) —
|
||||
a **bez session je EV == 0** (stop-session nevypíná jen tvrdý cíl, ale i
|
||||
oportunismus). Session zůstává v plánu i po dosažení targetu, dokud má headroom;
|
||||
**oportunistická vrstva není omezená deadline** (auto bývá doma dál, odjezd
|
||||
řeší rolling replan — rozhodnutí 2026-06-12).
|
||||
|
||||
### Min. výkon wallboxu a účtování via-bat (2026-06-12, dev)
|
||||
|
||||
- **`asset_ev_charger.min_power_w`** (1380 W = 6 A IEC 61851) jde přes
|
||||
`fn_planning_site_context` do solver_v2: binárka `ev_on[e][t]`,
|
||||
`setpoint ∈ {0} ∪ [min_power_w, max]` — žádné nevykonatelné 400–900 W.
|
||||
- **Tvrdý cíl** sčítá jen sloty **před** deadline (slot začínající v deadline
|
||||
už nepatří „do deadline" — oprava off-by-one).
|
||||
- **`ev_direct ≤ gi + PV`** (fyzikální split; via_bat kryje vybíjení baterie).
|
||||
- **Reporting:** kWh do EV z baterie (via_bat) neplatí slotový buy; solver_v2
|
||||
je oceňuje oportunitní cenou v `planning_interval.battery_arbitrage_czk`
|
||||
(min sell exportního slotu téhož pražského dne, jinak terminal value) a
|
||||
`fn_plan_current_bundle.intervals` nese `ev1/ev2_via_bat_w` pro UI.
|
||||
|
||||
Reference in New Issue
Block a user