Files
ems/.cursor/skills/ems-planner-bug-triage/reference.md
Dusan Vojacek 3161421d5c
Some checks failed
CI and deploy / migration-check (push) Failing after 15s
CI and deploy / deploy (push) Has been skipped
skill pro debug
2026-06-06 22:41:56 +02:00

7.5 KiB
Raw Blame History

EMS planner bug triage — reference (MCP)

Všechno jen read-only SELECT. Server: user-postgres-ems, nástroj query.

Seznam lokalit a fn_plan_explain_bundleems-plan-explain/reference.md.


1) Bug typy (klasifikace)

Typ Popis Typické flags / signály Fix větev
A Degradovaný solve — Infeasible retry krok 3+ any_relaxed_solve, relaxed_neg_prep_window, evening_push_hard_suppressed Branch 1: granulární relaxace + failed-run journal
B Večerní export chybí před neg dnem Vysoké SoC ve špičce, grid_setpoint_w > 0 @ ~5 Kč buy, neg_evening_push_ts prázdné, zítra buy<0 / vysoká FVE Branch 2: neg-večer k reserve_soc
C Fixní tarif — špatné nabíjení / žádný večerní push evening_push_ts: [], SoC ~6080 % ve slunci, v58 bc_pv=0 Branch 3: charge-slot-budget
D Provoz / exekuce, ne LP mode != AUTO, starý active run, ruční MANUAL Návrat do AUTO, ruční replan po fixu
E GEN port / pole B při sell<0 BA81 + deye_gen_microinverter_cutoff, audit export v sell<0 Branch 4: cutoff exekuce

2) MCP — aktivní run + relax flags

Nahraď $site_id (např. 2 = home-01):

select pr.id,
       pr.created_at,
       pr.run_type,
       pr.triggered_by,
       pr.soc_at_replan_wh,
       pr.solver_params->'inputs'->>'any_relaxed_solve' as relaxed,
       pr.solver_params->'inputs'->>'relaxed_expensive_import' as r_exp_import,
       pr.solver_params->'inputs'->>'relaxed_neg_buy_charge' as r_neg_buy,
       pr.solver_params->'inputs'->>'relaxed_neg_prep_window' as r_neg_prep,
       pr.solver_params->'inputs'->>'neg_sell_phases_fallback' as r_phases_off,
       pr.solver_params->'inputs'->>'evening_push_hard_suppressed' as push_suppressed,
       pr.solver_params->'inputs'->>'pre_neg_pv_export_forecast_ok' as pre_neg_ok,
       pr.solver_params->'inputs'->>'neg_evening_push_ts' as neg_eve_push,
       pr.solver_params->'inputs'->>'evening_push_ts' as evening_push,
       pr.solver_params->'inputs'->>'charge_acquisition_buy_czk_kwh' as acq,
       pr.solver_params->'inputs'->>'neg_sell_day_pv_usable_wh' as neg_pv_wh,
       pr.solver_params->>'planner_build_tag' as tag
  from ems.planning_run pr
 where pr.site_id = $site_id
   and pr.status = 'active'
 order by pr.created_at desc
 limit 1;

Poslední běhy (včetně comparison) za 48 h:

select pr.id, pr.status, pr.run_type, pr.created_at,
       pr.solver_params->'inputs'->>'relaxed_neg_prep_window' as r3,
       pr.solver_params->'inputs'->>'evening_push_hard_suppressed' as push_sup
  from ems.planning_run pr
 where pr.site_id = $site_id
   and pr.created_at >= now() - interval '48 hours'
 order by pr.created_at desc
 limit 20;

3) Site archetypy (orientace)

home-01 BA81 KV1
Buy spot fixed ~2,55 NT fixed 5,25
block_export_on_negative_sell false false true
Neg sell fáze 80 % prep default 100 % (off)
deye_gen_microinverter_cutoff false true false
planner_terminal_soc_value_factor 0,9 0,2 0,2
Typický večerní bug A + B (relaxed + drží SoC) C (no evening_push) občas A, jinak OK

Konfigurace z DB:

select s.code,
       smc.purchase_pricing_mode,
       sgc.block_export_on_negative_sell,
       ai.deye_gen_microinverter_cutoff_enabled,
       ab.reserve_soc_percent,
       ab.min_soc_percent,
       ab.planner_neg_sell_prep_soc_percent,
       ab.planner_terminal_soc_value_factor
  from ems.site s
  left join ems.site_market_config smc
    on smc.site_id = s.id and smc.valid_to is null
  left join ems.site_grid_connection sgc on sgc.site_id = s.id
  left join ems.asset_inverter ai
    on ai.site_id = s.id and ai.code = 'deye-main'
  left join ems.asset_battery ab
    on ab.site_id = s.id and ab.code = 'bat-main'
 where s.code in ('home-01', 'BA81', 'KV1');

4) Provozní režim a log

select mode_code from ems.site_operating_mode where site_id = $site_id;

select activated_at at time zone 'Europe/Prague' as ts_prague,
       mode_code,
       activated_by
  from ems.site_operating_mode_log
 where site_id = $site_id
 order by activated_at desc
 limit 8;

Rolling replan běží jen v AUTO.


5) Večerní okno — planning_interval

select pi.interval_start at time zone 'Europe/Prague' as slot_prague,
       pi.battery_setpoint_w,
       pi.grid_setpoint_w,
       pi.battery_soc_target_pct,
       pi.effective_buy_price,
       pi.effective_sell_price
  from ems.planning_interval pi
 where pi.run_id = (
         select id from ems.planning_run
          where site_id = $site_id and status = 'active'
          order by created_at desc limit 1
       )
   and pi.interval_start >= (current_timestamp at time zone 'Europe/Prague')::date
       + interval '17 hours'
   and pi.interval_start < (current_timestamp at time zone 'Europe/Prague')::date
       + interval '1 day' + interval '6 hours'
 order by pi.interval_start;

Červená vlajka: battery_setpoint_w = 0 a grid_setpoint_w > 0 při sell ~3 Kč a SoC > reserve — import místo exportu baterie.


6) Zítřejší neg ceny

select interval_start at time zone 'Europe/Prague' as slot_prague,
       effective_buy_price_czk_kwh as buy,
       effective_sell_price_czk_kwh as sell
  from ems.vw_site_effective_price
 where site_id = $site_id
   and interval_start >= (current_timestamp at time zone 'Europe/Prague')::date
       + interval '1 day'
   and interval_start < (current_timestamp at time zone 'Europe/Prague')::date
       + interval '2 days'
   and (effective_buy_price_czk_kwh < 0 or effective_sell_price_czk_kwh < 0)
 order by interval_start;

7) Slovník solver_params.inputs (výběr)

Klíč Význam
evening_push_hard_suppressed true = bez tvrdého ge_bat push (typicky retry krok 3)
relaxed_neg_prep_window Vypnuty neg-evening kotvy, prep hold, neg evening push
pre_neg_pv_export_forecast_ok Cushion FVE v sell<0 okně — false → nemá exportovat ranní PV před neg
neg_evening_push_ts Sloty D1 večer pro vývoj před neg oknem
charge_acquisition_buy_czk_kwh Účinná cena energie v baterii pro arbitráž exportu
neg_sell_day_pv_usable_wh Forecast Wh do baterie v sell<0 okně zítřka
morning_pre_neg_export_hard Tvrdý ranní export před sell<0

Plný snap: select ems.fn_planning_run_debug(<run_id>);


8) Fix větve (implementační plán v repu)

Branch Obsah Priorita
1 Failed-run journal, bisect Infeasible, granulární relaxace P0
2 home-01 neg-večer → reserve_soc, oddělit push od prep relax P0
3 charge-slot-budget v R__063, BA81/KV1 večerní export P1
4 BA81 GEN cutoff audit P1
5 Dynamický terminal SoC při future neg buy P2

Detail: plán v .cursor/plans/ nebo docs/planning-changelog.md + docs/04-modules/planning-charge-slot-budget.md.


9) Ověření po fixu

pytest backend/tests/test_planning_dispatch_milp.py -k "evening or NegSell or Infeasible"
python scripts/diagnose_home01_infeasible.py

MCP po deployi — nový active run bez relaxed_neg_prep_window nebo s evening_push_hard_suppressed: false a večerní sloty s grid_setpoint_w < 0.