Язык автоматизации Automation DSL позволяет создавать автоматизации, более сложные, чем те, которые описаны в руководстве по DSL — базовые автоматизации на Android .
Последовательный, с несколькими действиями
Автоматизация может выполнять несколько действий. Например, вместо одного узла action можно использовать несколько узлов action , которые выполняются последовательно:
automation {
sequential {
starter<_>(...)
condition {...}
action {...}
action {...}
action {...}
}
}
Последовательный, с множеством параллельных действий
Если разместить несколько узлов action в parallel узле, действия будут выполняться одновременно.
automation {
sequential {
starter<_>(...)
condition {...}
parallel {
action {...}
action {...}
action {...}
}
}
}
Если в sequential узле есть узлы action , следующие за parallel узлом, они ожидают завершения выполнения всех узлов в parallel узле.
Условное исполнение
По умолчанию автоматизация выполняет узлы последовательно или параллельно. Если вам нужна логика условного ветвления — выполнение различных действий или путей в зависимости от условий во время выполнения — используйте операторы if-then-else , которые строятся с использованием блоков DSL условного управления потоком: ifThen , elseIf и orElse .
В то время как стандартный узел condition ограничивает выполнение всей автоматизации (если условие оценивается как false , выполнение автоматизации немедленно прекращается), блоки ifThen позволяют осуществлять разветвленное управление потоком выполнения:
- Узел
condition: Останавливает выполнение всей автоматизации (или текущего пути выполнения), если выражениеfalse. -
ifThen/elseIf/orElse: Выполняет проверку условий по порядку. Если условиеfalse, выполнение переходит к следующей ветвиelseIf, к резервной ветвиorElseили продолжается к последующим узлам автоматизации, если ни одно условие не выполнено.
Выполнить действие на основе заданного условия.
Блок ifThen оценивает условное выражение. Если выражение true , выполняются действия DSL или узлы, вложенные в этот блок. Если оно false , действия пропускаются, и автоматизация продолжается с последующими узлами в последовательном потоке.
Блок ifThen можно использовать отдельно, если вы хотите выполнить действие только при определенных условиях, не блокируя и не завершая работу последующих узлов в автоматизации:
// 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."))
}
}
}
Выполнять различные действия в зависимости от условия.
Чтобы выполнить один набор действий, когда условие истинно, и альтернативный набор действий, когда оно ложно, добавьте необязательный блок .orElse { ... } после 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!"))
}
}
}
}
Последовательное выполнение нескольких условий
Вы можете объединить один или несколько необязательных блоков .elseIf(...) { ... } для последовательной оценки нескольких условий. Выполняется первая ветвь, условие которой true , а все остальные ветви пропускаются. Если ни одно из условий не true , выполняется необязательный блок .orElse { ... } (если он предоставлен):
// 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())
}
}
}
}
Вложенные условные потоки
Условные блоки могут быть вложены внутрь других блоков ifThen , elseIf или orElse , а также комбинироваться с узлами parallel , delayFor и stateReader .
Блоки ifThen , elseIf и orElse выполняют свое содержимое как последовательные потоки. Вы можете разместить любые последовательные узлы внутри каждой ветви, включая action , stateReader , parallel , delayFor и вложенные блоки ifThen .
Задержки
Вы можете добавлять паузы в свои автоматизации, используя ключевое слово delayFor , которое принимает аргумент java.time.Duration , указывающий, как долго нужно приостановить выполнение перед продолжением. Длительность паузы может составлять от пяти секунд до 24 часов.
Например, чтобы четыре раза переключить свет с пятисекундной паузой между каждым переключением:
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()) }
}
Подавление триггера
Trigger suppression is a capability that allows your automation to ignore a starter for a specified period of time after the initial triggering event. For example, if the automation has a starter that's triggered by motion detection, and if you specify a trigger suppression duration of five minutes, then when the starter triggers, it won't trigger again for the next five minutes. This prevents the automation from rapidly triggering over and over.
Для подавления срабатываний триггеров в вашей автоматизации используйте ключевое слово suppressFor с аргументом java.time.Duration , указывающим, как долго нужно ждать перед реагированием на последующие триггеры. Длительность подавления может составлять от пяти секунд до 24 часов.
automation {
sequential {
val starterNode = starter<_>(device, OccupancySensor, MotionDetection)
suppressFor(Duration.ofMinutes(30))
action(light, OnOffLightDevice) { command(OnOff.toggle()) }
}
Обратите внимание, что подавление триггеров затрагивает все starters автоматизации, предшествующие suppressFor .
Ограничьте количество выполнений.
Вы можете ограничить количество запусков автоматизации.
Например, вы можете настроить одноразовую автоматизацию, которая будет запускать пылесос, пока вас нет дома в течение дня.
Для этого установите значение поля метаданных maxExecutionCount для автоматизации. В следующем примере представлена автоматизация, которая может быть выполнена только один раз:
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()) } } }
Автоматизация немедленно удаляется после завершения ее последнего выполнения и достижения значения maxExecutionCount . Запись в истории автоматизации остается на вкладке «Активность» Google Home app (GHA) , включая automation_id .
Задайте атрибуты характеристик в действии
Чтобы задать значение атрибута признака:
- Создайте узел
updateвнутри узлаaction, включив соответствующий признак в качестве аргумента для узлаupdate:action(deviceReference, deviceType) { update(trait) { } } - Внутри узла
updateдля каждого изменяемого атрибута используйте функцию-мутатор и передайте ей новое значение. Чтобы сформировать имя функции-мутатора:- Напишите название атрибута с заглавной буквы.
- Добавьте к нему слово "
set".
defaultMoveRateвы используете функцию-мутатор с именемsetDefaultMoveRate.
Обратите внимание, что узел update может иметь несколько функций-мутаторов. Вот пример обновления двух атрибутов:
action(device, Fan) {
update(FanControl) {
setPercentSetting(50u)
setRockSetting(FanControlCluster.RockBitmap.rockUpDown)
}
}