Entities in Depth
In this section, we discuss entities, properties, capabilities, and attributes.
Entities are Reactor's term for a container for data about some thing. In most cases, an entity represents a device or a component of a device on a hub. In fact, the term entity is used by some hubs, like Home Assistant, in the same manner. Entities can also be spontaneously generated from other data sources, like weather APIs, database queries, etc.
There is not a one-to-one mapping of hub devices to entities. Depending on the needs of the implementation, a device may be represented by a single entity or multiple. Typically, the hub controller classes in Reactor try to mirror the hub's representation of devices as closely as possible, to keep it familiar, but not all hubs and devices can be modeled this way, so it's a guideline, not a rule.
Reactor entities have properties. Some properties of an entity are static and immutable, which means they never change once assigned. This includes the entity's ID (which is unique to the controller instance that manages it), and it's canonical ID, which is unique system-wide. Other properties, like the entity's name, may be changed but do not generally change frequently; and some properties change constantly, like the
lastupdate property that changes every time data on the entity is modified.
The following are the standard properties associated with every entity:
id— The entity's ID, unique to its parent controller instance. For entities that represent hub devices, this value usually is, or includes, the unique identifier used be the hub to identify the device (however, this fact is Reactor-controller dependent and may not be relied upon).
canonical_id— The canonical ID of an entity is a value that uniquely identifies the entity in the Reactor system. That makes this property the most commonly-used for identifying specific entities.
controller_id— ID of the controller instance that manages the entity.*
name— The name of the entity as known to its creator/manager; for most device entities, this is the name of the device as known to the parent hub. Entity names are not required to be unique in any scope; it's possible for two entities to have the same name, and it's up to you to sort out what that means.
capabilities— A private structure containing the definitions of the capabilities associated with the entity (see Capabilities below).
attributes— An object (map) containing other objects (maps) that describe, for each extended capability, the attribute names and values for that entity.
actions‐ A list of the actions defined for the entity.
lastupdate— The last-modified time of the entity; any change to the entity's data changes this property, not just changes to attribute values.
Capabilities, Attributes and Actions
Entities have capabilities, which describe the data that can be learned about the entity from the source/hub (its attributes) and actions that the entity can perform (what we can tell the hub/source to make it do). The controller instance that manages the entity determines, by default, which capabilities an entity may implement. User configuration to add capabilities is also possible, as described in other sections.
There are two types of capabilities: standard and extension. Standard capabilities are closely-managed, system-defined capabilities that all entities can use. One such capability is
power_switch, which represents the attributes and action possible when an entity can perform on-off binary switching of a load. It is expected that all controller implementations will map those devices with on/off switch behavior into this capability. Extension capabilities are defined uniquely by each controller implementation, and are very loosely managed. The attributes and actions of an extension capability are defined entirely by the controller implementation and not enforced by Reactor. These are often used to represent data or actions that do not map easily into standard attributes, and most controllers use them to ensure that all data known about a device (entity) is available to the user. They are easily recognized by the required prefix
x_ followed by an abbreviated form of the controller name (e.g.
x_vera for VeraController,
x_hass for HassController, etc.).
Attributes are the data of the device that reflect its state (in most cases), and are defined by a capability. For example, the
power_switch capability defines a
state attribute as a boolean representation of a switch's state (on or off, true or false). Whenever the underlying device changes, the controller instance is responsible for making sure the attributes on the Reactor entity correctly reflect those changes. Because attributes are defined by capabilities, you will almost never see an attribute name without its parent capability. For example, you will never see the state of a switch simply referred to as
state, it will always be referred to as
Properties and attributes are different things, so when communicating about them (on the forums, in bug reports, code comments, etc), it's important that you use the correct term. If you're having trouble keeping the difference between properties and attributes straight, think about these important differences:
- Properties are Reactor's data about an entity, while attributes are the hub's data about it.
- For the most part, properties don't change much, while attributes are constantly changing in active systems.
- Properties are tied directly to an entity, where attributes belong to a capability that is extended to an entity. This is why attributes are always referred to with a capability name, such as
power_switch.state, where properties are referred to without such qualification (e.g.
Actions are the actions that can be performed on a device/entity. For example, the
power_switch capability offers actions
off to change the state of the switch.
While Reactor itself provides the definition of a standard capability, the controller implementation must provide the implementation of that capability. That is, if a controller declares that an entity it manages has the
power_switch capability, then that controller must provide the implementation to map the data gathered from its source/hub into that capability's attributes, and it must implement the actions it defines. In this way, the
power_switch capability looks the same to the user regardless of which controller owns the entity or how the device ultimately operates. For example, the user just needs to know that performing the
power_switch.on action will turn a switch or dimmer on, even though the work by HassController and HubitatController to do that for a Home Assistant device or Hubitat device, respectively, are very different. The user is not required to use different actions for the devices just because they come from different brands of hub.
See also: List of Standard Capabilities