This commit is contained in:
lachtan
2026-09-09 14:40:49 +02:00
parent ca15778d53
commit bda4c2bb82
5 changed files with 185 additions and 0 deletions

58
projects/iot/memory.md Normal file
View File

@@ -0,0 +1,58 @@
- 2026-09-09: Založen projekt iot — zaměření na hardware, IoT a bastlení obecně (ESP32, Raspberry Pi, senzory). Motivace: teplotní senzor v pokoji „chlívek" (okno s holubími hřebí), zájem o ESP32 a RPi na testování. Serverové/Proxmox věci zůstávají v projektu proxmox.
- 2026-09-09: Vytyčeny čtyři témata projektu: 1) znovu zapojit měření teploty/vlhkosti v pokoji „chlívek"; 2) samostatný Proxmox LXC kontejner na MQTT broker; 3) provozovat Home Assistant ve VM na Proxmoxu; 4) otevřená otázka — jak dotáhnout čidla k HA, když jsou fyzicky jinde, hlavně Zigbee a Matter.
- 2026-09-09: Rozhodnutí k Zigbee architektuře: USB dongle v serveru/RPi odmítnut jako nepraktický — čidla jsou na místech bez počítače, RPi tam mít nechce, brána musí být jednoduchá, spolehlivá a okamžitě funkční (žádný boot, žádný maintenance). Směr: Ethernet Zigbee coordinator (SLZB-06 / UZG-01 typ), umístěný strategicky pro rádiový dosah, připojený přes LAN; Zigbee2MQTT + MQTT broker v LXC na Proxmoxu se k němu dostanou po TCP.
- 2026-09-09: Rozšíření rozhodnutí o Zigbee bráně: kladné volby — brána nesmí vyžadovat počítač (RPi ani nic jiného na místě čidel), musí být jednoduchá, okamžitě po power-loss funkční, bez boot procesu a maintenance. Navíc: **WiFi nutně, Ethernet kabel vyřazen jako nepoužitelný v daných místech**. Postavení vlastního routeru/bridge z RPi nechce. Max. zásah = přehrání firmware.
Ověřené kandidáty (network coordinator s WiFi):
1. **SMLIGHT SLZB-06p10 / SLZB-06M** — Zigbee 3.0 coordinator, podporuje Ethernet, USB i **WiFi** v jednom; firmware bez OS, okamžitý start; Z2M připojení `tcp://<ip>:6638`; správa přes vlastní web UI (vč. remote flash). Nejrozšířenější v komunitě, Z2M oficiálně podporuje jako síťový adapter.
2. **SONOFF ZB Bridge Pro (ZBBridge-P)** — WiFi Zigbee brána, **vyžaduje Tasmota flash** (EZSP firmware pro EFR32MG21), poté funguje jako network coordinator pro Z2M (`tcp://ip:8888` přes tasmota ZBBridge režim). Levnější, ale hacknutá cesta — flash přes webový proces, komunitní návody existují (stephengrier.com, haade.fr).
3. **SONOFF ZBDongle-Max (Dongle-Max)** — Zigbee/Thread PoE dongle (EFR32MG24 + ESP32), podporuje Ethernet, WiFi i USB; síťový mód pro Z2M. Novější kus, méně zavedený v Z2M než SLZB-06, ale funguje jako network adapter.
Zdroj: zigbee2mqtt.io (remote adapter how-to), smlight.tech manual, blakadder.com — vyhledáno, částečně ověřeno (Z2M remote adapter stránka potvrzuje síťový mód SONOFF ZBBridge přes Tasmota).
- 2026-09-09: Correction k Zigbee meshu: user opravuje dřívější tvrzení, že se Zigbee síť "doroste" k náplňovým čidlům přes mesh. Teoreticky Zigbee je mesh, ale prakticky to u čidel na CR2032 (a malé) baterky nefunguje — čidlo se probudí jednou za čas, odvysílá naměřené hodnoty, a v tu chvíli většinou nikdo jiný nevysílí (routery spí/nemají co přenášet), takže relay cesta přes mesh zařízení reálně nevzniká. Ověřeno prakticky mnohokrát. **Náplňové čidlo musí mít přímý rádiový dohled na coordinator**, jinak má smolíka (ztracené zprávy, odpojené čidlo). Důsledek pro architekturu: umístění WiFi coordinatoru je ještě kritičtější — musí být fyzicky blízko / v dohledu všech čidel, případně více coordinatorů na více místech (každý s vlastní Z2M instancí).
- 2026-09-09: Volba Zigbee brány: SONOFF ZB Bridge Pro (ZBBridge-P). Důvody: kompaktní provedení, rozumná cena (~29 USD), napájení USB (flexibilní umístění kdekoliv se zásuvkou/USB adaptérem, bez Ethernet kabelu). Přijatý tradeoff: vyžaduje Tasmota flash (EZSP firmware pro EFR32MG21) před použitím jako network coordinator pro Zigbee2MQTT (připojení tcp://ip:8888). Flash je v rámci akceptovaného zásahu (max. přehrání firmware). Odmítnuty: SLZB-06M (dražší, Ethernet-zaměřený tvar), ZBDongle-Max (dražší, PoE dongle tvar).
- 2026-09-09: User potvrzuje: napájení i Tasmota flash si zvládne sám, žádná asistence od agenta při fyzické instalaci není potřeba. Další krok až po fyzickém pořízení ZB Bridge Pro — pak navázat software stack (MQTT LXC, Z2M, HA VM) na Proxmoxu.
- 2026-09-09: Téma: Tuya WiFi čidla. User by je rád používal (levná, dostupná), ale problém: mají natvrdo vypálenou HTTPS adresu (cloud endpoint) — lokálně mluvit s nimi nejde přímo. Čidla jsou battery-powered, připojují se na WiFi jen v krátkých časových úsecích, když právě vysílají (probudí se, pošlou data na Tuya cloud, zase spí). Tím pádem: nelze je směrovat do vlastní sítě a čekat na trvalé spojení; lokální integrace by vyžadovala zachytit komunikaci v okamžiku vysílání (prakticky nespolehlivé) nebo přesměrovat DNS (ale čidlo mluví HTTPS na natvrdo daný endpoint — MITM/TLS pinning problém). Zatím otevřená otázka, jak s nimi pracovat, aniž by data šla do Tuya cloudu.
- 2026-09-09: User vlastní hromadu Tuya čidel, z nich velká část WiFi (historicky vybraná pro nejsnazší zapojení). Tuya aplikace hodnotí jako nahovno, Tuya cloud má omezení počtu API volání (rate limity). Požadavek: vycítání čidel mít plně ve vlastní režii (žádná závislost na Tuya cloudu, žádná API volání). Diskutované cesty: (a) cloud API bridge — nevyhovující, právě kvůli limitům a cloudu; (b) reflash na Tasmota/OpenBK — u WiFi čidel záleží na chipu (Realtek/ESP/Beken), ne vše jde reflashovat, battery čidla navíc vysílají jen krátce; (c) zachytávat Tuya lokální protokol — u battery WiFi čidel nemožné (krátká spojení, HTTPS pinning). Otevřená otázka zůstává: jak dostat existující Tuya WiFi battery čidla do vlastní režie; reálně znamená inventuru — projít jednotlivá čidla, zjistit chipy a určit, která jdou reflashovat, a která jsou mrtvá pro lokální použití.
- 2026-09-09: Vyřazeny cesty k Tuya WiFi čidlům: reflash nereálný — user má většinou novější Tuya čidla (chipy bez komunitní podpory, ne Beken/ESP generace); sniff/MITM zachytávání hodnoceno jako kravina, nedává to smysl jako režie. Zbývá jediné rozvětvení: (a) Tuya cloud API s rozumným pollingem — teplota/vlhkost se mění pomalu, takže limit volání nemusí být reálný problém, pokud se dotazuje např. jednou za 5-15 min a ne po každém čidle zvlášť; nebo (b) postupná náhrada Tuya WiFi battery čidel Zigbee variantami (brána ZB Bridge Pro už je zvolená). Fyzicky: čidla mluví HTTPS na natvrdo vypálený endpoint — data nelze dostat lokálně vůbec, jediná cesta ven je cloud API.
- 2026-09-09: Plan rozšířen o Tuya cloud API včítání: polling s nízkou frekvencí, cílově 10-15 min (user preference max 10-15 min). Data se publikují na MQTT jako u ostatních čidel.
Ověřeno na developer.tuya.com (primární zdroj), že cloud REALNĚ ví, kdy hodnota naposledy přišla:
- GET /v1.0/devices/{device_id} vrací kromě status[] (code/value) také "update_time" (timestamp poslední aktualizace stavu zařízení, sekundy) a "online" flag — stačí z jednoho endpointu.
- GET /v2.0/cloud/thing/{device_id}/report-logs (nebo /v1.0/iot-03/.../report-logs) vrací per-DP logy s "event_time" pro každý kód — přesná historie kdy co došlo, vč. časů jednotlivých reportů.
- Tzn. problém "app ukazuje hodnotu starou týden a neumí říct že neplatí" je řešitelný: náš tuya2mqtt script bude porovnávat update_time/event_time proti aktuálním časem a ke každé hodnotě připojí timestamp posledního reálného reportu (a/nebo flag "stale"), takže HA/možné notifikace můžou detekovat mrtvá čidla.
- 2026-09-09: Upřesnění tuya2mqtt designu: nechat API vrátit update_time pro každé zařízení, držet lokálně poslední známý update_time; pokud se mezi pollly nezměnil, hodnoty se na MQTT nepublikují vůbec (žádný stale flag ve zprávě, žádné opakované posílání stejných dat). MQTT tak zůstane čistý — zpráva = nová data. Detekce mrtvého čidla se pak dělá na straně konzumenta (HA/možný watchdog): absence zprávy na topicu za dlouhý čas = stale/offline; příp. HA MQTT device triggers / last_change sensor. Je to jednodušší a idempotentní, žádné duplikáty v brokeru.
- 2026-09-09: Ověřeno z Tuya primárních zdrojů (developer.tuya.com membership-service + support.tuya.com): IoT Core **Trial Edition** (free, jen pro osobní/debug použití) — basic resource pack = **26 000 API volání / měsíc** (+ 68 000 messages). Po vyčerpání: přístup omezen, Trial neumí overage (nelze dokoupit), obnoví se začátkem dalšího měsíce. Další Trial limity: max 50 zařízení v projektu, max 10 controllable devices, 1 data center, žádný log backtracking. Trial je navíc oficiálně časově omezený (6 měsíců, pak žádost o prodloužení — dle support.tuya.com lze prodloužit opětovnou žádostí). Rate limit navíc per-endpoint (např. ~10 req/s na některé, 500/s celkové API maximum) — pro náš use case irelevantní.
Spotřeba našeho designu: 1 hromadné volání za poll (GET /v1.0/iot-03/devices/status vrací status pro všechny device_id najednou) — při pollu co 15 min = 96 volání/den = ~2 880/měsíc, tj. cca 11 % kvóty. I s per-device report-logs voláními (pokud bychom chtěli event_time per DP) se do 26k vejdeme, ale hromadný status endpoint to pravděpodobně vyřeší i s update_time. Konec vahy: 15-min poll bezpečně v limitu; 10-min poll taky (~4 320/měsíc).
- 2026-09-09: Oprava/uhrazení hromadného status endpointu: GET /v1.0/iot-03/devices/status (Get the latest status of multiple devices) — ověřeno v API reference: vrací POUZE code/value per DP, ŽÁDNÝ timestamp (žádné update_time, žádný event_time). Navíc limit max 20 device_ids per volání. Userova zkušenost tedy potvrzena dokumentací — hromadný endpoint pro náš dedup-design (aktualizace dle update_time) NEVYHOVUJE, protože nevrací čas posledního reportu.
Zpětný dopad na design kvót: musí se volat per-device endpoint, který update_time vrací. Kandidáti:
(a) GET /v1.0/devices/{device_id} (Device Management) — vrací status[] + update_time + online (ověřeno dříve v docs); 1 volání per zařízení.
(b) GET /v2.0/cloud/thing/batch (Query Device Details in Bulk) — nutné ověřit, zda vrací update_time.
(c) GET /v2.0/cloud/thing/{device_id}/report-logs — event_time per DP, ale těžší volání.
Matematika s per-device voláním (a) při N čidlech:
- 10 čidel: poll 15 min = 96 pollů/den × 10 = 960 volání/den ≈ 29k/měsíc — TĚSNĚ PŘES 26k Trial limitem.
- 10 čidel, poll 20 min: 72 × 10 × 30 = 21 600 — pod limitem.
- Závěr: per-device read s update_time na Trial edici vyžaduje poll ≥ ~20 min při 10 čidlech, NEBO batch endpoint (b) pokud vrací update_time (ověřit), NEBO Message Service (push namísto pollingu — 68k messages/měsíc kvóta, nutno prověřit).
Dotaz usera "co znamená +68k zprav": 68 000 messages = kvóta Message Service — push zprávy od Tuya cloudu (device status changes doručené aktivně, ne polling). Zatím neověřeno, zda/v jakém formátu to zahrnuje device status reports; potenciálně řeší celý problém (push místo poll), ale vyžaduje ověření API a vlastní endpoint (MQTT bridge / webhook receiver).
- 2026-09-09: Ověření Tuya Message Service jako skalabilní cesty (místo per-device pollingu): Tuya Message Service používá Apache Pulsar (ne MQTT/HTTP webhook) — po aktivaci subscription na cloud projektu cloud aktivně PUSHuje event data, když se stav zařízení změní (data reporting, offline events, registrace). Klient se připojuje Pulsar SDK/consumerem, cloud doručuje zprávy do fronty, čte se pull-style z Pulsar topicu. Zdroj: developer.tuya.com (Get Messages by Message Queue — device-msg-queue-practice, subscribe-mq, integrate-mq). Klíčové fakty: "If the device status in the project changes, such as registration, data reporting, and offline events, Message Service is used to actively push event data to you with Pulsar" — tedy přesně náš use case, device status reports pushnuté okamžitě po reportu čidla.
Význam pro design: tím pádem NULOVÝ polling nutný pro běžný provoz — čidlo reportuje → cloud pushne zprávu → náš consumer publikuje na MQTT. 68k messages/měsíc Trial kvóta je v pohodě (čidlo reportuje typicky 1-2×/hodinu, 20 čidel = ~1-2k zpráv/den = max ~60k/měsíc, na hraně ale reálně méně, protože ne každý report = nová zpráva pro každé DP). Per-device poll (GET /v1.0/devices/{id}) si necháváme jako bootstrap/fallback (první načtení stavu po restartu, ověření že jsme nezmeškali nic).
Dopad na kvóty: API volání klesnou na minimum (bootstrap + health-check), messages se posunou do 68k kvóty. Skaluje se lineárně s počtem čidel bez nutnosti měnit poll frekvenci.
Otevřené body k doladění: (a) Pulsar consumer běží v našem LXC (Python klient existuje — tuya-iot-pulsar-sdk), (b) formát zprávy obsahuje data + timestamp (nutno ověřit na reálných datech), (c) offline events umožňují detekovat mrtvá čidla pushem, ne pollingem.
- 2026-09-09: User vytýká principiální problém pollingu: čidlo reportuje klidně každou minutu, ale uživatel to v HA vidí až za 20 minut (worst case = poll period). Tohle je přesně argument, proč polling je špatný model pro čidla, která reportují často. Pulsar push (Message Service) to řeší — zpráva dorazí okamžitě po reportu, tedy latence = sekundy, ne minuty. Tímto je designový směr definitivně: PULL (polling) jen jako fallback/bootstrap, primární tok = PUSH (Pulsar). 20-min poll fallback zůstává jako safety net pro případ výpadku consumeru, ale pro data je hlavní cesta push.
- 2026-09-09: DEFINITIVNÍ ZÁVĚR k Tuya WiFi čidlům: architektonický slepý konec. Tuya cloud brutálně omezuje přístup k vlastním datům — kvóty (26k API volání/měsíc, 68k messages), Trial limit 50 zařízení, žádný overage dokup, data nutně přes cizí cloud. Žádná z probraných cest (per-device poll, hromadný poll, Pulsar push) tohle neobejde — limit je v samotném modelu "data musí projít Tuya cloud", ne v designu.
Rozhodnutí:
- Target architektura = Zigbee (ZB Bridge Pro) + MQTT lokálně, plná vlastní režie, žádné kvóty.
- Alternativa = WiFi senzory ve vlastní režii (ESP32 DIY) publikující přímo na MQTT.
- Zpracování pravděpodobně v HA, ale ne nutně — MQTT je neutrální sběrnice, konzument může být cokoliv.
- tuya2mqtt bridge degradován na legacy: běží pro existující Tuya WiFi čidla, dokud se nevymění. Neškáluje a jednou vymře.
- Migrace postupná: Tuya čidlo umře / slabá baterie / špatné měření → náhrada Zigbee/ESP32 variantou. Žádná aktivní hromadná náhrada zdravých čidel.
- DŮLEŽITÉ DO BUDOUCNA: nekupovat už žádná Tuya WiFi battery čidla. Lekce: před nákupem čidla ověřit, že data jdou dostat v plné vlastní režii (MQTT-first, žádný povinný cloud).