Как отслеживать состояние устройства на Android

В Home API для Android отслеживать изменения состояния дома можно с помощью потоков в Kotlin. Отслеживать изменения в структурах, комнатах, метаданных устройств и их состоянии в Home API можно с помощью любого API, наследующего интерфейс HomeObjectsFlow. Это делается с помощью сбора данных из цепочки рассуждений.

Когда в подборку добавляется, удаляется или изменяется какой-либо объект, возвращается последний снимок подборки.

Разработчик может определить, какие именно изменения произошли, сравнив этот снимок с более ранней копией. Для этого можно использовать поле id, которое предоставляется для каждого родительского объекта в Home API.

Как использовать процессы

Ниже приведены основные примеры сбора данных из потоков в 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" }!!

Как отслеживать изменения определенного свойства устройства

Используйте любой признак, поддерживаемый устройством и API Google Home. Полный список приведен в статье Trait.

    val trait = device.type(DimmableLightDevice)?.map { it.trait(OnOff)}.first()

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

Как отслеживать изменения определенного типа на устройстве

Сбор данных запускается при следующих изменениях типа устройства:

Используйте любой тип устройства Matter, поддерживаемый API Home. Полный список приведен на странице DeviceType.

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

Как отслеживать изменения в комнате в структуре

Коллекция запускается при следующих изменениях в переговорной комнате:

Чтобы отслеживать, когда устройства добавляются в комнату или удаляются из нее, используйте devices() flow.

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

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

Как оформить подписку на события

В API Home события используются для обнаружения изменений в состоянии устройства.

Чтобы подписаться на события на определенном устройстве, вызовите один из трех методов HomeDevice.events – функции, каждая из которых возвращает 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
  }
}

Как оформить подписку на события, связанные с отношениями между объектами

Вы можете отслеживать события, которые происходят каждый раз, когда добавляется, удаляется или обновляется объект (например, структура, комната, устройство или автоматизация). Эти события являются экземплярами HomeObjectChangeEvent и содержат идентификатор изменившегося объекта.

Чтобы получить поток, который создает нужные вам события, вызовите метод stream() для объекта HomeObjectsFlow<T>, созданного соответствующим методом Flow:

Таблица: потоки событий
Объект Интерфейс Метод Flow
Structure HasStructures structures()
Room HasRooms rooms()
HomeDevice HasHomeDevices devices()
Automation HasAutomations automations()

Например, вот как можно обрабатывать изменения устройств:

val devicesStream = home.devices().stream()

// Collect and react to device changes.
devicesStream.collect { deviceEvent ->
  when (deviceEvent) {
    is HomeObjectAddedEvent ->
      println("New device now available with id: ${deviceEvent.id}")
    is HomeObjectUpdatedEvent -> println("Device ${deviceEvent.id} has been updated")
    is HomeObjectRemovedEvent -> println("Device is removed from your account")
    else -> {}
  }
}