In the Home APIs, observing changes to state in the home is made possible
through the use of flows
in Kotlin. Observing changes in structures, rooms, device metadata, and
device state in the Home APIs can be done with any API inheriting from the
HomeObjectsFlow
interface. This is done by
collecting from the flow. See Introducing Flows
for more information on flows.
When any item in a collection is added, deleted, or modified, the latest snapshot of the collection is returned.
It is up to the developer to deduce the specific changes by comparing this
snapshot with an older copy. The id
field provided for each parent object
type in the Home APIs can be used for
this purpose.
How to use flows
Let's look at some basic examples of collecting from flows in the Home APIs. For
the following examples, an instance of the Home
must be created before
accessing collections in the home:
val context = LocalContext.current
val homeManager = Home.getClient(context)
Track changes to a structure
The following changes to a structure trigger this collection:
- Structure name
homeManager.structures().map { it.firstOrNull() }.collect {
println("Structure ${it.id} updated to ${it}")
}
val structure = homeManager.structures().list().firstOrNull()!!
Track changes to a specific device
The following changes to a device trigger this collection:
- Connectivity state
- Device name
- Room membership
- The set of supported traits
- The set of supported types
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" }!!
Track changes to a specific trait on a device
Use any trait supported by the device and the Home APIs. For a full list, see
Trait
.
device.trait(OnOff).collect {
if (it != null) {
println("Got new state update! ${it.onOff}")
}
}
Track changes to a specific type on a device
The following changes to a device type trigger this collection:
- Changes to any trait within the generated device type
Use any Matter device type supported by the Home APIs. For
a full list, see DeviceType
.
device.type(DimmableLightDevice).collect { type ->
println("Got new state update! ${type.trait(LevelControl)?.currentLevel}")
}
Track changes to a room in a structure
The following changes to a room trigger this collection:
To track when devices are added or removed from a room, use the devices()
flow.
structure.rooms().collect {
println("Got a new updated set of rooms!")
for (room in it) {
println("Got room $room")
}
}
Subscribe to events
In the Home APIs, events are used to detect changes in the state of a device.
To subscribe to events on a specific device, call one of the three
HomeDevice
.events
functions, each of which returns aFlow<Event>
:
events(event: EventFactory<T>)
returns a flow for a specific kind of event:val eventFlow = homeDevice.type(DoorLockDevice).first().events(DoorLock.DoorLockAlarmEvent)
events(trait: TraitFactory<T>)
returns a flow of all events sent by a trait:val eventflow = homeDevice.type(DoorLockDevice).first().events(DoorLock)
events()
returns a flow of events available for the object:val eventflow = homeDevice.type(DoorLockDevice).first().events()
To consume events from a flow, use the flow.collect()
function:
eventflow.collect { event ->
if (event != null) {
logger.atInfo().log("Received event %s", event)
// do something
}
}