Files
ems/scripts/harness/README.md
Dusan Vojacek 484f1f85fc Fáze 0: ekonomický regresní harness plánovače
- scripts/harness/extract_fixtures.py: extrakce vstupů solveru
  (fn_planning_site_context + fn_load_planning_slots_full) do JSON fixtures
- backend/tests/test_golden_replay.py: golden gate — replay fixtures přes
  solve_dispatch_two_pass, bit-perfektní diff proti snapshotům (GOLDEN_UPDATE=1
  pro vědomou regeneraci); 4 scénáře: home-01 neg-sell extrém / normal, BA81, KV1
- scripts/harness/economics_report.py: actual (audit_interval) vs oracle MILP
  (perfect hindsight, čistá ekonomika bez heuristických penalt), SoC-adjusted

Baseline home-01 2026-05-12..06-09: GAP 2185 Kč / 29 dní (~27 %).
Známý stav: 4/124 testů test_planning_dispatch_milp.py failuje už na main.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-11 10:48:13 +02:00

79 lines
3.9 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. |
| `../../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
```
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í.