Docs
Global functions

Subscriptions and events

subscribe, unsubscribe, matchesState, subscribeToLocationEvent, sendLocationEvent, getEntityIds

Global functions available to smart-app code. Call them by bare name; there is no object to import.

FunctionSummary
subscribeSubscribe to entity state changes.
unsubscribeRemove entity subscriptions: everything, everything for one handler, or those on a given target.
matchesStateDoes value name state for this entity? value is the raw token ('on') or the friendly label the app shows ('Open', 'Armed Away'), case- and separator-insensitive.
subscribeToLocationEventSubscribe to a named location event (e.g.
sendLocationEventFire a named location event.
getEntityIdsNormalise an entity input to a list of entity ids: one id for a single pick, every id for a multi-select proxy, [] for anything else.

subscribe

Subscribe to entity state changes. The filter is validated strictly at subscribe() time (unknown keys throw, aborting installed()/updated()): {} matches any change (state OR attribute delta); from/to fire only on a real state transition; state is a legacy alias of to (never combine the two); attribute.value omitted = any change of that attribute. Mirrors smartAppSubscriptionFilterSchema in

Signature

function subscribe(target: unknown, filter: { from?: string; to?: string; state?: string; attribute?: { name: string; value?: unknown }; }, handler: unknown): void

Parameters

NameTypeRequiredDefaultDescription
targetunknownyes—An entity input (Entity), an array of them, or an entity id string. A multi-select input hydrates as an array-like proxy and subscribes every member.
filter{ from?: string; to?: string; state?: string; attribute?: { name: string; value?: unknown }; }yes—{} matches any change (state or attribute). from / to fire only on a real state transition and accept the raw token ('on') or the friendly label the app shows for that entity ('Open', 'Detected', 'Armed Away'), any case or separator. state is a legacy alias of to (never combine the two). attribute: { name, value? } watches one attribute; omit value for any change of it. Unknown keys throw.
handlerunknownyes—A top-level named function (or its name as a string). Handlers are dispatched by name, so arrow functions assigned to variables cannot be used. Receives an EntityChangeEvent.

Returns

void — Throws when an argument is missing or the host rejects the filter, which aborts the installed() / updated() call that made it.

Notes

  • Subscriptions are persisted and restored across hub reboots; you do not re-subscribe on systemStart.
  • Call unsubscribe() at the top of updated() before subscribing again, or a changed device picker leaves the old subscription dangling.
  • A label is resolved against the entity's domain and device class when the subscription is matched; the filter is stored as you wrote it. { to: 'on' } and { to: 'Open' } on the same handler collapse to one subscription and fire once.

Examples

subscribe($g.motionSensor, { state: 'on' }, onMotionDetected);
subscribe($g.motionSensor, { state: 'off' }, onMotionCleared);
Friendly labels
subscribe($g.frontDoor, { to: 'Open' }, onDoorOpen);          // binary_sensor/door: 'Open' → on
subscribe($g.panel, { to: 'Armed Away' }, onArmedAway);         // intrusion panel
subscribe($g.garage, { from: 'Closed', to: 'Opening' }, onLeaving);
Attribute change and manual-only gating
subscribe($g.light, { attribute: { name: 'brightnessPercent' } }, onBrightness);

function onBrightness(evt) {
  if (evt.newState.context?.actorType !== 'physical') return; // ignore app-driven changes
  console.log('Dimmed by hand to', evt.newState.attributes?.brightnessPercent);
}

See also

unsubscribe · EntityChangeEvent · subscription filter · subscriptions and events


unsubscribe

Remove entity subscriptions: everything, everything for one handler, or those on a given target.

Signature

function unsubscribe(target: unknown, filter?: unknown, handler?: unknown): void

Parameters

NameTypeRequiredDefaultDescription
targetunknownyes—Entity, array of entities, entity id, or undefined. With no target the call is a clear-all (optionally narrowed by handler).
filterunknownnoundefinedOptional: remove only subscriptions registered with exactly this filter.
handlerunknownnoundefinedOptional: remove only subscriptions for this handler (function or name).

Returns

void

Examples

$g.updated = function () {
  unsubscribe(undefined); // drop every subscription
  unschedule(undefined);  // and every schedule / timer
  initialize();
};

See also

subscribe


matchesState

Does value name state for this entity? value is the raw token ('on') or the friendly label the app shows ('Open', 'Armed Away'), case- and separator-insensitive. The handler-body twin of entity.is() — pass the event's snapshot, e.g. matchesState(evt.entityId, evt.newState.state, 'open'). Throws on an unknown entity.

Since 2026-10 (hubs running the friendly-state runtime; older hubs have no such method)

Signature

function matchesState(entityId: string, state: string | null | undefined, value: string): boolean

Parameters

NameTypeRequiredDefaultDescription
entityIdstringyes—The entity to resolve the label against (its domain and device class pick the label table).
statestring | null | undefinedyes—The state to test, normally evt.newState.state or evt.oldState.state so the event's snapshot is tested rather than the live row. null / undefined never match.
valuestringyes—A raw token ('on') or the friendly label the app shows for this entity ('Open', 'Armed Away'), any case; spaces, hyphens and underscores are interchangeable.

Returns

boolean — true when value names state. Throws when the entity is unknown.

Notes

  • The handler-body twin of entity.is(): use it on the event snapshot you were handed, because the live state may already have moved on.
  • Raw tokens always match themselves; labels are only an input alias. Numeric domains (sensor, input_number, counter) never resolve a label.

Examples

function onDoor(evt) {
  if (matchesState(evt.entityId, evt.newState.state, 'Open')) {
    sendPushNotification('Front door opened');
  }
}

See also

is · subscribe · subscriptions and events


subscribeToLocationEvent

Subscribe to a named location event (e.g. systemStart, fired once per boot after the framework restores schedules + subscriptions). The subscription is persisted and restored across reboots.

Signature

function subscribeToLocationEvent(eventName: string, handler: unknown): void

Parameters

NameTypeRequiredDefaultDescription
eventNamestringyes—Event name. The platform fires systemStart once per boot; any other name is a custom event sent by a smart app with sendLocationEvent.
handlerunknownyes—A top-level named function (or its name as a string). Handlers are dispatched by name, so arrow functions assigned to variables cannot be used. Receives the event payload ({ name, value, … }).

Returns

void

Examples

Re-arm one-shot sun timers after a reboot
subscribeToLocationEvent('systemStart', onSystemStart);

function onSystemStart() {
  scheduleAtSunset(onSunset);
}

See also

sendLocationEvent · subscriptions and events


sendLocationEvent

Available at runtime but not declared in ambient.d.ts; add your own declare line when authoring in TypeScript.

Fire a named location event. Every smart app subscribed to that name — including other apps — receives it, which makes it the inter-app back-channel.

Signature

function sendLocationEvent(eventName, data)

Parameters

NameTypeRequiredDefaultDescription
eventNameunknownyes—Any non-empty string. Pick a namespaced name (myorg.doorbell.pressed) to avoid collisions.
dataunknownyes—JSON-serialisable payload delivered to subscribers as the event value.

Returns

void

Notes

  • Not declared in ambient.d.ts yet, so TypeScript authors need declare function sendLocationEvent(eventName: string, data?: unknown): void;.

Examples

sendLocationEvent('house.guestMode', { enabled: true });

See also

subscribeToLocationEvent


getEntityIds

Available at runtime but not declared in ambient.d.ts; add your own declare line when authoring in TypeScript.

Normalise an entity input to a list of entity ids: one id for a single pick, every id for a multi-select proxy, [] for anything else.

Signature

function getEntityIds(entity)

Parameters

NameTypeRequiredDefaultDescription
entityunknownyes—A single Entity, a multi-select proxy, or any other value.

Returns

string[]

Notes

  • Not declared in ambient.d.ts; declare it yourself in TypeScript or use Array.isArray(input) ? input : [input] on the wrappers instead.

Examples

const ids = getEntityIds($g.lights); // ['light.kitchen', 'light.hall']
Generated from docs-bundle v0.1.0, novon-platform 9ce3486c (2026-10-09).

On this page