访问设备和设备元数据

您可以通过 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 时,请检查其 codemessage 字段,了解问题所在。

任何未处理的异常都会导致应用崩溃。

如需了解详情,请参阅错误处理

如需查看示例,请参阅向设备发送命令

调用示例

获取设备列表

结构可用后,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,则可以将 matterOriginalVendorIdmatterOriginalProductId 字段留空,并提供 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() 获取设备上可用的所有类型的列表。