Files
ems/docs/04-modules/pool-pump.md
Dusan Vojacek f70111f44b 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>
2026-06-14 22:00:49 +02:00

3.0 KiB
Raw Blame History

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_pumprated_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_ONhttp_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.