Intro

We’re continuing where we left off after Part 4: Mosquitto Docker Container.

In this Part 4, we’ll be adding Node-RED, which will give us a visual and feature-rich method for automating stuff. This is a personal preference and you may decide not to do this and stick to Home Assistant Automations instead.

Install Node-RED container

Docker-compose

We expand our docker-compose.yaml with the config for the Node-RED container.

services:
  [...]
  
  nodered:
    container_name: nodered
    image: nodered/node-red
    restart: unless-stopped
    ports:
      - "1880:1880/tcp"
    environment:
      - TZ=Europe/Brussels
    volumes:
      - /opt/nodered/data:/data
    depends_on:
      - homeassistant
      - mosquitto

Because our Node-RED automations are reliant on Home Assistant and we may be doing some stuff over MQTT as well, we want to make sure our HA Container and Mosquitto broker are running.

File permissions

If we now launch the Node-RED container using docker-compose up -d nodered you might notice you’re unable to open the web interface at http://<ip.of.our.box>:1880.

Checking the logs in Portainer or by running docker logs nodered, you may notice file permissions errors:

docker logs nodered

Error: EACCES: permission denied, copyfile '/usr/src/node-red/node_modules/node-red/settings.js' -> '/data/settings.js'
    at Object.copyFileSync (node:fs:2817:3)
    at copyFile (/usr/src/node-red/node_modules/fs-extra/lib/copy/copy-sync.js:73:6)
    at onFile (/usr/src/node-red/node_modules/fs-extra/lib/copy/copy-sync.js:59:25)
    at getStats (/usr/src/node-red/node_modules/fs-extra/lib/copy/copy-sync.js:51:44)
    at handleFilterAndCopy (/usr/src/node-red/node_modules/fs-extra/lib/copy/copy-sync.js:36:10)
    at Object.copySync (/usr/src/node-red/node_modules/fs-extra/lib/copy/copy-sync.js:29:10)
    at Object.<anonymous> (/usr/src/node-red/node_modules/node-red/red.js:129:20)
    at Module._compile (node:internal/modules/cjs/loader:1105:14)
    at Object.Module._extensions..js (node:internal/modules/cjs/loader:1159:10)
    at Module.load (node:internal/modules/cjs/loader:981:32) {
  errno: -13,
  syscall: 'copyfile',
  code: 'EACCES',
  path: '/usr/src/node-red/node_modules/node-red/settings.js',
  dest: '/data/settings.js'
}
node:internal/fs/utils:345
    throw err;
    ^

This has to do with how the mapping of users inside and outside a Docker container works.

Our Docker volume for the data directory was created by (and is owned by) our root user, who’s ID are uid=0 gid=0. The nodered user inside the container, which owns the /data directory, however has different IDs: 1000:1000 (uid:gid). We can fix this by changing the ownership of the Docker volume to the user with the ID 1000:1000 by running sudo chown -R 1000:1000 /opt/nodered/data.

Docker should notice the change in permissions and will restart the container. If not, recreate the container from the Portainer interface.

We can now open the Node-RED interface at http://<ip.of.our.box>:1880.

Home Assistant config

As we did with Portainer in Part 3, we can add Node-RED to the sidebar of our Home Assistant dashboard using the panel-iframe. This makes it easier to access Node-RED.

Add the following lines to configuration.yaml:

panel_iframe:
  portainer:     # part 3
    [...]
  nodered:
    title: Node-RED
    icon: mdi:lan
    url: http://192.168.10.106:1880/
    require_admin: true

Restart Home Assistant via the Developer Tools menu and you’ll side Node-RED appear in the sidebar.

Home Assistant sidebar showing Node-RED shortcut
Node-RED accessible from the sidebar

Access Token

In a minute we’ll setup Node-RED to interface with Home Assistant. To set up this connection, we will need a Long-Lived Access Token, so let’s grab one.

Click on your username at the bottom of the Home Assistant sidebar and scroll down in the Profile page untill you see the Long-Lived Access Tokens section.

Access token section in profile page
Create long-lived access tokens

Click create token and enter a name (e.g. Node-RED) for the token in the pop-up window. Finally copy the access token and paste it somewhere safe as you won’t be able to retrieve the token afterwards.

Node-RED configuration

Open the Node-RED interface either through the Home Assistant dashboard or by browsing to http://<ip.of.our.box>:1880.

Node-RED Welcome Screen
Node-RED welcomes us

Feel free to go through the walkthrough.

Home Assistant nodes

First we need to add the Home Assistant nodes to Node-RED.

  1. Open the hamburger menu at the top-right and click Manage Palette to get an overview of available and installed nodes.
  2. Open the Install tab.
  3. Search for and install node-red-contrib-home-assistant-websocket.
Node-RED Palette
Install HA Websockets in the Palette

Next we need to set up the connection between Node-RED and Home Assistant.

  1. Back in the flow editor, drag a events: all node from the Home Assistant section to the editor.
  2. Double-click the node to open its configuration.
  3. Choose for Add new server... next to Server and click the pencil icon.
  4. Give the server config a name (e.g. Home Assistant).
  5. Do NOT check Using the Home Assistant Add-on.
  6. Next to Base URL enter the address you use to access Home Assistant http://<ip.of.our.box>:8123.
  7. Enter the Access Token we got from Home Assistant a minute ago.
  8. Add, Save, and Deploy to store the server config.

Node-RED HA server setup
Setting up the HA server connection
Node-RED HA server setup details
Entering the server details

From now on, we’ll be able to communicate with Home Assistant from Node-RED. We can listen for state changes and call services exposed by Home Assistant and HA integrations.

Deploy Tip

You can choose to only deploy nodes that were added or modified so Node-RED doesn’t restart all flows when deploying.

Node-RED deploy dropdown
Deploy in full, modified flows or modified nodes

MQTT and Node-RED

Let’s also setup a connection from Node-RED to our MQTT broker so we can directly communicate with devices over MQTT from Node-RED.

MQTT user

I prefer to create an additional MQTT user for Node-RED. This will allow us to track communications coming from Node-RED in the Mosquitto logs.

Open a terminal window, connect to the Docker machine and run the following command:

docker exec -it mosquitto mosquitto_passwd /mosquitto/config/mqttuser nodered
# Enter a password

Node-RED setup

This setup is fairly similar to how we setup the Home Assistant connection. The main difference is that we don’t need to add a package as MQTT is support by default.

  1. Add a MQTT node.
  2. Double-click to open its configuration.
  3. Add a new MQTT server.
  4. In the Connection tab, fill in the Server address (<ip.of.our.box>) and Port (1883) of our broker, and pick a Client ID or let Node-RED generate a random one.
    Note that I picked “MQTT V3.1.1” as Protocal, but feel free to select “MQTT V5” if you want to. Mosquitto supports both.
  5. In the Security tab, enter the username and password for the MQTT user you just created.
  6. Add, save, and deploy to store our changes. Note that you may need to enter a MQTT topic to listen to, simply enter the # wildcard.
Node-RED MQTT broker setup
Connecting with MQTT broker

And with this part done, we can now setup the most exciting and visually pleasing automation flows and communicate directly with our MQTT broker without HA in-between.

Curious to see what I’ll add to my system next? Keep an eye open for the next blog post(s).