DSL-Konzepte

Hier finden Sie eine Übersicht über die grundlegenden Konzepte der Automation DSL.

Automatisierungskomponenten

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

  1. Auslöser: Hiermit werden die Anfangsbedingungen definiert, die die Automatisierung aktivieren, z. B. eine Änderung an einem Attribut. Eine Automatisierung muss einen Auslöser haben.
  2. Bedingung: Zusätzliche Einschränkungen, die nach der Aktivierung einer Automatisierung ausgewertet werden sollen. Der Ausdruck in einer Bedingung muss true ergeben, damit die Aktionen einer Automatisierung fortgesetzt werden.
  3. Aktion: Befehle oder Statusaktualisierungen, die ausgeführt werden, wenn alle Bedingungen erfüllt sind.

Vielleicht haben Sie beispielsweise eine Automatisierung, die das Licht in einem Raum gedimmt, wenn der Fernseher in diesem Raum zwischen Sonnenuntergang und Sonnenaufgang eingeschaltet ist. In diesem Fall gilt Folgendes:

  1. Starter: Der Fernseher wurde eingeschaltet. Dies ist eine Statusänderung bei einem Fernsehermerkmal.
  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 ist, aber nur ausgeführt, wenn die Bedingung „Zeit zwischen Sonnenuntergang und Sonnenaufgang“ erfüllt ist.

Zusätzlich zur grundlegenden Struktur enthalten Automatisierungen 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 nodes. Knoten sind abstrakte, wiederverwendbare Einheiten, die das Verhalten von Entitäten oder Ausführungsabläufe darstellen. Jeder Knoten kann Eingabe- und Ausgabevariablen haben, die von anderen Knoten verwendet werden können.

Tabelle: Arten von Automatisierungsknoten
Knoten Knotentyp Kotlin-Implementierung Beschreibung
Auslöser Verhaltensbezogen StarterNodeDsl Eine Automatisierung wird gestartet, wenn sich der Status eines Attributs ändert.
StateReader Verhaltensbezogen StateReaderNodeDsl Liest ein Merkmalattribut und ermöglicht es, den Wert für die Verwendung in Bedingungsknoten zu erfassen.
Aktion Verhaltensbezogen ActionNodeDsl Ruft Befehl(e) für Eigenschaften auf.
Sequenziell Ablauf der Ausführung SequentialFlow Führt verschachtelte Aktionsknoten nacheinander aus. Das ist das Standardausführungsverhalten.
Parallel Ablauf der Ausführung ParallelFlow Führt verschachtelte Aktionsknoten parallel aus.
Bedingung Ablauf der Ausführung ConditionNodeDsl Sie können den Ablauf der Ausführung bedingt anhand der Auswertung logischer Ausdrücke ändern. Bedingungen können mit einem Auslöser verknüpft sein (auslöserspezifische Bedingungen) oder global sein (für alle Auslöser gelten).
Auswählen Ablauf der Ausführung SelectFlow Ermöglicht es, eine Automatisierung durch mehrere Auslöser zu aktivieren.
Expression Wert Expression Kann der Wert des Attributs eines Merkmals, eine Konstante oder ein Literalwert sein und muss zu einer Liste, Zahl, einem booleschen Wert oder einem String führen.

Verhaltensknoten

Knoten wie Auslöser und Aktionen sind Verhaltensknoten. Auslöser aktivieren eine Automatisierung basierend auf Änderungen von Geräteattributen. Mit Aktionen werden Gerätebefehle ausgegeben oder Attribute aktualisiert.

Verhaltensknoten sind in der Regel mit Gerätemerkmalen und dem Ausgabemerkmalenstatus verknüpft, um sie als Eingabe in anderen Knoten zu verwenden.

Knoten des Ablaufs der Ausführung

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

Ein sequentieller Ablauf kann beispielsweise Knoten enthalten, die in einer bestimmten Reihenfolge ausgeführt werden. In der Regel sind das Auslöser, Bedingung und Aktion.

Sequenzielle Ausführungsabläufe
Abbildung 1: Sequenzieller Ablauf der Automatisierung

In einem parallelen Ablauf können mehrere Aktionsknoten gleichzeitig ausgeführt werden, z. B. wenn mehrere Lampen gleichzeitig eingeschaltet werden sollen. Knoten, die einem parallelen Ablauf folgen, werden erst ausgeführt, wenn alle Verzweigungen des parallelen Ablaufs abgeschlossen sind.

Abläufe für parallele Ausführung
Abbildung 2: Paralleler Automatisierungsablauf

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

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

Bedingter Ablauf
Abbildung 3: Ablauf mit Bedingungen

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

Sie können beispielsweise eine Automatisierung erstellen, die die Jalousien bei Sonnenuntergang schließt, wenn die Temperatur über einen bestimmten Wert steigt oder wenn die Helligkeit einen bestimmten Wert überschreitet. Für jedes dieser Szenarien werden drei separate Auslöser verwendet, die alle in einem select-Ablauf verpackt werden.

Ablauf auswählen
Abbildung 4: Ablauf auswählen

Verschachtelte Abläufe

In komplexen Automatisierungen können Ausführungsablaufknoten auch verschachtelt werden. Beispielsweise können Sie einen sequenziellen Ablauf haben, der einen parallelen Ablauf ausführt.

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

DSL-Knoten können je nach Ihren spezifischen Anforderungen auf verschiedene Arten verschachtelt und kombiniert werden. Beachten Sie dabei die Einschränkungen in der folgenden Tabelle. Die Spalte „Builder“ enthält einen Link zur Dokumentation der typensicheren Builder von Kotlin, in der beschrieben wird, was für jeden Knotentyp zulässig ist.

Tabelle: Kombinationsmöglichkeiten von Knoten
Knoten Builder Kann den folgenden Knotentyp und die folgenden Daten enthalten Muss zu einem der folgenden Knotentypen gehören
Auslöser AutomationBuilder Ausdruck Auswählen, Sequenziell
ManualStarter AutomationBuilder Auswählen, Sequenziell
StateReader AutomationBuilder Ausdruck (normalerweise ein Merkmalattributwert) Aktion, Bedingung
Aktion ActionBuilder Befehl, Entität, Ausdruck Parallel, Auswahl, Sequenziell
Sequenziell SequentialFlowBuilder Parallel, Auswahl, Sequenziell
Parallel ParallelFlowBuilder Aktion Sequenziell
Bedingung ConditionBuilder Ausdruck Parallel, Sequenziell
Auswählen AutomationBuilder Bedingung, Sequenziell, Auslöser, ManualStarter Sequenziell und muss der erste Knoten im Ablauf sein

Automation DSL

In den Home APIs werden Automatisierungen mit der Automation DSL (Domain-Specific Language) definiert. Die Automation DSL ist als Kotlin-DSL (domainspezifische Sprache) implementiert und verwendet typsichere Kotlin-Builder. Sie wurde speziell für die Definition von Automatisierungsvorlagen entwickelt.

Beim Kompilieren einer Automatisierung generieren typsichere Kotlin-Builder Kotlin-Datenklassen, die dann in Protocol Buffer JSON serialisiert werden. Diese werden verwendet, um die Automatisierungsdienste von Google aufzurufen.

Die Automation DSL vereinfacht und optimiert den Prozess zum Erstellen von Automatisierungen. Sie verwendet nativ dasselbe Datenmodell mit Matter-Standardmerkmalen und smart home-Merkmalen wie die Device API.

Die Automation DSL definiert auch die Logik einer Automatisierung 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 ebenfalls typsicher. Eine Automatisierung, die in der Automation DSL geschrieben ist, ist jedoch einfacher und prägnanter als dieselbe Automatisierung, die in reiner Kotlin-Syntax geschrieben ist.

Beispiel

Im Folgenden finden Sie ein Beispiel für eine Automatisierung, die ein Gerät einschaltet. Sie wurde mit der Automation 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 onOff-Attribut ändert sich in true), wird der Befehl on() gesendet, um device2 einzuschalten.

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

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