In der folgenden Anleitung wird beschrieben, wie du mit verschiedenen DSL-Knoten für die Automatisierung eine Automatisierung erstellen kannst.
Die gesamte Automatisierungs-DSL wird in einem einzelnen automation-Knoten platziert. Der Knoten automation bildet die Grenze zwischen dem äußeren Swift-Sprachkontext und dem eingebetteten DSL-Kontext.
Sequenzieller Ablauf
Der sequenzielle Ablauf ist der Standardtyp für Automatisierungsabläufe.
Hier ist eine sehr einfache Automation DSL-Vorlage, die einen sequenziellen Ablauf mit einem Auslöser, einer Bedingung und einer Aktion verwendet:
import GoogleHomeSDK
import GoogleHomeTypes
automation (
...
) {
starter(...)
condition {...}
action {...}
}
Dies kann durch Hinzufügen weiterer Knoten verfeinert werden.
Starter
Auslöserknoten definieren die anfänglichen Umstände, die eine Automatisierung aktivieren. Beispiel: eine Änderung des Status oder Werts. Eine Automatisierung muss mindestens einen Auslöser haben, sonst schlägt die Validierung fehl. Wenn du einer Automatisierung mehr als einen Auslöser hinzufügen möchtest, musst du einen select-Knoten verwenden.
Auslöser basierend auf einem Attribut
Wenn du einen Starterknoten deklarierst, der auf einem Trait-Attribut basiert, gib Folgendes an:
- das Gerät
- den Gerätetyp, zu dem das Attribut gehört
- das Merkmal
starter(
thermostat,
Matter.TemperatureSensorDeviceType.self,
Matter.TemperatureMeasurementTrait.self
)
Der Parameter „device_type“ ist erforderlich, da du damit angeben kannst, welchen Gerätetyp innerhalb eines Geräts die Automatisierung anspricht. Ein Gerät kann beispielsweise aus einem FanDeviceType und einem HeatingCoolingUnitDeviceType bestehen, die beide das Attribut OnOffTrait enthalten. Wenn du den Gerätetyp angibst, ist eindeutig, welcher Teil des Geräts die Automatisierung auslöst.
Auslöser basierend auf Ereignis
Wenn du einen Starterknoten deklarierst, der auf einem Ereignis basiert, gib Folgendes an:
- das Gerät
- den Gerätetyp, zu dem das Attribut gehört
- die Veranstaltung
starter(
doorbell,
Google.GoogleDoorbellDeviceType.self,
Google.DoorbellPressTrait.DoorbellPressedEvent
)
Auslöser basierend auf einem Gebäude und Ereignis, mit Parametern
Einige Ereignisse können Parameter haben. Diese Parameter müssen dann auch im Starter enthalten sein.
In diesem Beispiel wird der ScheduledEvent von TimeTrait verwendet, um die Automatisierung um 7:00 Uhr zu aktivieren:
typealias TimeTrait = Google.TimeTrait
let earlyMorning = starter(
structure,
TimeTrait.ScheduledEvent.self
) {
TimeTrait.ScheduledEvent.clockTime(TimeOfDay(hours: 7, minutes: 0))
}
Auslöser basierend auf dem Wetter
Du kannst aktuelle oder vorhergesagte Wetterbedingungen in einem Auslöser angeben, indem du das Attribut „Wetter“ verwendest:
let weatherState = starter<_>(structure, trait = Weather)
Weitere Informationen findest du auf der Seite Beispiele für automatisierte Abläufe unter Jalousien schließen, wenn es wahrscheinlich regnen wird.
Manueller Auslöser
Ein manueller Auslöser ist ein spezieller Auslöser, mit dem der Nutzer die Automatisierung manuell ausführen kann.
Wenn du einen manuellen Auslöser deklarierst:
- Gib kein Attribut und keinen Gerätetyp an.
- Stellen Sie ein UI-Element bereit, das
Automation.execute()aufruft.
Wenn du einen manuellen Auslöser zusammen mit einem anderen Auslöser in einem select-Ablauf platzierst, überschreibt der manuelle Auslöser den anderen Auslöser:
select {
manualStarter()
starter(
thermostat,
Matter.TemperatureSensorDeviceType.self,
Matter.TemperatureMeasurementTrait.self
)
}
Beachte, dass alle condition-Knoten, die auf einen manuellen Auslöser folgen, ausgewertet werden und die Ausführung der Automatisierung je nach condition-Ausdruck blockieren können.
Eine Möglichkeit, deine Automatisierung so zu strukturieren, dass condition-Knoten eine Automatisierung, die mit einem manuellen Auslöser aktiviert wurde, nicht blockieren, besteht darin, den anderen Auslöser zusammen mit seinem condition in einen separaten sequenziellen Ablauf zu platzieren:
import GoogleHomeSDK
import GoogleHomeTypes
automation (
...
) {
select {
sequential {
starter(...)
condition {...}
}
sequential {
manualStarter()
}
}
action {...}
}
Auf den Wert eines Attributs verweisen
Wenn Sie den Wert eines Attributs in einem Ausdruck verwenden möchten, verwenden Sie die folgende Syntax.
Mit einem stateReader:
typealias TimeTrait = Google.TimeTrait
let time = stateReader(structure, TimeTrait.self)
time
let currTime = time.currentTime
Mit einem starter:
typealias LaundryWasherDeviceType = Matter.LaundryWasherDeviceType
typealias OnOffTrait = Google.OnOffTrait
let starterNode = starter(device1, LaundryWasherDeviceType.self, OnOffTrait.self)
starterNode
condition {
starterNode.onOff.equals(true)
}
Bedingungsknoten und -ausdrücke
Ein Bedingungsknoten stellt einen Entscheidungspunkt dar, der bestimmt, ob die Automatisierung fortgesetzt wird oder nicht. Eine Automatisierung kann mehrere condition-Knoten haben.
Wenn der Ausdruck eines condition-Knotens als false ausgewertet wird, wird die Ausführung der gesamten Automatisierung beendet.
In einem condition-Knoten können Sie mehrere Bedingungskriterien mit verschiedenen Operatoren kombinieren, solange der Ausdruck zu einem einzelnen booleschen Wert ausgewertet wird. Wenn der resultierende Wert true ist, ist die Bedingung erfüllt und die Automatisierung fährt mit der Ausführung des nächsten Knotens fort. Wenn der Wert false ist, wird die Automatisierung an dieser Stelle beendet.
Ausdrücke werden ähnlich wie Ausdrücke in Swift gebildet und können primitive Werte wie Zahlen, Zeichen, Strings und boolesche Werte sowie Enum-Werte enthalten. Wenn Sie Unterausdrücke mit Klammern gruppieren, können Sie die Reihenfolge steuern, in der sie ausgewertet werden.
Hier ist ein Beispiel für einen condition, der mehrere Unterausdrücke in einem einzigen Ausdruck kombiniert:
condition {
let exp1 = starterNode.lockState.equals(.unlocked)
let exp2 = stateReaderNode.lockState.equals(true)
let exp3 = occupancySensingDevice.occupied.notEquals(0)
(exp1.and(exp2)).or(exp3)
}
Du kannst auf den Wert einer Eigenschaft verweisen, auf die über einen Auslöser zugegriffen wird:
typealias OnOffTrait = Matter.OnOffTrait
let starterNode = starter(device, OnOffTrait.self)
starterNode
condition {
starterNode.onOff.equals(true)
}
val starterNode = starter<_>(device, OnOff)
condition() { expression = starterNode.onOff equals true }
stateReader
Die andere Möglichkeit, auf Attributwerte von Eigenschaften in einem condition-Knoten zu verweisen, ist ein stateReader-Knoten.
Erfassen Sie dazu zuerst den Attributwert „trait“ in einem stateReader-Knoten. Ein stateReader verwendet die structure und das Attribut als Argumente:
typealias ActivatedCarbonFilterMonitoringTrait = Matter.ActivatedCarbonFilterMonitoringTrait
let filterMonitoringState = stateReader(structure, ActivatedCarbonFilterMonitoringTrait.self)
Verweisen Sie dann im Knoten condition auf die stateReader:
condition {
filterMonitoringState.changeIndication.equals(.warning)
}
Mit Vergleichs- und logischen Operatoren können mehrere stateReaders in einem condition-Knoten verwendet werden:
typealias ArmDisarm = Google.ArmDisarmTrait
typealias DoorLockDevice = Matter.DoorLockDeviceType
typealias DoorLock = Matter.DoorLockTrait
let armState = stateReader(doorLock, DoorLockDevice.self, ArmDisarm )
let doorLockState = stateReader(doorLock, DoorLockDevice.self, DoorLock)
armState
doorLockState
condition {
let exp1 = armState.armState
let exp2 = doorLockState.lockState
exp1.and(exp2)
}
Dauer der Bedingung
Zusätzlich zu einem booleschen Ausdruck in einer Bedingung kannst du einen Zeitraum angeben, in dem der Ausdruck wahr sein muss, damit die Automatisierung ausgeführt wird. Du kannst beispielsweise eine Bedingung definieren, die nur ausgelöst wird, wenn ein Licht zehn Minuten lang eingeschaltet war.
condition(for: .seconds(600)) {
lightStateReader.onOff.equals(true)
}
Die Dauer kann zwischen einer und 30 Minuten liegen.
Aktionsknoten
Im Aktionsknoten wird die Arbeit der Automatisierung ausgeführt.
In diesem Beispiel ruft die Aktion den Befehl broadcast() des AssistantBroadcastTrait auf:
action(speaker, SpeakerDeviceType.self) {
Google.AssistantBroadcastTrait.broadcast(msg: "Oven Cycle Complete")
}