Android DSL 概念

本文概述了 Android 上的 Automation DSL 的基本概念。

自动化组件

自动化操作由以下基本组件组成,这些组件通常按此顺序进行评估:

  1. 启动方式 \- 定义用于激活自动化操作的初始条件,例如特性更改。自动化操作必须具有启动方式。
  2. 条件 \- 自动化操作激活后要评估的任何其他限制。条件中的表达式必须求值为 true,自动化操作的操作才能继续。
  3. 操作 \- 在满足所有条件时执行的命令或状态更新。

例如,您可能有一项自动化操作,用于在日落和日出之间打开房间内的电视时调暗该房间内的灯光。在此示例中:

  1. 启动方式 \- 电视已打开,这是电视特性状态的变化。
  2. 条件— 评估电视所在住宅的当前时间。
  3. 操作 \- 调暗与电视位于同一房间内的灯光。

当房间内的电视打开时,自动化操作将被激活,但只有在满足“时间介于日落和日出之间”的条件时,自动化操作才会执行。

除了基本结构之外,Home API 中的自动化操作还包含 元数据,例如 namedescription,开发者和用户可以使用这些元数据来识别 自动化操作。

节点

在 Home API 中,自动化操作的逻辑结构由节点 组成。 节点是抽象的、可重复使用的单元,用于表示实体行为或执行流程。每个节点都可以有输入变量,以及可供其他节点使用的输出变量。

表:自动化节点的类型
节点 节点类型 Kotlin 实现 说明
启动方式 行为型 StarterNodeDsl 当特性的状态(任何属性)发生变化时,启动自动化操作。
StateReader 行为型 StateReaderNodeDsl 读取特性属性,并允许您捕获其值以在 条件节点中使用。
操作 行为型 ActionNodeDsl 调用特性命令。
依序 执行流程 SequentialFlow 按顺序执行嵌套的操作节点。这是默认的执行 行为。
并行 执行流程 ParallelFlow 并行执行嵌套的操作节点。
条件 执行流程 ConditionNodeDsl 根据对逻辑 表达式的评估有条件地更改执行流程。条件可以与启动方式相关联(特定于启动方式的条件 ),也可以是全局的(适用于所有启动方式)。
选择 执行流程 SelectFlow 允许多个启动方式激活自动化操作。
表达式 Expression 可以是特性属性的值、常量或字面量值, 并且必须求值为列表、数字、布尔值或字符串。

行为型节点

启动方式和操作等节点是行为型节点。启动方式根据设备属性更改激活自动化操作。操作会发出设备命令或更新属性。

行为型节点通常与设备特性相关联,并输出特性状态以用作其他节点的输入。

执行流程节点

某些节点表示执行流程,例如依序和并行。 每个节点都包含定义自动化操作的行为型节点。

例如,依序 流程可能包含按顺序执行的节点。通常,这些节点是启动方式、条件和操作。

顺序执行流程
图 1:依序自动化流程

并行 流程可能同时执行多个操作节点,例如同时打开多个灯。并行流程之后的节点只有在并行流程的所有分支都完成之后才会执行。

并行执行流程
图 2:并行自动化流程

另一种执行流程是条件流程,它可以根据表达式的评估结果更改 执行流程。

例如,您可能有一项自动化操作,用于根据是否为夜间执行操作。条件节点会检查一天中的时间,然后根据该评估结果遵循相应的执行路径。

条件流
图 3:条件流程

如果您希望有多个启动方式可以激活自动化操作,则 选择流程 非常有用。当您将两个或多个启动方式封装在 select 流程中时,任何一个启动方式都可以激活自动化操作。

例如,您可以编写一项自动化操作,用于在日落时降低百叶窗,或者在温度高于特定阈值时降低百叶窗,或者在亮度超过阈值时降低百叶窗。三个单独的启动方式处理这些场景中的每一个,并且这三个启动方式都将封装在 select 流程中。

选择流程
图 4:选择流程

嵌套流程

在复杂的自动化操作中,执行流程节点也可以嵌套。例如,您可能有一个依序流程,用于执行并行流程。

嵌套执行流程
图 5:嵌套的执行流程

DSL 节点可以根据下表中列出的限制以各种方式嵌套和组合。“构建器”列链接到 Kotlin 类型安全构建器文档,其中详细介绍了允许在每种类型的节点中使用哪些内容。

表:节点的组合方式
节点 可以包含以下节点类型和数据 必须位于以下节点类型之一中
启动方式 表达式 选择、依序
ManualStarter 选择、依序
StateReader 表达式(通常由特性属性值组成) 操作、条件
操作 命令、实体、表达式 并行、选择、依序
依序 并行、选择、依序
并行 操作 依序
条件 表达式 并行、依序
选择 条件、依序、启动方式、ManualStarter 依序,并且必须是流程中的第一个节点

Automation DSL

在 Home API 中,自动化操作是使用 Automation DSL(领域特定语言)定义的。Automation DSL 作为 Kotlin DSL(领域特定 语言)实现, 使用 Kotlin 类型安全构建器,并且专门用于定义 自动化模板。

编译自动化操作时,Kotlin 类型安全构建器会生成 Kotlin 数据类,然后将其序列化为协议缓冲区 JSON,该 JSON 用于调用 Google 的自动化服务。

Automation DSL 简化并精简了构建自动化操作的过程。它原生使用 Device API 中 Matter标准特性和smart home特性的相同数据模型

Automation DSL 还根据抽象设备类型(而不是用户住宅中的特定设备实例)定义自动化操作的逻辑。 它允许开发者提供可在运行时用于指定实际设备实例以及其他重要参数值的输入参数。

DSL 语法与 Kotlin 的语法类似,并且同样是类型安全的,但使用 Automation DSL 编写的自动化操作比使用纯 Kotlin 编写的相同自动化操作更简单、更简洁。

示例

以下是使用 Automation DSL 编写的用于打开设备的自动化操作示例:

val automation = automation {
  name = "MyFirstAutomation"
  description = "If light1 is on, turn on light2."
  isActive = true
  sequential {
    val onOffTrait = starter<_>(device1, OnOffLightDevice, OnOff)
    condition() { expression = onOffTrait.onOff equals true }
    action(device2, OnOffLightDevice) { command(OnOff.on()) }
  }
}

此自动化操作非常基本:当 device1(一个灯)打开(onOff 属性更改为 true)时,它会发送 on() 命令以打开 device2

自动化操作使用 sequential 节点,这表示其节点将按顺序运行。

sequential 节点内是行为型节点,例如 starterconditionactionstarter 节点的输出将分配给一个变量,以在 condition 节点中使用。