Pojęcia dotyczące DSL w Androidzie

To jest omówienie podstawowych pojęć związanych z DSL automatyzacji na Androidzie.

Komponenty automatyzacji

Automatyzacja składa się z tych podstawowych komponentów, które są zwykle oceniane w tej kolejności:

  1. Polecenie inicjujące – określa warunki początkowe, które aktywują automatyzację, np. zmianę cechy. Automatyzacja musi mieć polecenie inicjujące.
  2. Warunek – wszelkie dodatkowe ograniczenia, które należy ocenić po aktywowaniu automatyzacji. Aby działania automatyzacji mogły być kontynuowane, wyrażenie w warunku musi mieć wartość true.
  3. Działanie – polecenia lub aktualizacje stanu, które są wykonywane, gdy wszystkie warunki zostaną spełnione.

Możesz na przykład mieć automatyzację, która przyciemnia światła w pomieszczeniu, gdy telewizor w tym pomieszczeniu jest włączony między zachodem a wschodem słońca. W tym przykładzie:

  1. Polecenie inicjujące – telewizor został włączony, co jest zmianą stanu cechy telewizora.
  2. Warunek – oceniany jest aktualny czas w domu, w którym znajduje się telewizor.
  3. Działanie – światła w tym samym pomieszczeniu co telewizor są przyciemniane.

Automatyzacja zostanie aktywowana, gdy telewizor w pomieszczeniu zostanie włączony, ale zostanie wykonana tylko wtedy, gdy zostanie spełniony warunek „czas jest między zachodem a wschodem słońca”.

Oprócz podstawowej struktury automatyzacje w interfejsach Home API zawierają też metadane, takie jak name (nazwa) i description (opis), które mogą być używane do identyfikowania ich przez deweloperów i użytkowników.

Węzły

W interfejsach Home API logiczna struktura automatyzacji składa się z węzłów. Węzły to abstrakcyjne, wielokrotnego użytku jednostki, które reprezentują zachowania encji lub przepływy wykonania. Każdy węzeł może mieć zmienne wejściowe i wyjściowe, które mogą być używane przez inne węzły.

Tabela: typy węzłów automatyzacji
Węzeł Typ węzła Implementacja w Kotlinie Opis
Polecenie inicjujące Behawioralny StarterNodeDsl Uruchamia automatyzację, gdy zmieni się stan cechy (dowolny atrybut).
StateReader Behawioralny StateReaderNodeDsl Odczytuje atrybut cechy i umożliwia przechwycenie jego wartości do użycia w węzłach warunków.
Działanie Behawioralny ActionNodeDsl Wywołuje polecenia cech.
Sekwencyjny Przepływ wykonania SequentialFlow Wykonuje zagnieżdżone węzły działań w sekwencji. Jest to domyślne zachowanie wykonania.
Równoległy Przepływ wykonania ParallelFlow Wykonuje zagnieżdżone węzły działań równolegle.
Warunek Przepływ wykonania ConditionNodeDsl Warunkowo zmienia przepływ wykonania na podstawie ocen wyrażeń logicznych. Warunki mogą być powiązane z poleceniem inicjującym (warunki specyficzne dla polecenia inicjującego ) lub globalne (dotyczą wszystkich poleceń inicjujących).
Wybierz Przepływ wykonania SelectFlow Umożliwia aktywowanie automatyzacji przez więcej niż 1 polecenie inicjujące.
Wyrażenie Wartość Expression Może to być wartość atrybutu cechy, stała lub wartość literału, musi mieć wartość listy, liczby, wartości logicznej lub ciągu znaków.

Węzły behawioralne

Węzły takie jak polecenia inicjujące i działania są węzłami behawioralnymi. Polecenia inicjujące aktywują automatyzację na podstawie zmian atrybutów urządzenia. Działania wysyłają polecenia do urządzenia lub aktualizują atrybuty.

Węzły behawioralne są zwykle powiązane z cechami urządzenia i stanem cechy wyjściowej, który jest używany jako dane wejściowe w innych węzłach.

Węzły przepływu wykonania

Niektóre węzły reprezentują przepływy wykonania, np. sekwencyjne i równoległe. Każdy z tych węzłów zawiera węzły behawioralne, które definiują automatyzację.

Na przykład przepływ sekwencyjny może zawierać węzły, które są wykonywane w kolejności. Zwykle są to polecenie inicjujące, warunek i działanie.

Przepływy wykonywane sekwencyjnie
Rysunek 1. Sekwencyjny przepływ automatyzacji

Przepływ równoległy może mieć kilka węzłów działań wykonywanych w tym samym czasie, np. włączanie kilku świateł jednocześnie. Węzły następujące po przepływie równoległym nie zostaną wykonane, dopóki nie zakończą się wszystkie gałęzie przepływu równoległego.

Przepływy wykonywane równolegle
Rysunek 2. Równoległy przepływ automatyzacji

Innym typem przepływu wykonania jest przepływ warunku, który może zmieniać przepływ wykonania na podstawie oceny wyrażenia.

Możesz na przykład mieć automatyzację, która wykonuje działanie w zależności od tego, czy jest noc. Węzeł warunku sprawdza porę dnia, a następnie wykonuje odpowiednią ścieżkę wykonania na podstawie tej oceny.

Przepływ warunku
Rysunek 3. Przepływ warunku

Przepływ wyboru jest przydatny, gdy chcesz mieć więcej niż 1 polecenie inicjujące, które może aktywować automatyzację. Gdy umieścisz 2 lub więcej poleceń inicjujących w przepływie select, dowolne z nich może aktywować automatyzację.

Możesz na przykład napisać automatyzację, która opuszcza rolety o zachodzie słońca, jeśli temperatura wzrośnie powyżej określonego progu lub jeśli jasność przekroczy próg. Każdy z tych scenariuszy jest obsługiwany przez 3 oddzielne polecenia inicjujące, a wszystkie 3 będą zawarte w przepływie select.

Wybierz przepływ
Rysunek 4. Przepływ wyboru

Zagnieżdżone przepływy

W złożonych automatyzacjach węzły przepływu wykonania mogą być też zagnieżdżone. Możesz na przykład mieć przepływ sekwencyjny, który wykonuje przepływ równoległy.

Zagnieżdżone przepływy wykonania
Rysunek 5. Zagnieżdżone przepływy wykonania

Węzły DSL można zagnieżdżać i łączyć na różne sposoby, aby spełnić określone potrzeby, zgodnie z ograniczeniami podanymi w tabeli poniżej. Kolumna Builder zawiera linki do dokumentacji bezpiecznego typu buildera w Kotlinie, która szczegółowo opisuje, co można używać w każdym typie węzła.

Tabela: sposoby łączenia węzłów
Węzeł Może zawierać ten typ węzła i dane Musi znajdować się w jednym z tych typów węzłów
Polecenie inicjujące Wyrażenie Wybierz, Sekwencyjny
ManualStarter Wybierz, Sekwencyjny
StateReader Wyrażenie (zwykle składające się z wartości atrybutu cechy) Działanie, Warunek
Działanie Polecenie, Encja, Wyrażenie Równoległy, Wybierz, Sekwencyjny
Sekwencyjny Równoległy, Wybierz, Sekwencyjny
Równoległy Działanie Sekwencyjny
Warunek Wyrażenie Równoległy, Sekwencyjny
Wybierz Warunek, Sekwencyjny, Polecenie inicjujące, ManualStarter Sekwencyjny i musi być pierwszym węzłem w przepływie

DSL automatyzacji

W interfejsach Home API automatyzacje są definiowane za pomocą DSL automatyzacji (języka specyficznego dla domeny). DSL automatyzacji jest implementowany jako DSL Kotlin (język specyficzny dla domeny), przy użyciu bezpiecznych typowo builderów Kotlin i jest specjalnie zaprojektowany do definiowania szablonów automatyzacji.

Gdy automatyzacja jest kompilowana, bezpieczne typowo buildery Kotlin generują klasy danych Kotlin, które są następnie serializowane do JSON bufora protokołu, który jest używany do wywoływania usług automatyzacji Google.

DSL automatyzacji upraszcza i usprawnia proces tworzenia automatyzacji. Natywnie używa tego samego modelu danych cech standardu Matter i cech smart home dostępnych w interfejsie Device API.

DSL automatyzacji definiuje też logikę automatyzacji w kategoriach abstrakcyjnych typów urządzeń, a nie konkretnych instancji urządzeń znajdujących się w domu użytkownika. Umożliwia deweloperowi podawanie parametrów wejściowych, które mogą być używane w czasie działania do określania rzeczywistych instancji urządzeń, a także innych ważnych wartości parametrów.

Składnia DSL jest podobna do składni Kotlin i jest równie bezpieczna typowo, ale automatyzacja napisana w DSL automatyzacji jest prostsza i bardziej zwięzła niż ta sama automatyzacja napisana w czystym Kotlinie.

Przykład

Oto przykład automatyzacji, która włącza urządzenie, napisanej za pomocą DSL automatyzacji:

val automation = automation {
  name = "MyFirstAutomation"
  description = "If light1 is on, turn on light2."
  isActive = true
  sequential {
    val onOffTrait = starter<_>(device1, OnOffLightDevice, OnOff)
    condition() { expression = onOffTrait.onOff equals true }
    action(device2, OnOffLightDevice) { command(OnOff.on()) }
  }
}

Ta automatyzacja jest bardzo prosta: gdy device1 (światło) się włączy (atrybut onOff zmieni się na true), wysyła polecenie on() , aby włączyć device2.

Automatyzacja używa węzła sequential, który wskazuje, że jego węzły będą uruchamiane w kolejności.

W węźle sequential znajdują się węzły behawioralne, takie jak starter, condition i action. Dane wyjściowe węzła starter są przypisywane do zmiennej, która jest używana w węźle condition.