監控裝置狀態

在 Home API 中,您可以使用 Kotlin 中的流程,觀察住家狀態的變更。您可以使用從 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" }!!

追蹤裝置上特定特徵的變更

使用裝置和 Google Home API 支援的任何特徵。如需完整清單,請參閱 Trait

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

追蹤裝置上特定類型的變更

下列裝置類型變更會觸發這項收集作業:

使用 Google 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")
  }
}

訂閱事件

在 Google Home API 中,事件用於偵測裝置狀態的變更。

如要訂閱特定裝置上的事件,請呼叫其中一個 HomeDeviceevents 函式,每個函式都會傳回 Flow<Event>

  1. events(event: EventFactory<T>) 會傳回特定事件類型的資料流:

    val eventFlow = homeDevice.type(DoorLockDevice).first().events(DoorLock.DoorLockAlarmEvent)
    
  2. events(trait: TraitFactory<T>) 會傳回特徵傳送的所有事件流程:

    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
  }
}