Mit der Automatisierungs-DSL können komplexere automatisierte Abläufe erstellt werden als die, die im DSL-Leitfaden – Grundlegende automatisierte Abläufe unter iOS beschrieben werden.
Sequenziell mit mehreren Aktionen
Eine Automatisierung kann mehrere Aktionen ausführen. Anstelle des einzelnen action-Knotens könnten Sie beispielsweise mehrere action-Knoten haben, die nacheinander ausgeführt werden:
import GoogleHomeSDK
import GoogleHomeTypes
automation (
...
) {
starter(...)
condition {...}
action {...}
action {...}
action {...}
}
Sequenziell mit mehreren parallelen Aktionen
Wenn Sie mehrere action-Knoten in einem parallel-Knoten platzieren, werden die Aktionen gleichzeitig ausgeführt.
import GoogleHomeSDK
import GoogleHomeTypes
automation (
...
) {
starter(...)
condition {...}
parallel {
action {...}
action {...}
action {...}
}
}
Wenn im Knoten sequential nach dem Knoten parallel noch action Knoten vorhanden sind, wird mit deren Ausführung gewartet, bis alle Knoten im Knoten parallel ausgeführt wurden.
Bedingte Ausführung
Standardmäßig werden Knoten in einer Automatisierung nacheinander oder parallel ausgeführt. Wenn Sie eine bedingte Verzweigungslogik benötigen, um je nach Laufzeitbedingungen unterschiedliche Aktionen oder Pfade auszuführen, verwenden Sie if-then-else-Anweisungen, die mit den DSL-Blöcken für den bedingten Kontrollfluss erstellt werden:
ifThen,
elseIf und
orElse.
Während ein Standard-condition-Knoten die gesamte Automatisierung blockiert (wenn die Bedingung als false ausgewertet wird, wird die Ausführung der Automatisierung sofort beendet), ermöglichen ifThen-Blöcke die Verzweigung des Kontrollflusses:
condition-Knoten: Beendet die Ausführung der gesamten Automatisierung (oder des aktuellen Ausführungspfads), wenn der Ausdruckfalseist.ifThen/elseIf/orElse: Wertet Bedingungen in der angegebenen Reihenfolge aus. Wenn eine Bedingungfalseist, wird die Ausführung auf den nächstenelseIf-Zweig, denorElse-Fallback-Zweig oder auf nachfolgende Knoten in der Automatisierung übertragen, wenn keine Bedingung erfüllt ist.
Aktion basierend auf einer Bedingung ausführen
Der ifThen-Block wertet einen Bedingungsausdruck aus. Wenn der Ausdruck als true ausgewertet wird, werden die im Block verschachtelten DSL-Aktionen oder -Knoten ausgeführt. Wenn das Ergebnis false ist, werden die Aktionen übersprungen und die Automatisierung wird mit den nachfolgenden Knoten im sequenziellen Ablauf fortgesetzt.
Du kannst einen eigenständigen ifThen-Block verwenden, wenn du eine Aktion nur unter bestimmten Bedingungen ausführen möchtest, ohne nachfolgende Knoten in der Automatisierung zu blockieren oder zu beenden:
// When a door opens, turn on the light only if it is off,
// and always broadcast an announcement.
typealias ContactSensorDevice = Matter.ContactSensorDeviceType
typealias BooleanStateTrait = Matter.BooleanStateTrait
typealias DimmableLightDevice = Matter.DimmableLightDeviceType
typealias OnOffTrait = Matter.OnOffTrait
automation {
let contactState = starter(
contactSensor,
ContactSensorDevice.self,
BooleanStateTrait.self
)
let lightState = stateReader(
light,
DimmableLightDevice.self,
OnOffTrait.self
)
contactState
lightState
condition {
// Door opened (contact sensor open)
contactState.stateValue.equals(false)
}
// Conditionally turn on the light if it's off
ifThen(lightState.onOff.equals(false)) {
action(light, DimmableLightDevice.self) {
OnOffTrait.on()
}
}
// Continue executing subsequent actions in the sequential flow
action(structure) {
Google.AssistantBroadcastTrait.broadcast(msg: "The door was opened.")
}
}
Verschiedene Aktionen basierend auf einer Bedingung ausführen
Wenn Sie eine Reihe von Aktionen ausführen möchten, wenn eine Bedingung wahr ist, und eine alternative Reihe von Aktionen, wenn sie falsch ist, verketten Sie den optionalen .orElse { ... }-Block nach ifThen(...) { ... }:
// When the door is unlocked, turn on the entryway light if it is off;
// otherwise, broadcast a welcome message.
typealias DoorLockDevice = Matter.DoorLockDeviceType
typealias DoorLockTrait = Matter.DoorLockTrait
typealias DimmableLightDevice = Matter.DimmableLightDeviceType
typealias OnOffTrait = Matter.OnOffTrait
automation {
let doorLockEvent = starter(
doorLock,
DoorLockDevice.self,
DoorLockTrait.LockOperationEvent.self
)
let lightState = stateReader(
light,
DimmableLightDevice.self,
OnOffTrait.self
)
doorLockEvent
lightState
condition {
doorLockEvent.lockOperationType.equals(.unlock)
}
ifThen(lightState.onOff.equals(false)) {
action(light, DimmableLightDevice.self) {
OnOffTrait.on()
}
}.orElse {
action(structure) {
Google.AssistantBroadcastTrait.broadcast(msg: "Welcome home!")
}
}
}
Mehrere Bedingungen nacheinander verketten
Sie können einen oder mehrere optionale .elseIf(...) { ... }-Blöcke verketten, um mehrere Bedingungen nacheinander auszuwerten. Der erste Zweig, dessen Bedingung als true ausgewertet wird, wird ausgeführt und alle verbleibenden Zweige werden übersprungen. Wenn keine der Bedingungen als true ausgewertet wird, wird ein optionaler .orElse { ... }-Block ausgeführt (falls angegeben):
// Adjust climate controls based on room temperature changes.
typealias TemperatureSensorDeviceType = Matter.TemperatureSensorDeviceType
typealias TemperatureMeasurementTrait = Matter.TemperatureMeasurementTrait
typealias ThermostatDeviceType = Matter.ThermostatDeviceType
typealias SimplifiedThermostatTrait = Google.SimplifiedThermostatTrait
typealias FanDeviceType = Matter.FanDeviceType
typealias OnOffTrait = Matter.OnOffTrait
automation {
let tempStarter = starter(
tempSensor,
TemperatureSensorDeviceType.self,
TemperatureMeasurementTrait.self
)
tempStarter
// If temperature is high (>= 28°C / 2800 mC), switch thermostat to Cool mode
ifThen(tempStarter.measuredValue.greaterThanOrEquals(2800)) {
action(thermostat, ThermostatDeviceType.self) {
SimplifiedThermostatTrait.setSystemMode(systemMode: .cool)
}
}.elseIf(tempStarter.measuredValue.lessThan(1800)) {
// If temperature is low (< 18°C / 1800 mC), switch to Heat mode
action(thermostat, ThermostatDeviceType.self) {
SimplifiedThermostatTrait.setSystemMode(systemMode: .heat)
}
}.orElse {
// Otherwise, turn on the fan
action(fan, FanDeviceType.self) {
OnOffTrait.on()
}
}
}
Verschachtelte bedingte Abläufe
Bedingte Blöcke können in anderen ifThen-, elseIf- oder orElse-Blöcken verschachtelt und mit parallel-, delay(for:)- und stateReader-Knoten kombiniert werden.
ifThen-, elseIf- und orElse-Blöcke führen ihren Inhalt als sequenzielle Abläufe aus. Sie können beliebige sequenzielle Knoten in jedem Zweig platzieren, einschließlich action, stateReader, parallel, delay(for:) und verschachtelter ifThen-Blöcke.
Verzögerungen
Mit der Methode delay(for:) kannst du Pausen in deine automatisierten Abläufe einfügen. Sie verwendet das Argument Duration, das angibt, wie lange die Pause dauern soll, bevor die Ausführung fortgesetzt wird. Die Pausendauer kann zwischen fünf Sekunden und 24 Stunden betragen.
Beispiel: Eine Lampe viermal mit einer Pause von fünf Sekunden zwischen den einzelnen Schaltvorgängen umschalten:
typealias OnOffLightDevice = Matter.OnOffLightDeviceType
typealias OnOffTrait = Matter.OnOffTrait
sequential {
action(light, OnOffLightDevice.self) { OnOffTrait.toggle() }
delay(for:.seconds(5))
action(light, OnOffLightDevice.self) { OnOffTrait.toggle() }
delay(for:.seconds(5))
action(light, OnOffLightDevice.self) { OnOffTrait.toggle() }
delay(for:.seconds(5))
action(light, OnOffLightDevice.self) { OnOffTrait.toggle() }
}
Triggerunterdrückung
Mit der Triggerunterdrückung kann deine Automatisierung einen starter für einen bestimmten Zeitraum nach dem ersten auslösenden Ereignis ignorieren. Wenn die Automatisierung beispielsweise einen starter hat, der durch Bewegungserkennung ausgelöst wird, und du eine Dauer für die Auslöserunterdrückung von fünf Minuten festlegst, wird der starter nach dem Auslösen für die nächsten fünf Minuten nicht noch einmal ausgelöst. So wird verhindert, dass die Automatisierung schnell hintereinander ausgelöst wird.
Wenn du die Auslöserunterdrückung auf deine Automatisierung anwenden möchtest, verwende das Schlüsselwort suppress(for:) mit einem Duration-Argument, das angibt, wie lange gewartet werden soll, bevor auf nachfolgende Auslöser reagiert wird.
Die Dauer der Unterdrückung kann zwischen fünf Sekunden und 24 Stunden betragen.
typealias OccupancySensorDevice = Matter.OccupancySensorDeviceType
typealias OnOffLightDevice = Matter.OnOffLightDeviceType
typealias MotionDetectionTrait = Google.MotionDetectionTrait
typealias OnOffTrait = Matter.OnOffTrait
automation {
let starterNode = starter(device, OccupancySensorDevice.self, MotionDetectionTrait.self)
starterNode
suppress(for: .seconds(30 * 60)) // 30 minutes
action(light, OnOffLightDevice.self) { OnOffTrait.toggle() }
}
Die Auslöserunterdrückung wirkt sich auf alle starters in einer Automatisierung aus, die vor dem Suppression liegen.
Anzahl der Ausführungen begrenzen
Du kannst die Anzahl der Ausführungen einer Automatisierung begrenzen.
Du kannst beispielsweise eine einmalige Automatisierung einrichten, die den Staubsauger laufen lässt, während du tagsüber nicht zu Hause bist.
Legen Sie dazu das Metadatenfeld maxExecutionCount der Automatisierung fest.
Das folgende Beispiel ist eine Automatisierung, die nur einmal ausgeführt werden kann:
import GoogleHomeSDK
import GoogleHomeTypes
typealias RoboticVacuumCleanerDevice = Matter.RoboticVacuumCleanerDeviceType
typealias RvcRunModeTrait = Matter.RvcRunModeTrait
typealias AreaPresenceStateTrait = Google.AreaPresenceStateTrait
let draftAutomation = automation(
name: "Vacuum home away",
description: "Run the vacuum once when everyone is away.",
maxExecutionCount: 1
) {
let homeAwayState = starter(structure, AreaPresenceStateTrait.self)
homeAwayState
condition {
homeAwayState.presenceState.equals(.presenceStateVacant)
}
action(vacuum, RoboticVacuumCleanerDevice.self) {
RvcRunModeTrait.changeToMode(newMode: 1)
}
}
Die Automatisierung wird sofort gelöscht, nachdem sie zum letzten Mal ausgeführt wurde und maxExecutionCount erreicht ist. Der Verlaufseintrag der Automatisierung bleibt auf dem Tab Google Home app (GHA) Aktivität erhalten, einschließlich der automation_id.
Eigenschaftsattribute in einer Aktion festlegen
So legen Sie den Wert eines Attributs fest:
- Erstelle einen
update-Knoten innerhalb einesaction-Knotens und füge die relevante Eigenschaft als Argument für denupdate-Knoten hinzu:action(deviceReference, deviceType) { update(trait) { } } - Verwenden Sie im Knoten
updatefür jedes zu ändernde Attribut eine Mutatorfunktion und übergeben Sie ihr den neuen Wert. So bilden Sie den Namen der Mutatorfunktion:- Schreiben Sie den Namen des Attributs groß.
- Stellen Sie ihr das Wort
setvoran.
defaultMoveRateaktualisieren möchten, verwenden Sie eine Mutatorfunktion namenssetDefaultMoveRate.
Ein update-Knoten kann mehrere Mutatorfunktionen haben. Hier ist ein Beispiel, in dem zwei Attribute aktualisiert werden:
typealias FanDeviceType = Matter.FanDeviceType
typealias FanControlTrait = Matter.FanControlTrait
action(fan, FanDeviceType.self) {
update(FanControlTrait.self) {
$0.setFanMode(.on)
}
}