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>
60 lines
3.0 KiB
Markdown
60 lines
3.0 KiB
Markdown
# 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.
|