iOS DSL 指南

请参阅以下指南,了解如何使用各种 Automation DSL 节点构建自动化操作。

所有自动化 DSL 都位于单个 automation 节点中。automation 节点构成了外部 Swift 语言上下文与嵌入式 DSL 上下文之间的边界。

顺序流

顺序流程是自动化流程的默认类型。

顺序 DSL 示例

以下是一个非常基本的自动化 DSL 模板,它使用由启动器、条件和操作组成的顺序流程:

import GoogleHomeSDK
import GoogleHomeTypes

automation (
...
) {
  starter(...)
  condition {...}
  action {...}
}

您可以通过添加其他节点来优化此模型。

入门版

启动器节点用于定义启用自动化操作的初始情况。例如,状态或值的变化。自动化操作必须至少有一个启动器,否则将无法通过验证。如需向自动化操作添加多个启动器,您必须使用 select 节点。

基于 trait 属性的起始页

声明基于 trait 属性的起始节点时,请指定:

  • 设备
  • 特征所属的设备类型
  • trait
starter(
  thermostat,
  Matter.TemperatureSensorDeviceType.self,
  Matter.TemperatureMeasurementTrait.self
)

设备类型参数是必需的,因为您可以通过该参数指定自动化操作要处理的设备中的哪种设备类型。例如,设备可能由 FanDeviceTypeHeatingCoolingUnitDeviceType 组成,这两个 widget 都包含 OnOffTrait trait。通过指定设备类型,可以明确设备的哪个部分触发自动化操作。

基于事件的启动器

声明基于事件的启动器节点时,请指定:

  • 设备
  • 特征所属的设备类型
  • 事件
starter(
  doorbell,
  Google.GoogleDoorbellDeviceType.self,
  Google.DoorbellPressTrait.DoorbellPressedEvent
)

基于结构和事件的起始代码(包含参数)

某些事件可能包含参数,因此这些参数也需要包含在起始配置中。

例如,此启动器使用 TimeTraitScheduledEvent 在 7:00 上午启用自动化操作:

typealias TimeTrait = Google.TimeTrait

let earlyMorning = starter(
  structure,
  TimeTrait.ScheduledEvent.self
) {
  TimeTrait.ScheduledEvent.clockTime(TimeOfDay(hours: 7, minutes: 0))
}

手动启动器

手动启动器是一种特殊类型的启动器,可让用户手动运行自动化操作。

声明手动启动器时:

将手动启动器与其他启动器一起放置在 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)
}

您可以引用通过启动器访问的 trait 的值:

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 节点中引用 trait 属性值的另一种方法是使用 stateReader 节点。

为此,请先捕获 stateReader 节点中的 trait 属性值。stateReaderstructure 和 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 分钟之间。

操作节点

操作节点是自动化操作的工作场所。在此示例中,操作会调用 AssistantBroadcastTraitbroadcast() 命令:

action(speaker, SpeakerDeviceType.self) {
  Google.AssistantBroadcastTrait.broadcast(msg: "Oven Cycle Complete")
}