feat(pool): řízení bazénu Phase 1 — nejlevnější okno + dump-load (bez solveru)
fn_pool_schedule_slot: nejlevnější souvislé okno denního runtime budgetu (fn_pool_daily_runtime_min) z vw_site_effective_price + dump-load při sell<=0. fn_pool_control_tick: každých 15 min spočte stav a zařadí POOL_PUMP_ON (jen když existuje signal_route → bezpečné před aktivací). lifespan job pool_control. Shelly přes signal_service, žádné Modbus. Bazál odečet (R__003) se tím stává správným (řízená+plánovaná zátěž). Aktivace provozně: daily_runtime_min=480, schedulable, signal_route. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
59
docs/04-modules/pool-pump.md
Normal file
59
docs/04-modules/pool-pump.md
Normal file
@@ -0,0 +1,59 @@
|
||||
# Bazénové čerpadlo (Shelly) — řízení
|
||||
|
||||
Řízená zátěž: filtrační čerpadlo bazénu přes Shelly Plug S Gen3 (relé). EMS ho
|
||||
spíná podle cen, čte telemetrii a započítává do plánu.
|
||||
|
||||
## Datový model (V087, V092)
|
||||
|
||||
- `ems.asset_pool_pump` — `rated_power_w`, `min_run_min`, `daily_runtime_min`
|
||||
(statický cíl filtrace/den), `schedulable`, `shelly_switch_id`, `endpoint_id`,
|
||||
teplotní parametry: `runtime_base_min`, `runtime_min_per_c`, `runtime_ref_temp_c`,
|
||||
`runtime_min_min`, `runtime_max_min`, `water_temp_sensor_id`.
|
||||
- `ems.telemetry_pool_pump` — 1min: `is_on`, `power_w`, `energy_wh_total` (hypertable).
|
||||
|
||||
## Denní runtime budget — `fn_pool_daily_runtime_min(pump_id)`
|
||||
|
||||
`clamp(runtime_base_min + runtime_min_per_c × (teplota − runtime_ref_temp_c),
|
||||
runtime_min_min, runtime_max_min)` z poslední teploty vody (`telemetry_loxone_sensor`,
|
||||
< 24 h). **Bez čidla** → fallback `daily_runtime_min` (např. 480 = 8 h). Teplotní
|
||||
režim se zapne pouhým napojením `water_temp_sensor_id` — žádný kód navíc.
|
||||
|
||||
## Rozvrh do slotů (Phase 1, bez solveru) — `fn_pool_schedule_slot(pump_id, slot)`
|
||||
|
||||
Vrací ON/OFF pro 15min slot:
|
||||
- **Nejlevnější souvislé okno** délky = runtime budget (z `vw_site_effective_price`,
|
||||
kalendářní den slotu v Europe/Prague, řazeno dle efektivní nákupní ceny). PV/záporné
|
||||
dny → okno padne automaticky přes poledne.
|
||||
- **+ dump-load overlay:** `sell <= 0` (záporná/nulová výkupní cena) → ON i mimo okno
|
||||
(zkonzumuj přebytek místo exportu se ztrátou).
|
||||
- `false` když pump není `schedulable` nebo nejsou ceny pro den.
|
||||
|
||||
## Control smyčka — `fn_pool_control_tick()` + APScheduler
|
||||
|
||||
Job `pool_control` (každých 15 min, hranice slotu, `lifespan.py`) volá
|
||||
`fn_pool_control_tick()` → pro každý aktivní řiditelný bazén spočte
|
||||
`fn_pool_schedule_slot` a **idempotentně** zařadí signál `POOL_PUMP_ON`
|
||||
(`fn_signal_enqueue_bool`) — **jen když existuje `signal_route`** (jinak bezpečně
|
||||
nic). Doručení na Shelly (`Switch.Set`) + readback verify (`Switch.GetStatus`) řeší
|
||||
`signal_service` (každých 15 s). Žádné Modbus.
|
||||
|
||||
## Bazál
|
||||
|
||||
`fn_update_baseline_stats` (R__003) bazén **odečítá** z bazálu — to je správné
|
||||
**jen** když ho zároveň řídíme (řízená + plánovaná zátěž). Bez řízení by to
|
||||
plánovač oslepilo. S tímto řízením je odečet korektní.
|
||||
|
||||
## Aktivace (provozní, per site)
|
||||
|
||||
1. `asset_pool_pump.daily_runtime_min` = cílové minuty (480 = 8 h), `schedulable = true`.
|
||||
2. Seed `signal_route` (`POOL_PUMP_ON` → `http_rest` na Shelly endpoint, `map_bool`
|
||||
true/false → on/off; `verify_config_json` přes `Switch.GetStatus`).
|
||||
3. Ověřit `fn_pool_schedule_slot` vrací rozumné sloty + telemetrii Shelly, pak teprve
|
||||
ostře (control tick enqueueuje až s existující route).
|
||||
|
||||
## Roadmap
|
||||
|
||||
- **Phase 2:** `pool_on[t]` do solveru (`solver_v2`) — co-optimalizace proti
|
||||
baterii/exportu (golden gate). Dump-load pak z živého SoC/PV, ne jen z ceny.
|
||||
- Teplotní čidlo: napojit `water_temp_sensor_id` → runtime se prodlouží/zkrátí dle
|
||||
teploty vody automaticky.
|
||||
Reference in New Issue
Block a user