5.6 KiB
5.6 KiB
name, description
| name | description |
|---|---|
| ems-planner-bug-triage | Triages EMS planner bugs from live Postgres (MCP): degraded Infeasible retry chain, evening export vs battery hold, neg-buy/neg-sell days, fixed-tariff sites (BA81/KV1), failed replan vs stale active plan. Use when the user reports planner errors, wrong evening export, battery held while buy ~5 Kč/kWh, relaxed_neg_prep_window, evening_push_hard_suppressed, or multi-site planner comparison. Complements ems-plan-explain — use this skill for incident/bug classification and fix-branch hints. |
EMS — triáž bugů plánovače
Kdy použít (vs. ems-plan-explain)
| Situace | Skill |
|---|---|
| „Proč v tom slotu nabíjí / neexportuje?“ | ems-plan-explain |
| „Plánovač blbne / neprodává večer / 422 Infeasible / BA81 vs home-01“ | tento skill |
Degradovaný plán (relaxed solve) ale run active |
tento skill |
| Porovnání více lokalit uživatel explicitně jmenoval | tento skill (jinak jedna site) |
Typické spouštěče: neprodává večer, drží baterku @ 5 Kč, nepřeplánovalo po OTE, Solver: Infeasible, evening_push prázdný, sell<0 a výroba do site.
Tvrdá pravidla
- MCP first — server
user-postgres-ems, nástrojquery, jenSELECT. Po chybě: přesný text + VPN/MCP zapnutý. - Selhání plánu není v
planning_run— status je jenactive/superseded/comparison/draft. API 422 a scheduler exception = logy backendu; aktivní run může být starý nebo degradovaný. - Rozliš: plán v DB vs exekuce —
site_operating_mode != AUTO→ rolling replan se přeskakuje (ne nutně solver bug). - Dvě podlahy SoC: export / strategie →
reserve_soc_percent(~20 %); dům v noci (Deye PASSIVE) → může jít kmin_soc_percent(~10 %). Před návrhem večerního vývoje se u exportu domluvreserve, nemin_soc, pokud uživatel neřekne jinak. neg sell≠buy < 0: vyprázdnit předsell < 0(headroom FVE) není totéž co strategie předbuy < 0(levný import).
Checklist triáže
- [ ] site_id (kód / id / výběr ze seznamu — viz ems-plan-explain reference §0)
- [ ] site_operating_mode + poslední řádky site_operating_mode_log
- [ ] active planning_run: id, created_at, run_type, triggered_by, soc_at_replan_wh
- [ ] solver_params.inputs: relaxed_*, evening_push_hard_suppressed, neg_evening_*,
pre_neg_pv_export_forecast_ok, charge_acquisition_buy_czk_kwh
- [ ] Večerní okno: planning_interval (battery/grid setpoint, soc target, ceny)
- [ ] Zítra: neg sloty ve vw_site_effective_price; snap neg_sell_day_pv_usable_wh
- [ ] Klasifikace bug typu A–E (reference.md §1)
- [ ] Návrh fix větve + ověření po fixu
Rozhodovací strom
Replan 422 / žádný nový run po OTE?
├─ mode != AUTO → provozní (MANUAL/SELF_SUSTAIN), plán zastaralý
├─ poslední run any_relaxed + evening_push_hard_suppressed
│ └─ BUG typ A/B: degradovaný solve — Branch 1 + 2
└─ žádný řádek v planning_run → backend log „Infeasible“ (Branch 1)
Večer neprodává, drží vysoké SoC?
├─ evening_push_hard_suppressed = true → tvrdý push vypnutý (Branch 2)
├─ grid import @ drahý buy + vysoké SoC → terminal SoC + pos_sell_pre_neg_buy (Branch 2/5)
├─ zítra buy<0 + vysoká FVE, pre_neg ok = false
│ └─ měl jít večer k reserve, ne držet ~80 % (Branch 2)
└─ fixed tarif + evening_push_ts = [] → v58 / charge-slot-budget (Branch 3)
BA81: sell<0, výroba „do site“ / export?
└─ deye_gen_microinverter_cutoff + pole B — exekuce GEN (Branch 4)
Retry řetězec (solve_dispatch)
Při Infeasible solver postupně zapíná (viz planning_engine.py ~4216):
relaxed_expensive_importrelaxed_neg_buy_chargerelaxed_neg_prep_window→ vypne neg-evening push, kotvy, prep hold;evening_push_hard_suppressed = trueneg_sell_phases_fallback(prep_soc = 100 %)
Symptom degradace: run active, ale ve špičce import ze sítě místo exportu baterie; neg_evening_push_ts prázdné; plán drží SoC nad očekávání před neg dnem.
Výstup pro uživatele (šablona)
- Fakta z DB — run id, čas, mode, 3–5 klíčových flags, 2–3 večerní sloty (W, SoC %, buy/sell).
- Root cause — jedna věta: degradovaný retry / konfigurace site / režim / exekuce.
- Bug typ — A–E z reference.md.
- Doporučená větev opravy — Branch 1–5 + soubor v repu.
- Ověření — MCP dotaz nebo
pytest backend/tests/test_planning_dispatch_milp.py -k "…".
Kód a dokumentace
| Téma | Soubor |
|---|---|
| LP + retry | backend/services/planning_engine.py — solve_dispatch |
evening_push_hard_suppressed |
~2810 |
pos_sell_pre_neg_buy → ge=0 |
~3929 |
| SQL masky | db/routines/R__063_fn_load_planning_slots_full.sql |
| Charge-slot budget (plán) | docs/04-modules/planning-charge-slot-budget.md |
| Changelog v55–v57 | docs/planning-changelog.md |
| Bisect fixture | scripts/diagnose_home01_infeasible.py |
SQL a archetypy site
Anti-patterns
- Diagnostikovat Infeasible bez
solver_params.inputsz posledního úspěšného runu — může být právě ten degradovaný. - Zaměnit „plán neexportuje“ s „exporter neběží“ — v MANUAL/SELF_SUSTAIN se plán nemusí aktualizovat.
- U fixního tarifu očekávat stejné
evening_push_tsjako u home-01 — BA81/KV1 mají jinou větev (viz reference §3).