📖 Příběh · Výzvy

S čím systém musí bojovat

Smart home v reálném světě není „set and forget". Tady je seznam reálných problémů, které jsem řešil — a které řešit musíš taky, jakmile překročíš úroveň „pár chytrých žárovek".

Zigbee battery devices & deep sleep

Zigbee senzory na baterce (door/window, motion) chodí spát kvůli úspoře energie. Když je probudíš a hned dotáz, často odpoví až po několika sekundách — nebo neodpoví vůbec. Některé starší kusy padají do deep sleep, ze kterého se hub jejich přítomnost ztrácí (zařízení vypadá offline i s plnou baterkou).

Konkrétní incident: Door/Window Sensor SNZB-04 v jídelně. Známý firmware bug — periodicky padá do unreachable stavu i 2 metry od hubu, plná baterka. Způsobil 23. dubna 20-minutové zpoždění reakce na příchod (čistička se nevypnula při otevření okna). Řešení: náhrada za Aqara P2 (Matter/Thread, stabilnější firmware). V mezičase — multi-signal fallback (motion v kuchyni jako backup signál).

Re-pair = nové UUID = silent fail

Když vyměníš baterku nebo re-installuješ Zigbee zařízení, Homey vygeneruje nové UUID. Flow karty + skripty + device map referencující OLD UUID silently fail — žádný error v UI, automatizace prostě nereaguje.

Reálný case 26.4.: Door/Window Sensor Jidelna1 re-pair → 3 flows broken, čistička se nevypínala při otevření okna. Diagnóza: GET /devices/device/<old_id> → 404. Fix: bulk OLD→NEW swap přes PUT každého affected flow. Preventivní scanner find_orphan_device_refs.py v backlogu.

SIGABRT — Homey zabije skript bez vysvětlení

Homey runtime zabije procesy při detekci problémů (nekonečná smyčka, příliš mnoho paralelních skriptů, memory leak). Nikdy nepíše proč — skript prostě zmizí z exec logu. Debugging SIGABRT je čistá detektivka: izolace, binární search, test.

Klasická past: setValue() volá logEvent(), logEvent() volá setValue() pro zápis do sh_log_payloadnekonečná rekurze → SIGABRT. Pravidlo: setValue() smí volat jen getVar + updateVariable + log. Nikdy logEvent().

setTimeout neexistuje (a crashne)

Přirozený JS reflex pro async delay je setTimeout. V HomeyScript runtime není dostupné a volání vede k záhadnému crashi bez error message — skript jednoduše přestane existovat.

Řešení: vlastní wait() funkce v kombinaci s Promise.race() pro timeouty HTTP volání. Tohle jsem musel opravit v desítkách skriptů — bylo to systematické, ne ojedinělé.

Smazání skriptu = nové UUID = broken flows

V Homey nikdy nesmím smazat HomeyScript. Smazání vygeneruje nové UUID, což přetrhne všechny Flow karty odkazující na skript. Jediná bezpečná editace je in-place: otevři skript, Ctrl+A, paste, Save.

Tohle pravidlo způsobilo jeden velký výpadek než jsem to pochopil. Cleanup wave skriptů (20× DELETE_CANDIDATE) má proto vlastní workflow s 48h soak monitoring + canary testing před skutečným delete přes GitHub Actions.

Audio pipeline race conditions

Audio bylo nejtvrdší technický oříšek. Mnoho pohyblivých částí — priority engine, audio brain, speaker router, TTS orchestrátor, Cast Flow, resume logika. Každý díl měl race conditions, každá kombinace stavů přidávala edge case.

Příklad: briefing v 3:20 ráno. Pipeline: Gemini API (15s timeout) → TTS text → priority 55 > rádio 50 → audio brain přeruší rádio → Cast TTS → resume rádio. Každý krok mohl selhat. Crashy: setTimeout, Google Cast 200 char limit, priority conflict, resume race condition. Watchdog sh_audio_pipeline_watchdog_v1 hlídá stuck stav každou minutu.

Ghost values — proměnné, které lžou

sh_audio_request zůstal na hodnotě tts_kitchen_alert přes noc. Ráno se rádio nespustilo, protože audio brain viděl nevyřízený request — proměnná tvrdila stav, který už neplatil.

Řešení vyústilo v sh_state_validator_v1, který porovnává očekávaný a reálný stav. První produkční detekce: priority_active=tts ghost, který blokoval audio pipeline od 00:40 do rána. Bez validátoru by se to opakovalo donekonečna.

Args[] z Flow nejsou spolehlivé

Homey Flow umí předat argument skriptu přes „con l'argomento". Jenže args[] je nespolehlivý — hodnota někdy chybí, race condition mezi triggerem a skriptem.

Dnes všechny módy jdou přes dedikované Homey Logic proměnné (sh_kitchen_mode, sh_energy_mode), ne přes args. Flow vždy: set variable → run script. Skript čte z proměnné, ne z argumentu.

Některé API jsou prostě nedostupné

Homey.notifications.createNotification existuje v dokumentaci, vypadá funkčně, ale v HomeyScript kontextu není dostupné. Výsledek: is not a function. 19 tichých chyb za jediný den v logu, než jsem to našel.

Stejný pattern: castRadio (jen flow-only), některé Homey.scripts volání. Pravidlo: API se musí empiricky ověřit v sandboxu, ne věřit dokumentaci. Tichá selhání jsou nejhorší kategorie.