您可以通过 Home API 访问设备 API。将以下软件包导入您的应用:
import com.google.home.Home
import com.google.home.HomeDevice
import com.google.home.Id
如需将特定设备类型或特征与 Device API 搭配使用,必须单独导入这些类型或特征。
例如,如需使用 Matter 开/关 trait 和开/关插件设备类型,请将以下软件包导入您的应用:
import com.google.home.matter.standard.OnOff
import com.google.home.matter.standard.OnOffPluginUnitDevice
如需了解详情,请参阅数据模型。
错误处理
Home API 中的任何方法都可能会抛出 HomeException
,因此我们建议您使用 try-catch
块捕获所有调用的 HomeException
。
处理 HomeException
时,请检查其 code
和 message
字段,了解问题所在。
任何未处理的异常都会导致应用崩溃。
如需了解详情,请参阅错误处理。
如需查看示例,请参阅向设备发送命令。
调用示例
获取设备列表
结构可用后,devices()
调用会返回您可以通过该结构访问的设备的 Flow:
// Get a flow of all devices accessible to the user val allDevicesFlow: HomeObjectsFlow<HomeDevice> = home.devices() // Calling list() on a HomeObjectsFlow returns the first Set of elements. val allDevices: Set<HomeDevice> = allDevicesFlow.list()
从中,您可以访问每台设备的状态,并可以向设备发送支持的命令。
读取设备状态
我们来看一个示例,了解如何从设备的开/关 trait 检查 OnOff
属性。使用 Home API trait 数据模型(其中此 trait 标识为 OnOff
),您可以通过设备类型的 standardTraits
类检索 trait 数据:
// Assuming we have a device. val deviceFlow = home.devices().itemFlow(myDeviceId) val device = deviceFlow.first() // Get a flow of a standard trait on the type. distinctUntilChanged() is needed to only trigger // on the specific trait changes and not the whole type. val onOffTraitFlow: Flow<OnOff?> = device.type(DimmableLightDevice).map { it.standardTraits.onOff }.distinctUntilChanged() val onOffTrait: OnOff = onOffTraitFlow.first()!!
如需详细了解 Kotlin 流函数,请参阅 distinctUntilChanged
。
使 trait 订阅中的状态失效
TraitStateInvalidation
接口提供了一种能力,可在状态未正确报告的情况下,使通过对目标设备的订阅检索到的状态失效。可能无法正确报告状态的一些示例包括:在 Matter trait 中使用质量为“C”的属性,或者由于设备实现意外导致问题。
此 API 会强制读取当前 trait 状态,并通过现有 trait 流程返回结果。
获取 trait,然后对 trait 运行 forceRead
:
val generalDiagnosticsTrait = device.trait(GeneralDiagnostics).first()
generalDiagnosticsTrait.forceRead()
获取设备类型 trait 的列表
设备类型应用作读取 trait 的入口点,因为它们会将设备分解为其功能组件(例如 Matter 中的端点)。
它们还会考虑以下情况:如果设备具有两种设备类型,并且这两种设备类型都可能具有相同的特征,则会发生特征冲突。例如,如果某个设备既是音箱又是可调光灯,则它将具有两个开/关特征和两个亮度控制特征。
如需获取可调光灯设备类型的可用 trait 列表,请执行以下操作:
// Get all types available on this device. Requires the types to be part of the registry during // SDK initialization. val typesFlow: Flow<Set<DeviceType>> = device.types() // Get a snapshot of all types. val types: Set<DeviceType> = typesFlow.first() // Get the DimmableLightDevice instance from the set of types. val dimmableLightDevice = types.filterIsInstance<DimmableLightDevice>().firstOrNull() // Get all traits in the type + traits registered val allTraits: Set<Trait> = dimmableLightDevice!!.traits()
如果设备具有两个同名的 trait,则可能会发生另一种 trait 冲突。例如,onOff
可以是指标准 OnOff
trait 的实例,也可以是指制造商定义的 OnOff
trait 的实例。为消除关于要使用的 trait 的任何潜在歧义,通过设备引用的 Trait
实例应在前面加上限定命名空间。对于标准 trait(即类似于 Matter 标准集群的 trait),请使用 standardTraits
。对于 Google 特征,请使用 googleTraits
:
// Accessing standard traits on the type. val onOffTrait: OnOff? = dimmableLightDevice.standardTraits.onOff val levelControlTrait: LevelControl? = dimmableLightDevice.standardTraits.levelControl
如需访问特定于制造商的特征,请直接引用该特征:
// Accessing a custom trait on the type. val customTrait = dimmableLightDevice.trait(MyCustomTrait)
获取具有特定 trait 的设备列表
Kotlin 中的 filter
函数可用于进一步优化 API 调用。例如,如需获取住宅中所有具有开/关 trait 的设备的列表,请执行以下命令:
// Get all devices that support OnOff val onOffDevices: Flow<List<HomeDevice>> = home.devices().map { devices -> devices.filter { it.has(OnOff) } }
如需查看 Home API 中提供的特征的完整列表,请参阅 Trait
接口。
获取具有类似设备类型的设备列表
如需获取代表住宅中所有灯具的设备列表,请执行以下操作:
// Get a list of devices with similar device types (lights) val lightDevices = home.devices().map { devices -> devices.filter { it.has(DimmableLightDevice) || it.has(OnOffLightDevice) || it.has(ColorTemperatureLightDevice) || it.has(ExtendedColorLightDevice) } }
Home API 中有多种设备类型可以表示核心设备类型。例如,没有“灯”设备类型。而是有四种不同的设备类型可以表示灯具,如前面的示例所示。因此,若要全面了解住宅中更高级别的设备类型,过滤后的流中必须包含多种设备类型。
如需查看 Home API 中提供的设备类型的完整列表,请参阅 DeviceType
接口。
获取设备的供应商 ID 或产品 ID
BasicInformation
trait 包含设备的供应商 ID、产品 ID、产品名称和序列号等信息:
// Get device basic information. All general information traits are on the RootNodeDevice type. val basicInformation = device.type(RootNodeDevice).first().standardTraits.basicInformation!! println("vendorName ${basicInformation.vendorName}") println("vendorId ${basicInformation.vendorId}") println("productId ${basicInformation.productId}")
识别云到云设备
如果您是设备制造商,并且构建了 Cloud-to-cloud 设备,为了通过 BasicInformation
trait 识别您的 Cloud-to-cloud 设备,您可以在其 SYNC
响应中添加以下字符串字段:
连接标准联盟 (CSA) 签发的供应商 ID:
"matterOriginalVendorId": "0xfff1",
用于唯一标识供应商商品的商品标识符:
"matterOriginalProductId": "0x1234",
设备的唯一标识符,采用制造商专用的方式构建:
"matterUniqueId": "matter-device-id",
输入这些字符串字段时,请使用您的 Matter 供应商 ID 和商品 ID(如果有)。如果您不是 CSA 成员,并且未获得这些 ID,则可以将 matterOriginalVendorId
和 matterOriginalProductId
字段留空,并提供 matterUniqueId
作为标识符。
SYNC 响应示例展示了这些字段的用法:
{
"requestId": "ff36a3cc-ec34-11e6-b1a0-64510650abcf",
"payload": {
"agentUserId": "1836.15267389",
"devices": [
{
"id": "456",
"type": "action.devices.types.LIGHT",
"traits": [
"action.devices.traits.OnOff",
"action.devices.traits.Brightness",
"action.devices.traits.ColorSetting",
],
"willReportState": true,
"deviceInfo": { ... },
"matterOriginalVendorId": "0xfff1",
"matterOriginalProductId": "0x1234",
"matterUniqueId": "matter-device-id",
"otherDeviceIds": [
{
"deviceId": "local-device-id",
}
]
}
]
}
}
如需了解详情,请参阅 Cloud-to-cloud SYNC
文档。
设备和 trait 元数据
Home API 中的设备和特征都与元数据相关联,这有助于管理应用中的用户体验。
Home API 中的每个 trait 都包含一个 sourceConnectivity
属性,其中包含与 trait 的在线状态和本地性(本地或远程路由)相关的信息。
获取设备的主要类型
某些设备可能会通过 Home API 呈现多种设备类型。 为确保在应用中向用户显示适用于其设备的选项(例如设备控制和建议的自动化操作),请务必检查设备的主要类型。
首先,使用 type()
获取设备的类型,然后确定主类型:
val types = device.types().first() val primaryType = types.first { it.metadata.isPrimaryType }
检查 trait 是否在线
使用 connectivityState()
方法检查 trait 的连接性:
val onOffConnectivity = onOffTrait?.metadata?.sourceConnectivity?.connectivityState
如果设备无法连接到互联网,某些 trait(通常是 Google smart home trait)可能会离线显示。这是因为这些 trait 是基于云的,没有本地路由。
检查设备的连接情况
实际上,系统会在设备类型级别检查设备的连接性,因为某些设备支持多种设备类型。返回的状态是该设备上所有 trait 的连接状态的组合。
val lightConnectivity = dimmableLightDevice.metadata.sourceConnectivity.connectivityState
如果混合设备类型且没有互联网连接,则可能会观察到 PARTIALLY_ONLINE
状态。由于本地路由,Matter 标准 trait 可能仍处于在线状态,但基于云的 trait 将处于离线状态。
检查 trait 的网络路由
Home API 中也提供 trait 的地区性。dataSourceLocality
表示 trait 是通过云端(远程)、本地(通过本地集线器)还是点对点(直接从设备到设备,无集线器)进行路由。
例如,在应用启动且尚未到达用于设备连接的集线器或服务器时,可能会出现未知本地性值 UNSPECIFIED
。这些设备无法访问,并且会拒绝来自命令或事件的互动请求。客户端可以自行决定如何处理此类设备。
val onOffLocality = onOffTrait?.metadata?.sourceConnectivity?.dataSourceLocality
检查设备的网络路由
与连接性一样,系统会在设备类型级别检查本地性。返回的状态是该设备上所有 trait 的本地性的组合。
val lightLocality = dimmableLightDevice.metadata.sourceConnectivity.dataSourceLocality
在与 PARTIALLY_ONLINE
连接类似的场景中,可能会观察到 MIXED
状态:某些 trait 是基于云的,而其他 trait 是本地的。
API 列表
创建 Home
实例后,您可以通过该实例访问以下设备 API:
API | 说明 |
---|---|
devices() |
获取 Google 账号中所有结构中的所有设备。返回一个 HomeObjectsFlow ,用于提供进一步的检索和过滤选项。 |
获得 HomeDevice
后,您可以通过它访问以下 API:
API | 说明 |
---|---|
allCandidates() |
返回设备及其子项的所有自动化操作候选项。 |
candidates() |
返回设备的所有自动化操作候选项。 |
connectivityStateChanged |
设备状态最近一次发生变化的时间。 |
events(event) |
获取特定事件的流程。 |
events(trait) |
按此 trait 获取所有事件的流。 |
events(traits) |
根据这些 trait 获取所有事件的流。 |
getSourceConnectivity(trait) |
获取特定 trait 的元数据。返回 SourceConnectivity 。 |
has(trait) |
检查设备是否支持当前请求的特征。 |
has(type) |
设备是否支持所提供的类型。 |
id |
设备的唯一系统 ID。 |
isInRoom |
设备是否在房间内。 |
isInStructure |
设备是否位于结构中。 |
isMatterDevice |
设备是否由 Matter 支持。 |
name |
用户提供的设备名称。 |
room() |
设备所属的房间。返回 Room 。 |
roomId |
设备所属房间的 ID。返回 Id 。 |
sourceConnectivity |
设备的来源连接性,表示设备特征的汇总连接状态和网络位置信息。 |
structure() |
设备分配到的结构。返回 Structure 。 |
structureId |
分配给设备的结构的 ID。返回 Id 。 |
type(type) |
获取已填充特征(如果有)的类型定义,以便直接访问。始终返回 trait 的最新快照。 |
types() |
获取设备上可用的所有类型的列表。 |