🎭 Entity Proxies
Entity proxies are references to specific entities, which allow for a variety of operations to be performed:
- read current attributes / state
- listen for state changes
- issue targeted service calls
- modify entity state and attributes
- access historical data
Creating references
The most common method of creating references is using hass.refBy.id
:
import { TServiceParams } from "@digital-alchemy/hass";
export function ExampleService({ hass }: TServiceParams) {
const mySensor = hass.refBy.id("sensor.my_special_sensor");
// that's it!
}
The hass.refBy
also allows for lookups against area
, device
, label
, floor
, platform
, and unique_id
to create an array of references.
// simple lookup, returns array of references
hass.refBy.area("living_room");
// limit by domain(s)
hass.refBy.floor("downstairs", "light", "switch");
// lookup by unique ID
hass.refBy.unique_id("unique_sensor_id");
State lookups
The most common way to access state is via the .state
& .attributes
properties.
const mySwitch = hass.refBy.id("switch.example");
logger.info(`current state is ${mySwitch.state}`); // on
These perform lookups against an internal entity state registry within hass
to retrieve the current value at that moment.
You may also perform lookups against the immediately previous state
logger.info(`previous state was ${mySwitch.previous.state}`);
Note: internal registry state changes are performed before emitting update events
Modifying Entity State
Entity proxies support direct modification of state and attributes:
const myEntity = hass.refBy.id("sensor.temperature");
// Set state directly
myEntity.state = 72;
// Update attributes
myEntity.attributes = {
unit_of_measurement: "°F",
friendly_name: "Living Room Temp"
};
Note: State modifications are sent via REST API and may not be supported by all entity types
Historical Data
Access historical state changes for an entity:
const mySensor = hass.refBy.id("sensor.outdoor_temperature");
// Get history for the last 24 hours
const history = await mySensor.history(
dayjs().subtract(24, 'hours'),
dayjs()
);
// history contains array of { state, attributes, date } objects
Event Hooks
The most common way of attaching to events is via the .onUpdate
hook.
These run in response to entities emitting changes to their state or attributes via the socket
// ⚠️ either param may be null for operations like entity add / remove
mySwitch.onUpdate((new_state, old_state) => {
if (old_state?.state === "on" && new_state?.state === "off") {
// perform action
}
});
Removable
Some workflows work best with shorter term or more precise listeners. A basic onUpdate
can be removed like by 2 methods:
- return value
const { remove } = mySwitch.onUpdate(callback);
remove()
- remover in params
mySensor.onUpdate(function (new_state, old_state, remove) {
remove();
});
A few related methods are also provided:
entity.waitForState(target_state, [timeout_ms])
: resolves promise when entity state changes to provided valueentity.nextState([timeout_ms])
: wait for a state change (ignores updates that doesn't change state)entity.once
: same as onUpdate, but only runs once
Service Calls
The final ability of entity references is to issue targeted service calls. These are a convenience for when the service call's domain is the same as the entity.
hass.refBy.id("light.office").turn_on()
// same as
hass.call.switch.turn_on({ entity_id: ["light.office"] });