🔋
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_payload → nekoneč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.