Android DSL 指南

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

所有 Automation DSL 都位于单个 automation 节点内。automation 节点构成了外部 Kotlin 语言上下文与嵌入式 DSL 上下文之间的边界。

顺序流

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

顺序 DSL 示例

下面是一个非常基本的 Automation DSL 模板,它使用由启动方式、条件和操作组成的顺序流:


import com.google.home.automation.action
import com.google.home.automation.automation
import com.google.home.automation.condition
import com.google.home.automation.sequential
import com.google.home.automation.starter

...

automation {
  sequential {
    starter<_>(...)
    condition {...}
    action {...}
  }
}

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

启动方式

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

基于 trait 属性的启动器

声明基于 trait 属性的启动器节点时,请指定:

  • 设备
  • 特征所属的设备类型
  • 特征
starter<_>(thermostat, TemperatureSensorDevice, TemperatureMeasurement)

设备类型参数是必需的,因为它可以让您指定自动化操作所针对的设备中的哪个设备类型。例如,设备可能由 一个 FanDevice 和一个 HeatingCoolingUnitDevice组成, 这两者都包含 OnOff 特征。通过指定设备类型,可以明确是设备的哪个部分触发了自动化操作。

基于事件的启动方式

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

  • 设备
  • 特征所属的设备类型
  • 事件
starter<_>(doorBell, GoogleDoorbellDevice, DoorbellPressed)

基于结构和事件的启动方式,带有参数

某些事件可以有参数,因此这些参数也需要包含在启动器中。

例如,此启动方式使用 Time特征的ScheduledTimeEvent在上午 7:00 激活自动化操作:

val earlyMorning = starter<_>(structure, Time.ScheduledTimeEvent) {
  parameter(Time.ScheduledTimeEvent.clockTime(
    LocalTime.of(7, 0, 0, 0)))
}

基于天气的启动方式

您可以使用 Weather trait 在启动方式中指定当前或预测的天气状况:

val weatherState = starter<_>(structure, trait = Weather)

请参阅如果可能会下雨,请关闭百叶窗示例自动化操作页面上。

手动启动方式

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

声明手动启动器时:

将手动启动器与另一个启动器一起放置在 select 流中时,手动启动器会替换另一个启动器:

select {
  manualStarter()
  starter<_>(thermostat, TemperatureSensorDevice, TemperatureMeasurement)
}

请注意,手动启动方式后面的任何 condition 节点都将被评估,并且可能会阻止自动化操作的执行,具体取决于 condition 表达式。

将手动启动方式与条件启动方式分离

如需构建自动化操作,使 condition 节点不会阻止使用手动启动方式激活的自动化操作,一种方法是将另一个启动方式及其 condition 放在单独的顺序流中:

automation_graph {
  sequential {
    select {
      sequential {
        starter<_>(...)
        condition {...}
      }
      sequential {
        manualStarter()
      }
    }
    action {...}
  }
}

引用属性的值

如需在表达式中使用属性的值,请使用以下语法。

使用 stateReader

val time = stateReader<_>(structure, Structure, Time)
val currTime = time.currentTime

使用 starter

val starterNode = starter<_>(device1, LaundryWasherDevice, OnOff)
condition() {
  expression = starterNode.onOff equals true
}

条件节点和表达式

条件节点表示一个决策点,用于确定自动化操作是否继续。自动化操作可以有多个 condition 节点。 如果任何 condition 节点的表达式的计算结果为 false,则整个自动化操作的执行将结束。

condition 节点中,您可以使用 各种 运算符组合多个条件标准,只要表达式 的计算结果为单个 布尔值即可。如果结果值为 true,则满足条件,自动化操作将继续执行下一个节点。如果结果值为 false,则自动化操作将在该点停止执行。

表达式的构成方式与 Kotlin 中的表达式类似,并且可能包含原始值(例如数字、字符、字符串和布尔值)以及枚举值。使用圆括号对子表达式进行分组,可让您控制它们的计算顺序。

下面是一个 condition 的示例,它将多个子表达式组合成一个表达式:

condition() {
  val expr1 = starterNode.lockState equals DlLockState.Unlocked
  val expr2 = stateReaderNode.lockState equals true

  val expr3 = occupancySensingDevice.occupied notEquals 0
  val expr4 = timeStateReaderNode
    .currentTime
    .between(
      timeStateReaderNode.sunsetTime,
      timeStateReaderNode.sunriseTime)
  expression = (expr1 and expr2) or (expr3 and expr4)
}

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

val starterNode = starter<_>(device, OnOff)
condition() { expression = starterNode.onOff equals true }

stateReader

condition 节点中引用特征属性值的另一种方法是使用 stateReader 节点。

为此,请先在 stateReader 节点中捕获特征属性值。stateReaderstructure 和特征作为实参:

import com.google.home.automation.stateReader
...
val filterMonitoringState = stateReader<_>(structure, ActivatedCarbonFilterMonitoring)

然后在 condition 节点中引用 stateReader

condition() {
  expression =
    filterMonitoringState.changeIndication
      .equals(ChangeIndicationEnum.Warning)
}

使用 比较运算符逻辑运算符,可以在 condition 节点中使用多个 stateReaders

val armState = stateReader<_>(doorLock, DoorLockDevice, ArmDisarm )
val doorLockState = stateReader<_>(doorLock, DoorLockDevice, DoorLock)
condition() {
  expression =
    (armState.armState equals true)
    and
    (doorLockState.lockState equals true)
}

条件持续时间

除了条件中的布尔表达式之外,您还可以指定一个时间范围,在此期间表达式必须为 true 才能运行自动化操作。例如,您可以定义一个条件,该条件仅在灯亮十分钟后触发。

  condition {
    expression(lightStateReader.onOff == true)
    forDuration(Duration.ofMinutes(10))
  }

持续时间范围为 5 秒到 24 小时。

操作节点

操作节点是自动化操作执行工作的位置。 在此示例中,操作会调用 AssistantBroadcast 特征的 broadcast() 命令:

action(device, SpeakerDevice) {
  command(AssistantBroadcast.broadcast("Intruder detected!"))
}

import 语句

在开发自动化操作时,如何将 Home API 的各种元素导入到代码中并不总是很明显。

特征属性是从特征的 Companion 对象导入的:

import com.google.home.matter.standard.OnOff.Companion.onOff

由特征定义的数据结构是从名称以“-Trait”结尾的特征类导入的:

import com.google.home.matter.standard.MediaPlaybackTrait.PlaybackStateEnum

特征命令是从特征的 Companion 对象导入的:

import com.google.home.matter.standard.Thermostat.Companion.setTemperatureSetpointHold