Android-DSL-Konzepte

Dies ist eine Übersicht über die grundlegenden Konzepte der Automatisierungs-DSL unter Android.

Automatisierungskomponenten

Eine Automatisierung besteht aus den folgenden grundlegenden Komponenten, die normalerweise in dieser Reihenfolge ausgewertet werden:

  1. Auslöser: Definiert die Anfangsbedingungen, die die Automatisierung aktivieren, z. B. eine Änderung eines Merkmals. Eine Automatisierung muss einen Auslöser haben.
  2. Bedingung: Alle zusätzlichen Einschränkungen, die nach der Aktivierung einer Automatisierung ausgewertet werden sollen. Der Ausdruck in einer Bedingung muss als true ausgewertet werden, damit die Aktionen einer Automatisierung fortgesetzt werden können.
  3. Aktion: Befehle oder Statusaktualisierungen, die ausgeführt werden, wenn alle Bedingungen erfüllt sind.

Beispiel: Du hast eine Automatisierung, die das Licht in einem Raum dimmt, wenn der Fernseher in diesem Raum zwischen Sonnenuntergang und Sonnenaufgang eingeschaltet wird. In diesem Fall gilt Folgendes:

  1. Auslöser: Der Fernseher wurde eingeschaltet. Das ist eine Statusänderung bei einer Eigenschaft des Fernsehers.
  2. Bedingung: Die aktuelle Uhrzeit für das Zuhause, in dem sich der Fernseher befindet, wird ausgewertet.
  3. Aktion – Die Lampen im selben Raum wie der Fernseher werden gedimmt.

Die Automatisierung wird aktiviert, wenn der Fernseher im Raum eingeschaltet wird. Sie wird jedoch nur ausgeführt, wenn die Bedingung „Zeit zwischen Sonnenuntergang und Sonnenaufgang“ erfüllt ist.

Zusätzlich zur grundlegenden Struktur enthalten automatisierte Abläufe in den Home APIs auch Metadaten wie name und description, mit denen sie für Entwickler und Nutzer identifiziert werden können.

Knoten

In den Home APIs besteht die logische Struktur einer Automatisierung aus Knoten. Knoten sind abstrakte, wiederverwendbare Einheiten, die das Verhalten von Entitäten oder Ausführungsabläufe darstellen. Jeder Knoten kann Eingabevariablen sowie Ausgabevariablen haben, die von anderen Knoten verwendet werden können.

Tabelle: Arten von Automatisierungsknoten
Knoten Knotentyp Kotlin-Implementierung Beschreibung
Starter Verhalten StarterNodeDsl Startet eine Automatisierung, wenn sich der Status eines Merkmals (beliebiges Attribut) ändert.
StateReader Verhalten StateReaderNodeDsl Liest ein Trait-Attribut und ermöglicht es Ihnen, seinen Wert für die Verwendung in Bedingungsknoten zu erfassen.
Aktion Verhalten ActionNodeDsl Ruft Befehle für Attribute auf.
Sequenziell Ablauf der Ausführung SequentialFlow Führt verschachtelte Aktionsknoten nacheinander aus. Dies ist das Standardverhalten bei der Ausführung.
Parallel Ablauf der Ausführung ParallelFlow Führt verschachtelte Aktionsknoten parallel aus.
Bedingung Ablauf der Ausführung ConditionNodeDsl Ändern Sie den Ausführungsablauf bedingt basierend auf Auswertungen logischer Ausdrücke. Bedingungen können mit einem Auslöser verknüpft sein (auslöserspezifische Bedingungen) oder global sein (gelten für alle Auslöser).
Auswählen Ablauf der Ausführung SelectFlow Ermöglicht, dass mehr als ein Auslöser eine Automatisierung aktiviert.
IfFlow Ablauf der Ausführung IfFlowDsl Führt höchstens eine Aktion (oder einen Zweig) aus, je nachdem, welche Bedingung (falls vorhanden) als wahr ausgewertet wird (ähnlich einer if-then-else-Anweisung).
Expression Wert Expression Kann der Wert eines Attributs eines Merkmals, eine Konstante oder ein Literalwert sein und muss als Liste, Zahl, boolescher Wert oder String ausgewertet werden.

Verhaltensknoten

Knoten wie Auslöser und Aktionen sind Verhaltensknoten. Auslöser aktivieren einen automatisierten Ablauf basierend auf Änderungen von Geräteattributen. Aktionen geben Gerätebefehle aus oder aktualisieren Attribute.

Verhaltensknoten sind in der Regel mit Gerätemerkmalen verknüpft und geben den Status von Merkmalen aus, der als Eingabe in anderen Knoten verwendet werden kann.

Knoten für den Ausführungsablauf

Einige Knoten stellen Ausführungsabläufe dar, z. B. sequenziell und parallel. Jeder dieser Knoten enthält die Verhaltensknoten, die die Automatisierung definieren.

Ein sequenzieller Ablauf kann beispielsweise Knoten enthalten, die nacheinander ausgeführt werden. In der Regel sind das Auslöser, Bedingung und Aktion.

Sequenzielle Ausführungsabläufe
Abbildung 1: Sequenzieller Automatisierungsablauf

Bei einem parallelen Ablauf können mehrere Aktionsknoten gleichzeitig ausgeführt werden, z. B. das gleichzeitige Einschalten mehrerer Lampen. Knoten, die einem parallelen Ablauf folgen, werden erst ausgeführt, wenn alle Zweige des parallelen Ablaufs abgeschlossen sind.

Parallele Ausführungsabläufe
Abbildung 2: Paralleler Automatisierungsablauf

Ein weiterer Typ von Ausführungsablauf ist ein Bedingungsablauf, der den Ausführungsablauf basierend auf der Auswertung eines Ausdrucks ändern kann.

Beispiel: Du hast eine Automatisierung, die eine Aktion ausführt, wenn es Nacht ist. Ein Bedingungsknoten prüft die Uhrzeit und folgt dann dem entsprechenden Ausführungspfad basierend auf dieser Bewertung.

Bedingungsablauf
Abbildung 3: Bedingungsablauf

Ein Auswahl-Ablauf ist nützlich, wenn du mehr als einen Auslöser haben möchtest, der deine Automatisierung aktivieren kann. Wenn du zwei oder mehr Auslöser in einen select-Ablauf einfügst, kann jeder der Auslöser die Automatisierung aktivieren.

Du könntest beispielsweise eine Automatisierung erstellen, die die Jalousien bei Sonnenuntergang herunterlässt, wenn die Temperatur einen bestimmten Schwellenwert überschreitet oder wenn die Helligkeit einen Schwellenwert überschreitet. Für jedes dieser Szenarien gibt es einen separaten Starter. Alle drei werden in einem select-Ablauf zusammengefasst.

Ablauf auswählen
Abbildung 4: Ablauf auswählen

Ein if-then-else-Ablauf (IfFlow) ermöglicht die verzweigte bedingte Ausführung innerhalb einer Automatisierung. Im Gegensatz zu einem condition-Knoten, der die gesamte Automatisierung stoppt, wenn die Bedingung false ist, führt ein If-Then-Else-Ablauf bestimmte Aktionen bedingt aus, wenn eine Bedingung erfüllt ist. Er kann auf alternative Bedingungen oder Fallback-Aktionen zurückgreifen oder mit nachfolgenden Knoten in der Automatisierung fortfahren. Weitere Informationen finden Sie unter Bedingte Ausführung.

Verschachtelte Abläufe

In komplexen automatisierten Abläufen können Ausführungsablaufknoten auch verschachtelt sein. Sie können beispielsweise einen sequenziellen Ablauf haben, der einen parallelen Ablauf ausführt.

Verschachtelte Ausführungsabläufe
Abbildung 5: Verschachtelte Ausführungsabläufe

DSL-Knoten können auf verschiedene Weise verschachtelt und kombiniert werden, um Ihren spezifischen Anforderungen gerecht zu werden. Dabei gelten die in der folgenden Tabelle aufgeführten Einschränkungen. Die Spalte „Builder“ enthält Links zur Dokumentation zum typsicheren Kotlin-Builder, in der detailliert beschrieben wird, was für die Verwendung in den einzelnen Knotentypen zulässig ist.

Tabelle: Wie Knoten kombiniert werden können
Knoten Kann den folgenden Knotentyp und die folgenden Daten enthalten Muss innerhalb eines der folgenden Knotentypen liegen
Starter Ausdruck Auswählen, Sequenziell
ManualStarter Auswählen, Sequenziell
StateReader Ausdruck (besteht in der Regel aus einem Attributwert) IfFlow, Parallel, Sequential
Aktion Befehl, Entität, Ausdruck IfFlow, Parallel, Select, Sequential
Sequenziell IfFlow, Parallel, Select, Sequential
Parallel Aktion IfFlow, sequenziell
Bedingung Ausdruck IfFlow, Parallel, Sequential
Auswählen Condition, Sequential, Starter, ManualStarter Sequenziell und muss der erste Knoten im Ablauf sein
IfFlow Action, Condition, Delay, IfFlow, Parallel, Sequential, StateReader, Suppression Sequenziell

Automatisierungs-DSL

In den Home APIs werden automatisierte Abläufe mithilfe der Automation DSL (Domain-Specific Language) definiert. Die Automatisierungs-DSL ist als Kotlin-DSL (domänenspezifische Sprache) implementiert. Sie verwendet typsichere Kotlin-Builder und wurde speziell für die Definition von Automatisierungsvorlagen entwickelt.

Wenn eine Automatisierung kompiliert wird, generieren typsichere Kotlin-Builder Kotlin-Datenklassen, die dann in Protokollzwischenspeicher-JSON serialisiert werden. Diese werden verwendet, um Aufrufe an die Automatisierungsdienste von Google zu senden.

Die Automatisierungs-DSL vereinfacht und optimiert den Prozess der Erstellung von Automatisierungen. Es verwendet nativ dasselbe Datenmodell mit Matter-Standard-Traits und smart home-Traits, die in der Device API enthalten sind.

Die Automatisierungs-DSL definiert die Logik einer Automatisierung auch in Bezug auf abstrakte Gerätetypen, im Gegensatz zu bestimmten Geräteinstanzen im Zuhause eines Nutzers. Der Entwickler kann Eingabeparameter angeben, die zur Laufzeit verwendet werden können, um tatsächliche Geräteinstanzen sowie andere wichtige Parameterwerte anzugeben.

Die DSL-Syntax ähnelt der von Kotlin und ist ebenso typsicher. Eine in der Automatisierungs-DSL geschriebene Automatisierung ist jedoch einfacher und prägnanter als dieselbe Automatisierung in reinem Kotlin.

Beispiel

Das folgende Beispiel zeigt eine Automatisierung, die ein Gerät einschaltet, geschrieben mit der Automation DSL:

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()) }
  }
}

Diese Automatisierung ist sehr einfach: Wenn device1, eine Lampe, eingeschaltet wird (das Attribut onOff ändert sich zu true), wird der Befehl on() gesendet, um device2 einzuschalten.

Die Automatisierung verwendet einen sequential-Knoten, was bedeutet, dass die Knoten nacheinander ausgeführt werden.

Im Knoten sequential befinden sich Verhaltensknoten wie starter, condition und action. Die Ausgabe des Knotens starter wird einer Variablen zugewiesen, die im Knoten condition verwendet werden soll.