Files
ems/scripts/harness/README.md
Dusan Vojacek 826c776c34 HU1: realistická studie přechodu na spot (den-po-dni solver_v2, 2 roky OTE)
scripts/harness/hu1_realistic_eval.py — realistická simulace BESS 128 kWh/36 kW
na spotu místo perfect hindsight: D−1 plán přes solve_dispatch_v2 (informační
množina = ceny zítřka z OTE D−1 13:30), SoC řetězené mezi dny, parametry
baterie/grid z DB site 5 (fn_planning_site_context). Scénáře fix/spot ×
bez/s baterií, Kč/den po měsících a sezónách, roční projekce, citlivosti
(degradace 0.15/0.5/1.0, spread compression −30 %), GAP vs 7denní hindsight.
Varianty běží paralelně (ProcessPoolExecutor). HU1 nemá telemetrii →
parametrizovaný průmyslový odběr (konstanty v hlavičce, přepsat čísly
od majitele); fixní cena = proxy BA81 (--fix-buy).

Výsledky (788 dní 2024-04-14…2026-06-12, 2 zimy): D−B (přechod na spot
s baterií) −163,6 tis. Kč/rok base, konzervativně −110,1 tis.; léto −629,
zima −254 Kč/den, nejhorší měsíc (12/2024) −41 Kč/den — stále úspora.
GAP realistic vs hindsight ≈ 0 (ceny jsou D−1 známé) → dřívější horní mez
byla nadhodnocená sezónností, ne neznalostí budoucnosti.

Doc: docs/studies/hu1-spot-realistic.md (generuje skript, opakovatelné);
README harness doplněn.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-12 21:56:03 +02:00

85 lines
4.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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 04) 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. |
| `hu1_realistic_eval.py` | Investiční studie HU1 (hulin-bess): realistická den-po-dni simulace BESS na spotu přes `solve_dispatch_v2` (D1 informační množina, řetězené SoC), scénáře fix/spot × bez/s baterií, citlivosti, GAP vs hindsight; generuje `docs/studies/hu1-spot-realistic.md`. Perfect-hindsight horní mez: `hu1_bess_study.py`. |
| `../../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.
```bash
export EMS_DB_DSN="postgresql://ems_user:***@10.200.200.1:5432/ems"
```
## Golden replay gate (regresní brána dekompozice)
```bash
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
```bash
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
```
`--keep-ev` zmrazí do fixture i otevřené EV sessions z doby extrakce (default je
vynulovat — historické okno bez session). Hodí se pro EV scénáře (deadline,
měkký cíl / oportunistické nabíjení, min. výkon wallboxu); `meta.keep_ev`
ve fixture říká, jak byla pořízena.
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“)
```bash
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í.