请参阅以下指南,了解如何使用各种自动化 DSL 节点来构建自动化。
所有自动化 DSL 都放置在单个 automation 节点中。automation 节点构成了外部 Swift 语言上下文与嵌入式 DSL 上下文之间的边界。
依序流程
顺序流程是默认的自动化流程类型。
下面是一个非常基本的自动化 DSL 模板,它使用由启动方式、条件和操作组成的顺序流程:
import GoogleHomeSDK
import GoogleHomeTypes
automation (
...
) {
starter(...)
condition {...}
action {...}
}
您可以通过添加其他节点来优化此设置。
入门版
启动方式节点定义了激活自动化操作的初始情况。例如,状态或值的变化。自动化操作必须至少有一个启动器,否则将无法通过验证。如需向自动化操作添加多个启动方式,您必须使用 select 节点。
基于特征属性的启动器
声明基于特征属性的起始节点时,请指定:
- 此设备
- 特征所属的设备类型
- trait
starter(
thermostat,
Matter.TemperatureSensorDeviceType.self,
Matter.TemperatureMeasurementTrait.self
)
设备类型参数是必需的,因为您可以通过它指定自动化操作针对的是设备中的哪种设备类型。例如,设备可能由 FanDeviceType 和 HeatingCoolingUnitDeviceType 组成,两者都包含 OnOffTrait 特征。通过指定设备类型,可以明确设备的哪个部分触发了自动化操作。
基于事件的启动方式
声明基于事件的起始节点时,请指定:
- 此设备
- 特征所属的设备类型
- 事件
starter(
doorbell,
Google.GoogleDoorbellDeviceType.self,
Google.DoorbellPressTrait.DoorbellPressedEvent
)
基于结构和事件的启动器,带有参数
某些事件可以具有参数,因此这些参数也需要包含在 starter 中。
例如,此启动方式使用 TimeTrait 的 ScheduledEvent 在上午 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 中的表达式类似,可能包含原始值(例如数字、字符、字符串和布尔值)以及枚举值。使用圆括号对子表达式进行分组,可让您控制其求值顺序。
以下示例展示了如何使用 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 节点。
为此,请先在 stateReader 节点中捕获特征属性值。stateReader 接受 structure 和 trait 作为参数:
typealias ActivatedCarbonFilterMonitoringTrait = Matter.ActivatedCarbonFilterMonitoringTrait
let filterMonitoringState = stateReader(structure, ActivatedCarbonFilterMonitoringTrait.self)
然后在 condition 节点中引用 stateReader:
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)
}
条件持续时间
除了在条件中指定布尔表达式之外,您还可以指定一个时间范围,在此期间,表达式必须为 true 才能运行自动化操作。例如,您可以定义一个仅在灯亮了 10 分钟后才触发的条件。
condition(for: .seconds(600)) {
lightStateReader.onOff.equals(true)
}
时长可以介于 1 到 30 分钟之间。
操作节点
操作节点是执行自动化操作的地方。
在此示例中,该操作会调用 AssistantBroadcastTrait 的 broadcast() 命令:
action(speaker, SpeakerDeviceType.self) {
Google.AssistantBroadcastTrait.broadcast(msg: "Oven Cycle Complete")
}