自动化功能可让住宅中的任务和设备设置自动执行。 自动化操作已在 Google Home 生态系统中作为 Google Home app (GHA) 中的日常安排提供,并通过 Google Home for web 上的 automation script editor 提供。
现在,您可以通过 Home API for Android 使用 Google Home 生态系统中的自动化操作。它们使用 GHA 日常安排和 script editor 中使用的相同基本概念,但具有只能通过 Home API 实现的增强功能和能力,包括:
- 访问 Home API 中提供的设备的所有 Matter 标准和 smart home 特性。
- 支持顺序、并行和选择执行流程。
自动化操作是使用自动化 DSL 编写的,这是一种专为在 Kotlin 中构建自动化操作而设计的领域特定语言。
您打算在应用中通过 Device & Structure API 或 Automation API 使用的所有特征和类型都必须在初始化时注册。请参阅在 Android 上初始化住宅。
用户撤销完整权限时的指导
如果用户撤消完整权限,所有现有自动化操作都将停止运行。此外,如果用户撤消对特定设备的访问权限,则与这些设备关联的启动方式、条件和操作将停止运行。
每次应用启动时,请务必检查权限是否仍然有效。如果权限已被撤消,请务必移除所有先前的数据,包括应用中缓存的所有数据。
撤消结构访问权限后,系统会向您的云后端发送 StructureAccessRevokedEvent。如需了解端到端合作伙伴云和移动应用撤消工作流,请参阅结构授权。
开发者历程
Automation API 只是整个开发历程的一部分。它在集成 Structure API 和 Device API 之后进行,以确保用户在想要使用自动化操作时能够顺利使用。
- 开发者规划其自动化操作,并使用自动化 DSL 进行定义。
- 开发者将自动化定义嵌入到 Kotlin Android 应用中。
- 该应用会根据用户设备的相关信息(包括使用 Discovery API 或 Device API 收集的特征、属性、命令和事件)向用户显示自动化操作。
- 借助 Discovery API,应用可以根据用户结构中存在的设备类型和特征,生成自定义的自动化操作草稿,无论用户是否输入。
- Device API 可以提供与 Discovery API 几乎相同的信息,但它并未针对自动化用例进行优化。如需了解详情,请参阅比较 Device API 和 Discovery API。
- 应用会创建与所选结构相对应的实际自动化操作。
- 该自动化操作现已上架用户的结构,并且可以使用 Structure API 方法执行或删除。
用户可以随时创建自动化操作的新实例,选择不同的结构,或者根据应用逻辑选择一组不同的设备。每次用户执行此操作时,应用都会生成一个新的自动化操作实例。
在最基本的场景中,您可以向用户建议执行相对基本任务的预定义自动化操作。或者,您也可以提供一个自动化操作框架,让用户根据自己的需求进行自定义。或者,您也可以编写一个开放式自动化编辑器,让用户能够使用 Automation API 中提供的所有构建块来构建复杂的自动化操作。
自动化建议
Home API 可以根据空间中存在的设备类型等因素,为 Structure 建议自动化操作。
自动化建议由 AutomationSuggestion 类表示。
Structure 接口包含 HasSuggestions 接口,后者提供 suggestions() 函数,该函数会返回自动化建议的集合。
likeSuggestion() 和 dislikeSuggestion() 方法旨在连接到 和 界面控件,用户可以点按这些控件来提供反馈。
第三种方法 clearSuggestionFeedback() 可让用户移除针对建议的自动化操作提供的反馈。
用户反馈会影响未来的建议。
此示例演示了如何使用 likeSuggestion()、clearSuggestionFeedback() 和 dislikeSuggestion() 检索 Structure 的可用自动化建议、提取建议 ID 并记录用户反馈。
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.google.home.Structure
import kotlinx.coroutines.launch
class AutomationSuggestionsViewModel(private val structure: Structure) : ViewModel() {
fun loadAndGiveFeedback() {
viewModelScope.launch {
// 1. Fetch suggestions from structure
val suggestions = structure.suggestions()
val firstSuggestion = suggestions.firstOrNull() ?: return@launch
// Extract string suggestion ID
val suggestionId: String = firstSuggestion.id.id
// 2. Like the suggestion (thumbs up)
val liked = structure.likeSuggestion(suggestionId)
// 3. Clear previous feedback if the user toggled it off
if (liked) {
structure.clearSuggestionFeedback(suggestionId)
}
// 4. Dislike the suggestion (thumbs down)
structure.dislikeSuggestion(suggestionId)
}
}
}
动态命令参数
借助动态命令参数,开发者可以构建在运行时动态解析的操作参数,而无需严格依赖静态常量值。这可实现以下两个主要功能:
- 从启动器(例如事件载荷)或状态读取器节点,或从自动化流程中声明的局部变量传递属性值的引用。
- 捕获运行时动态值(例如事件属性或状态值)并将动态值直接传递到命令参数中的表达式。
使用场景
将发送多按事件的实体旋转开关绑定到可调光灯。点击次数是在运行时传递到 LevelControl 步骤命令中的动态值。
动态参数的运作方式
在 Android 上的自动化 DSL 中,命令参数直接接受 Expression 或 Reference 实例,而不是静态常量值。在构建自动化操作时,DSL 会将这些内容封装到 Parameter 定义中。
验证规则
动态命令参数遵循以下验证限制:
- 在发现期间,动态参数被假定为结构有效,因为发现 API 仅评估静态实参的具体值限制条件。
- 引用或表达式节点必须先出现在自动化图表的上游,然后才能在下游命令操作中被引用。
在 Android 上使用动态命令参数
直接将动态表达式传递给命令参数:
import com.google.home.automation.action
import com.google.home.automation.automation
import com.google.home.automation.fieldSelect
import com.google.home.automation.sequential
import com.google.home.automation.starter
import com.google.home.matter.standard.DimmableLightDevice
import com.google.home.matter.standard.DimmerSwitchDevice
import com.google.home.matter.standard.LevelControl
import com.google.home.matter.standard.LevelControlTrait.StepModeEnum
import com.google.home.matter.standard.Switch
val keypressAutomation = automation {
name = "Dynamic command parameters example"
description = "Pass starter event field directly to command"
sequential {
val dimmerStarter = starter(
dimmerSwitch,
DimmerSwitchDevice,
Switch.MultiPressOngoingEvent,
)
val clickCountExpr = fieldSelect<Switch.MultiPressOngoingEvent, UInt>(
dimmerStarter,
Switch.MultiPressOngoingEvent.EventFields.currentNumberOfPressesCounted,
)
action(dimmableLight, DimmableLightDevice) {
command(
LevelControl.step(
stepMode = StepModeEnum.Up,
stepSize = clickCountExpr,
)
)
}
}
}
或者,将表达式分配给局部变量声明,并在流中的后续位置引用该变量:
import com.google.home.automation.action
import com.google.home.automation.automation
import com.google.home.automation.fieldSelect
import com.google.home.automation.sequential
import com.google.home.automation.starter
import com.google.home.automation.variable
import com.google.home.matter.standard.DimmableLightDevice
import com.google.home.matter.standard.DimmerSwitchDevice
import com.google.home.matter.standard.LevelControl
import com.google.home.matter.standard.LevelControlTrait.StepModeEnum
import com.google.home.matter.standard.Switch
val myAutomationWithVariable = automation {
name = "Dynamic command parameters with variables"
description = "Declare a variable, assign value, and pass reference"
sequential {
val dimmerStarter = starter(
dimmerSwitch,
DimmerSwitchDevice,
Switch.MultiPressOngoingEvent,
)
val clickCountExpr = fieldSelect<Switch.MultiPressOngoingEvent, UInt>(
dimmerStarter,
Switch.MultiPressOngoingEvent.EventFields.currentNumberOfPressesCounted,
)
val clickCountVar = variable<UInt>()
clickCountVar.assign(clickCountExpr)
action(dimmableLight, DimmableLightDevice) {
command(
LevelControl.step(
stepMode = StepModeEnum.Up,
stepSize = clickCountVar,
)
)
}
}
}
类型限制
确保变量和表达式的类型与接收命令参数所需的 Matter 架构类型定义(例如 UShort、UByte 或 UInt8)保持一致。
资源限制
Home API 中的自动化操作存在以下限制:
| 指标 | 限制 |
|---|---|
| 每个结构中的自动化操作数量上限 | 64 |
| 每个自动化操作的节点数上限 | 128 |
| 每个自动化操作的表达式节点数上限 | 64 |
| 每个结构中的自动化实例数上限 | 1024 |
| 每个开发者在每个住宅中可创建的自动化实例数量上限 | 64 |
| 每个结构每天的执行次数上限 | 1024 |
| 每位开发者每天针对每个住宅的执行次数上限 | 128 |