В этом руководстве рассказывается, как использовать различные узлы DSL автоматизации для создания автоматизации.
Весь DSL автоматизации размещается в одном узле automation. Узел automation формирует границу между внешним контекстом языка Swift и встроенным контекстом DSL.
Последовательный поток
Последовательный процесс автоматизации используется по умолчанию.
Вот пример простого шаблона DSL для автоматизации, в котором используется последовательный поток, состоящий из триггера, условия и действия:
import GoogleHomeSDK
import GoogleHomeTypes
automation (
...
) {
starter(...)
condition {...}
action {...}
}
Вы можете добавить дополнительные узлы.
Для начинающих
Узлы условий определяют начальные обстоятельства, которые активируют автоматизацию. Например, изменение состояния или значения. В автоматизации должно быть хотя бы одно условие, иначе она не пройдет проверку. Чтобы добавить в автоматизацию несколько условий запуска, используйте узел select.
Стартовое условие на основе атрибута свойства
При объявлении начального узла, основанного на атрибуте признака, укажите:
- устройство
- тип устройства, к которому относится свойство;
- трейт
starter(
thermostat,
Matter.TemperatureSensorDeviceType.self,
Matter.TemperatureMeasurementTrait.self
)
Параметр device type обязателен, поскольку он позволяет указать, к какому типу устройств относится автоматизация. Например, устройство может состоять из FanDeviceType и HeatingCoolingUnitDeviceType, и оба они содержат типаж OnOffTrait. Указав тип устройства, вы точно определите, какая его часть запускает автоматизацию.
Стартовое условие на основе события
При объявлении начального узла на основе события укажите:
- устройство
- тип устройства, к которому относится свойство;
- мероприятие
starter(
doorbell,
Google.GoogleDoorbellDeviceType.self,
Google.DoorbellPressTrait.DoorbellPressedEvent
)
Стартовый шаблон на основе структуры и события с параметрами
У некоторых событий могут быть параметры, которые также нужно включить в стартер.
Например, это условие использует ScheduledEvent устройства TimeTrait, чтобы запустить автоматизацию в 7:00:
typealias TimeTrait = Google.TimeTrait
let earlyMorning = starter(
structure,
TimeTrait.ScheduledEvent.self
) {
TimeTrait.ScheduledEvent.clockTime(TimeOfDay(hours: 7, minutes: 0))
}
Триггер на основе погоды
Вы можете указать текущие или прогнозируемые погодные условия в стартовом запросе, используя типаж "Погода":
let weatherState = starter<_>(structure, trait = Weather)
См. пример Закрыть жалюзи, если возможен дождь на странице Примеры автоматизаций.
Ручной стартер
Условие запуска вручную – это особый тип условия, который позволяет пользователю запускать автоматизацию вручную.
При объявлении условия запуска вручную:
- Не указывайте тип устройства или его характеристики.
- Добавьте элемент интерфейса, который вызывает
Automation.execute().
Если в автоматизации select есть условие запуска вручную и другое условие, то условие запуска вручную переопределяет другое условие.
select {
manualStarter()
starter(
thermostat,
Matter.TemperatureSensorDeviceType.self,
Matter.TemperatureMeasurementTrait.self
)
}
Обратите внимание, что все узлы condition, следующие за условием запуска вручную, будут оцениваться и могут блокировать выполнение автоматизации в зависимости от выражения condition.
Чтобы узлы condition не блокировали автоматизацию, запущенную вручную, можно поместить другой стартер в отдельный последовательный поток вместе с его condition:
import GoogleHomeSDK
import GoogleHomeTypes
automation (
...
) {
select {
sequential {
starter(...)
condition {...}
}
sequential {
manualStarter()
}
}
action {...}
}
Как ссылаться на значение атрибута
Чтобы использовать значение атрибута в выражении, используйте следующий синтаксис.
С stateReader:
typealias TimeTrait = Google.TimeTrait
let time = stateReader(structure, TimeTrait.self)
time
let currTime = time.currentTime
С starter:
typealias LaundryWasherDeviceType = Matter.LaundryWasherDeviceType
typealias OnOffTrait = Google.OnOffTrait
let starterNode = starter(device1, LaundryWasherDeviceType.self, OnOffTrait.self)
starterNode
condition {
starterNode.onOff.equals(true)
}
Узлы и выражения условий
Узел условия представляет собой точку принятия решения, которая определяет, продолжается ли автоматизация. В автоматизации может быть несколько узлов condition.
Если выражение любого узла condition оценивается как false, выполнение всей автоматизации прекращается.
В узле condition можно объединить несколько критериев условий с помощью различных операторов, если выражение возвращает одно логическое значение. Если полученное значение – true, условие выполнено и автоматизация переходит к следующему узлу. Если возвращается значение false, автоматизация останавливается.
Выражения формируются так же, как и в Swift, и могут содержать примитивные значения, такие как числа, символы, строки и логические значения, а также значения Enum. Группировка подвыражений с помощью круглых скобок позволяет управлять порядком их вычисления.
Вот пример condition, в котором несколько подвыражений объединены в одно:
condition {
let exp1 = starterNode.lockState.equals(.unlocked)
let exp2 = stateReaderNode.lockState.equals(true)
let exp3 = occupancySensingDevice.occupied.notEquals(0)
(exp1.and(exp2)).or(exp3)
}
Вы можете ссылаться на значение свойства, доступ к которому получен через триггер:
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
Другой способ сослаться на значения атрибутов черты в узле condition – использовать узел stateReader.
Для этого сначала запишите значение атрибута trait в узел stateReader. stateReader принимает structure и признак в качестве аргументов:
typealias ActivatedCarbonFilterMonitoringTrait = Matter.ActivatedCarbonFilterMonitoringTrait
let filterMonitoringState = stateReader(structure, ActivatedCarbonFilterMonitoringTrait.self)
Затем укажите ссылку на stateReader в узле condition:
condition {
filterMonitoringState.changeIndication.equals(.warning)
}
С помощью операторов сравнения и логических операторов в узле condition можно использовать несколько элементов stateReaders:
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)
}
Длительность условия
Помимо логического выражения в условии, вы можете указать временные рамки, в течение которых выражение должно быть истинным, чтобы запустить автоматизацию. Например, можно задать условие, которое срабатывает, только если свет горит в течение десяти минут.
condition(for: .seconds(600)) {
lightStateReader.onOff.equals(true)
}
Продолжительность может составлять от 1 до 30 минут.
Узлы действий
Узел действия – это место, где выполняется работа автоматизации.
В этом примере действие вызывает команду broadcast() объекта AssistantBroadcastTrait:
action(speaker, SpeakerDeviceType.self) {
Google.AssistantBroadcastTrait.broadcast(msg: "Oven Cycle Complete")
}