Pojęcia dotyczące DSL w Androidzie

To jest omówienie podstawowych pojęć związanych z językiem 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ć element inicjujący.
  2. Warunek – dodatkowe ograniczenia, które są sprawdzane po aktywowaniu automatyzacji. Aby działania automatyzacji mogły zostać wykonane, 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 pokoju, gdy telewizor w tym pokoju jest włączony między zachodem a wschodem słońca. W tym przykładzie:

  1. Starter – telewizor został włączony, co oznacza zmianę stanu cechy telewizora.
  2. Warunek – sprawdzany jest bieżący czas w domu, w którym znajduje się telewizor.
  3. Działanie – światła w tym samym pomieszczeniu co telewizor zostają przyciemnione.

Automatyzacja zostanie aktywowana po włączeniu telewizora w pokoju, ale zostanie wykonana tylko wtedy, gdy zostanie spełniony warunek „czas między zachodem a wschodem słońca”.

Oprócz podstawowej struktury automatyzacje w Home API zawierają też metadane, takie jak nazwa i opis, które mogą służyć do identyfikowania ich przez deweloperów i użytkowników.

Węzły

W interfejsach Home API struktura logiczna automatyzacji składa się z węzłów. Węzły to abstrakcyjne jednostki wielokrotnego użytku, które reprezentują zachowania encji lub przepływy wykonywania. 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 języku Kotlin Opis
Starter Behawioralne StarterNodeDsl Uruchamia automatyzację, gdy zmieni się stan cechy (dowolny atrybut).
StateReader Behawioralne StateReaderNodeDsl Odczytuje atrybut cechy i umożliwia przechwycenie jego wartości do użycia w węzłach warunków.
Działanie Behawioralne ActionNodeDsl Wywołuje polecenia cechy.
Sekwencyjna Przepływ wykonywania SequentialFlow Wykonuje zagnieżdżone węzły działań w sekwencji. Jest to domyślne zachowanie podczas wykonywania.
Równoległe Przepływ wykonywania ParallelFlow Wykonuje równolegle zagnieżdżone węzły działań.
Warunek Przepływ wykonywania ConditionNodeDsl Warunkowo zmieniaj przepływ wykonywania na podstawie oceny wyrażeń logicznych. Warunki mogą być powiązane z elementem inicjującym (warunki dotyczące elementu inicjującego) lub globalne (dotyczące wszystkich elementów inicjujących).
Wybierz Przepływ wykonywania SelectFlow Umożliwia aktywowanie automatyzacji przez więcej niż 1 polecenie inicjujące.
IfFlow Przepływ wykonywania IfFlowDsl Wykonuje maksymalnie 1 działanie (lub gałąź) na podstawie tego, który warunek (jeśli występuje) jest spełniony (podobnie jak instrukcja if-then-else).
Expression Wartość Expression Może to być wartość atrybutu cechy, stała lub wartość literału i musi zwracać listę, liczbę, wartość logiczną lub ciąg znaków.

Węzły behawioralne

Węzły takie jak polecenia inicjujące i działania to węzły behawioralne. Zdarzenia inicjujące aktywują automatyzację na podstawie zmian atrybutów urządzenia. Działania wysyłają polecenia do urządzeń lub aktualizują atrybuty.

Węzły zachowania są zwykle powiązane z cechami urządzenia i stanem cech wyjściowych, które są używane jako dane wejściowe w innych węzłach.

Węzły przepływu wykonywania

Niektóre węzły reprezentują przepływy wykonywania, takie jak 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 sekwencyjnej. Zwykle są to polecenie inicjujące, warunek i działanie.

Sekwencyjne przepływy wykonywania
Ilustracja 1. Sekwencyjna automatyzacja

Równoległy przepływ może mieć wiele węzłów działania wykonywanych jednocześnie, np. włączanie kilku świateł w tym samym czasie. Węzły 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 wykonywania równoległego
Rysunek 2. Równoległy przepływ automatyzacji

Innym typem przepływu wykonywania jest przepływ warunkowy, który może zmienić przepływ wykonywania 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 podąża odpowiednią ścieżką wykonania na podstawie tej oceny.

Przepływ warunku
Ilustracja 3. Przepływ warunku

Przepływ wyboru jest przydatny, gdy chcesz mieć więcej niż 1 element inicjujący, który może aktywować automatyzację. Gdy w przepływie select umieścisz co najmniej 2 polecenia inicjujące, każde z nich może aktywować automatyzację.

Możesz na przykład utworzyć automatyzację, która opuszcza rolety o zachodzie słońca, gdy temperatura wzrośnie powyżej określonego progu lub gdy jasność przekroczy określony poziom. Każdy z tych scenariuszy jest obsługiwany przez osobny starter, a wszystkie 3 są opakowane w proces select.

Wybierz przepływ
Rysunek 4. Wybór procesu

Przepływ if-then-else (IfFlow) umożliwia rozgałęzione wykonywanie warunkowe w automatyzacji. W przeciwieństwie do węzła condition, który zatrzymuje całą automatyzację, jeśli warunek jest false, przepływ if-then-else warunkowo wykonuje określone działania, gdy warunek jest spełniony, i może powrócić do warunków alternatywnych lub działań zastępczych albo przejść do kolejnych węzłów w automatyzacji. Więcej informacji znajdziesz w artykule na temat wykonywania warunkowego.

Zagnieżdżone przepływy

W skomplikowanych automatyzacjach węzły przepływu wykonywania 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 wykonywania
Rysunek 5. Zagnieżdżone przepływy wykonywania

Węzły DSL można zagnieżdżać i łączyć na różne sposoby, aby spełniały określone potrzeby, zgodnie z ograniczeniami opisanymi w tabeli poniżej. Kolumna Kreator zawiera linki do dokumentacji kreatora Kotlin typesafe, która szczegółowo opisuje, co jest dozwolone w każdym typie węzła.

Tabela: jak można łączyć węzły
Węzeł Może zawierać ten typ węzła i te dane: Musi być jednym z tych typów węzłów:
Starter Wyrażenie Sekwencyjne,
ManualStarter Sekwencyjne,
StateReader wyrażenie (zwykle składające się z wartości atrybutu cechy), IfFlow, Parallel, Sequential
Działanie Polecenie, element, wyrażenie IfFlow, Parallel, Select, Sequential
Sekwencyjna IfFlow, Parallel, Select, Sequential
Równoległe Działanie IfFlow, Sequential
Warunek Wyrażenie IfFlow, Parallel, Sequential
Wybierz Condition, Sequential, Starter, ManualStarter Sekwencyjny, musi być pierwszym węzłem w przepływie
IfFlow Action, Condition, Delay, IfFlow, Parallel, Sequential, StateReader, Suppression Sekwencyjny

DSL automatyzacji

W interfejsach Home API automatyzacje są definiowane za pomocą języka DSL (Domain-Specific Language) automatyzacji. DSL automatyzacji jest implementowany jako Kotlin DSL (język dziedzinowy), który korzysta z bezpiecznych typów kreatorów Kotlin i jest przeznaczony specjalnie do definiowania szablonów automatyzacji.

Po skompilowaniu automatyzacji konstruktory zabezpieczeń wpisywania w Kotlin generują klasy danych Kotlin, które są następnie serializowane do formatu 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, który obejmuje Matter standardowych cech i smart home cech dostępnych w interfejsie Device API.

DSL automatyzacji definiuje też logikę automatyzacji w odniesieniu do abstrakcyjnych typów urządzeń, a nie konkretnych urządzeń w domu użytkownika. Umożliwia deweloperowi podanie 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 Kotlina i jest równie bezpieczna, ale automatyzacja napisana w języku Automation DSL jest prostsza i bardziej zwięzła niż ta sama automatyzacja napisana w czystym języku Kotlin.

Przykład

Poniżej znajduje się przykładowa automatyzacja, która włącza urządzenie, napisana przy użyciu języka 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, czyli światło, włącza się (atrybut onOff zmienia się na true), wysyła polecenie on(), aby włączyć device2.

Automatyzacja używa węzła sequential, co oznacza, że jej węzły będą działać w kolejności sekwencyjnej.

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