164 lines
6.3 KiB
Markdown
164 lines
6.3 KiB
Markdown
# Modul: Telemetry (Sběr dat ze zařízení)
|
||
|
||
## Co modul dělá
|
||
|
||
- Čte data ze střídače Deye, EV nabíječek Teltonika a tepelného čerpadla Samsung přes Modbus TCP
|
||
- Ukládá surová měření do DB (1min granularita)
|
||
- Detekuje výpadky komunikace a loguje chyby
|
||
- Agreguje 1min data na 15min průměry pro spotřebu, audit a plánování
|
||
|
||
---
|
||
|
||
## Komponenta: `telemetry_collector` (Python service)
|
||
|
||
Samostatná Python služba. Běží jako smyčka, nezávislá na FastAPI.
|
||
|
||
### Polling intervaly
|
||
|
||
| Zařízení | Interval | Důvod |
|
||
|---|---|---|
|
||
| Deye střídač | 60 s | 1min granularita telemetrie |
|
||
| Teltonika EV nabíječka 1 | 60 s | |
|
||
| Teltonika EV nabíječka 2 | 60 s | |
|
||
| Samsung tepelné čerpadlo | 60 s | |
|
||
|
||
### Chování při chybě
|
||
|
||
- Chyba komunikace: záznam se nezapíše, chyba se loguje
|
||
- 3 po sobě jdoucí chyby = alert (log WARNING)
|
||
- 10 po sobě jdoucích chyb = log ERROR + pokus o reconnect
|
||
- Data se neinterpolují – chybějící minuty zůstanou prázdné (audit to pozná)
|
||
|
||
---
|
||
|
||
## Deye SUN-20K – Modbus registry
|
||
|
||
Komunikace: Modbus TCP, Unit ID dle DIP přepínače na střídači (typicky 1).
|
||
|
||
> Mapování v kódu: `backend/services/telemetry_collector.py` (holding registry, decimal adresa = offset pro `read_holding_registers`).
|
||
|
||
| Dec (hex) | Typ | Popis | Jednotka | Poznámka |
|
||
|---|---|---|---|---|
|
||
| 500 (0x01F4) | uint16 | Provozní stav střídače | enum | raw do `run_state`, ladění |
|
||
| 514 (0x0202) | uint16 | Dnešní nabití baterie | Wh | `batt_charge_today_wh` |
|
||
| 515 (0x0203) | uint16 | Dnešní vybití baterie | Wh | `batt_discharge_today_wh` |
|
||
| 588 (0x024C) | uint16 | Battery SoC | % | `battery_soc_percent` |
|
||
| 590 (0x024E) | int16 | Tok výkonu baterie | W | signed: **+ vybíjení, − nabíjení** |
|
||
| 625 (0x0271) | int16 | Výkon sítě | W | signed: **+ import, − export** |
|
||
| 653 (0x028D) | uint16 | Celková spotřeba | W | `load_power_w` |
|
||
| 667 (0x029B) | int16 | Výkon GEN portu (FVE pole B) | W (signed) | `gen_port_power_w`; záporné při zpětném toku / bez výroby — **číst signed** |
|
||
| 672 (0x02A0) | int16 | Výkon PV1 | W (signed) | `pv1_power_w`; při špatném unsigned čtení se záporné hodnoty jeví jako desítky kW |
|
||
| 673 (0x02A1) | int16 | Výkon PV2 | W (signed) | `pv2_power_w` |
|
||
|
||
`pv1_power_w` / `pv2_power_w` / `gen_port_power_w` v DB = **signed W** z Modbus (mohou být záporné).
|
||
|
||
`pv_power_w` = **max(0, PV1) + max(0, PV2) + max(0, GEN)** — okamžitá **kladná** výroba FVE pro dashboard a souhrny; záporné kanály do součtu nepatří (typicky večer při exportu z baterie do sítě).
|
||
|
||
`gen_port_power_w` zůstává uložen samostatně pro audit zeleného bonusu a diagnostiku.
|
||
|
||
**Ověření po změně sběru:** za denního SVitu zkontrolovat, že `pv_power_w` a jednotlivé kanály odpovídají očekávanému max. výkonu instalace (logika: `aggregate_pv_production_w` v `telemetry_collector.py`, unit testy `tests/test_telemetry_pv_signed.py`).
|
||
|
||
**Zápis setpointů (plánování → Deye):**
|
||
|
||
| Registr (hex) | Typ | Popis | Hodnota |
|
||
|---|---|---|---|
|
||
| 0x00F3 | Write Single | Battery charge power limit | W |
|
||
| 0x00F4 | Write Single | Battery discharge power limit | W |
|
||
| 0x00F6 | Write Single | Grid export power limit | W |
|
||
| 0x00F0 | Write Single | Work mode | enum (viz tabulka) |
|
||
|
||
Rychlá kontrola komunikace: `scripts/test_modbus_deye.py`.
|
||
|
||
---
|
||
|
||
## Teltonika TeltoCharge – Modbus registry
|
||
|
||
Komunikace: Modbus TCP přes Waveshare, Unit ID = 1 (ověřit).
|
||
|
||
> Registry doplnit z Teltonika TeltoCharge Modbus dokumentace / Loxone šablony.
|
||
|
||
| Registr | Typ | Popis | Jednotka |
|
||
|---|---|---|---|
|
||
| TBD | Read | Stav konektoru (OCPP status enum) | enum |
|
||
| TBD | Read | Aktuální výkon | W |
|
||
| TBD | Read | Kumulativní energie session | Wh |
|
||
| TBD | Read | Proud L1/L2/L3 | 0.1A |
|
||
| TBD | Read | Napětí | 0.1V |
|
||
| TBD | Read | Session ID | uint |
|
||
| TBD | Read | Error code | uint |
|
||
| TBD | Write | Max proud (charge limit) | A (6–32A) |
|
||
| TBD | Write | Povolení nabíjení (on/off) | bool |
|
||
|
||
---
|
||
|
||
## Samsung tepelné čerpadlo – Modbus registry
|
||
|
||
Komunikace: Modbus TCP přes Waveshare.
|
||
|
||
> Registry doplnit ze Samsung NASA Modbus dokumentace / Loxone šablony.
|
||
|
||
| Registr | Typ | Popis | Jednotka |
|
||
|---|---|---|---|
|
||
| TBD | Read | Venkovní teplota | 0.1°C |
|
||
| TBD | Read | Teplota vody vstup | 0.1°C |
|
||
| TBD | Read | Teplota vody výstup | 0.1°C |
|
||
| TBD | Read | Teplota zásobníku TUV | 0.1°C |
|
||
| TBD | Read | Příkon | W |
|
||
| TBD | Read | Provozní režim | enum |
|
||
| TBD | Read | Alarm kód | uint |
|
||
| TBD | Read | Odmrazování aktivní | bool |
|
||
| TBD | Write | Povolení provozu | bool |
|
||
| TBD | Write | Požadovaná teplota TUV | °C |
|
||
|
||
---
|
||
|
||
## Kód telemetrie (Python)
|
||
|
||
Implementace: `backend/services/telemetry_collector.py` — `poll_inverter()` používá konstanty `DEYE_REG_*` a třídu `ModbusDevice`; hlavní smyčka je `run_telemetry_loop` / `run_telemetry_loop_wrapper`.
|
||
|
||
---
|
||
|
||
## Agregace 1min → 15min
|
||
|
||
Prováděna PostgreSQL funkcí `ems.fn_fill_audit_interval()` a `ems.fn_fill_baseline_consumption()`.
|
||
Spouštěna každých 15 minut jako scheduled task (Python APScheduler nebo pg_cron).
|
||
|
||
```sql
|
||
-- Příklad agregace telemetrie na 15min průměr
|
||
-- (součást fn_fill_audit_interval)
|
||
SELECT
|
||
site_id,
|
||
time_bucket('15 minutes', measured_at) AS interval_start,
|
||
AVG(pv_power_w)::INT AS avg_pv_power_w,
|
||
AVG(battery_power_w)::INT AS avg_battery_power_w,
|
||
AVG(grid_power_w)::INT AS avg_grid_power_w,
|
||
AVG(load_power_w)::INT AS avg_load_power_w,
|
||
LAST(battery_soc_percent, measured_at) AS last_soc_pct
|
||
FROM ems.telemetry_inverter
|
||
WHERE measured_at >= $1 AND measured_at < $1 + INTERVAL '15 minutes'
|
||
AND site_id = $2
|
||
GROUP BY site_id, time_bucket('15 minutes', measured_at);
|
||
```
|
||
|
||
---
|
||
|
||
## Konfigurace (env proměnné)
|
||
|
||
```env
|
||
TELEMETRY_POLL_INTERVAL_SEC=60
|
||
TELEMETRY_ERROR_WARN_THRESHOLD=3 # počet chyb před WARNING logem
|
||
TELEMETRY_ERROR_RECONNECT_THRESHOLD=10
|
||
MODBUS_CONNECT_TIMEOUT_SEC=5
|
||
MODBUS_READ_TIMEOUT_SEC=3
|
||
```
|
||
|
||
---
|
||
|
||
## Otevřené body
|
||
|
||
- [x] Základní mapování Deye (holding registry 500–673) v `telemetry_collector.py`
|
||
- [ ] Doplnit Modbus registry Teltonika z dokumentace / Loxone šablony
|
||
- [ ] Doplnit Modbus registry Samsung z dokumentace / Loxone šablony
|
||
- [ ] Ověřit Unit ID všech zařízení při instalaci
|
||
- [ ] Optimalizovat čtení Deye jako jeden `read_holding_registers` blok místo jednotlivých registrů
|