Skip to main content

Running Node-RED on Enapter Gateway

What Is Node-RED?

Node-RED is an open-source flow-based development tool for visual programming of event-driven applications. It is built on top of Node.js and provides a browser-based flow editor that allows developers to wire together devices, APIs, and online services in a visual way. Node-RED is very helpful for converting, amendment of different protocols or different services.

This guide will cover some applications of Node-RED:

  • Translation of Zigbee2MQTT MQTT Protocol to HTTP

Requirements

Setting Up Node-RED Using Docker Container

Connect to the Gateway Terminal either over SSH or Cloud and switch to the root shell.

Connect to the Gateway Terminal either over SSH or Cloud. Switch to the shell using the bash command, and then switch to root with the sudo su - command.

Create Node-RED data directory at /user/nodered-data/

Create Node-RED data directory: mkdir -p /user/node-red/.

Open /user/etc/docker-compose/docker-compose.yml with nano editor and put the following configuration under services section.

Zigbee2MQTT Web Interface
services:
node-red:
image: nodered/node-red:3.1
container_name: nodered
environment:
- TZ=Asia/Yerevan
ports:
- "1880:1880"
restart: unless-stopped
user: root:root
volumes:
- /user/nodered-data:/data

Press CTRL+X to exit, save your configuration and restart docker compose with systemctl restart enapter-docker-compose command.

If everything was done correctly, you will be able to connect to the Node-RED web interface using the URL http://YOUR_GATEWAY_IP:1880.

Zigbee2MQTT Web Interface

The Node-RED is installed and ready for use!

Translation of Zigbee2MQTT MQTT Protocol to HTTP

At the time of writing this guide, virtual UCM doesn't support direct connection using the MQTT protocol. Therefore, to work with MQTT, for example, in the case of using Zigbee2MQTT, an MQTT to HTTP translation is required for the integration of such devices into Enapter Cloud.

Luckily, Node-RED is perfect for this task!

Requirements

To set up translation, you will require having:

To set up translation, you require to know the following:

  • Zigbee2MQTT base topic. In our example it will be zigbee2mqtt.
  • Enapter Gateway Public MQTT username. In our example it will be mqtt.
  • Enapter Gateway Public MQTT password. In our example it will be password.
  • At least one Zigbee device Friendly name. We will use Living Room Climate in this example.

Setting UP Node-RED Flow

In Node-RED, a flow is a visual representation of a sequence of actions or processes. It's the core building block used in the Node-RED editor to create event-driven applications. A flow consists of nodes that perform specific tasks and wires that connect these nodes to define the flow of data between them.

Open Node-RED Web interface at `http://YOUR_GATEWAY_IP:1880. Click on Menu -> Import

Zigbee2MQTT Web Interface

Copy and paste the JSON configuration below and press Import button.

[
{
"id": "d6582bdba1670443",
"type": "tab",
"label": "Zigbee2MQTT HTTP API",
"disabled": false,
"info": "",
"env": []
},
{
"id": "860dd4ce0709cb68",
"type": "mqtt in",
"z": "d6582bdba1670443",
"name": "Connection to Zigbee2MQTT",
"topic": "zigbee2mqtt/+",
"qos": "2",
"datatype": "utf8",
"broker": "ec4fd85471d86387",
"nl": false,
"rap": true,
"rh": 0,
"inputs": 0,
"x": 160,
"y": 40,
"wires": [["13fee8ea81ce27c5", "4ef9a256ada441aa"]]
},
{
"id": "13fee8ea81ce27c5",
"type": "debug",
"z": "d6582bdba1670443",
"name": "debug msg object",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "true",
"targetType": "full",
"statusVal": "",
"statusType": "auto",
"x": 510,
"y": 40,
"wires": []
},
{
"id": "56d54b820ee3959a",
"type": "function",
"z": "d6582bdba1670443",
"name": "Lookup Device Data",
"func": "// default response message is empty object\n// we'll use it if we don't have a data or device\n// name is not provided\nmsg.payload = \"{}\"\n\nconst device_name = msg.req.query[\"device\"];\n\nif (device_name != null && device_name != \"\") {\n const device_name_key = \"device-\" + device_name.replace(/\\s/g, \"_\");\n const device_telemetry = flow.get(device_name_key);\n \n if (device_telemetry != null && device_telemetry != \"\") {\n msg.payload = device_telemetry\n }\n}\n\nreturn msg;",
"outputs": 1,
"timeout": "",
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 380,
"y": 200,
"wires": [["cfe268da996ec193"]]
},
{
"id": "486a47da3b33483b",
"type": "http in",
"z": "d6582bdba1670443",
"name": "[GET] /zigbee",
"url": "/zigbee",
"method": "get",
"upload": false,
"swaggerDoc": "",
"x": 110,
"y": 200,
"wires": [["56d54b820ee3959a"]]
},
{
"id": "cfe268da996ec193",
"type": "http response",
"z": "d6582bdba1670443",
"name": "HTTP Response",
"statusCode": "200",
"headers": {},
"x": 600,
"y": 200,
"wires": []
},
{
"id": "4ef9a256ada441aa",
"type": "function",
"z": "d6582bdba1670443",
"name": "Save Device Data",
"func": "const device_name_regexp = new RegExp(\"zigbee2mqtt/([^/]+)\");\n\nconst matches = msg.topic.match(device_name_regexp);\nconst device_name = matches[1]\n\nif (device_name != null && device_name != \"\") {\n const data = msg.payload;\n const device_name_key = \"device-\" + device_name.replace(/\\s/g, \"_\");\n \n flow.set(device_name_key, data);\n}\n\nreturn msg;",
"outputs": 1,
"timeout": "",
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 510,
"y": 100,
"wires": [[]]
},
{
"id": "ec4fd85471d86387",
"type": "mqtt-broker",
"name": "Enapter GW Public MQTT",
"broker": "10.88.0.1",
"port": "9883",
"clientid": "",
"autoConnect": true,
"usetls": false,
"protocolVersion": "4",
"keepalive": "60",
"cleansession": true,
"autoUnsubscribe": true,
"birthTopic": "",
"birthQos": "0",
"birthRetain": "false",
"birthPayload": "",
"birthMsg": {},
"closeTopic": "",
"closeQos": "0",
"closeRetain": "false",
"closePayload": "",
"closeMsg": {},
"willTopic": "",
"willQos": "0",
"willRetain": "false",
"willPayload": "",
"willMsg": {},
"userProps": "",
"sessionExpiry": ""
}
]

You will get Zigbee2MQTT HTTP API flow imported. Click on Zigbee2MQTT HTTP API tab to open it.

Zigbee2MQTT Web Interface

Double-click on Connection to Zigbee2MQTT node.

Zigbee2MQTT Web Interface

Check that Topic is set to correct Zigbee2MQTT Base Topic - zigbee2mqtt/# in our example. Click edit button right after the Enapter GW Public MQTT server name.

Zigbee2MQTT Web Interface
note

The default IP address of Enapter Gateway in Docker network is 10.88.0.1 and Public MQTT is running on port 9883.

Switch to the Security tab and put the username and password for your Public MQTT connection.

Zigbee2MQTT Web Interface

Click on Update button. In the opened windows click Done button to apply your settings.

Now you are ready to deploy your flow!

Click on the Deploy button in the top right corner.

As soon as the project is deployed, you will start receiving debug messages from Zigbee2MQTT. You will be able to see them in the debug panel.

Zigbee2MQTT Web Interface

Testing Zigbee2MQTT HTTP API

Wait for a few minutes to receive at least one message from the Zigbee device you would like to test HTTP API for. Open a new tab in your browser and navigate to the following URL:

http://YOUR_GATEWAY_IP:1880/zigbee?device=ZIGBEE_DEVICE_FRIENDLY_NAME

In our example: http://192.168.123.10:1880/zigbee?device=Living Room Climate.

You will be able to see JSON file with all metrics from your Zigbee device.

Zigbee2MQTT Web Interface

Contacts

Feel free to ask any questions or give any proposals for improving this guide in our Discord

All Rights Reserved © 2024 Enapter AG.