监控设备状态

在 Home API 中,您可以通过在 Kotlin 中使用 flow 来监控住宅状态的变化。您可以使用从 HomeObjectsFlow 接口继承的任何 API 来观察 Home API 中结构、房间、设备元数据和设备状态的变化。这可以通过从流中收集来实现。如需详细了解流程,请参阅流程简介

当集合中的任何内容被添加、删除或修改时,系统都会返回该集合的最新快照。

开发者可以通过将此快照与较旧的副本进行比较,推断出具体更改。为 Home API 中的每个父级对象类型提供的 id 字段可用于此目的。

如何使用数据流

我们来看看在 Home API 中从数据流收集数据的一些基本示例。对于以下示例,必须先创建 Home 的实例,然后才能访问住宅中的集合:

val context = LocalContext.current
val homeManager = Home.getClient(context)

跟踪结构的更改

对结构进行以下更改会触发此集合:

homeManager.structures().map { it.firstOrNull() }.collect {
  println("Structure ${it.id} updated to ${it}")
}

val structure =  homeManager.structures().list().firstOrNull()!!

跟踪特定设备的更改

以下设备更改会触发此集合:

structure
  .devices()
  .map { devices -> device.filter { it.name == "Bedroom Lamp" }.single() }
  .collect {
    println("The bedroom lamp has changed!")
  }

val device = structure.devices().list().firstOrNull { it.name == "Bedroom Lamp" }!!

跟踪设备上特定 trait 的更改

使用设备和 Home API 支持的任何 trait。如需查看完整列表,请参阅 Trait

device.trait(OnOff).collect {
  if (it != null) {
    println("Got new state update! ${it.onOff}")
  }
}

跟踪设备上特定类型的更改

对设备类型进行以下更改会触发此集合:

使用 Home API 支持的任何 Matter 设备类型。如需查看完整列表,请参阅 DeviceType

device.type(DimmableLightDevice).collect { type ->
    println("Got new state update! ${type.trait(LevelControl)?.currentLevel}")
}

跟踪结构中房间的更改

对房间进行以下更改会触发此集合:

如需跟踪设备何时添加或移除到/从房间,请使用 devices() 流程

structure.rooms().collect {
  println("Got a new updated set of rooms!")

  for (room in it) {
    println("Got room $room")
  }
}

订阅事件

在 Home API 中,事件用于检测设备状态的变化。

如需订阅特定设备上的事件,请调用以下三个 HomeDevice 之一。events 函数,每个函数都会返回一个 Flow<Event>

  1. events(event: EventFactory<T>) 会返回特定类型事件的流程:

    val eventFlow = homeDevice.type(DoorLockDevice).first().events(DoorLock.DoorLockAlarmEvent)
    
  2. events(trait: TraitFactory<T>) 会返回 trait 发送的所有事件的流:

    val eventflow = homeDevice.type(DoorLockDevice).first().events(DoorLock)
    
  3. events() 会返回可供对象使用的事件流:

    val eventflow = homeDevice.type(DoorLockDevice).first().events()
    

如需使用来自流的事件,请使用 flow.collect() 函数:

eventflow.collect { event ->
  if (event != null) {
    logger.atInfo().log("Received event %s", event)
    // do something
  }
}