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ć 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 po spełnieniu wszystkich warunków.

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.
Sekwencyjna Przepływ wykonania SequentialFlow Wykonuje zagnieżdżone węzły działań w kolejności. Jest to domyślne zachowanie wykonania.
Sieć równoległa 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, które są 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 wykonywania
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, Sekwencyjna
ManualStarter Wybierz, Sekwencyjna
StateReader Wyrażenie (zwykle składające się z wartości atrybutu cechy) Działanie, Warunek
Działanie Polecenie, Encja, Wyrażenie Sieć równoległa, Wybierz, Sekwencyjna
Sekwencyjna Sieć równoległa, Wybierz, Sekwencyjna
Sieć równoległa Działanie Sekwencyjna
Warunek Wyrażenie Sieć równoległa, Sekwencyjna
Wybierz Warunek, Sekwencyjna, Polecenie inicjujące, ManualStarter Sekwencyjna i musi być pierwszym węzłem w przepływie

DSL automatyzacji

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

Gdy automatyzacja jest kompilowana, bezpieczne typy builderów w Kotlinie generują klasy danych w Kotlinie, 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 korzysta z 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ń oraz innych ważnych wartości parametrów.

Składnia DSL jest podobna do składni Kotliny i jest równie bezpieczna pod względem typów, ale automatyzacja napisana w DSL automatyzacji jest prostsza i bardziej zwięzła niż ta sama automatyzacja napisana w czystej 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, co oznacza, że jej węzły będą wykonywane 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.