Files
Dusan Vojacek 1429d402e5
Some checks failed
CI and deploy / migration-check (push) Failing after 13s
CI and deploy / deploy (push) Has been skipped
zdokumentovani noveho pohleud na planovani nabijeni
2026-06-01 19:53:04 +02:00

7.3 KiB
Raw Permalink Blame History

name, description
name description
ems-plan-explain Explains EMS dispatch plans from live Postgres (MCP): why battery/grid/PV/curtailment for a site and time window. If the user does not explicitly name a site (id, code, or unambiguous name), query ems.site (with active plan hint), show a numbered list, and ask which site to use — do not run plan analysis for multiple sites in one turn. Use when the user asks why the plan looks a certain way, planning_interval rows, negative prices, export zero, rolling replan, or says „vysvětli plán“, „proč nabíjí“, „proč škrtí FVE“.

EMS — vysvětlení plánu (živá DB + kontext kódu)

Kdy skill použít

  • Otázky typu proč plán dělá X (nabíjení, export, curtailment, režim, ceny).
  • Uživatel zmíní kód lokality (BA81, …) nebo „aktuální plán“.
  • Porovnání model vs realita (záporná cena, nulový export, pole A/B).

Tvrdá pravidla

  1. Nejdřív data z DB přes MCP (user-postgres-ems, nástroj query, pouze SELECT). Nevysvětlovat konkrétní sloty „z hlavy“ bez dotazu.
  2. Pokud MCP selže: uvést přesnou chybu a praktické kroky (VPN, MCP zapnutý, dostupnost DB).
  3. site_id jen po explicitní volbě uživatele (kód, id, potvrzení jedné řádky), nebo když uživatel lokalitu v dotazu sám pojmenoval. Neuvedená lokalita → nejprve jen dotaz na výběr (viz Krok 1); zakázáno analyzovat plán pro více site v jedné odpovědi „preventivně“.
  4. V odpovědi rozlišit: co říká plán v DB vs co předpokládá LP model vs co omeží hardware (např. taper nabíjení u vysokého SoC dnes v LP není).

Postup (zkopíruj checklist)

- [ ] Zjistit site_id: uživatel ji v dotazu pojmenoval? → případně MCP lookup. Jinak MCP seznam + **zeptat se** (viz Krok 1); až po odpovědi → jedna `site_id`
- [ ] MCP: fn_plan_explain_bundle(site_id, hours) — default hours=6
- [ ] Z JSONu: operating_mode, grid limity, battery limity, intervals_next_window
- [ ] Potřebuji konkrétní čas? → doplnit SELECT na planning_interval (viz reference.md)
- [ ] Vysvětlit bilanci slotu + relevantní LP pravidla (solve_dispatch)

Krok 1 — site_id

Co znamená „lokalita explicitně zmíněná“: v textu uživatele je číselné site_id, kód lokality (BA81, home-01, …), nebo jednoznačný název/fragment, ze kterého MCP vrátí právě jednu řádku ems.site.

  • Pokud uživatel dal site_id jako číslo: ověřit MCP, že řádek v ems.site existuje → použít.
  • Pokud dal kód nebo část názvu (BA81, …): MCP select id, code, name from ems.site where code ilike … or name ilike ….
    • 0 řádků → nabídnout seznam z reference.md §0 (všechny lokality) + zeptat se, kterou myslí.
    • 1 řádek → použít jeho id.
    • Více řádků → číslovaný výpis + zeptat se na jednu (můžeš hintnout kdo má aktivní plán, ale nepouštěj analýzu dřív než výběr).
  • Pokud lokalita vůbec zmíněná není („vysvětli plán“, „proč nabíjí“ bez kódu apod.):
    1. MCP: SQL z reference.md §0 (seřazený seznam site + active_planning_run_id).
    2. V odpovědi uvést číslovaný seznam id | code | name | má aktivní plán?.
    3. Výslovně se zeptat uživatele, kterou lokalitu myslí (číslo z výpisu, code, nebo id).
    4. fn_plan_explain_bundle ani rozšířený SELECT na planning_interval pro tuto otázku nespouštěj, dokud uživatel nevybere jednu lokalitu (kód / číslo řádku / id / jednoznačné „tu s BA81“). Nepředvybírej „beru první řádek“ ani nespouštěj paralelně bundle pro všechny site_id — je to zbytečná zátěž a matoucí výstup.
    5. Je v DB jen jeden záznam ems.site: stejně nejdřív napiš která lokalita to je a zeptej se na krátké potvrzení (např. „Mám plán vysvětlit pro CODE?“ / stačí „ano“) — bez fn_plan_explain_bundle před odpovědí. Výjimku tvoří jen situace, kdy uživatel v téže zprávě současně explicitně odkáže na tuto jedinou lokalitu (pak není „neuvedená“).

Krok 2 — balík pro vysvětlení

select ems.fn_plan_explain_bundle(<site_id>, <hours>);
  • <hours>: default 6. Jiná hodnota jen když uživatel explicitně chce delší/kratší okno.
  • Výstup je jeden JSONB (bundle): viz .cursor/rules/plan-explain-bundle.mdc — které klíče číst.

Krok 3 — interpretace (struktura odpovědi)

Krátce a v pořadí:

  1. Kontext: operating_mode.mode_code, active_planning_run (run_type, triggered_by, soc_at_replan_wh, forecast_correction_factor).
  2. Slot(y): z intervals_next_window nebo z dodatečného SQL — pro každý relevantní interval:
    • Výkon: battery_setpoint_w (+ nabíjení / vybíjení), grid_setpoint_w (+ import / export), load_baseline_w.
    • FVE: pv_a_forecast_solver_w, pv_b_forecast_solver_w, pv_a_curtailed_w (useknuté W na pole A).
    • Ceny: effective_buy_price, effective_sell_price, is_predicted_price.
    • Exekuce Deye (pokud je ve sloupcích): deye_physical_mode, deye_gen_cutoff_enabled.
  3. Proč (odkaz na logiku, ne dlouhá citace):
    • Záporná prodejní cena → export do sítě v LP neekonomický / u části instalací tvrdě 0; přebytek → nabíjení / curtailment A / GEN cutoff (viz solve_dispatch v backend/services/planning_engine.py).
    • Pole B je v modelu nekontrolovatelné — nelze ho pv_a_curtailed omezit.
    • Zelený bonus není v účelové funkci LP; počítá se v auditu (fn_green_bonus_revenue) — viz docs/04-modules/planning.md.
    • ~60 % SoC ve slunci (BA81/KV1) nebo ranní export před sell<0 (home-01): často v58 (bc_pv=0 při sell > min+0,20) nebo v33 pre-neg cushion — plánovaná náhrada: docs/04-modules/planning-charge-slot-budget.md (zatím ne v produkci).
  4. Mezery modelu (upozornit jednou větu, když je to relevantní):
    • LP používá horní strop max_charge_power_w bez závislosti na SoC → u vysokého SoC může reálný proud být nižší než plán.

Kdy se zeptat uživatele

  • Lokalita neuvedená nebo nejednoznačná — vždy nejdřív výběr / potvrzení (viz Krok 1); nikdy hned neanalyzovat všechny lokality najednou.
  • Čas bez časové zóny („v 11:15“) — potvrdit Europe/Prague nebo explicitní offset.
  • Širší horizont než pár hodin — domluvit hours nebo přesné from/to UTC pro doplnkový SELECT.

Další SQL a šablony

reference.md

Anti-patterns

  • Hromadná analýza (fn_plan_explain_bundle, planning_interval pro více site_id) jen proto, že uživatel neřekl kterou lokalitu — vždy se nejprve zeptat.
  • Nevyhledávat plán přes desítky ad-hoc dotazů, když stačí fn_plan_explain_bundle a případně jeden doplnkový SELECT na časové okno.
  • Nezaměňovat pv_a_curtailed_w (plán) s tím, co je vždy zapsané na Modbus — exekuce curtailmentu na Deye může být instalacně závislá; při pochybnostech říct „ověřit v docs/05-todo.md / modbus docs“.