# Class Accessory

java.lang.Object
com.codename1.home.Accessory

public final class Accessory extends Object

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`.

- ## Constructor Summary

  Constructors
  Constructor
  Description
  `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.

- ## Method Summary

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

  ### Methods inherited from class Object

  `clone, equals, getClass, hashCode, notify, notifyAll, wait, wait, wait`

- ## 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`: the accessory identifier, unique within the backend

    - `name`: the user-visible name, or `null` for none

    - `roomId`: the room it is in, or `null` when it is in none

    - `category`: roughly what it is; `null` becomes `AccessoryCategory.OTHER`

    - `manufacturer`: the maker, or `null`

    - `model`: the model name, or `null`

    - `firmwareVersion`: the firmware version, or `null`

    - `reachable`: whether the platform could talk to it when the snapshot was taken

    - `bridgeAccessoryId`: the bridge it sits behind, or `null` when it talks to the platform directly

    - `services`: 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`: 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`: 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`: the trait to test, or `null`

    ###### Returns

    `true` when at least one service has it

  - ### toString

    public String toString()
    Description copied from class: `Object`
    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())
    Overrides:
      `toString` in class `Object`