Mit der Automatisierungs-DSL können komplexere Automatisierungen erstellt werden als die, die im DSL-Leitfaden – grundlegende Automatisierungen unter Android 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:
automation {
sequential {
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.
automation {
sequential {
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.
automation {
sequential {
val contactState = starter<_>(
contactSensor,
ContactSensorDevice,
BooleanState,
)
val lightState = stateReader<_>(
light,
DimmableLightDevice,
OnOff,
)
condition {
// Door opened (contact sensor open)
expression = contactState.stateValue equals false
}
// Conditionally turn on the light if it's off
ifThen(lightState.onOff equals false) {
action(light, DimmableLightDevice) { command(OnOff.on()) }
}
// Continue executing subsequent actions in the sequential flow
action(structure) {
command(AssistantBroadcast.broadcast("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.
automation {
sequential {
val doorLockEvent = starter<_>(
doorLock,
DoorLockDevice,
LockOperationEvent,
)
val lightState = stateReader<_>(
light,
DimmableLightDevice,
OnOff,
)
condition {
expression =
doorLockEvent.lockOperationType equals LockOperationTypeEnum.Unlock
}
ifThen(lightState.onOff equals false) {
action(light, DimmableLightDevice) { command(OnOff.on()) }
}.orElse {
action(structure) {
command(AssistantBroadcast.broadcast("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.
automation {
sequential {
val tempStarter = starter<_>(
tempSensor,
TemperatureSensorDevice,
TemperatureMeasurement,
)
// If temperature is high (>= 28°C / 2800 mC), switch thermostat to Cool mode
ifThen(tempStarter.measuredValue greaterThanOrEquals 2800) {
action(thermostat, ThermostatDevice) {
command(
SimplifiedThermostat.setSystemMode(
SimplifiedThermostatSystemModeEnum.Cool
)
)
}
}.elseIf(tempStarter.measuredValue lessThan 1800) {
// If temperature is low (< 18°C / 1800 mC), switch to Heat mode
action(thermostat, ThermostatDevice) {
command(
SimplifiedThermostat.setSystemMode(
SimplifiedThermostatSystemModeEnum.Heat
)
)
}
}.orElse {
// Otherwise, turn on the fan
action(fan, FanDevice) {
command(OnOff.on())
}
}
}
}
Verschachtelte bedingte Abläufe
Bedingte Blöcke können in anderen ifThen-, elseIf- oder orElse-Blöcken verschachtelt und mit parallel-, delayFor- 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, delayFor und verschachtelter ifThen-Blöcke.
Verzögerungen
Mit dem Schlüsselwort delayFor kannst du Pausen in deine Automatisierungen einfügen. Es verwendet ein java.time.Duration-Argument, 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:
sequential {
action(light, OnOffLightDevice) { command(OnOff.toggle()) }
delayFor(Duration.ofSeconds(5))
action(light, OnOffLightDevice) { command(OnOff.toggle()) }
delayFor(Duration.ofSeconds(5))
action(light, OnOffLightDevice) { command(OnOff.toggle()) }
delayFor(Duration.ofSeconds(5))
action(light, OnOffLightDevice) { command(OnOff.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 suppressFor mit einem java.time.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.
automation {
sequential {
val starterNode = starter<_>(device, OccupancySensor, MotionDetection)
suppressFor(Duration.ofMinutes(30))
action(light, OnOffLightDevice) { command(OnOff.toggle()) }
}
Die Auslöserunterdrückung wirkt sich auf alle starters in einer Automatisierung aus, die vor dem suppressFor 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:
automation { // The automation can only be executed once. maxExecutionCount = 1 // When the door lock state changes sequential { val doorLockEvent = starter<_>(doorLock, DoorLockDevice, LockOperationEvent) // if the door is unlocked condition() { expression = (doorLockEvent.lockOperationType equals LockOperationTypeEnum.Unlock) } // turn the light on action(light, DimmableLightDevice) { command(OnOff.on()) } } }
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:
action(device, Fan) {
update(FanControl) {
setPercentSetting(50u)
setRockSetting(FanControlCluster.RockBitmap.rockUpDown)
}
}