services/planning/solver_v2.py: MILP s objective = reálné peníze (cash + degradace − terminal SoC value z DB faktoru). Tvrdá pravidla: bilance, SoC dynamika, breaker (tvrdý), curtail jen A, GEN cutoff binárka, neg-buy/neg-sell export bloky, export z baterie ⇒ arb floor (p.19), zákaz současného imp+exp, EV deadline (placený slack 50 Kč/kWh místo infeasibility), TUV look-ahead, provozní režimy. SQL masky allow_* vědomě ignorovány (heuristika, ne fyzika). solver_v2_eval.py: v2 vs v1 na golden fixtures (SoC-fér): v2 lepší na VŠECH 5 řešitelných (+231.5 Kč ≈ +22 %), extreme_neg_buy den v1=INFEASIBLE → v2 OK (−674.5 Kč). Časy 0.4–10 s (2× na time limitu — TODO). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Ekonomický regresní harness (Fáze 0 — „Čistý plánovač“)
Nástroje pro objektivní měření ekonomiky plánovače a regresní bránu pro jeho dekompozici. Kontext a fáze: viz strategie refaktoru (Fáze 0–4) v paměti projektu / plánu „Čistý plánovač“.
Komponenty
| Soubor | Účel |
|---|---|
extract_fixtures.py |
Stáhne z EMS DB kompletní vstupy plánovače (context + sloty fn_load_planning_slots_full) pro zadanou site a pražský den → JSON fixture do backend/tests/golden/fixtures/. |
economics_report.py |
Pro rozsah dní spočítá skutečný cashflow (audit_interval) vs. oracle LP (perfect hindsight, čistý model bez heuristických penalt) → tabulka GAP per den. |
../../backend/tests/test_golden_replay.py |
Pytest gate: replay fixtures přes solve_dispatch_two_pass, porovnání s golden snapshoty v backend/tests/golden/snapshots/. |
Připojení k DB
Všechny skripty čtou DSN v pořadí --dsn > EMS_DB_DSN > DB_HOST/DB_PORT/
DB_USER/DB_PASSWORD/DB_NAME (default lokální docker 127.0.0.1:5432/ems).
Čtou pouze (SELECT) — bezpečné proti produkci.
export EMS_DB_DSN="postgresql://ems_user:***@10.200.200.1:5432/ems"
Golden replay gate (regresní brána dekompozice)
cd backend
python3 -m pytest tests/test_golden_replay.py -q # ověření (identity refactor → musí projít)
GOLDEN_UPDATE=1 python3 -m pytest tests/test_golden_replay.py -q # vědomá změna chování → regenerace
Pravidla:
- Fáze 1 (dekompozice): snapshoty se NIKDY neregenerují — výstup musí být bitově shodný (floaty zaokrouhleny na 4 d.m.).
- Fáze 2/3 (změny ekonomiky): regenerace snapshotů je povolená pouze s odůvodněním
v commit message a se zlepšeným/nezhoršeným GAPem v
economics_report.py. - Fixtures jsou zmrazené vstupy z reálné DB (konfigurace k datu extrakce, EV sessions
vynulovány,
operating_mode=AUTO) — deterministické, bez DB při běhu testu.
Přidání fixture
python3 scripts/harness/extract_fixtures.py --site-code home-01 --day 2026-06-07 --tag neg_sell_deep
cd backend && GOLDEN_UPDATE=1 python3 -m pytest tests/test_golden_replay.py -q
Pokryté scénáře (v4 fixtures): home-01 hluboký neg-sell (sell −1.57, buy −0.89), home-01 běžný spot den, BA81 běžný den, KV1 fixní nákup. Při změnách heuristik přidávej scénář, který změnu pokrývá.
Ekonomický report (metrika „kolik necháváme na stole“)
python3 scripts/harness/economics_report.py --site-code home-01 --from 2026-05-12 --to 2026-06-09
- actual = skutečný cashflow dne z auditu (import × eff. buy − export × eff. sell),
- oracle = dolní mez: čistý MILP se skutečnou PV/spotřebou/cenami (perfect foresight),
- obojí SoC-adjusted: koncový SoC oceněn průměrnou denní nákupní cenou, aby den „nevyhrával“ vybitím baterie,
- gap = actual − oracle = chyba forecastu + neefektivita dispatche. Oracle je nedosažitelná dolní mez; sleduj TREND gapu (před/po změně plánovače), ne absolutní nulu.
Vyloučeno z obou stran: zelený bonus PV B (nezávislý na dispatch rozhodnutích), přesouvání EV/TČ zátěže (spotřeba je brána jako fixní).
Známý stav k 2026-06-11 (baseline)
tests/test_planning_dispatch_milp.py: 4 ze 124 testů failují už na main (test_future_neg_buy_evening_export_at_high_soc_relaxed_prep,test_grid_charge_respects_import_and_battery_caps,test_morning_exports_pv_when_cushion_ok,test_evening_reserve_soc_near_reserve_after_discharge) — všechny z neg-sell/prep heuristik. Nezakrývat regenerací; vyřešit ve Fázi 1/2.- Golden snapshot home-01 neg-sell dne:
penalty_czk = 2119 Kčpři cashflow −163 Kč — heuristické penalty v objective 13× převažují reálné peníze. To je kvantifikace problému, který Fáze 2/3 odstraňují.