Tasmota/Sonoff MQTT and NodeRed

I've automated my home using Sonoff modules re-flashed with Tasmota. All the switches are controlled by MQTT messages.

This Hackaday article got me excited about Node-Red, so started fooling around with it. Despite it's apparent ease of use, I found it very difficult to piece together documentation explaining how to get Node-Red to play nice with the JSON messages that the MQTT messages carry.

I've implemented some gauges to display temperatures and humidities, and some buttons to send MQTT messages to turn things on and off. This page documents exactly how I got these things to work.

First is the button. It both sends and receives MQTT messages, so that if other devices send an MQTT message to change the state (on/off) of this light, this graphical switch will show the new state.

This is the "flow" for the button. There are two MQTT inputs feeding the button, which then sends to an MQTT output.

The first MQTT input reads the tele/.../STATE messages sent by the device (Sonoff). The messages are emitted on a regular basis (every few minutes by default, but changeable in the Tasmota configuration.) The output is a "parsed JSON object".

The JSON node converts the JSON object to a Javascript object.

The function node extracts the POWER value and emits a message with "ON" or "OFF". This feeds into the "switch" node.

The second MQTT input gets the simple "ON" or "OFF" string from the stat/.../POWER message. It feeds into the "switch" node. This message is emitted by the Tasmota/Sonoffs immediately they get an MQTT command.

The switch node accepts the strings "ON" and "OFF" from either input, and uses that to control the visual appearance of the graphical "toggle". Clicking on the toggle in the UI view causes the switch node to emit the MQTT message to turn the lamp on or off.

The MQTT output node is common to all my switch nodes; those switch nodes all specify topic and payload so this MQTT node has no special configuration.

Some of my sensors are not Tasmota and I have made them just emit a simple MQTT message with their value, and it is not JSON encoded. This flow handles those simple MQTT messages.

This MQTT input node subscribes to the topic, and the output is a string containing the value, like "70.3".

This gauge node accepts a string value and displays it on the UI.

The Tasmota/Sonoffs that have temperature and or temperature/humidity sensors attached emit those sensor values JSON encoded (plus much other information, like WiFi RSSI, uptime, etc.) This flow handles displaying those values on a gauge node.

This node listens for the tele/.../SENSOR message from an MQTT device and emits the payload as a "parsed JSON object". That payload has many different values in it.

The json node converts the "parsed JSON object" to a "JavaScript Object".

If people tell you that you don't need to learn JavaScript to use Node-Red, they're lying, at least if you intend to do any more than the Node-Red equivalent of "hello, world." The function node extracts the values we want from the JavaScript Object and returns them as string values.

You can return 1 or more values from a function node. Make sure that "outputs" is set to the number of values you are returning. If you are returning only one, emit the square brackets in the "return" statement, like this:

return temp;

This gauge node is connected to output 1 of the function node, and it displays the string value it receives on an "analog meter" in the UI.

This gauge node is connected to output 2 of the function node, and it displays the string value it receives on another "analog meter" in the UI.

William Dudley
January 24, 2020