Dashboard Config Center + Weather restore — 8 vln v jeden den

15. května večer. Po sérii R2-R6A oprav Homey runtime jsme se přesunuli na druhou stranu — dashboard. Tři výstupy, tři rozlišení: WaveShare 10.1″ 1024×600 (RPi kiosk), 14″ notebook 1920×1080, 32″ master 2880×1800. Cíl: stabilní render, žádné silent-fail buttony, a hlavně žádný zápis czech literálů jako doma, pryc, ano do logických proměnných.

Wave 1 — canonical enum guard

Před vlnou 1 mohl dashboard psát do sh_rezim_doma hodnotu 'doma', zatímco zbytek systému (sh_morning_brain, sh_audio_brain, sh_light_router) pracoval s 'home'. Tichý mismatch — žádný error, jen automatika neudělala to, co měla. Stejné u 'pryc' vs 'away', 'ano' vs 'yes', 'strong_yes' vs 'yes'.

Wave 1 přidal helper __CANON_ENUMS přímo do HTML. Před každým writeVar dashboard porovná hodnotu s povoleným enumem (anglické tokeny). Pokud najde czech literál nebo true/false, zablokuje write a logne. 9 zakázaných literálů celkem.

Wave 2A + 2B — weather restore

Po nedávné migraci RPi na SSD se kiosk renderer vrátil ke staré verzi počasí (OpenWeatherMap proxy přes Homey), která mezitím přestala fungovat. Diagnostika nebyl kód bug — byl to deploy-channel regression. SSD rebuild přepsal patched canonical soubor starším OWM file-em.

Wave 2A: cache-first renderer (čte přímo sh_weather_3d_json z Homey logic vars) byl re-deployed na RPi přes SSH. Wave 2B oživil cron sh_weather_yr_bridge_v1, který každých 10 min stahuje yr.no JSON a píše ho do té same var. Žádné API klíče, žádné OWM, žádný proxy hop — yr.no je free a stabilní.

Wave 3 — roleta = PURE LUX truth

Roleta v Jídelně měla dvě protichůdné podmínky: sh_house_state a venkovní lux. Když sh_house_state bylo 'home_normal', short-circuit a roleta nahoře bez ohledu na lux. Reálně to ale způsobovalo drift — roleta zůstala nahoře i v noci, když lux byl 0. Wave 3 odstranil ten short-circuit. Teď jediná pravda je lux + hysteresis (R3 throttle deploy z 13.5. zůstal in place).

Wave 6 — desktop parity

v7_1920 (notebook) a v7_2880 (32″ master) dostaly stejný __CANON_ENUMS guard jako RPi. Tři výstupy, identický write contract.

Wave 4A → 4B-6 — Config Center

Tady byla největší změna. Místo aby každý config tile měl vlastní inline write logiku, Wave 4A přidal DASHBOARD_CONFIG_SCHEMA objekt + helper writeVarValidated(varName, value). Schema definuje pro každou logic var: typ, min, max, enum, cross-field závislosti, soft warnings.

Wave 4B postupně rozšířil schema z 18 entries (4B-1) na 128+ entries (4B-6). Pokrývá: morning routine cfg (alarm window, kaffe immediate, score boost), heating cfg (target_temp s min:5 pro frostsave 7°C, manual_override_temp s min:-99 pro sentinel), audio cfg, light cfg, occupancy thresholds, vacancy guardian timeouts, roleta lux thresholds, energy budget caps, scene engine modes (idle, reset, romantika, relax, kino, vareni, work).

writeCfg dispatcher unifikoval všechny config write paths. Aktuálně běží v soft-reject módu — log warning, ale write pustí. Po 24h soaku přepneme na hard-reject (true block). Final RPi sha: e3216213e4b9f73772c1a555d790cd5e411bac5b2031c290ffaf36e791bd7aec.

Čemu jsem se vyhnul přitom

B11 misdiagnóza: chtěl jsem na začátku přidat nový helper setHeatingBoost(30) do dashboardu. Při čtení live source jsem ale zjistil, že už existuje a je správně wired. Žádný nový kód, REUSE FIRST, revert. Stejně tak scene engine — dashboardy chtěly nabízet comfort a night jako scene IDs, ale engine je nezná. Sedm IDs only. Wave 5 (Homey-side scene enumeration) je naplánovaný ale ne tonight.

Co dál

Overnight soak. Ráno automatický OVERNIGHT_SOAK_REPORT_2026-05-16_0600.md fire-ne v 06:00 Prague. Po něm: Wave 4B hard-mode flip, R6A morning verify (čte EventLog za poslední morning routine), pak R6B (Gemini brain + morning score heartbeat) a R5 SIGABRT main hunt (~7-8 crashů/h baseline, root cause nevyřešen).

Dashboard je teď v stavu, kdy odmítá psát glupost. To je první milník od kdy nemusím při review pull request-ů hlídat enum hodnoty ručně.