From f09dcbf10d2855524bcfe239a6f200f18dd8ea76 Mon Sep 17 00:00:00 2001 From: oskar Date: Thu, 23 Jul 2026 17:17:38 +0200 Subject: [PATCH] =?UTF-8?q?fix(ha/ken):=20fix-pack=201=20po=20audycie=20?= =?UTF-8?q?=E2=80=94=20alerty=20wodne,=20respekt=20manual,=203am=20punktow?= =?UTF-8?q?o,=20klima=20OFF=20za=20auto?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Zmiany wyłącznie w repo (config/ken/ automations), deploy LIVE robi operator. - 1752086407230 "dry in Kuchnia": trigger moist -> not_moist (kopiuj-wklej z "moist in Kuchnia", "sucho" nigdy nie przyjdzie). - 1752085965483 "dry in Lazienka": literówka mesaage -> message (skrypt notify_email_ntfy dostawał niezdefiniowane message, akcja się wykładała). - 1764190493305 "after 15 minutes anyway": dodany warunek stanu automation.turn_off_lights_in_kuchania == on, żeby respektować ręczne "Disable AUTO off" (double-click) zamiast unieważniać je po 15 minutach. - 1700832676138 "unconditionally at 3am": time_pattern hours: '3' (60 odpaleń/noc) -> punktowy trigger time: 03:00:00, zgodnie z intencją aliasu. - 1784804668795 "Klima salon: wyłącz...": dodany warunek input_boolean.klima_salon_auto == on dla gałęzi sunset/balkon (automat ubija tylko chłodzenie, którym sam zarządza — ręczne chłodzenie przy zgaszonym auto zostaje nietknięte). Trigger auto_off (zgaszenie klima_salon_auto) ma osobną gałąź choose bez tego warunku — graceful shutdown suszenia parownika działa nawet gdy przełącznik właśnie zgasł. Zweryfikowano na żywym ken: helpery klimy istnieją (input_boolean. klima_salon_auto=off, input_number.klima_salon_temp_docelowa=24.0, input_number.klima_salon_tolerancja=3.0). DESIGN.md: nowa sekcja "Decyzje operatora po audycie 2026-07-23" — co zaimplementowane, co świadomie odłożone (enforcer sleep mode + konsolidacja nocnych wyłączników -> projekt night_mode; OwnTracks / Leave batch 02 / alerty on-leave -> bez zmian). docs/backlog.md: cztery nowe wpisy w Aktywne — guard TRV przed sezonem grzewczym, przycisk graceful shutdown klimy na dashboard, diagnoza wspólnej awarii sprzętowej 2026-07-17 (czujniki ruchu + pilot 4button + xiaomi_miot), projekt architektura night_mode. Walidacja: round-trip scripts/ha/lib/normalize.py na wszystkich 5 zmienionych plików (stabilny), 4 zestawy testów offline scripts/ha/tests/*.sh (wszystkie PASS), dry-run scripts/ha/deploy.sh ken --dry-run per plik na żywym ken (wszystkie: check_config valid, brak driftu, brak abortu). Choinkowe automatyzacje (audyt 4.2) celowo nietknięte w plikach — disable to stan runtime, nie config; operator wyłączy je przez UI. Co-Authored-By: Claude Sonnet 5 --- docs/backlog.md | 79 +++++++++++++++++++ services/home-assistant/DESIGN.md | 45 +++++++++++ .../config/ken/automations/1700832676138.yaml | 4 +- .../config/ken/automations/1752085965483.yaml | 2 +- .../config/ken/automations/1752086407230.yaml | 2 +- .../config/ken/automations/1764190493305.yaml | 3 + .../config/ken/automations/1784804668795.yaml | 40 ++++++++-- 7 files changed, 163 insertions(+), 12 deletions(-) diff --git a/docs/backlog.md b/docs/backlog.md index b6cec6a..e7f7876 100644 --- a/docs/backlog.md +++ b/docs/backlog.md @@ -102,6 +102,85 @@ historia incydentów, out-of-band watchdog. ## Aktywne +### HA ken: guard TRV kalibracji przed sezonem grzewczym (~2026-09) + +**Data**: 2026-07-23 +**Źródło**: `services/home-assistant/docs/audyt-automatyzacji-2026-07-23.md` sekcja 1.4 +(pkt 2 checklisty operatora) +**Problem**: kalibracje TRV sypialnia (`1764751049013`) i Tymek (`1765817937658`) liczą +`room_temp` jako średnią z czujnika zhimi, który jest `unavailable` od 2026-07-17 → +`float(0)` w formule zaniża temperaturę o połowę → kalibracja dojechała do −5.0 +(potwierdzone w fixtures). Latem (TRV `off`) nieszkodliwe; w sezonie grzewczym = +trwałe przegrzewanie obu pokoi. Dodatkowo wszystkie 6 automatyzacji TRV pollują co +40–50s (baterie 20–38%), a SalonPrawy ma clamp `diff` ±5 zamiast ±1.5 jak reszta. +**Fix (przed sezonem)**: (1) guard `is not unavailable` na czujnikach zhimi zamiast +ślepego uśredniania; (2) ręczny reset kalibracji sypialnia/Tymek po naprawie; (3) +zwolnić pętle do ≥5 min lub trigger na zmianę stanu; (4) ujednolicić clamp SalonPrawy; +(5) reanimować albo wyłączyć TRV łazienki (`number.*_calibration` unavailable — +urządzenie zniknęło z sieci). + +--- + +### HA ken: przycisk graceful shutdown klimy salonowej na kartę dashboardu + +**Data**: 2026-07-23 +**Źródło**: `services/home-assistant/docs/audyt-automatyzacji-2026-07-23.md` sekcja 3.1, +fix-pack 1 (`task/ha-fix-pack-1`, DESIGN.md „Decyzje operatora po audycie 2026-07-23") +**Kontekst**: po fix-packu 1 „Klima salon: wyłącz…" (`1784804668795`) respektuje +`klima_salon_auto = on` dla gałęzi sunset/balkon; suszenie parownika przy ręcznym +zgaszeniu `klima_salon_auto` działa już tylko jako efekt uboczny przełącznika trybu +auto (osobna gałąź `choose` na trigger `auto_off`). Brakuje wygodnego jednego +przycisku „wyłącz klimę i osusz teraz" niezależnego od przełącznika auto. +**Fix**: dodać na dashboard przycisk/skrypt wywołujący `script.klima_salon_dry_off` +bezpośrednio (bez przełączania `klima_salon_auto`), żeby ręczne graceful shutdown nie +wymagało znajomości wewnętrznej logiki automatyzacji. + +--- + +### HA ken: diagnoza wspólnej awarii sprzętowej 2026-07-17 (czujniki ruchu, pilot 4button, xiaomi_miot) + +**Data**: 2026-07-23 +**Źródło**: `services/home-assistant/docs/audyt-automatyzacji-2026-07-23.md` sekcje 1.2, +1.6, 4.5 (pkt 1, 3, 15 checklisty operatora) +**Problem**: restart HA / update Supervisora 2026-07-17 15:07 zbiega się z +`unavailable` na: klaster czujników ruchu/obecności (mdwejscie, mdsypialnia, mdheli — +przynajmniej od restartu; occusalon/mdtymka/mdubikacja gasną w kolejnych dniach — +obraz siadających baterii), całej integracji xiaomi_miot (fan.zhimi_mb3/mc2, czujniki +temperatury zhimi używane w kalibracjach TRV) i `sensor.4button_battery` (mimo że pilot +4button strzelał jeszcze 2026-07-12 — 8 automatyzacji salonu na tym urządzeniu). Nie +jest jasne, czy to jedna awaria (Zigbee coordinator/integracja) czy zbieg kilku. +**Fix**: (1) sprawdzić fizycznie baterie/re-pairing 6 czujników ruchu + czujnik +wycieku WC (pkt 1 checklisty); (2) zdiagnozować integrację xiaomi_miot po stronie HA +zamiast łatać pojedyncze automatyzacje (pkt 3); (3) sprawdzić fizycznie baterię pilota +4button (pkt 15). Reanimacja czujników ruchu odblokuje też ~15 cicho martwych +automatyzacji (alerty on-leave, nocne gaszenie, `Poranek start`) — patrz audyt sekcja +1.2 dla pełnej listy skutków. + +--- + +### HA ken: projekt „architektura night_mode" (konsolidacja sleep/night mode) + +**Data**: 2026-07-23 +**Źródło**: `services/home-assistant/docs/audyt-automatyzacji-2026-07-23.md` sekcje 2.2, +2.4, 6 (pkt 7, 9 checklisty operatora — świadomie NIE załatane w fix-packu 1, patrz +DESIGN.md „Decyzje operatora po audycie 2026-07-23") +**Problem**: cztery flagi trybu (`sleep_mode`, `night_mode`, `passive_mode`, +`movie_mode`) o częściowo pokrywającej się semantyce, sprawdzane niespójnie (raz jedna +flaga, raz druga, raz OR obu); `automation.turn_off_sleep_mode_at_sunrise` steruje w +rzeczywistości `night_mode`. Cztery nakładające się automatyzacje gaszą ten sam zestaw +świateł nocą (`1702844937214` martwa, `1763384250145` martwa, `1768946230585` enforcer +co ~10 min całą noc, `1700832676138` o 3:00) — po reanimacji martwych czujników (patrz +wpis wyżej) trzy z nich ożyją naraz i zaczną się ścigać. `1768946230585` ma dodatkowo +trigger `time_pattern /5` obok krawędziowego `off→on`, więc mimo aliasu „5 minut po +aktywacji" gasi światła cyklicznie całą noc — do decyzji, czy to zamierzone. +**Fix (projekt, nie one-liner)**: skonsolidować do jednego `input_select.tryb_domu` + +jednej automatyzacji „nocne domknięcie" z jasnym priorytetem trybów i enforcerem +(cykliczny dozorca vs. jednorazowe zadziałanie po aktywacji — decyzja pkt 7), plus +finalny/ostateczny wyłącznik nocny zastępujący dzisiejsze cztery. Zakres większy niż +fix-pack — osobny task. + +--- + ### Executor: zepsuty JSON w `approved/` retry'owany w nieskończoność co 10s zamiast trafić do `failed/`/`rejected/` **Data**: 2026-07-23 diff --git a/services/home-assistant/DESIGN.md b/services/home-assistant/DESIGN.md index 692941a..3cec4fd 100644 --- a/services/home-assistant/DESIGN.md +++ b/services/home-assistant/DESIGN.md @@ -165,6 +165,51 @@ Plan: archival import for historical reference → `docker stop` (not `rm`) for the ha-diag-agent re-pointing and wind-down follow-ups this incident generated. +## Decyzje operatora po audycie 2026-07-23 + +Zobacz `docs/audyt-automatyzacji-2026-07-23.md` (sekcja "Do decyzji operatora", +17 punktów) — poniżej wyłącznie decyzje, które doprowadziły do zmian w +fix-pack 1 (`task/ha-fix-pack-1`) albo świadomie do braku zmian. Reszta +checklisty (baterie/re-pairing czujników, kalibracje TRV, xiaomi_miot, +konsolidacja aliasów, higiena 4.x) zostaje otwarta w `docs/backlog.md`. + +- **Pkt 6 (klima salon: sunset ubija też ręczne chłodzenie?)** — decyzja: + NIE. „Klima salon: wyłącz…" (`1784804668795`) ma teraz respektować + `input_boolean.klima_salon_auto` — gałąź sunset/balkon działa tylko gdy + `klima_salon_auto = on` (automat wyłącza tylko chłodzenie, którym sam + zarządza). Wyjątek świadomy: trigger „`klima_salon_auto` przechodzi w + `off`" nadal odpala suszenie parownika bez tego warunku (`choose` z osobną + gałęzią) — to jest graceful shutdown samego automatu, nie efekt trybu + auto, więc warunek `auto = on` by go zawsze ucinał (przełącznik właśnie + zgasł). Zweryfikowano na żywym `ken`: helpery klimy (`klima_salon_auto`, + `_temp_docelowa`, `_tolerancja`) **istnieją** (pkt 5 checklisty — obawa o + martwe helpery z 1.1 nieaktualna). +- **Pkt 7 (enforcer sleep mode gasi światła cyklicznie całą noc) i pkt 9 + (konsolidacja czterech nocnych wyłączników)** — bez zmian w tym fix-packu. + Oba wchłania przyszły projekt „architektura night_mode" (patrz + `docs/backlog.md`) — punktowa łatka tu tylko dodałaby kolejny wariant do + już przegęszczonego zestawu nakładających się automatyzacji (audyt 2.2). +- **Pkt 11 (OwnTracks: przywrócić czy skasować) i pkt 12 (Leave auto on: + batch 02 — włączyć z powrotem?)** — świadomie bez zmian; obie wymagają + decyzji operatora spoza zakresu tego fix-packu (integracja/urlop), nie + jednoliniowej poprawki. +- **On-leave alerty ruchu (1.2a)** — świadomie bez zmian: martwe przez + sprzęt (czujniki `unavailable`, pkt 1 checklisty), nie przez logikę + automatyzacji; poprawka logiki niczego by nie naprawiła bez wymiany + baterii/re-pairingu. + +Zaimplementowane w tym fix-packu (bez decyzji operatora — jednoliniowe +poprawki oczywistych bugów, audyt 2.6 i 2.3): + +- `1752086407230` „dry in Kuchnia": trigger `moist` → `not_moist`. +- `1752085965483` „dry in Lazienka": literówka `mesaage` → `message`. +- `1700832676138` „…at 3am": `time_pattern hours: '3'` → punktowy trigger + `time: 03:00:00` (było 60 odpaleń/noc, teraz 1). +- Pkt 8 (`1764190493305` „after 15 minutes anyway" ma respektować ręczne + „Disable AUTO off"?) — TAK: dodany warunek `state: automation. + turn_off_lights_in_kuchania = on` (double-click wyłącza tę automatyzację; + „anyway" teraz cofa się przed tym stanem zamiast go unieważniać po 15 min). + ## Open questions - What actually drives the phase-3 operational agent (a new agent process diff --git a/services/home-assistant/config/ken/automations/1700832676138.yaml b/services/home-assistant/config/ken/automations/1700832676138.yaml index e522b0e..a2f045d 100644 --- a/services/home-assistant/config/ken/automations/1700832676138.yaml +++ b/services/home-assistant/config/ken/automations/1700832676138.yaml @@ -30,5 +30,5 @@ description: '' id: '1700832676138' mode: single triggers: -- hours: '3' - trigger: time_pattern +- at: 03:00:00 + trigger: time diff --git a/services/home-assistant/config/ken/automations/1752085965483.yaml b/services/home-assistant/config/ken/automations/1752085965483.yaml index 3f980fa..5776b33 100644 --- a/services/home-assistant/config/ken/automations/1752085965483.yaml +++ b/services/home-assistant/config/ken/automations/1752085965483.yaml @@ -1,7 +1,7 @@ actions: - action: script.notify_email_ntfy data: - mesaage: Alert wilgotnośći w Łazience - sucho + message: Alert wilgotnośći w Łazience - sucho alias: email on water sensor dry in Lazienka conditions: [] description: '' diff --git a/services/home-assistant/config/ken/automations/1752086407230.yaml b/services/home-assistant/config/ken/automations/1752086407230.yaml index 7256dec..7bbd424 100644 --- a/services/home-assistant/config/ken/automations/1752086407230.yaml +++ b/services/home-assistant/config/ken/automations/1752086407230.yaml @@ -16,4 +16,4 @@ triggers: minutes: 0 seconds: 10 trigger: device - type: moist + type: not_moist diff --git a/services/home-assistant/config/ken/automations/1764190493305.yaml b/services/home-assistant/config/ken/automations/1764190493305.yaml index 5bdc299..8a6760c 100644 --- a/services/home-assistant/config/ken/automations/1764190493305.yaml +++ b/services/home-assistant/config/ken/automations/1764190493305.yaml @@ -25,6 +25,9 @@ actions: entity_id: automation.turn_off_lights_in_kuchania alias: Turn off lights in Kuchnia after 15 minutes anyway conditions: +- condition: state + entity_id: automation.turn_off_lights_in_kuchania + state: 'on' - condition: device device_id: dd84e859ed748c2cd3ede0f6d449f76a domain: binary_sensor diff --git a/services/home-assistant/config/ken/automations/1784804668795.yaml b/services/home-assistant/config/ken/automations/1784804668795.yaml index 0eeb07b..8065b33 100644 --- a/services/home-assistant/config/ken/automations/1784804668795.yaml +++ b/services/home-assistant/config/ken/automations/1784804668795.yaml @@ -1,22 +1,46 @@ actions: -- action: script.turn_on - target: - entity_id: script.klima_salon_dry_off +- choose: + - conditions: + - condition: trigger + id: + - sunset + - balkon_temp + - condition: state + entity_id: input_boolean.klima_salon_auto + state: 'on' + - condition: state + entity_id: climate.gree_ir_blaster_klimatyzacja + state: cool + sequence: + - action: script.turn_on + target: + entity_id: script.klima_salon_dry_off + - conditions: + - condition: trigger + id: auto_off + - condition: state + entity_id: climate.gree_ir_blaster_klimatyzacja + state: cool + sequence: + - action: script.turn_on + target: + entity_id: script.klima_salon_dry_off + default: [] alias: 'Klima salon: wyłącz chłodzenie i osusz parownik' -conditions: -- condition: state - entity_id: climate.gree_ir_blaster_klimatyzacja - state: cool -description: 'Wyłącza tryb chłodzenia klimatyzacji w salonie i uruchamia suszenie parownika. managed-by: repo' +conditions: [] +description: 'Wyłącza tryb chłodzenia klimatyzacji w salonie i uruchamia suszenie parownika, ale tylko gdy klima_salon_auto = on (nie ubija ręcznie włączonego chłodzenia). Wyjątek: gdy to samo zgaszenie klima_salon_auto jest triggerem (auto_off), suszenie parownika i tak się wykonuje — to graceful shutdown całej automatyki klimy, nie zwykłe zadziałanie trybu auto. managed-by: repo' id: '1784804668795' mode: single triggers: - event: sunset + id: sunset offset: 0 trigger: sun - for: 00:15:00 + id: balkon_temp trigger: template value_template: '{{ states(''sensor.thtuyabalkon_temperature'') | float(0) <= states(''sensor.thsalon_temperature'') | float(0) }}' - entity_id: input_boolean.klima_salon_auto + id: auto_off to: 'off' trigger: state