Node Red: A widget based dashboard working with Homey trough MQTT


I really wanted a dashboard in the wall to control everything I want. Last couple of week’s I’ve discovered homey-dash. Great I thought, and build an old iPad 2 inside the wall. Sadly, the dashboard was very limited. I could only start some flows, and control some switches. To see information on some devices, I needed to press them several times, and to use a slider I needed to long press a device. I thought I could adjust my electric blinds, but sadly the slider didn’t work for blinds… Anyway, I was hoping for some kind of really adjustable widget dashboard… And last week I’ve found it.


Dashboard from DeepBlueNine with custom CSS (Get it here)

It’s called “Node Red”. A free and open source complete framework to create and compile any dashboard you want: https://nodered.org/
It’s even capable replacing all the flows from Homey. It’s quite an intuitive mechanic. You build structures in the back end with nodes and wires. But it’s not that complicated and you can go as complicated as you want. It took me one weekend of research to get an interesting dashboard with all the items that I want. I’ve made this quick start guide to help someone else trying to do the same thing and save them for some of the hurdles I need to go trough. (note all screenshots are in Dutch)

With my current dashboard I can:

  • Activate lighting (or other) flows directly to set a mood
  • Control lights directly (on/of, brightness, mode… but haven’t figured out how to control the hue)
  • Control the curtains and blinds with slider controls
  • See the state of security like open doors
  • Control the heater
  • See all kinds of data like humidity, temperature (outside inside) air pressure
  • Can even create graphs, dials and other interesting gauges
  • If I’m not home, it displays a list of doorbell ringers
  • Show a camera feed if someone presses the doorbell
  • Multiple pages or hide / show elements based on
  • Other non-homey elements like a online rain radar etc.


Where do you install Node-red?
You need to install it on a dedicated server. Like a Raspberry pi, an Q-nap Nas or like I did, on a Synology NAS. On the NAS I installed “Docker” a virtualization app, and installed Node-red on it. (Google for your preferred platform)

So how does it communicate with homey?
First I thought I could use / reverse engineer the Homey dash JavaScript communication. (I actually still think it’s a better solution but more on that later). It uses MQTT “Message Queuing Telemetry Transport” Luckily there are apps for homey to send and receive these messages.
To use MQTT you need to install at least 2 apps on Homey: The “client”:

and the “hub”:

The client receives MQTT communication from Node Red, the Hub pushes communication to Node Red.
Then you also need a broker… This is the main MQTT server. There’s also a MQTT broker app for homey, so you can run it on Homey if you like:

There’s only one BIG drawback… It uses a lot of Homey RAM. I discovered the client uses 38MB, the Broker 41 and the Hub 35… that’s 115MB. So its advisable to run the broker somewhere else. (Like where Node red is hosted.)

[EDIT 30-10-2019] The memory usage seems to be going down after a couple weeks of usage. Maybe its the new Homey V3.0 but my current memory usage is now:
MQTT Hub: 23.8 MB
MQTT Client: 22 MB
Dont know about the Broker (I’m running this on my Synology NAS now)

Now find the ip address of the broker and connect the client and the hub (see settings app) to it. The port is usually 1883
Go to the hub and change the “topic” to something more understandable like “homie/homey-topic” (apparently “homie” is some kind of MQTT device).
If the broker does not transmit Homey MQTT data, you might restart the client and the hub. Also, if you install a new device on Homey, you need to restart the hub. It also can take a couple of minutes for the broker to discover devices.

Now go into the backend of node-red. The address is usually [Ip address of the node red server]+port 1880. Like http://192.168.178.26:1880


Inside this backend you can past node code snippets. For every example I made a JSON code snippet you can paste on the form:
Press the hamburger menu (upper right): import => clipboard. Paste the code and add it to the form.
pastecode

First of all you need to install the dashboard UI elements:

Here’s a video with some basic understanding:

Another one:

After that, add a MQTT node and link it to a debug node
Double click the MQTT node and add a server (pencil icon). Fill in the ip address and port and save / update. Give the node a name and press done. And fill in a # at the Topic (this is a wildcard).


JSON CODE (remember to change Ip address):

[{"id":"3b132935.45f326","type":"mqtt in","z":"82ee69e8.f9757","name":"MQTT receiver","topic":"#","qos":"2","datatype":"auto","broker":"d094d3b7.a558a8","x":424.20001220703125,"y":724.2000122070312,"wires":[["9a46ebd1.1b884"]]},{"id":"9a46ebd1.1b884","type":"debug","z":"82ee69e8.f9757","name":"Output debug","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","x":777.2000732421875,"y":723.2000122070312,"wires":[]},{"id":"d094d3b7.a558a8","type":"mqtt-broker","z":"","name":"Homey MQTT","broker":"192.168.178.15","port":"1883","clientid":"","usetls":false,"compatmode":true,"keepalive":"60","cleansession":true,"birthTopic":"","birthQos":"0","birthPayload":"","closeTopic":"","closeQos":"0","closePayload":"","willTopic":"","willQos":"0","willPayload":""}]

Now watch the debug window and press activate some lights inside homey. If all went well, you should see some information like:
homie/homey-topic/light/onoff : msg.payload : string[4] "true"

Great! You’ve received some info.

With this info you can create all kinds of widgets. Like connect this to a switch or use a switch to switch the light:
Add a switch node to the nodefield and create a group.
Add a MQTT Output node and connect it to the switch

Double click the Output node, select the MQTT server (previous created) and fill in the topic (from the debug window): homie/homey-topic/light/onoff/set
NOTE!: you NEED to add “/set” behind to topic to control it.
The node will automatically use the parameter that the switch generates (msg.payload).
firstswitch
JSON CODE (remember to set the right topic and ip address):

[{"id":"663c4f31.504ed","type":"ui_switch","z":"82ee69e8.f9757","name":"Light switch","label":"Light","tooltip":"","group":"2b0d2624.525502","order":9,"width":"3","height":"1","passthru":false,"decouple":"false","topic":"homie/homey-topic/binnenring/onoff/set","style":"","onvalue":"true","onvalueType":"bool","onicon":"","oncolor":"","offvalue":"false","offvalueType":"bool","officon":"","offcolor":"","x":411.20001220703125,"y":878.2000122070312,"wires":[["9e05359f.40d86"]]},{"id":"9e05359f.40d86","type":"mqtt out","z":"82ee69e8.f9757","name":"MQTT Light transmit","topic":"","qos":"","retain":"","broker":"d094d3b7.a558a8","x":668.2000122070312,"y":878.3333740234375,"wires":[]},{"id":"2b0d2624.525502","type":"ui_group","z":"","name":"Lampen","tab":"2f1cda12.393b96","order":1,"disp":true,"width":"6","collapse":false},{"id":"d094d3b7.a558a8","type":"mqtt-broker","z":"","name":"Homey MQTT","broker":"192.168.178.15","port":"1883","clientid":"","usetls":false,"compatmode":true,"keepalive":"60","cleansession":true,"birthTopic":"","birthQos":"0","birthPayload":"","closeTopic":"","closeQos":"0","closePayload":"","willTopic":"","willQos":"0","willPayload":""},{"id":"2f1cda12.393b96","type":"ui_tab","z":"","name":"Homey Dashboard","icon":"dashboard","order":1,"disabled":false,"hidden":false}]

Go in the webbrowser to the node-red front end UI (this is the dashboard): ip adress + port + /ui. Like http://192.167.178.10:1880/ui
Switch the switch and the light should go on or off.
Now, we want to switch the virtual UI switch also when we control the light outside of node-red. We can connect the already placed MQTT receiver to the switch. But… the switch needs a Boolean, and everything MQTT sends are strings. (some nodes convert these automatically, like gauges) So it needs an extra step to convert a string Boolean to a real Boolean.
Connect the MQTT receiver to a function node (this is a node where you can add a piece of javascript) double click and add:
if(msg.payload === "true"){ msg.payload = true; }else{ msg.payload = false; } return msg;

This converts a string to a Boolean (I know there are shorter smarter ways to do this, but this is more understandable)
Now connect the function node to the switch and it should switch on and of with the light outside of node red. (You might want to uncheck the pass through, otherwise you get a continuous loop).

JSON CODE (again, remember to set the correct ip / topic) :

[{"id":"1d187528.c409e3","type":"ui_switch","z":"82ee69e8.f9757","name":"Light Switch","label":"Light Switch","tooltip":"","group":"2b0d2624.525502","order":9,"width":"3","height":"1","passthru":false,"decouple":"true","topic":"homie/homey-topic/binnenring/onoff/set","style":"","onvalue":"true","onvalueType":"bool","onicon":"","oncolor":"","offvalue":"false","offvalueType":"bool","officon":"","offcolor":"","x":780.1666259765625,"y":956.2000122070312,"wires":[["f0575ce5.e23a58"]]},{"id":"f0575ce5.e23a58","type":"mqtt out","z":"82ee69e8.f9757","name":"MQTT Transmitter","topic":"","qos":"","retain":"","broker":"d094d3b7.a558a8","x":990.1666870117188,"y":956.3333740234375,"wires":[]},{"id":"de41fdc2.8f4218","type":"mqtt in","z":"82ee69e8.f9757","name":"MQTT receiver light","topic":"homie/homey-topic/light/onoff","qos":"2","datatype":"auto","broker":"d094d3b7.a558a8","x":294,"y":957.2667236328125,"wires":[["80c8f8f1.e28b9"]]},{"id":"80c8f8f1.e28b9","type":"function","z":"82ee69e8.f9757","name":"Convert String to Boolean","func":"if(msg.payload === \"true\"){\n   msg.payload = true;  \n}else{\n   msg.payload = false;\n}\nreturn msg;","outputs":1,"noerr":0,"x":555.3333282470703,"y":956.800048828125,"wires":[["1d187528.c409e3"]]},{"id":"2b0d2624.525502","type":"ui_group","z":"","name":"Lampen","tab":"2f1cda12.393b96","order":1,"disp":true,"width":"6","collapse":false},{"id":"d094d3b7.a558a8","type":"mqtt-broker","z":"","name":"Homey MQTT","broker":"192.168.178.15","port":"1883","clientid":"","usetls":false,"compatmode":true,"keepalive":"60","cleansession":true,"birthTopic":"","birthQos":"0","birthPayload":"","closeTopic":"","closeQos":"0","closePayload":"","willTopic":"","willQos":"0","willPayload":""},{"id":"2f1cda12.393b96","type":"ui_tab","z":"","name":"Homey Dashboard","icon":"dashboard","order":1,"disabled":false,"hidden":false}]

If you want to know every homey device and “subject” go to the homey mqtt hub configuration and press “broadcast”. (make sure you monitor the MQTT debug output) this will send all MQTT options. If there’s too many (te debug window can only hold a limited amount of lines) add a function between the MQTT server and debugger with the code (replace “filter” with a keyword you want to search for):

if(msg.payload.includes("filter")){ return msg; }


JSON CODE (replace the keyword in the function and set the correct ip address, also disable the other debugs by right dimming the green light on the right of the node. Otherwise every enabled debug will output):

[{"id":"1608a4fb.7adc93","type":"mqtt in","z":"82ee69e8.f9757","name":"","topic":"#","qos":"2","datatype":"auto","broker":"d094d3b7.a558a8","x":269.20001220703125,"y":1166.5999755859375,"wires":[["2e252941.9e749e","953951fe.c35e18"]]},{"id":"2e252941.9e749e","type":"debug","z":"82ee69e8.f9757","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","x":659.2000885009766,"y":1168.5999755859375,"wires":[]},{"id":"953951fe.c35e18","type":"function","z":"82ee69e8.f9757","name":"filterword","func":"if(msg.payload.includes(\"filterword\")){\n   return msg;\n}","outputs":1,"noerr":0,"x":495.2000274658203,"y":1118.3999786376953,"wires":[["85b3909.66610f"]]},{"id":"85b3909.66610f","type":"debug","z":"82ee69e8.f9757","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":659.2001800537109,"y":1118.7999114990234,"wires":[]},{"id":"d094d3b7.a558a8","type":"mqtt-broker","z":"","name":"Homey MQTT","broker":"192.168.178.15","port":"1883","clientid":"","usetls":false,"compatmode":true,"keepalive":"60","cleansession":true,"birthTopic":"","birthQos":"0","birthPayload":"","closeTopic":"","closeQos":"0","closePayload":"","willTopic":"","willQos":"0","willPayload":""}]

[EDIT] User xAPPO pointed out a great app to explore all MQTT communication:

So these are the basics… Just experiment and google like I did. There is a big library of examples and extra node plugins on the node red site. https://flows.nodered.org/
If you made a dashboard or have some great idea’s, please post them!

Future plans:
I think it’s a good idea to eliminate the whole MQTT communication structure and develop dedicated Homey integration node receiver and transmitter plugins. I haven’t dived into It (And I’m not a developer) but I think it’s doable getting functions out of the Homey Dash project and creating dedicated red-nodes with it. This will eliminate the emulation of MQTT on Homey and saves a lot of RAM. Maybe a real developer can step in, or give me some pointers how to accomplish this.

70 Likes

very good description, thank you very much! it works great. Only the part with the clock does not want to work. I only find tutorials, how to install the clock in the header. Do you have an example code for me?

Sure, I don’t know if I did it the most efficient, but it works.

You need the folowing nodes installed:
node-red-contrib-simpletime (this generates a date/time)
node-red-contrib-moment (this changes the timezone)


First I use a “inject” node that executes every second. This activates a simple time node that generates time / date then I connected that to a “Moment” node that adjusted the timezone, finally it’s coupled to a text UI output.

For the date I did the same, but instead of every second, I execute the inject node every minute. A better way was to execute the simple time node every time 0:00 is passed, but I was lazy :wink:

I added also a translation function to translate the weeks and months to dutch, but if you want to keep it English, you can remove it.
I did not want to couple it to the “every second” node. The extra time / date queries and translating the weeks / months adds useless workload to the system.

I also personaly store the time and date in a global variable (not shown here). If nobody’s home (detected by the “smart presence” Homey app) it uses this variable to generates a list with time/dates if the front doorbell is ringed.

Here’s the JSON code:
[{"id":"13d721bf.d3941e","type":"simpletime","z":"82ee69e8.f9757","name":"Tijd","x":565.2000122070312,"y":1507.4000244140625,"wires":[["dc0026f4.0f02e"]]},{"id":"9008e318.fbd948","type":"inject","z":"82ee69e8.f9757","name":"","topic":"","payload":"","payloadType":"date","repeat":"1","crontab":"","once":false,"onceDelay":0.1,"x":378.2559051513672,"y":1507.3184814453125,"wires":[["13d721bf.d3941e"]]},{"id":"dc0026f4.0f02e","type":"moment","z":"82ee69e8.f9757","name":"","topic":"","input":"payload","inputType":"msg","inTz":"Europe/Berlin","adjAmount":"2","adjType":"hours","adjDir":"add","format":"HH:mm:ss","locale":"POSIX","output":"","outputType":"msg","outTz":"Etc/UTC","x":781.7510986328125,"y":1505.2630615234375,"wires":[["ca36bae6.13083"]]},{"id":"ca36bae6.13083","type":"ui_text","z":"82ee69e8.f9757","group":"2d1af1bb.5b107e","order":1,"width":0,"height":0,"name":"Tijd","label":"<font size=\"16\">{{msg.payload}}","format":"","layout":"row-center","x":1317.592529296875,"y":1499.8316040039062,"wires":[]},{"id":"608493fa.d046bc","type":"moment","z":"82ee69e8.f9757","name":"","topic":"","input":"payload","inputType":"msg","inTz":"Europe/Berlin","adjAmount":"2","adjType":"hours","adjDir":"add","format":"dddd DD MMMM YYYY","locale":"POSIX","output":"","outputType":"msg","outTz":"Etc/UTC","x":780.7925567626953,"y":1590.631591796875,"wires":[["b0fd422d.771458"]]},{"id":"21e5e675.9eb1ba","type":"ui_text","z":"82ee69e8.f9757","group":"2d1af1bb.5b107e","order":1,"width":0,"height":0,"name":"Datum","label":"<font size=\"4\"> {{msg.payload}}","format":"","layout":"row-center","x":1319.79248046875,"y":1588.631591796875,"wires":[]},{"id":"b0fd422d.771458","type":"function","z":"82ee69e8.f9757","name":"Translate","func":"var mapObj = {\n Monday:\"Maandag\",\n Tuesday:\"Dinsdag\",\n Wednesday:\"Woensdag\",\n Thursday:\"Donderdag\",\n Friday:\"Vrijdag\",\n Saturday:\"Zaterdag\",\n Sunday:\"Zondag\",\n January:\"januari\",\n February:\"februari\",\n March:\"maart\",\n April:\"april\",\n May:\"mei\",\n June:\"juni\",\n July:\"juli\",\n August:\"augustus\",\n September:\"september\",\n October:\"oktober\",\n November:\"november\",\n December:\"december\"\n};\nmsg.payload = msg.payload.replace(/Monday|Tuesday|Wednesday|Thursday|Friday|Saturday|Sunday|January|February|March|April|May|June|July|August|September|October|November|December/gi, function(matched){\n return mapObj[matched];\n});\n\n\nreturn msg;","outputs":1,"noerr":0,"x":1020.5925903320312,"y":1592.2315673828125,"wires":[["21e5e675.9eb1ba"]]},{"id":"21acc76.c12e7b8","type":"simpletime","z":"82ee69e8.f9757","name":"Tijd","x":569.7925415039062,"y":1589.631591796875,"wires":[["608493fa.d046bc"]]},{"id":"3bfbc670.f96eb2","type":"inject","z":"82ee69e8.f9757","name":"","topic":"","payload":"","payloadType":"date","repeat":"60","crontab":"","once":false,"onceDelay":0.1,"x":379.8484344482422,"y":1589.550048828125,"wires":[["21acc76.c12e7b8"]]},{"id":"2d1af1bb.5b107e","type":"ui_group","z":"","name":"Vandaag","tab":"2f1cda12.393b96","order":2,"disp":true,"width":"6","collapse":false},{"id":"2f1cda12.393b96","type":"ui_tab","z":"","name":"Homey Dashboard","icon":"dashboard","order":1,"disabled":false,"hidden":false}]

4 Likes

Thank you so much! Works perfectly. I simply translated the days and months into German. It works for me. I am lazy too :grin:

2 Likes

Really useful and detailed post Michel - well done.

I use Node-RED a lot although not the dashboard. It was quite primitive a while back but looks to have evolved a lot… so I will take another looK.

Kevin

1 Like

Awesome work, great thx! :clap:t3:

Perhaps 3.0 new APIs may bring such a clever integration w/ the most used IoT-Projects such as NodeRed, HASS or OpenHAB.
Cannot really imagine that Athom missed the huge effort Users spent into that area.

Again - awesome work!!

Don’t count on it, given that all of those projects are (more or less) direct competitors to Homey.

1 Like

:thinking: You’re right, they are.
But: I experience all of them as being way tooooo complicated as they are - correct me if I’m wrong - all open source and the need of having programming skills is way toooo much for an average joe smart home standard user as I am.
They didn’t develop any further in terms of user friendliness so they’re still focussed on more or less nerdy guys.

But it’s OT, I know :grin: therefore:
Perhaps 3.0 will bring a dedicated DASHBOARD onboard!? :thinking::man_shrugging:

This is just awesome! I made something similar for FutureHome, a norwegian Z-Wave hub before i migrated to Homey. Despite all it’s flaws, i really do miss the API that Futurehome provided. Would you be interested in colaborating a bit on your future plans @Satoer ?

Does anyone know if there is an active Homey/Homey community Slack?

Slack here.

1 Like

I must miss something…
I dont get the nice dahboard
Only gets this.

Hi,

i installed Nodered in a Docker on my nas, added the apps on Homey, my broker is now 192.168.1.11, i changed the ip on Nodered and it says it`s connected, but when i switch a lamp in the homey app there is no debug output. What am i doing wrong?

Did you connect the Client and Hub also to the broker?
Can you guy’s install this application on a desktop and connect to the broker?

Does it get any information?

@Kalle_Kronbeck: I do see a switch on your dashboard screenshot… I’m not sure what you where expecting to see… Something exactly like mine? The whole deal with the Node red dashboard is that you can customize it just like you want. Add all kinds of widgets, buttons, graph’s, sliders, layout… and connect it to any device you like. It’s not a preconfigured dashboard like Homey-dash… You need to add all the functionally yourself. It’s fully customizable.

aaaahhh I thought it would give me more widgets etc
I will try putting that togheter myself :slight_smile:

aaaahhh I thought it would give me more widgets etc


It gives you more “Widgets”. These are all UI elements you can add to your form and customize the way you want. If you want a button that executes a specific task, it can do that. If you want a gauge that shows a specific value (temperature / humidity / or any sensor) it can do that. You just need to drag it to the form and couple the right source to it.

But if you want an instant Dashboard, without lots of customization, the Homeydash project might be more suitable.

1 Like

Well… the future plan is to code a dedicated Homey-receive and Homey-sent node-plugin for Node red. This will eliminate the need for the 3 MQTT apps. I think it’s doable by copy parts of the Homey Dash code. I did a quick look at the Homey-ink source code (this is the base code of homey Dash). And I don’t think it’s too complicated. But I’m not experienced in Java script or node-red programming. (But I do know the basics of Java script / C / VB / Python/ Pascall / delphi / php etc programming, so I’m not a complete noob :wink:). The main question about the Homey-ink project I have right now, is if new data from Homey (like a light switch pressed) get’s pushed to the Homey-ink dashboard, or does the Homey-ink needs to poll the data constantly.

Anyhow… it would help if a homey-dash project insider could create a simple push and pull example.

1 Like

Does anyone got a working forecast in a dashboard.
I would prefer from YR.no
https://hjelp.yr.no/hc/en-us/sections/360000421433-Free-weather-data

There are several weather data nodes you can install. There’s also a YR node. Haven’t tried it, but if you want weather information on your dashboard, I would first try a couple of the installable ones.

I downloaded that but didnt know how to use it. Will try more this weekend.
Worked more with my dashboard and got switches, gauges and diagrams to work.
But is there a way to get the status of switch/lamp?
If if It’s turned on for example by another flow or switch the switches on my dashboard wont know that.

The same way like you did the gauges an diagrams. Just monitor the MQTT message stream when you switch a light outside of node red. there’s probably a message like:

homie/homey-topic/lightname/onoff : msg.payload : string[4]
“true”

I did made an example in the openings post.