Files
ems/docs/04-modules/operating-modes.md
Dusan Vojacek d8221e3169
Some checks failed
CI and deploy / migration-check (push) Failing after 15s
CI and deploy / deploy (push) Has been skipped
prekopani SELL
2026-04-19 22:48:51 +02:00

4.3 KiB
Raw Blame History

Provozní režimy EMS

Keep it simple

  • Méně heuristik a pevných wattových práhů v řízení — každá magická konstanta je místo, kde se rodí neshody s plánem a ekonomikou.
  • SELL na Deye používej jen tam, kde produktově opravdu chceme režim „vylít baterii do sítě“ (selling first). Vše ostatní patří do PASSIVE a tok FVE ↔ baterie ↔ síť se řeší reg. 108 / 109 / 142 podle plánu a instalace.
  • Novou logiku vždy ověřit proti reálnému řádku plánu (audit / planning_interval) a typické chybě „plán říká kW, měnič jede na MW“.

Přehled

Mode Solver constraints Deye fyzický režim Baterie
AUTO žádné PASSIVE/SELL/CHARGE dle plánu dle plánu
SELF_SUSTAIN no_export, min_import vždy PASSIVE plné limity
CHARGE_CHEAP no_export, no_discharge CHARGE nabíjení max
PRESERVE no_charge, no_discharge PASSIVE lock (0/0)
MANUAL solver neběží EMS nezapisuje

Implementace: omezení LP v planning_engine.solve_dispatch() podle mode_code z ems.site_operating_mode; zápis Deye v control_exporter.write_inverter_setpoints() (včetně lock_battery u PRESERVE).

Fyzické režimy Deye (výstup control_exporteru)

Detekce v get_deye_mode (battery_w = battery_setpoint_w z plánu, záporné = vybíjení; grid_setpoint_w záporné = export do sítě):

  • CHARGE: battery_w > 500 a grid_setpoint_w > 200 → nabíjení ze sítě; reg. 142 dle CHARGE větve v exporteru, 178 = 48.
  • SELL: grid_setpoint_w < 0 a battery_w < 0 a |battery_w| ≥ |grid_setpoint_w| → záměr vybíjet baterii do sítě (selling first); reg. 142 = 0, 178 = 32, 108 = 0, 109 = max, reg. 143 omezen podle |grid_setpoint_w| (viz control_exporter.py).
  • PASSIVE: vše ostatní — tok FVE a baterie řídí reg. 108 (nabíjení) a 109 (vybíjení, škálované podle |battery_w|), 142 = deye_zero_export_mode, 145 = 1, 178 = 48.

SELF_SUSTAIN: battery_w = None ⇒ v get_deye_mode jako 0 ⇒ typicky PASSIVE; v write_inverter_setpoints při self_sustain_local_use=True108 i 109 = max, reg. 142 = zero export dle DB, TOU SOC = min_soc_percent. PRESERVE: lock_battery108 = 0, 109 = 0.

EMS politiky (nejsou fyzické stavy Deye)

  • PV_SELL_ONLY: AUTO + constraint solveru max_discharge_from_pv
  • BLOCK_EXPORT: AUTO + záporná sell_price → ge[t]=0
  • NEGATIVE_HARVEST: AUTO + záporná buy_price → max charge/load
  • PROTECT: SELF_SUSTAIN s konzervativními limity

Tyto politiky jsou parametrizace AUTO/SELF_SUSTAIN, ne samostatné fyzické stavy.


Loxone a UI (shrnutí)

EMS a Loxone sdílí pojmenované provozní režimy; Loxone dostává číslo režimu přes Virtual Input a může fungovat autonomně (watchdog při výpadku EMS).

POST /api/v1/sites/{site_id}/mode
{
  "mode": "SELF_SUSTAIN",
  "valid_until": null,
  "notes": "…"
}

Backend: ems.fn_set_mode přes run_fn_set_mode_with_discord (při skutečné změně mode_code → Discord, pokud je DISCORD_WEBHOOK_URL) + HTTP na Loxone /dev/sps/io/EMS_Mode/{loxone_mode_value}. Dočasné přepisy s valid_until ruší ems.fn_expire_modes(), která vrací řádky (site_id, site_code, old_mode, new_mode) pro každé přepnutí — scheduler je použije pro stejné Discord upozornění.

Klíčový princip: Loxone watchdog nečte DB sleduje pulzy EMS_Heartbeat. Detail: docs/loxone-integration.md. Detail Modbus / Discord: docs/04-modules/modbus-command-journal.md.

Tabulka režimů (Loxone / zátěže)

Kód Loxone int EV Poznámka
AUTO 1 dle plánu dle plánu setpointy z plánu
SELF_SUSTAIN 2 stop stop fallback / výpadek EMS
CHARGE_CHEAP 3 stop stop max nabíjení ze sítě
PRESERVE 4 stop stop baterie uzamčena (Modbus 0/0)
MANUAL 0 stop stop servis, EMS neexportuje

Otevřené body

  • Doplnit alerty při ems_heartbeat_status = 'stale' (Discord při změně provozního režimu z backendu je popsán v modbus-command-journal.md)