Home Assistant Websocket Flow for Node-RED

I threw together a subflow to make it easier to retrieve Home Assistant Events via Websocket into Node-RED. This will allow you to replace your YAML automation in Home Assitant with Node-RED.

I have moved all of my automation and scripts over to Node-RED via this Websocket subflow, that way I can not only make changes to my automation without restarting Home Assistant, but it also gives me access to more capabilities that are simply not available by using Home Assitant’s current implementation of automation by opening it up to ALL of the Node-RED nodes and features, while still utilizing Home Assistant for everything else.

http://flows.nodered.org/flow/d3439d33e85b76b5832ac2a0212ef567

7 Likes

Would you mind giving a bit more in depth details regarding what functionality you enable by moving to Node red?

/R

Well, pretty much everything. Home Assistant automation is limited to the constraints of what services they allow you to call, what 3rd party features you can access via existing integrations, and even the extensibility of using jinja code and templates is still very limited. With Node-RED, you are not limited in any way what so ever. You do not have to wait for new features and 3rd party integrations, you have full access to ALL javascript libraries and all of the existing nodes already developed by the Node-RED group as well as thousands of nodes and flows written by 3rd parties, and I have also written my own custom nodes as well to extend to personal services I have running.

It’s hard to explain unless you have come across the limitations of Home Assistants automation engine. It is very similar to using the AppDaemon 3rd party addon you can read about here in the forums. He wrote that python application also because of the limitations of Home Assistant. I was using AppDaemon for a long time, but I had been relying on Node-RED for so many other services, as well as being the endpoint for all of my Amazon Alexa skills, that I slowly started recreating my automation in Node-RED, and it was then that I realized how shackled I was with the limitations of Home Assitant’s built-in automation features.

Don’t get me wrong, I love Home Assitant, and it is the primary interface for my entire automation system in both houses, but in the backend, for taking off the training wheels, I have found that Node-RED not only gives me access to do literally anything, with any online cloud service or 3rd party hardware interaction, but it makes it so much easier to design automation with dragging and dropping of nodes and wiring them together visually, as well as being able to make changes on the fly without having to restart Home Assistant.

That is probably the BIGGEST benefit right there. Go ahead and try to make any changes to ANY of your automation in Home Assistant without having to then restart ALL of Home Assistant, and then let me know if you would prefer to have the ability to makes changes on the fly and have them work instantly.

That is also why the Home Assistant team made the EventSource stream as well as the Websocket Stream available to 3rd parties, because they knew that others would want to either utilize other services, such as Node-RED, to do a lot of the backend work, as well as allowing you to make your own frontends instead of using Home Assitant’s GUI frontend. It’s all part of Home Assistant being open instead of proprietary and closed.

Whether you use Node-RED with Websockets (since I am better at javascript than python) or AppDaemon (for those that are better with python), both of these options unleash your ability to do pretty much ANYTHING you can think of. For those not familiar with Node-RED, or who prefer python, I would definitely recommend using AppDaemon, it is amazing. I personally feel more comfortable with Javascript, and am very accustom to working with Node-RED, so it works better for me to use the Websockets flow I threw together to achieve the same results.

1 Like

@jbardi For those of us that are not as familiar with Node-RED do you mind publishing an example minimal workflow (with screenshots) that demonstrates the plumbing to get started. Inputs\outputs, etc.

Thanks.

@jbardi I rolled up my sleeves and implemented your pattern. Thanks…now I have to plan out next steps. :slight_smile:

Thank you, and look forward to any enhancements.

Here is a more full flow with an example. I am using the websocket to retrieve the events from Home Assistant, but I don’t like the way in which the websocket is used to send data back to Home Assistant (such as turning on/off a light switch), so for the communication back to Home Assitant for my automations, I use straight HTTP requests to Home Assistants RESTful API, as it is straight forward and just uses the http node already built into Node-RED which you can see in the example.

The example is turning on a lamp in the living room when the living room motion sensor is triggered.

Below is the link to the flow to import into Node-RED. Remember to rename YOUR_API_PASSWORD and YOUR_HASS_IP to your actual info, as there are a few more places in this flow that have to be changed. When you click on the link, you can copy the flow by clicking the RAW button, which will display all of the text in a new window.

If you already imported my original subflow, you will end up with 2 subflows, 1 named HASS Websocket and 1 named HASS Websocket 2, so I would suggest deleting the first subflow before importing this. You can delete a subflow by double clicking on it in the left side bar in Node-RED, and in the edit screen there will be a delete button at the top.

https://gist.github.com/jbardi/86666f30d00910480b659f94fe8122a2[details=Summary]This text will be hidden[/details]

1 Like

@jbardi Thank you for the example, that one is even better than the original. I’ll look at remove the websocket for the send, even though I have it working.

I started the original workflow and I get many errors (loop). “TypeError: Cannot read property ‘event_type’ of undefined” Not sure if this a configuration problem in Node RED or HA. Thoughts?

Each event from the websocket comes in as msg.payload.event, and the event_type would be msg.payload.event.event_type, and although there are many event_types from Home Assistant, my subnode is only looking for either state_changed, homeassistant_start, zwave.network_ready and zwave.scene_activated. If it does not match one of those 4 event_types, it should not output anything, so I am not sure why you are getting those errors, unless it has to do with the configuration of the YOUR_API_PASSWORD and YOUR_HASS_IP

Did you change all instances of YOUR_API_PASSWORD and YOUR_HASS_IP to match the password you have set for Home Assistant and the IP Address of your Home Assistan in the flow before doing the clipboard import into Node-RED? I have not tested it for a setup that does not use an API Password, so I’m not sure you if are using a password or not.

I find it easier to paste the flow json code into a text editor, then do a search and replace on YOUR_API_PASSWORD and YOUR_HASS_IP, and then copy and paste it into Node-RED’s import window. If you are on a Mac and use TextEdit.app, you may find that TextEdit changes all the quotes to a fancy style quote that will mess up the code, so I would use a different text editor than TextEdit if you are on a Mac when you are searching and replacing the instances of YOUR_API_PASSWORD and YOUR_HASS_IP

Since you already imported though, you can just look inside the nodes themselves and track down all the references and change them inside Node-RED as well.

As for the websocket send, from my testing, you have to send each request with a unique ID that is higher than the previous ID, so to me it seemed annoying to have to keep incrementing the ID of each new request. I figured after a week or so of running Home Assistant, with all the events going on, the ID numbers would in the thousands, and continue to climb, so unless I mis-understood Home Asistants websocket API documentation, it seemed kind of absurd, so I found it easier to use the direct RESTapi when calling back to Home Assistant to turn things on and off. Also, having only one set of nodes to do On, Off and Toggle for all device types (switch, light, input_boolean, script, etc) by using the msg.action and msg.type as variables in the http node made it a lot easier and cleaner. So for every action I wanted Home Assitant to carry out, I only had to supply msg.type, msg.action and msg.payoad (entity_id), so it just seemed easier.

So…

msg.action = "turn_on"
msg.type = "switch"
msg.payload = {
     "entity_id":"switch.living_room_lamp"
}

With the variables of the URL in the http node:

http://YOUR_HASS_IP:8123/api/services/{{{type}}}/{{{action}}}

would become

http://YOUR_HASS_IP:8123/api/services/switch/turn_on

For those not familiar with Node-RED beyond the initial nodes that come pre-installed, remember, you can go to http://flows.nodered.org to find and install additional nodes and flows, that are being added to daily, so that you can increase your ability to interact with more and more devices, services and utilities.

1 Like

@jbardi I really like what you have done. I am learning more about Node-RED and seeing the benefits\simplicity.

I think I may have found my issue. I have been creating multiple flows an using the websocket in several of them. It might be a concurrency thing from cut and pasting. I did put a null check node before your event check to filter out any random events that came through. Not sure if this is really necessary if I clean up my duplicates.

I have switched my flows to use the REST API as well. Seems a little easier to create simple generic sub-flows to execute services and Get State on the fly.

Packaging up these sub-flows into a little library, put together a few simple use cases and provide instructions on how to install node-RED in a Docker could really help the community looking for a “UI” for developing automations.

Beyond this initial message thread I hope that I can keep your information for future reference. What you have put together is pretty innovative and well documented. Thank you.

I was thinking about node-based automations for some time, and even just posted a thread about it, before I noticed this one.

It seems that unless HASS integrates some node-graph editor itself, Node-RED may be the way to go. I will have a chance to play with it in a few weeks, when I start setting up all the automation at my new home.

So, I guess in this workflow HASS is used just like a HUB connecting all the devices, zwave, etc together, sort of event\command relay, and also a web-dashboard, while Node-RED is responsible for all automations, right?

1 Like

Thank you for your flow jbardi! There’s a thing I can’t understand right now: where can changes of an items attributes (e.g. brightness level of a light) be found?
State updates for lights (not only changes) are reported properly, but not the brightness level itself, which can be found in an items attributes (at least it’s like that for zwave dimmers). Changes in brightness result in “state changed” event message from “on” to “on”, which is kind of correct but a little more information would be great.
Do you know, if there’s a way to receive web socket updates about item attribute changes/updates as well?

Update:
Never mind - dug into the subflow and found the attributes.

Thanks for this, I’ve added node-red into my docker-compose setup and trying to get a connection setup. I’m seeing an issue and wondering if anyone else sees the same. Basically, after putting in my url/port the connection fails, presumebly before getting sent as output from the websocket node, as an attached debug node does not log anything.

I’ve tried the examples @jbardi has provided, put a brand new websocket base node into a new flow, checked urls etc… but I can’t even get the auth request from hass to get sent as output to be able to parse and complete the handshake. Websocket node just says ‘disconnected’

I know the connection is making it to the hass server though as I see the below log entries in the hass log output, unfortuantly node-red doesn’t output anything useful and I increased the node-red logging in the settings.json file as well just to make sure.

Any thoughts? The only difference I can think of is running from within docker, but I don’t see how that would have an effect here, although I am about to go try locally anyways because I can’t think of anything else.

17-03-22 01:46:20 DEBUG (MainThread) [homeassistant.components.websocket_api] WS 139815698892336: Connected
hass_1                     | 17-03-22 01:46:20 DEBUG (MainThread) [homeassistant.components.websocket_api] WS 139815698892336: Sending {'ha_version': '0.41.0.dev0', 'type': 'auth_required'}
hass_1                     | 17-03-22 01:46:20 DEBUG (MainThread) [homeassistant.components.websocket_api] WS 139815698892336: Connection closed by client
hass_1                     | 17-03-22 01:46:20 DEBUG (MainThread) [homeassistant.components.websocket_api] WS 139815698892336: Closed connection

Can somebody post some examples?

I’m looking for the following:

  • Switch on a light based on certain conditions: when it’s dark(sun below horizon), and I’m home(mqtt_room), switch on the lights in my livingroom

  • How can I send command to the mediaplayer apart from on/off. I would like to have my receiver(pioneer/onkyo model) turn on and select the correct HDMI input when I select watch TV.

  • anyone an idea on how to handle z-wave scenes( a remote that sends out scene commands)

@jbardi, what happens when HASS gets restarted? Does the websocket reconnect on its own? I didn’t see any reconnect logic.

Otherwise, this looks great, thanks for sharing!

I have a similar setup but, since my rig uses a SmartThings hub, I bridge the ST to a MQTT server and use Node-Red to trigger on/send MQTT statements. Works great.

One advantage for NR is that it’s not limited to the protocols used by HA. Recommend visiting https://nodered.org/ and clicking on the “Flows” link on the upper right (to explore the features).

Only issue that I’ve come across is of the shoot-yourself-in-the-foot type. My bullet hole: I’m using both the HA interface and Node-Red’s web dashboard. Care needs to be taken to not create logic loops. I once created a Squeezbox interface where selecting one stream turned the previous stream off. Making NR’s switches available in HA (via MQTT) created a logic loop which caused all of the switches to “chatter”. After some minor tweaking, both play well together.

I have the same problem. One of the biggest drawbacks of node-red is the missing debug functionality once some node doesn’t work.

There is a debug feature. I’ve used it to figure a few things out myself.

Actually you can run node-red within the Chrome or VS Code V8 debugger, I often do this when developing a new node. These are my steps off the top of my head:

git clone https://github.com/node-red/node-red.git ~/some-dir/node-red` \
&& cd ~/some-dir/node-red  && npm install && npm run build
  • Start to test out initially working: node red.js --userDir ~/.node-red/ flows.json
  • Now you can install nodes into ~/some-dir/node-red or wherever you cloned the node-red repo
  • To run in debugger: node --inspect-brk red.js --userDir ~/.node-red/ flows.json
    • 5a. To run and restart on changes use nodemon or pm2nodemon --inspect-brk red.js -- --userDir ~/.......
  1. Open the URL that is given on the CLI for debugging via Chrome
  2. Bonus points, use VSCode debugger by adding a config to project settings when opening the node-red cloned dir via VSCode
{
    "version": "0.2.0",
    "configurations": [
        {
            "type":                   "node",
            "request":                "attach",
            "name":                   "Attach Node",
            "port":                   9229,
            "restart":                true,
            "timeout":                20000,
            "internalConsoleOptions": "neverOpen",
            "skipFiles": [
                "<node_internals>/**/*.js"
            ],
        }
    ]
}

Thanks for the help. I went with the node-red-contrib-home-assistant instead of websocket flows.
If I have enough time on my hands I will try your approach to find out why it doesnt connect my websockets!

From my research the docker seems to pass websocket data back slightly differently from other installs. Unfortunately a bug in the node.js websocket code deals with this incorrectly.

I use docker on Synology so I think I’m going to have to wait for a node.js update and then for a node-red update to pick up that correction