home-assistant / home-assistant-js-websocket

:aerial_tramway: JavaScript websocket client for Home Assistant
Other
284 stars 85 forks source link

Read single entities #511

Open RonnyWinkler opened 4 months ago

RonnyWinkler commented 4 months ago

Use case: An app is using a small set of entities, On startup, the current entity state should be read from HA to initialize the app with current/valid states.

The app can listen to entity state changed, but this will only update if the state changes on HA (event state_changed). The app can read all entities (message get_states). But it's not possible to read single entity states. Did I miss that or is it not implemented yet?

wjtje commented 1 month ago

After facing the same issue I went looking into the code and found an (undocumented) command that can be used for this:

{
  "id": 1,
  "type": "subscribe_entities",
  "entity_ids": [
    "light.my_light"
  ]
}

This will create an subscription to that entity, but will also send the current state. You can use Unsubscribing from events to unsubscribe.

Sources:

Other notable sources:

Tsjippy commented 1 month ago

After facing the same issue I went looking into the code and found an (undocumented) command that can be used for this:

{
  "id": 1,
  "type": "subscribe_entities",
  "entity_ids": [
    "light.my_light"
  ]
}

This will create an subscription to that entity, but will also send the current state. You can use Unsubscribing from events to unsubscribe.

Sources:

Other notable sources:

Thank you for this answer.

But I don't understand the code well enough to understand your answer. Can you give me an example? To which function do you supply this data?

Tsjippy commented 2 weeks ago

After facing the same issue I went looking into the code and found an (undocumented) command that can be used for this:

{
  "id": 1,
  "type": "subscribe_entities",
  "entity_ids": [
    "light.my_light"
  ]
}

This will create an subscription to that entity, but will also send the current state. You can use Unsubscribing from events to unsubscribe. Sources:

Other notable sources:

Thank you for this answer.

But I don't understand the code well enough to understand your answer. Can you give me an example? To which function do you supply this data?

I figured it out! But I don't understand typescript so i cannot make a pull request. This is what I changed: entities.js:

export const entitiesColl = (conn, entity_ids=[]) => atLeastHaVersion(conn.haVersion, 2022, 4, 0)
    ? getCollection(conn, "_ent", undefined, subscribeUpdates, {unsubGrace: true, entity_ids: entity_ids})
    : getCollection(conn, "_ent", legacyFetchEntities, legacySubscribeUpdates);
export const subscribeEntities = (conn, onChange, entity_ids=[]) => entitiesColl(conn, entity_ids).subscribe(onChange)
const subscribeUpdates = (conn, store, entity_ids=[]) => {
    conn.subscribeMessage((ev) => processEvent(store, ev), {
        type: "subscribe_entities",
        entity_ids: entity_ids,
    });
}

collection.js:

export const getCollection = (conn, key, fetchCollection, subscribeUpdates, options = { unsubGrace: true, entity_ids: [] }) => {
....
(line 48)
if (subscribeUpdates) {
    unsubProm = subscribeUpdates(conn, store, options.entity_ids);
}
...

So maybe someone can implement in case this project is still maintained?