Automatyzacja działa przy testach, a potem co trzeci wieczór nic nie robi. Rzadko winny jest błąd w Home Assistancie. Zwykle chodzi o kilka zasad: kiedy automatyzacja startuje, co Home Assistant uznaje za zmianę, co się dzieje, gdy wyzwalacz zadziała w trakcie poprzedniego przebiegu, i co z rozpoczętym przebiegiem robi ponowne uruchomienie systemu. Kto je zna, ten w większości „losowych” awarii zobaczy przewidywalny mechanizm.

Automatyzacja rusza w chwili zmiany

Dokumentacja Home Assistanta mieści to w dwóch zdaniach. Automatyzacja startuje w chwili, gdy coś się zmienia, a nie przez cały czas, gdy jakiś stan trwa. Warunki sprawdza tylko raz, zaraz po zadziałaniu wyzwalacza.

Stąd biorą się typowe niespodzianki:

  • Wyzwalacz otwarcia drzwi nie zadziała, jeśli drzwi były już otwarte w chwili zapisania automatyzacji. Poczeka, aż ktoś je zamknie i znowu otworzy.
  • Wyzwalacz temperatury powyżej 25 °C nic nie zrobi, gdy w pokoju już jest 26 °C. Zadziała dopiero wtedy, gdy temperatura spadnie do 25 °C lub niżej i znowu wzrośnie.
  • Jeśli warunek nie jest spełniony w chwili zadziałania wyzwalacza, przebieg się kończy, nawet gdy minutę później warunek byłby już spełniony. Warunek nigdy sam nie uruchamia automatyzacji.

Dokumentacja podaje taki przykład: światło w salonie ma się zapalić, gdy Paulus jest w domu i słońce już zaszło. Jeśli wyzwalaczem będzie powrót Paulusa, a warunkiem pora po zachodzie, to w dzień, kiedy Paulus wróci przed zmrokiem i zostanie w domu, nic się nie stanie. Rozwiązanie polega na tym, żeby każda zmiana miała własny wyzwalacz, a każdą sytuację sprawdzał warunek:

triggers:
  - trigger: state
    entity_id: person.paulus
    to: "home"
  - trigger: sun
    event: sunset
conditions:
  - condition: state
    entity_id: person.paulus
    state: "home"
  - condition: sun
    after: sunset
actions:
  - action: light.turn_on
    target:
      entity_id: light.living_room

Teraz automatyzację uruchamia to zdarzenie, które nastąpi jako drugie, a warunki sprawdzają, czy pierwsze nadal obowiązuje. Jeśli automatyzacja ma też nadrobić zaległości po ponownym uruchomieniu Home Assistanta, dodaj jeszcze jeden wyzwalacz: trigger: homeassistant z event: start. O tym, czy jest coś do zrobienia, zdecydują warunki.

Co Home Assistant uznaje za zmianę

Nie każda aktualizacja encji uruchamia wyzwalacz, a niektóre uruchamiają go wtedy, gdy się tego nie spodziewasz.

Zmiany atrybutów. Wyzwalacz „Stan zmieniony” („State changed”) bez pól „Z” i „Na” (From, To) reaguje na każdą zmianę encji, także na zmianę atrybutu, na przykład jasności lampy albo poziomu baterii czujnika. Jeśli interesuje cię tylko stan, w polu „Na” wybierz „Dowolny stan (ignorując zmiany atrybutów)”. W YAML to to: null: klucz jest obecny, ale bez wartości.

Powrót z niedostępności. Gdy urządzenie zniknie z sieci i wróci, jego stan zmienia się z unavailable na przykład na on. Wyzwalacz z from: "off" takiej zmiany nie złapie i automatyzacja milczy. Usuń pole „Z”, jeśli poprzedni stan nie ma znaczenia. Większość nowszych wyzwalaczy przygotowanych dla konkretnych encji, na przykład wyzwalacz włączenia światła, w ogóle nie reaguje na powrót z niedostępności. Wyzwalacz „Stan zmieniony” reaguje.

Surowe stany. Interfejs pokazuje, że drzwi są otwarte, a czujnik wykrył ruch, ale wyzwalacz porównuje surowy stan, czyli on. Wybierz stan z listy w edytorze albo sprawdź surową wartość w menu Ustawienia > Narzędzia > Stany (Settings > Tools > States).

Ponowne ustawienie tej samej wartości zwykle nie jest zmianą stanu, więc nic się nie uruchomi.

Czujniki, które skaczą między stanami

Czujnik ruchu, który co chwilę przełącza się między wykryciem ruchu a jego brakiem, albo odczyt mocy krążący wokół progu potrafią uruchamiać automatyzację co kilka sekund. Zwykle pomaga opcja „Przynajmniej przez” („For at least”, w YAML for:) w wyzwalaczu: zmiana liczy się dopiero wtedy, gdy nowy stan utrzyma się przez podany czas.

Trzeba o niej wiedzieć dwie rzeczy. Odliczanie zaczyna się od nowa za każdym razem, gdy encja opuści dany stan, więc krótkie ponowne wykrycie ruchu zeruje dziesięciominutowe czekanie na brak ruchu. Odliczanie przepada też przy ponownym uruchomieniu Home Assistanta i przy przeładowaniu automatyzacji. Podobnie jest z warunkiem stanu z opcją „Przynajmniej przez”: po ponownym uruchomieniu Home Assistant liczy czas od swojego startu, a nie od faktycznej zmiany.

Wybierz właściwy tryb

Czasem wyzwalacz zadziała ponownie, zanim skończy się poprzedni przebieg, najczęściej wtedy, gdy automatyzacja czeka w opóźnieniu. Co się wtedy stanie, zależy od trybu:

  • Pojedynczy („Single”, domyślny): nowe uruchomienie zostaje pominięte, a w logach pojawia się ostrzeżenie „Already running”.
  • Uruchom ponownie („Restart”): bieżący przebieg zostaje przerwany razem z opóźnieniem albo oczekiwaniem, a nowy startuje od początku, o ile warunki są spełnione.
  • Kolejkowanie („Queued”): nowy przebieg czeka, aż skończą się wcześniejsze. Startują w kolejności uruchomienia.
  • Równoległy („Parallel”): nowy, niezależny przebieg rusza obok trwających.

W trybach kolejkowania i równoległym maksymalna liczba przebiegów wynosi domyślnie 10 (najmniej 2). Tryb zmienisz w edytorze przez Menu > Zmień tryb (Change mode) albo kluczami mode: i max: w YAML.

Każdy tryb pasuje do innego zadania. Światło na czujnik ruchu potrzebuje trybu „Uruchom ponownie”, bo każdy nowy ruch ma zerować odliczanie:

mode: restart
triggers:
  - trigger: state
    entity_id: binary_sensor.hallway_motion
    to: "on"
actions:
  - action: light.turn_on
    target:
      entity_id: light.hallway
  - wait_for_trigger:
      - trigger: state
        entity_id: binary_sensor.hallway_motion
        to: "off"
  - delay: "00:02:00"
  - action: light.turn_off
    target:
      entity_id: light.hallway

Powiadomienie, które ma przychodzić nie częściej niż co jakiś czas, załatwisz trybem pojedynczym i opóźnieniem na końcu. W przykładzie z dokumentacji automatyzacja działa najwyżej raz na 5 minut, a max_exceeded: silent wycisza ostrzeżenia o pominiętych uruchomieniach. Kolejkowanie przydaje się przy urządzeniu, które nie przyjmie kilku poleceń naraz. Tryb równoległy pasuje do powiadomienia, które ma wyjść przy każdym zdarzeniu.

Ten sam tryb w złym miejscu potrafi zaszkodzić. Jeśli w śladzie widzisz przebieg przerwany w trakcie opóźnienia dokładnie w chwili, gdy ruszył nowy, to tryb „Uruchom ponownie” robi to, do czego służy. Jeśli opóźnienie ma się dokończyć, wybierz tryb pojedynczy.

Ponowne uruchomienie przerywa trwające przebiegi

Gdy Home Assistant uruchamia się ponownie, na przykład po aktualizacji, wszystkie trwające automatyzacje się zatrzymują. Opóźnienie, oczekiwanie albo odliczanie „Przynajmniej przez” przepada, a po starcie automatyzacja nie wraca do miejsca, w którym przerwała. Przebieg kończy się też, gdy zapiszesz zmienioną automatyzację (pozostałe działają dalej), gdy ją wyłączysz albo gdy zmienisz jej identyfikator encji.

Dwuminutowe opóźnienie zwykle nikomu nie przeszkadza. Trzygodzinne prędzej czy później trafi na aktualizację. Dokumentacja podsuwa dwa zamienniki:

  • Na konkretną godzinę użyj wyzwalacza czasu zamiast czekania.
  • Na określony czas trwania użyj pomocnika typu minutnik. Utworzysz go w menu Ustawienia > Urządzenia oraz usługi > Pomocnicy > Utwórz pomocnika > Minutnik (Timer). Włącz w nim opcję „Przywróć stan i czas po uruchomieniu Home Assistanta”. Przywrócony minutnik zachowuje pozostały czas mimo ponownego uruchomienia. Uruchamiasz go w jednej automatyzacji, a na jego zakończenie (wyzwalacz Timer finished) reagujesz w drugiej.

Takie rozwiązanie sprawdza się, gdy naraz trwa tylko jedno odliczanie, a akcje po odliczaniu nie potrzebują danych wyzwalacza, na przykład tego, który czujnik ją uruchomił. Zostaje jedna luka: jeśli minutnik skończy odliczać, gdy Home Assistant jest wyłączony, wyzwalacz zakończenia minutnika po starcie się nie uruchomi. Załatwia to wyzwalacz uruchomienia Home Assistanta. Oto wentylator w łazience, który pracuje 20 minut po zgaszeniu światła:

alias: "Wentylator w łazience: start"
triggers:
  - trigger: state
    entity_id: light.bathroom
    to: "off"
actions:
  - action: fan.turn_on
    target:
      entity_id: fan.bathroom
  - action: timer.start
    target:
      entity_id: timer.bathroom_fan
    data:
      duration: "00:20:00"
alias: "Wentylator w łazience: stop"
triggers:
  - trigger: timer.finished
    target:
      entity_id: timer.bathroom_fan
  - trigger: homeassistant
    event: start
conditions:
  - condition: state
    entity_id: timer.bathroom_fan
    state: "idle"
actions:
  - action: fan.turn_off
    target:
      entity_id: fan.bathroom

Minutnik ma stan idle, gdy skończył odliczać, został anulowany albo jeszcze nie ruszył, a stan active, gdy odlicza. Po ponownym uruchomieniu przywrócony minutnik, któremu zostało jeszcze trochę czasu, znowu jest aktywny. Warunek zatrzymuje wtedy drugą automatyzację, a wentylator pracuje, dopóki minutnik nie skończy. Minutnik, który skończył odliczać w czasie przerwy, jest bezczynny, więc wyzwalacz uruchomienia wyłączy wentylator. Ma to swoją cenę: wentylator włączony ręcznie też zostanie wyłączony przy najbliższym ponownym uruchomieniu.

Oczekiwanie, które się nie kończy albo kończy za wcześnie

Dwa bloki oczekiwania działają odwrotnie:

  • „Czekaj na wyzwalacz” („Wait for a trigger”) reaguje tylko na zmianę, która nastąpi po rozpoczęciu oczekiwania. Jeśli drzwi już są zamknięte, czekanie na zamknięcie drzwi nigdy się nie skończy.
  • „Oczekiwanie na szablon” („Wait for a template”) przechodzi dalej od razu, jeśli szablon już jest prawdziwy.

Oba bloki mają limit czasu, a opcja „Kontynuuj po przekroczeniu limitu czasu” jest domyślnie włączona. Po upływie limitu automatyzacja idzie więc dalej, jakby oczekiwanie się udało. Wyłącz tę opcję, jeśli przebieg ma się wtedy zakończyć, albo sprawdź wait.completed w bloku „Jeżeli coś - to coś” (If-then): przyjmuje wartość false, gdy oczekiwanie przerwał limit czasu.

Kilka wyzwalaczy w jednej automatyzacji

Zamiast trzech automatyzacji dla jednego urządzenia możesz zrobić jedną z kilkoma wyzwalaczami i rozgałęzić ją warunkiem „Wyzwolone przez” („Triggered by”) w bloku „Wybór” (Choose). Edytor sam nada wyzwalaczom identyfikatory. W YAML ustaw id: przy każdym wyzwalaczu i użyj condition: trigger z tym identyfikatorem. Wyzwalacz bez identyfikatora jest rozpoznawany po pozycji liczonej od 0, choć edytor numeruje wyzwalacze od 1.

Uważaj na podwójne przebiegi. Wyzwalacz na lampie i drugi na grupie, do której ta lampa należy, zadziałają oba, gdy lampa się zapali, i każdy uruchomi automatyzację. Na górze każdego śladu widać, który wyzwalacz go rozpoczął.

Korzystaj ze śladów i testuj na prawdziwych danych wyzwalacza

Każda automatyzacja domyślnie zapisuje ślady 5 ostatnich przebiegów (w edytorze przycisk „Ślady”, Traces). Ślad pokazuje wyzwalacz, wynik każdego warunku i to, co zrobiła każda akcja. Na liście przebiegów widać też, jak się zakończyły, na przykład „Zatrzymano z powodu niespełnienia warunku”. Żeby przechowywać więcej, dopisz w YAML:

trace:
  stored_traces: 20

Automatyzacje pisane w YAML muszą mieć id, inaczej ich ślady nie będą dostępne.

Ostrożnie z poleceniem „Uruchom akcje” („Run actions”). Pomija ono wyzwalacze oraz warunki i działa bez danych wyzwalacza, więc warunek „Wyzwolone przez” nigdy nie będzie spełniony, a szablony korzystające z trigger nie mają czego odczytać. Żeby przetestować automatyzację na prawdziwych danych wyzwalacza, zasymuluj zmianę: ustaw stan encji w menu Ustawienia > Narzędzia > Stany albo wywołaj zdarzenie w menu Ustawienia > Narzędzia > Zdarzenia (Events). Uruchomią się wtedy wszystkie automatyzacje, które czekają na tę zmianę, a ich akcje sterują prawdziwymi urządzeniami. Zanim klikniesz, sprawdź, co jeszcze zareaguje.