Android-DSL-Konzepte

Hier finden Sie eine Übersicht über die grundlegenden Konzepte der Automatisierungs-DSL auf Android.

Automatisierungskomponenten

Eine Automatisierung besteht aus den folgenden grundlegenden Komponenten, die in der Regel 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 : Zusätzliche Einschränkungen, die nach der Aktivierung einer Automatisierung ausgewertet werden. Der Ausdruck in einer Bedingung muss true ergeben, damit die Aktionen einer Automatisierung ausgeführt werden können.
  3. Aktion : Befehle oder Statusaktualisierungen, die ausgeführt werden, wenn alle Bedingungen erfüllt sind.

Beispiel: Sie haben eine Automatisierung, die die Lichter 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 für ein TV-Merkmal.
  2. Bedingung : Die aktuelle Uhrzeit für das Zuhause, in dem sich der Fernseher befindet, wird ausgewertet.
  3. Aktion : Die Lichter 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 „Uhrzeit liegt zwischen Sonnenuntergang und Sonnenaufgang“ erfüllt ist.

Neben der grundlegenden Struktur enthalten Automatisierungen in den Home APIs auch Metadaten wie Name und Beschreibung, 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 Entitätsverhalten 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
Auslöser Verhaltensbezogen StarterNodeDsl Startet eine Automatisierung, wenn sich der Status eines Merkmals (ein beliebiges Attribut) ändert.
StateReader Verhaltensbezogen StateReaderNodeDsl Liest ein Attribut eines Merkmals und ermöglicht es Ihnen, seinen Wert für die Verwendung in Bedingungsknoten zu erfassen.
Aktion Verhaltensbezogen ActionNodeDsl Ruft Merkmalsbefehle 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 Ändert den Ablauf der Ausführung bedingt auf der Grundlage von 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 es, dass mehr als ein Auslöser eine Automatisierung aktiviert.
Ausdruck Wert Expression Kann der Wert eines Attributs eines Merkmals, eine Konstante oder ein Literalwert sein, und muss eine Liste, eine Zahl, einen booleschen Wert oder einen String ergeben.

Verhaltensbezogene Knoten

Knoten wie Auslöser und Aktionen sind verhaltensbezogene Knoten. Auslöser aktivieren eine Automatisierung basierend auf Änderungen von Geräteattributen. Aktionen geben Gerätebefehle aus oder aktualisieren Attribute.

Verhaltensbezogene Knoten sind in der Regel mit Geräteattributen verknüpft und geben den Status des Merkmals als Eingabe für andere Knoten aus.

Knoten für den Ablauf der Ausführung

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

Ein sequenzieller Ablauf kann beispielsweise Knoten enthalten, die in sequenzieller Reihenfolge ausgeführt werden. In der Regel sind das Auslöser, Bedingungen und Aktionen.

Sequenzielle Ausführungsabläufe
Abbildung 1: Sequenzieller Automatisierungsablauf

Ein paralleler Ablauf kann mehrere Aktionsknoten haben, die gleichzeitig ausgeführt werden, z. B. das gleichzeitige Einschalten mehrerer Lichter. 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

Eine weitere Art von Ausführungsablauf ist ein Bedingungsablauf, der den Ausführungsablauf basierend auf der Auswertung eines Ausdrucks ändern kann.

Beispiel: Sie haben eine Automatisierung, die eine Aktion ausführt, je nachdem, ob es Nacht ist. Ein Bedingungsknoten prüft die Tageszeit und folgt dann dem entsprechenden Ausführungspfad basierend auf dieser Auswertung.

Bedingungsablauf
Abbildung 3: Bedingungsablauf

Ein Auswahlablauf ist nützlich, wenn Sie mehr als einen Auslöser haben möchten, der Ihre Automatisierung aktivieren kann. Wenn Sie zwei oder mehr Auslöser in einen select-Ablauf einschließen, kann jeder der Auslöser die Automatisierung aktivieren.

Beispiel: Sie können eine Automatisierung schreiben, die die Jalousien bei Sonnenuntergang herunterlässt, wenn die Temperatur einen bestimmten Schwellenwert übersteigt oder wenn die Helligkeit einen Schwellenwert übersteigt. Drei separate Auslöser verarbeiten jedes dieser Szenarien und alle drei werden in einen select-Ablauf eingeschlossen.

Vorgang auswählen
Abbildung 4: Auswahlablauf

Verschachtelte Abläufe

In komplexen Automatisierungen können auch Knoten für den Ablauf der Ausführung verschachtelt werden. Beispiel: Sie haben einen sequenziellen Ablauf, 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 zu entsprechen. Dabei müssen die in der folgenden Tabelle aufgeführten Einschränkungen beachtet werden. Die Spalte „Builder“ enthält Links zur typsicheren Kotlin-Builder-Dokumentation, in der detailliert beschrieben wird, was in den einzelnen Knotentypen verwendet werden darf.

Tabelle: So können Knoten kombiniert werden
Knoten Kann den folgenden Knotentyp und die folgenden Daten enthalten Muss in einem der folgenden Knotentypen enthalten sein
Auslöser Ausdruck Auswählen, Sequenziell
ManualStarter Auswählen, Sequenziell
StateReader Ausdruck (besteht in der Regel aus einem Attributwert des Merkmals) Aktion, Bedingung
Aktion Befehl, Entität, Ausdruck Parallel, Auswählen, Sequenziell
Sequenziell Parallel, Auswählen, Sequenziell
Parallel Aktion Sequenziell
Bedingung Ausdruck Parallel, Sequenziell
Auswählen Bedingung, Sequenziell, Auslöser, ManualStarter Sequenziell und muss der erste Knoten im Ablauf sein

Automatisierungs-DSL

In den Home APIs werden Automatisierungen mit der Automatisierungs-DSL (Domain-Specific Language) definiert. Die Automatisierungs-DSL wird als Kotlin-DSL (Domain-Specific Language), implementiert. Dabei werden typsichere Kotlin-Builder verwendet und sie wurde speziell für die Definition von Automatisierungsvorlagen entwickelt.

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

Die Automatisierungs-DSL vereinfacht und optimiert den Prozess der Erstellung von Automatisierungen. Sie verwendet nativ dasselbe Datenmodell der Matter Standardmerkmale und smart home Merkmale die in der Device API enthalten sind.

Die Automatisierungs-DSL definiert die Logik einer Automatisierung auch in Bezug auf abstrakte Gerätetypen und nicht auf bestimmte Geräteinstanzen im Zuhause eines Nutzers. So kann der Entwickler Eingabeparameter bereitstellen, 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, die in reinem Kotlin geschrieben wurde.

Beispiel

Im Folgenden finden Sie ein Beispiel für eine Automatisierung, die ein Gerät einschaltet. Sie wurde mit der Automatisierungs-DSL geschrieben:

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, der angibt, dass die Knoten in sequenzieller Reihenfolge ausgeführt werden.

Innerhalb des sequential-Knotens befinden sich verhaltensbezogene Knoten wie starter, condition und action. Die Ausgabe des starter-Knotens wird einer Variablen zugewiesen, die im condition-Knoten verwendet wird.