Язык автоматизации Automation DSL позволяет создавать автоматизации, более сложные, чем те, которые описаны в руководстве по DSL — базовые автоматизации на iOS .
Последовательный, с несколькими действиями
Автоматизация может выполнять несколько действий. Например, вместо одного узла action можно использовать несколько узлов action , которые выполняются последовательно:
import GoogleHomeSDK
import GoogleHomeTypes
automation (
...
) {
starter(...)
condition {...}
action {...}
action {...}
action {...}
}
Последовательный, с множеством параллельных действий
Если разместить несколько узлов action в parallel узле, действия будут выполняться одновременно.
import GoogleHomeSDK
import GoogleHomeTypes
automation (
...
) {
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.
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.")
}
}
Выполнять различные действия в зависимости от условия.
Чтобы выполнить один набор действий, когда условие истинно, и альтернативный набор действий, когда оно ложно, добавьте необязательный блок .orElse { ... } после 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!")
}
}
}
Последовательное выполнение нескольких условий
Вы можете объединить один или несколько необязательных блоков .elseIf(...) { ... } для последовательной оценки нескольких условий. Выполняется первая ветвь, условие которой true , а все остальные ветви пропускаются. Если ни одно из условий не true , выполняется необязательный блок .orElse { ... } (если он предоставлен):
// 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()
}
}
}
Вложенные условные потоки
Условные блоки могут быть вложены в другие блоки ifThen , elseIf или orElse , а также комбинироваться с узлами parallel , delay(for:) и stateReader .
Блоки ifThen , elseIf и orElse выполняют свое содержимое как последовательные потоки. Вы можете разместить любые последовательные узлы внутри каждой ветви, включая action , stateReader , parallel , delay(for:) и вложенные блоки ifThen .
Задержки
Вы можете вводить паузы в свои автоматизации, используя метод delay(for:) , который принимает аргумент Duration , указывающий, как долго нужно приостановить выполнение перед его продолжением. Длительность паузы может составлять от пяти секунд до 24 часов.
Например, чтобы четыре раза переключить свет с пятисекундной паузой между каждым переключением:
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() }
}
Подавление триггера
Функция подавления срабатывания позволяет вашей автоматизации игнорировать starter в течение заданного периода времени после первоначального срабатывания. Например, если в автоматизации есть starter , срабатывающее при обнаружении движения, и вы задали продолжительность подавления срабатывания в пять минут, то после срабатывания starter оно не будет срабатывать снова в течение следующих пяти минут. Это предотвращает быстрое и многократное срабатывание автоматизации.
Для подавления срабатывания триггеров в вашей автоматизации используйте ключевое слово suppress(for:) с аргументом Duration , указывающим, как долго нужно ждать перед реагированием на последующие триггеры. Длительность подавления может составлять от пяти секунд до 24 часов.
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() }
}
Обратите внимание, что подавление триггеров затрагивает все starters в автоматизации, предшествующие Suppression .
Ограничьте количество выполнений.
Вы можете ограничить количество запусков автоматизации.
Например, вы можете настроить одноразовую автоматизацию, которая будет запускать пылесос, пока вас нет дома в течение дня.
Для этого установите значение поля метаданных maxExecutionCount для автоматизации. В следующем примере представлена автоматизация, которая может быть выполнена только один раз:
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)
}
}
Автоматизация немедленно удаляется после завершения ее последнего выполнения и достижения значения maxExecutionCount . Запись в истории автоматизации остается на вкладке «Активность» Google Home app (GHA) , включая automation_id .
Задайте атрибуты характеристик в действии
Чтобы задать значение атрибута признака:
- Создайте узел
updateвнутри узлаaction, включив соответствующий признак в качестве аргумента для узлаupdate:action(deviceReference, deviceType) { update(trait) { } } - Внутри узла
updateдля каждого изменяемого атрибута используйте функцию-мутатор и передайте ей новое значение. Чтобы сформировать имя функции-мутатора:- Напишите название атрибута с заглавной буквы.
- Добавьте к нему слово "
set".
defaultMoveRateвы используете функцию-мутатор с именемsetDefaultMoveRate.
Обратите внимание, что узел update может иметь несколько функций-мутаторов. Вот пример обновления двух атрибутов:
typealias FanDeviceType = Matter.FanDeviceType
typealias FanControlTrait = Matter.FanControlTrait
action(fan, FanDeviceType.self) {
update(FanControlTrait.self) {
$0.setFanMode(.on)
}
}