# Modul: Operating Modes (Provozní režimy) ## Koncept EMS a Loxone komunikují přes **provozní režimy** – pojmenované stavy které mají smysl pro obě strany. EMS rozhoduje a přepíná režimy. Loxone dostane kód režimu jako číslo přes Virtual Input a ví jak se v daném režimu chovat **autonomně a nezávisle na EMS**. ``` EMS backend (každou minutu) → HTTP GET /dev/sps/io/EMS_Heartbeat/1 ← pulz do Loxone EMS backend (při přepnutí režimu) → ems.fn_set_mode(site_id, 'SELF_SUSTAIN') ← zapsat do DB → HTTP GET /dev/sps/io/EMS_Mode/2 ← informovat Loxone Loxone (zcela nezávisle na EMS) → sleduje přítomnost EMS_Heartbeat pulzů → pokud 5min žádný pulz → sám přepne na SELF_SUSTAIN → řídí střídač dle aktivního režimu bez čekání na setpointy ``` **Klíčový princip:** Loxone watchdog nečte DB. Sleduje pouze HTTP pulzy přímo. Pokud padne celý server (RPi, Docker, síť) – Loxone to pozná sám a přepne bezpečný režim. Viz `docs/loxone-integration.md` pro kompletní popis Loxone implementace. --- ## Přehled režimů | Kód | Loxone int | EV | TČ | Baterie | Síť | Loxone autonomní | |---|---|---|---|---|---|---| | `AUTO` | 1 | dle plánu | dle plánu | dle plánu | dle plánu | **ne** – čeká na setpointy | | `SELF_SUSTAIN` | 2 | ❌ stop | ❌ stop | vybíjí do domu | bez exportu | **ano** | | `CHARGE_CHEAP` | 3 | ❌ stop | ❌ stop | max nabíjení | import ok | **ne** – EMS posílá výkon | | `PRESERVE` | 4 | ❌ stop | ❌ stop | drží SoC | import ok | **ano** | | `MANUAL` | 0 | ❌ stop | ❌ stop | žádné akce | žádné akce | **ano** | ### `AUTO` Normální provoz. EMS posílá přesné setpointy W každých 15 minut. Loxone je čistý exekutor – přijme číslo a zapíše do střídače. Pokud setpoint nepřijde (výpadek EMS) → Loxone watchdog přepne na `SELF_SUSTAIN`. ### `SELF_SUSTAIN` ← výchozí stav + fallback Aktivuje se: - automaticky watchdogem při výpadku EMS (5min bez pulzu) - manuálně uživatelem z UI (dovolená, odchod z domu) - při prvním startu systému (seed data) Loxone sám bez EMS: - FVE pokrývá spotřebu - baterie vybíjí do domu (ne do sítě) - blokuje export do sítě - zastavuje EV nabíjení a TČ ### `CHARGE_CHEAP` Manuální přepis. EMS posílá max charge setpoint. Použít při levné ceně nebo přetoku FVE ze sousedství (pokud víš o levné ceně dopředu). ### `PRESERVE` Dovolená / servis. Loxone drží baterii na aktuálním SoC, žádné optimalizace. Autonomní – Loxone nevyžaduje setpointy od EMS. ### `MANUAL` Technické práce. Žádná logika neřídí střídač. Pouze pro servis. --- ## Přepínání z UI (React) ``` POST /api/sites/{site_id}/mode { "mode": "SELF_SUSTAIN", "valid_until": null, // nebo "2025-03-15T06:00:00+01:00" pro dočasný přepis "notes": "Odjezd na dovolenou" } ``` Backend při přepnutí: 1. Zavolá `ems.fn_set_mode(site_id, mode, 'user:'+username)` → zápis do DB + log 2. Okamžitě odešle HTTP do Loxone: `/dev/sps/io/EMS_Mode/{loxone_mode_value}` 3. Pokud `CHARGE_CHEAP` nebo návrat na `AUTO` → spustí replanning **Dočasný přepis s automatickým návratem:** `fn_expire_modes()` běží každou minutu a přepíná zpět lokality s prosahlým `valid_until`. --- ## EMS restart / reconnect Při startu backendu: 1. Přečíst z Loxone aktuální `EMS_Mode_Active` (Virtual Output) přes HTTP GET 2. Porovnat s `ems.site_operating_mode` v DB 3. Pokud Loxone přepnul na `SELF_SUSTAIN` během výpadku → logovat, informovat, spustit nový plán 4. Přepnout na `AUTO` a začít posílat setpointy + heartbeat pulzy --- ## Heartbeat v DB – pouze informační Tabulka `ems.site_heartbeat` zaznamenává kdy EMS naposledy úspěšně odeslal pulz do Loxone. Slouží pro EMS dashboard (`vw_site_status.ems_heartbeat_status`) a případný alerting. **Neplní funkci watchdogu** – to je čistě na Loxone straně. ```python # backend/services/control_exporter.py – každou minutu async def send_heartbeat(site_id: int, loxone_endpoint, db): try: await loxone_http.get(f"/dev/sps/io/EMS_Heartbeat/1") await db.execute( "SELECT ems.fn_update_heartbeat($1, 'ok', $2)", site_id, EMS_VERSION ) except Exception as e: logger.error(f"Heartbeat failed for site {site_id}: {e}") await db.execute( "SELECT ems.fn_update_heartbeat($1, 'error', $2)", site_id, EMS_VERSION ) # EMS nemůže nic dělat – Loxone watchdog to vyřeší sám ``` --- ## Otevřené body - [ ] Ověřit Deye Modbus registry pro přepnutí Self-Consumption / Grid-First modu (pro SELF_SUSTAIN) - [ ] Implementace Loxone watchdog – viz `docs/loxone-integration.md` - [ ] Alert notifikace (email / push) pokud `ems_heartbeat_status = 'stale'` déle než 10 minut