Use observed SoC for neg-prep cushion and evening drain (v40).
Some checks failed
CI and deploy / migration-check (push) Failing after 26s
CI and deploy / deploy (push) Has been skipped

Pre-neg forecast cushion and evening push before negative-sell days now use telemetry SoC instead of chaining LP targets across days, so the planner does not stop discharging early when BMS is higher than the model.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Dusan Vojacek
2026-05-29 00:20:05 +02:00
parent a7dff75e58
commit 88df09640c
5 changed files with 306 additions and 34 deletions

View File

@@ -162,6 +162,20 @@ večer 26.5 → vybít bat před neg 27.5 (headroom)
**Ověření:** `NegSellPrepWindowV36Tests`, `solver_params.inputs.pre_neg_cushion_by_day`, `neg_evening_before_neg_slots`.
### 4.6 v40 — pozorované SoC pro neg-prep (Plan 5) ✅
**Tag:** `2026-05-29-neg-prep-observed-soc-v40`
| Problém v36 | Oprava v40 |
|-------------|------------|
| Cushion / večerní výboj z **modelového** SoC (řetězení cílů mezi dny) | **`observed_soc_wh`** z telemetrie; žádné `soc_est := soc_target[first_neg]` |
| BMS výš → plán „už mám headroom“ nevidí | Cushion OK pokud `observed_soc ≥ soc_target[first_neg]` |
| Večerní výboj pod exportuje | Rozpočet `max(0, observed reserve night_baseload_buffer)``neg_evening_push_slots` |
**Kód:** `_pre_neg_pv_export_bundle`, `_neg_evening_discharge_budget_wh`, `_neg_evening_before_neg_push_indices` v `planning_engine.py`.
**Ověření:** `ObservedSocNegPrepTests`; MCP `solver_params.inputs.observed_soc_wh`, `neg_evening_export_budget_wh`, `neg_evening_push_slots`.
---
## 5. Specifikace rampy (v35 — reference)

View File

@@ -50,7 +50,7 @@
**Planner tag v26:** v25 + upřesnění večerního exportu — viz sekce **Večerní export z baterie** níže a changelog v26.
**Planner tag v23:** v22b + **výboj baterie do sítě** před `buy<0` (`_pre_neg_buy_discharge_indices`, sell≥1 Kč/kWh, push `ge_bat` z DB limitů). Viz changelog v23.
V `solve_dispatch` (AUTO): **`charge_slots`** = `allow_charge` z DB + **`buy < 0`** + všechny sloty **`sell < 0`** s PV přebytkem > 500 W (i bez `block_export_on_negative_sell`, BA81). **`pv_charge_shortfall`** / **`NEG_SELL_CURTAIL_PENALTY`** platí v těchto slotech. Při **`sell < 0`** (legacy): safety deficit cílí **`soc_max_wh`**; po posledním **`sell < 0`**: **`post_neg_pv_topup`**. **Planner tag v32:** fázované SoC — viz níže.
- **Záporný výkup — strategie home-01 (v32v36 prep hotovo):** **[`planning-neg-sell-strategy.md`](planning-neg-sell-strategy.md)**. **v35:** rampa B. **v36 prep:** oprava **T**, pre-neg per den (cushion A+B), večer D1 (`2026-05-28-neg-prep-window-v36`). **v36 termika** (TČ/TUV) — otevřeno.
- **Záporný výkup — strategie home-01 (v32v40 prep hotovo):** **[`planning-neg-sell-strategy.md`](planning-neg-sell-strategy.md)**. **v35:** rampa B. **v36 prep:** oprava **T**, pre-neg per den (cushion A+B), večer D1. **v40:** cushion a večerní výboj z **`observed_soc_wh`** (telemetrie), rozpočet `neg_evening_export_budget_wh` (`2026-05-29-neg-prep-observed-soc-v40`). **v36 termika** (TČ/TUV) — otevřeno.
- **Před sell&lt;0 — export FVE s forecast pojistkou (v33):** `_pre_neg_pv_export_forecast_cushion_ok` — export FVE v kladných slotech před prvním `sell<0` jen pokud součet predikovaného PV přebytku v sell&lt;0 okně (týž pražský den) pokryje dobítí na prep SoC (× **1,15**). Jinak LP raději nabíjí z FVE (riziko deště). Při splněné pojistce: `bc_pv=0` v `pre_neg_pv_export_ts`, shortfall na `ge_pv`, penalizace `bc_pv`. `solver_params.inputs.pre_neg_pv_export_forecast_ok`, `pre_neg_pv_export_slots`. Testy `PreNegPvExportForecastTests`. U **fixního tarifu** s polem B: **`ge_pv ≤ pv_b`** (ne pv_store **`ge_pv = 0`**). Při **`deye_gen_microinverter_cutoff_enabled`**: **`ge == 0` jen** pokud **`block_export_on_negative_sell`** (KV1), ne kvůli samotnému `z_gen_cutoff` (BA81 musí moci exportovat B při plné baterii). Vstupní **`soc_wh`** z telemetrie se před MILP omezí přes **`_planner_soc_for_solver`** (rezerva ~650 Wh pod `soc_max`, jinak Infeasible při 100 % SoC a dlouhém záporném výkupu). **`planner_build_tag`** v `solver_params`. Changelog: [`docs/planning-changelog.md`](../planning-changelog.md).
- **Záporná nákupní cena:**
- horní mez `grid_import` zahrnuje `load_baseline_w` + nabíjení/EV/TČ (bez nekonečného importu).