There is no easy way to do this currently. Even in HA you canât do this actually. Device actions and device triggers are your only way of interacting with devices currently. If you find yourself in a template with an entity ID thereâs no way to find out the device, area or integration it comes from at the moment.
However Node RED does have one advantage over HA here - it can make calls to the websockets API as part of its flows and use the response. All this information is exposed in the websockets API but HA doesnât really have a way to interact with that. You can make REST sensors for the REST API but there is no integration for a websockets API. Node RED can.
Hereâs what I made to handle this:
[{"id":"16fdbd81.9d9b82","type":"subflow","name":"Store HA config","info":"Keep config of HA up to date and easily accessible in globals. That includes:\n\n- Config entries\n- Areas\n- Devices\n- Entities\n\nIt also flattens areas into entities. So any time devices or areas are updated it also updates entities by filling out their `area_id` field. Normally entities have this blank and instead expect the device to set the area.","category":"","in":[{"x":160,"y":40,"wires":[{"id":"b09b8d39.fe41e"},{"id":"bd3c0c61.c6069"},{"id":"9349652e.f4a0c"}]}],"out":[{"x":1120,"y":160,"wires":[{"id":"447143e7.58fbf4","port":0}]}],"env":[],"color":"#DDAA99","status":{"x":240,"y":360,"wires":[{"id":"4e6fd6ff.adeda8","port":0}]}},{"id":"7b548b89.a5c924","type":"ha-api","z":"16fdbd81.9d9b82","name":"Areas","server":"cc03735a.94933","debugenabled":false,"protocol":"websocket","method":"get","path":"","data":"{\"type\":\"config/area_registry/list\"}","dataType":"json","location":"payload.areas","locationType":"msg","responseType":"json","x":370,"y":160,"wires":[["447143e7.58fbf4"]]},{"id":"bd3c0c61.c6069","type":"ha-api","z":"16fdbd81.9d9b82","name":"Devices","server":"cc03735a.94933","debugenabled":false,"protocol":"websocket","method":"get","path":"","data":"{\"type\":\"config/device_registry/list\"}","dataType":"json","location":"payload","locationType":"msg","responseType":"json","x":320,"y":220,"wires":[["e9500159.2c764"]]},{"id":"b09b8d39.fe41e","type":"ha-api","z":"16fdbd81.9d9b82","name":"Entities","server":"cc03735a.94933","debugenabled":false,"protocol":"websocket","method":"get","path":"","data":"{\"type\":\"config/entity_registry/list\"}","dataType":"json","location":"payload","locationType":"msg","responseType":"json","x":320,"y":280,"wires":[["418cca4a.cbe594"]]},{"id":"dc8fe39c.fde6d8","type":"ha-api","z":"16fdbd81.9d9b82","name":"Config entries","server":"cc03735a.94933","debugenabled":false,"protocol":"http","method":"get","path":"/api/config/config_entries/entry","data":"{}","dataType":"json","location":"payload.entries","locationType":"msg","responseType":"json","x":760,"y":220,"wires":[["447143e7.58fbf4"]]},{"id":"2c4c713b.bb30ae","type":"server-events","z":"16fdbd81.9d9b82","name":"Entity reg updated","server":"cc03735a.94933","event_type":"entity_registry_updated","exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"waitForRunning":true,"x":110,"y":280,"wires":[["b09b8d39.fe41e"]]},{"id":"9633cbe3.e13cd8","type":"server-events","z":"16fdbd81.9d9b82","name":"Device reg updated","server":"cc03735a.94933","event_type":"device_registry_updated","exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"waitForRunning":true,"x":110,"y":220,"wires":[["bd3c0c61.c6069"]]},{"id":"1f22fbb3.0144d4","type":"server-events","z":"16fdbd81.9d9b82","name":"Area reg updated","server":"cc03735a.94933","event_type":"area_registry_updated","exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"waitForRunning":true,"x":100,"y":160,"wires":[["9349652e.f4a0c"]]},{"id":"447143e7.58fbf4","type":"function","z":"16fdbd81.9d9b82","name":"Update global","func":"const data = msg.payload;\n\nif(data.entries){\n update_config_entries(data.entries);\n node.status({text:`Updated config entries (${data.entries.length})`});\n}\nif(data.areas){\n update_areas(data.areas);\n node.status({text:`Updated areas (${data.areas.length})`});\n}\nif(data.devices){\n update_devices(data.devices);\n node.status({text:`Updated devices (${data.devices.length})`});\n}\nif(data.entities){\n update_entities(data.entities);\n node.status({text:`Updated entities (${data.entities.length})`});\n}\n\nreturn msg;\n\nfunction update_entities(entities){\n if(!entities){\n entities = global.get('homeassistant.config.entities') || [];\n }\n \n devices = global.get('homeassistant.config.entities');\n for (let e of entities){\n if(!e.area_id && e.device_id){\n e.area_id = devices.find(d => d.id == e.device_id) || null;\n }\n }\n \n global.set('homeassistant.config.entities', entities);\n}\n\nfunction update_devices(devices){\n global.set('homeassistant.config.devices', devices);\n update_entities();\n}\n\nfunction update_areas(areas){\n global.set('homeassistant.config.areas', areas);\n update_entities();\n}\n\nfunction update_config_entries(entries){\n global.set('homeassistant.config.entries', entries);\n}","outputs":1,"noerr":0,"initialize":"","finalize":"","x":1000,"y":160,"wires":[[]]},{"id":"fc6ceac.c313e98","type":"join","z":"16fdbd81.9d9b82","name":"Make payload","mode":"custom","build":"object","property":"payload","propertyType":"msg","key":"topic","joiner":"\\n","joinerType":"str","accumulate":false,"timeout":"1","count":"","reduceRight":false,"reduceExp":"","reduceInit":"","reduceInitType":"","reduceFixup":"","x":580,"y":220,"wires":[["dc8fe39c.fde6d8"]]},{"id":"e9500159.2c764","type":"change","z":"16fdbd81.9d9b82","name":"Set topic","rules":[{"t":"set","p":"topic","pt":"msg","to":"devices","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":415,"y":220,"wires":[["fc6ceac.c313e98"]],"l":false},{"id":"418cca4a.cbe594","type":"change","z":"16fdbd81.9d9b82","name":"Set topic","rules":[{"t":"set","p":"topic","pt":"msg","to":"entities","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":415,"y":280,"wires":[["fc6ceac.c313e98"]],"l":false},{"id":"4e6fd6ff.adeda8","type":"status","z":"16fdbd81.9d9b82","name":"","scope":["447143e7.58fbf4"],"x":140,"y":360,"wires":[[]]},{"id":"9349652e.f4a0c","type":"change","z":"16fdbd81.9d9b82","name":"Clear payload","rules":[{"t":"set","p":"payload","pt":"msg","to":"{}","tot":"json"}],"action":"","property":"","from":"","to":"","reg":false,"x":275,"y":160,"wires":[["7b548b89.a5c924"]],"l":false},{"id":"e44a4a26.6bef2","type":"server-events","z":"16fdbd81.9d9b82","name":"HA client","server":"cc03735a.94933","event_type":"home_assistant_client","exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"waitForRunning":true,"x":80,"y":100,"wires":[["2a46ac.c8a18954"]]},{"id":"2a46ac.c8a18954","type":"switch","z":"16fdbd81.9d9b82","name":"Connected event","property":"payload","propertyType":"msg","rules":[{"t":"eq","v":"connected","vt":"str"}],"checkall":"true","repair":false,"outputs":1,"x":175,"y":100,"wires":[["b09b8d39.fe41e","bd3c0c61.c6069","9349652e.f4a0c"]],"l":false},{"id":"cc03735a.94933","type":"server","name":"Home Assistant","legacy":false,"addon":true,"rejectUnauthorizedCerts":true,"ha_boolean":"y|yes|true|on|home|open","connectionDelay":true,"cacheJson":true},{"id":"61f1c6b.d44ccb8","type":"inject","z":"a74fee2d.ac9068","name":"Manual","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":870,"y":1260,"wires":[["5ed06966.73fa48"]]},{"id":"5ed06966.73fa48","type":"subflow:16fdbd81.9d9b82","z":"a74fee2d.ac9068","name":"","env":[],"x":1020,"y":1260,"wires":[[]]}]
Itâs still somewhat of a work in progress but its been working pretty well for me so far. Essentially this subflow will listen for events saying that the area, device or entity registries have been updated. Then it will pull the corresponding registry and stash it in the homeassistant.config
global. It will also recreate the entire homeassistant.config
object when the home assistant client connects to HA or when you press the manually update button.
Then you can use this data throughout your node red flows.