public final class Accessory

  1. Object
  2. Accessory

One physical device in the home: HomeKit’s HMAccessory, a Google Home device, one Matter node.

An immutable snapshot, not a live handle

Every getter here reads a field. Nothing calls into the platform, so nothing here can block, fail, or care which thread you are on.

The alternative – a proxy over the platform’s own live object – was rejected: HMAccessory is a mutable Objective-C object whose properties are only safe to touch on the main queue, so every getter would have been a cross-boundary call with a threading rule attached, and under ParparVM an expensive one. Reading six properties to lay out a row would be six hops.

The cost is that a snapshot goes stale. When the topology moves – an accessory added, removed, renamed, moved between rooms, or its reachability flipping – a HomeStructureListener fires and you fetch again. Trait values are not part of the snapshot at all; read them with SmartHome.read(TraitReadRequest) or watch them with a TraitSubscription.

Constructors

public Accessory(String id, String name, String roomId, AccessoryCategory category, String manufacturer, String model, String firmwareVersion, boolean reachable, String bridgeAccessoryId, List<AccessoryService> services)Creates an accessory snapshot.

Methods

public String getId()The identifier this accessory is addressed by.
public String getName()The user-visible name, empty when the accessory has none.
public String getRoomId()The room this accessory is in.
public AccessoryCategory getCategory()Roughly what this accessory is, for icons and grouping.
public String getManufacturer()The manufacturer, empty when unknown.
public String getModel()The model name, empty when unknown.
public String getFirmwareVersion()The firmware version, empty when unknown.
public boolean isReachable()Whether the platform could talk to this accessory when the snapshot was taken.
public boolean isBridged()Whether this accessory sits behind a bridge rather than talking to the platform directly.
public String getBridgeAccessoryId()The bridge this accessory sits behind.
public List<AccessoryService> getServices()Every functional endpoint of this accessory.
public AccessoryService getService(String serviceId)One service by identifier.
public AccessoryService getPrimaryService()The accessory’s main service – what a UI showing one control for the whole device should drive.
public List<AccessoryService> getServicesSupporting(Trait trait)Every service on this accessory that exposes a trait.
public boolean supports(Trait trait)Whether any service on this accessory exposes a trait.
public String toString()Returns a string representation of the object.

Inherited methods

Constructor details

Accessory

public Accessory(String id, String name, String roomId, AccessoryCategory category, String manufacturer, String model, String firmwareVersion, boolean reachable, String bridgeAccessoryId, List<AccessoryService> services)
Creates an accessory snapshot. Called by the ports and by the local home; application code receives these rather than building them.

Parameters

id String
the accessory identifier, unique within the backend
name String
the user-visible name, or null for none
roomId String
the room it is in, or null when it is in none
category AccessoryCategory
roughly what it is; null becomes AccessoryCategory.OTHER
manufacturer String
the maker, or null
model String
the model name, or null
firmwareVersion String
the firmware version, or null
reachable boolean
whether the platform could talk to it when the snapshot was taken
bridgeAccessoryId String
the bridge it sits behind, or null when it talks to the platform directly
services List<AccessoryService>
its functional endpoints; null becomes empty

Throws

IllegalArgumentException
when id is null or empty

Method details

getId

public String getId()

The identifier this accessory is addressed by.

Unique across the whole backend, not merely within its structure, so a read or a write needs only this and a service id.

Stable for the life of the process on every backend, and stable across launches wherever the platform provides a stable identifier – which both do today. SmartHome.areIdsPersistent() is the honest answer for a given backend, and is what to check before persisting one as a user’s favourite.

Returns

the identifier, never null

getName

public String getName()

The user-visible name, empty when the accessory has none.

This is the user’s own text, from their ecosystem app. Treat it as untrusted for anything beyond display.

Returns

the name, never null

getRoomId

public String getRoomId()
The room this accessory is in.

Returns

the room identifier, or null when it is not assigned to one

getCategory

public AccessoryCategory getCategory()
Roughly what this accessory is, for icons and grouping. Read the services to decide what it can do.

Returns

the category, never null

getManufacturer

public String getManufacturer()
The manufacturer, empty when unknown.

Returns

the manufacturer, never null

getModel

public String getModel()
The model name, empty when unknown.

Returns

the model, never null

getFirmwareVersion

public String getFirmwareVersion()
The firmware version, empty when unknown.

Returns

the firmware version, never null

isReachable

public boolean isReachable()

Whether the platform could talk to this accessory when the snapshot was taken.

A snapshot’s answer, so it can be out of date; the current answer arrives through StructureChangeKind.REACHABILITY_CHANGED. An operation on an unreachable accessory fails with HomeError.ACCESSORY_UNREACHABLE, which is worth handling even when this said true.

Returns

true when the accessory was reachable

isBridged

public boolean isBridged()

Whether this accessory sits behind a bridge rather than talking to the platform directly.

Worth surfacing because a bridge going offline takes every accessory behind it with it, and “twelve lights stopped responding” is much easier to explain when you can name the one device that actually failed.

Returns

true when getBridgeAccessoryId() names a bridge

getBridgeAccessoryId

public String getBridgeAccessoryId()
The bridge this accessory sits behind.

Returns

the bridge’s accessory id, or null when it is not bridged

getServices

public List<AccessoryService> getServices()
Every functional endpoint of this accessory.

Returns

an immutable list, possibly empty

getService

public AccessoryService getService(String serviceId)
One service by identifier.

Parameters

serviceId String
the identifier to look up, or null

Returns

the service, or null when this accessory has no such service

getPrimaryService

public AccessoryService getPrimaryService()

The accessory’s main service – what a UI showing one control for the whole device should drive.

Falls back to the first service when none is flagged primary, and to null only when there are no services at all.

Returns

the primary service, or null

getServicesSupporting

public List<AccessoryService> getServicesSupporting(Trait trait)

Every service on this accessory that exposes a trait.

More than one for a device with repeated endpoints – the two halves of a two-gang switch both expose Trait.ON_OFF – which is exactly why a write names a service rather than an accessory.

Parameters

trait Trait
the trait to look for, or null

Returns

an immutable list, possibly empty

supports

public boolean supports(Trait trait)
Whether any service on this accessory exposes a trait.

Parameters

trait Trait
the trait to test, or null

Returns

true when at least one service has it

toString

public String toString()
Returns a string representation of the object. In general, the toString method returns a string that “textually represents” this object. The result should be a concise but informative representation that is easy for a person to read. It is recommended that all subclasses override this method. The toString method for class Object returns a string consisting of the name of the class of which the object is an instance, the at-sign character `@’, and the unsigned hexadecimal representation of the hash code of the object. In other words, this method returns a string equal to the value of: getClass().getName() + ‘@’ + Integer.toHexString(hashCode())