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

On the same server as Node Red. In the node red dist folder

Now when I turn my lights off then the lights will turn on automatically. This is my flow:

[{"id":"9f116efb.7362c","type":"mqtt in","z":"ad80e500.3c7e98","name":"MQTT receiver light","topic":"homie/homey-5d14b942367eb80ccf0c77c3/woonkamer/onoff","qos":"2","datatype":"auto","broker":"a4ac80e1.bc5fe","x":190,"y":560,"wires":[["75713fab.deb13"]]},{"id":"75713fab.deb13","type":"function","z":"ad80e500.3c7e98","name":"Kleur en icoon","func":"// note that this flow is triggered by an mqtt message AND by the repeating timestamp node\n// here we deal with the message payload only\nif (msg.payload === \"true\"){\n\n    flow.set(\"statusWoonkamerLamp\", true);\n}\nelse if (msg.payload ===\"false\") {\n    flow.set(\"statusWoonkamerLamp\", false);\n}\nelse {\n    // don't do anything here as this could be your timestamp trigger\n}\n\n// here we deal with the flow variable.\nif (flow.get(\"statusWoonkamerLamp\")){\n    msg.ui_control = {icon:\"icons/light-bulb-on-60.png\", tooltip:\"Licht is aan\"};\n    msg.label = \"Licht is aan\"\n}\nelse {\n    msg.ui_control = {icon:\"icons/light-bulb-off-60.png\", tooltip:\"Licht is uit\"};\n    msg.label = \"Licht is uit\"\n}\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":420,"y":560,"wires":[["1cf370ef.c5275f"]]},{"id":"1ef377ea.07b3a8","type":"mqtt out","z":"ad80e500.3c7e98","name":"MQTT Transmitter","topic":"homie/homey-5d14b942367eb80ccf0c77c3/woonkamer/onoff/set","qos":"","retain":"","broker":"a4ac80e1.bc5fe","x":1030,"y":560,"wires":[]},{"id":"1cf370ef.c5275f","type":"ui_template","z":"ad80e500.3c7e98","group":"b290cc21.d734d","name":"Woonkamer","order":7,"width":4,"height":3,"format":"<md-button class=\"btn1\" id=\"buttonlight\" style=\"background-color:#ff333333\" ng-click=\"send({payload: msg.payload })\"> \n    <img id=\"imgofbutton\" src=\"{{msg.ui_control.icon}}\">\n    <div class=\"textofbutton\">\n         <b id=\"buttonslighttext\">Woonkamer</b>\n    </div>\n</md-button>","storeOutMessages":false,"fwdInMessages":false,"resendOnRefresh":false,"templateScope":"local","x":650,"y":560,"wires":[["6ce1b6de.567ff8"]]},{"id":"6ce1b6de.567ff8","type":"function","z":"ad80e500.3c7e98","name":"","func":"\nif (msg.payload === \"false\" ){\n    msg.payload = \"true\";\n}\nelse { msg.payload = \"false\";\n}\nreturn [msg];","outputs":1,"noerr":0,"initialize":"","finalize":"","x":820,"y":560,"wires":[["1ef377ea.07b3a8"]]},{"id":"cf84f42a.fdca58","type":"mqtt out","z":"ad80e500.3c7e98","name":"MQTT Transmitter","topic":"homie/homey-5d14b942367eb80ccf0c77c3/woonkamer/dim/set","qos":"","retain":"","broker":"a4ac80e1.bc5fe","x":1030,"y":640,"wires":[]},{"id":"2d570c90.8fbc24","type":"mqtt in","z":"ad80e500.3c7e98","name":"MQTT receiver light","topic":"homie/homey-5d14b942367eb80ccf0c77c3/woonkamer/dim","qos":"2","datatype":"auto","broker":"a4ac80e1.bc5fe","x":190,"y":640,"wires":[["6bc7cc75.5d06d4","b2bcb601.de5fb8"]]},{"id":"6bc7cc75.5d06d4","type":"debug","z":"ad80e500.3c7e98","name":"light_slider","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":450,"y":700,"wires":[]},{"id":"279500ed.f416b","type":"ui_template","z":"ad80e500.3c7e98","group":"b290cc21.d734d","name":"Woonkamerdim","order":14,"width":4,"height":1,"format":"<div id=\"slidernew1\">\n    <md-slider-container>\n    <md-slider min=\"0\" max=\"100\" ng-model=\"msg.payload\" ng-change=\"send(msg)\"></md-slider>\n    <span style=\"padding-right: 18px; text-align: right\">{{msg.payload}}</span>\n</md-slider-container> \n</div>","storeOutMessages":true,"fwdInMessages":true,"resendOnRefresh":true,"templateScope":"local","x":660,"y":640,"wires":[["cf84f42a.fdca58"]]},{"id":"b2bcb601.de5fb8","type":"function","z":"ad80e500.3c7e98","name":"set variable","func":"flow.set(\"statusWoonkamerLampDim\", msg.payload);\n// here we deal with the flow variable.\nflow.get(\"statusWoonkamerLampDim\")\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":430,"y":640,"wires":[["279500ed.f416b"]]},{"id":"242fdd78.18f232","type":"inject","z":"ad80e500.3c7e98","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"15","crontab":"","once":true,"onceDelay":"5","topic":"","payload":"","payloadType":"date","x":210,"y":520,"wires":[["75713fab.deb13"]]},{"id":"a4ac80e1.bc5fe","type":"mqtt-broker","z":"","name":"Homey MQTT","broker":"192.168.1.6","port":"1883","clientid":"","usetls":false,"compatmode":true,"keepalive":"60","cleansession":true,"birthTopic":"","birthQos":"0","birthPayload":"","closeTopic":"","closeQos":"0","closePayload":"","willTopic":"","willQos":"0","willPayload":""},{"id":"b290cc21.d734d","type":"ui_group","z":"","name":"Buttons","tab":"2a0bd1d7.7ca9ce","order":1,"disp":false,"width":30,"collapse":false},{"id":"2a0bd1d7.7ca9ce","type":"ui_tab","z":"","name":"Tab3","icon":"dashboard","order":3,"disabled":false,"hidden":false}]

Since we share a similar set of flows; please note that in my function nodes:

I use reverse boolean logic: where a true is received from the MQTT broker on the left-hand side, the function node sends out a false message on the right-hand side and vice versa.

This is my code:

if (msg.payload === "true"){ // RECEIVE TRUE
    msg.color = "#FFAA00";    
    flow.set("state", "false"); // SEND FALSE
}
else { // RECEIVE FALSE
    msg.color = "#44AAFF";
    flow.set("state", "true"); // SEND TRUE
}
return msg;

Hope this helps.

I’ve discovered that it also depends on the broker. Apparently some brokers keep track of all settings and rebroadcast them if Node-red is deployed. (If I press deploy I get a massive amount of MQTT data on the debug node). This was not the case when I used the Homey MQTT broker. You can also manually re-broadcast all settings by pressing the “Broadcast” button inside the MQTT Hub configuration panel.

Nice thanks for sharing. Did you know there’s a great list UI node for node red?



You simply add all kinds of things like icons easily to the list without need to code the html yourself :wink:
1 Like

A full spec MQTT broker has an ability to remember all messages if the client posts them with ‘retained true’ . So every time a new client connects and subscribes to the MQTT broker all that ‘retained’ information is sent - even if the originating client is no longer connected.

If the original client does not publish ‘retained’ then when a new client connects and subscribes it will receive no information. It’s a function of the original publishing client.

Some versions of MQTT hub published state with retain false but I believe the latest - or beta version, publishes with retained true. I do not know the capabilities of the inbuilt MQTT broker.

Hi All,

Just began to make my own dahsboard, and followed the tutorial in the beginning of this post.
It is working good, however i noticed when i turned on a lamp via the homey app, or a lamp turned on via a flow, the status on my dashboard doesn’t change. This is what i got, do i miss something?

Also, is there some good instruction how to style the dashboard with css? or how did you do it?
Thanks in advance!

It seems that I need to check this out :wink: - Thanks!

Hey folks; i have a little question.
Been messing about with the Node-Red dashboard for a while now and i’m almost happy with my buttons.

The custom CSS in the startpost really helped getting closer to my desired look, thanks for that!

The 1 thing i would like though is to have the button have a “glowing” border when the light is on.

Currently i have it like this:
Button when light is off
image
Button when light is on.
image

and the corresponding json for it;

[{“id”:“325c798d.0afbc6”,“type”:“ui_button”,“z”:“5c665611.5dc198”,“name”:“HueTV-Button”,“group”:“50cbc251.33a45c”,“order”:1,“width”:“2”,“height”:“2”,“passthru”:false,“label”:“”,“tooltip”:“”,“color”:“{{msg.iconcolor}}”,“bgcolor”:“”,“icon”:“fa-lightbulb-o fa-4x”,“payload”:“lightstate”,“payloadType”:“global”,“topic”:“homie/homey-topic/hue-color—tv-meubel/onoff/set”,“x”:740,“y”:100,“wires”:[[“e5f9e9a3.404a98”]]},{“id”:“e5f9e9a3.404a98”,“type”:“function”,“z”:“5c665611.5dc198”,“name”:“Toggle On / Off”,“func”:“//this function runs when you are pressing the button.\n// read current state of light\nvar lightstate = flow.get("lightstate") || false;\n\n//Payload is NOT (!) the lightstate. inverts the boolean (true / false)\nmsg.payload = !lightstate;\n\nreturn msg;”,“outputs”:1,“noerr”:0,“initialize”:“”,“finalize”:“”,“x”:920,“y”:100,“wires”:[[“b6593e0f.a6364”]],“inputLabels”:[“input”],“outputLabels”:[“to button”]},{“id”:“c4d79b8.c4b7668”,“type”:“mqtt in”,“z”:“5c665611.5dc198”,“name”:“MQTT TV - Status”,“topic”:“homie/homey-topic/hue-color—tv-meubel/onoff”,“qos”:“2”,“datatype”:“auto”,“broker”:“398b4fb0.59644”,“x”:330,“y”:100,“wires”:[[“bdba58a8.5fbe68”]]},{“id”:“bdba58a8.5fbe68”,“type”:“function”,“z”:“5c665611.5dc198”,“name”:“store the state of light”,“func”:“var lightstate = flow.get("lightstate") || undefined;\nvar label;\nvar color;\n\nif(msg.payload === "true"){\n// state is true (lets make button green)\n label = "ON";\n lightstate = true;\n iconcolor = ‘yellow’;\n}\nelse{\n // state is false (lets make button red)\n label = "OFF";\n lightstate = false;\n iconcolor = ‘white’;\n}\n\nflow.set("lightstate",lightstate);\nmsg = {enabled:true, topic:label, iconcolor:iconcolor};\nreturn msg;”,“outputs”:1,“noerr”:0,“initialize”:“”,“finalize”:“”,“x”:540,“y”:100,“wires”:[[“325c798d.0afbc6”]]},{“id”:“b6593e0f.a6364”,“type”:“mqtt out”,“z”:“5c665611.5dc198”,“name”:“MQTT Light transmit”,“topic”:“”,“qos”:“”,“retain”:“”,“broker”:“398b4fb0.59644”,“x”:1120,“y”:100,“wires”:},{“id”:“50cbc251.33a45c”,“type”:“ui_group”,“z”:“”,“name”:“TV”,“tab”:“d0e7bb9b.ea1608”,“order”:2,“disp”:false,“width”:“2”,“collapse”:false},{“id”:“398b4fb0.59644”,“type”:“mqtt-broker”,“z”:“”,“name”:“Homey MQTT”,“broker”:“nodered.vandenberge.nu”,“port”:“8883”,“tls”:“d041e890.a6d038”,“clientid”:“NodeRed”,“usetls”:true,“compatmode”:true,“keepalive”:“60”,“cleansession”:true,“birthTopic”:“”,“birthQos”:“0”,“birthPayload”:“”,“closeTopic”:“”,“closeQos”:“0”,“closePayload”:“”,“willTopic”:“”,“willQos”:“0”,“willPayload”:“”},{“id”:“d0e7bb9b.ea1608”,“type”:“ui_tab”,“z”:“”,“name”:“test”,“icon”:“dashboard”,“order”:26},{“id”:“d041e890.a6d038”,“type”:“tls-config”,“z”:“”,“name”:“”,“cert”:“”,“key”:“”,“ca”:“”,“certname”:“”,“keyname”:“”,“caname”:“”,“servername”:“”,“verifyservercert”:false}]

How can i make it so that an enabled light gets a border?
I call it a glowing border but of course it’s just a yellow or green border :wink:

thanks for any help!

Thanks for this nice topic, didn’t know this was a thing, just started to build my dashboard, so still a WiP… First worked on the CSS (not done yet), now adding all devices… what a work haha. Will post some screenshots when it’s more filled with stuff/devices.

Hi @tmaniac
Just add this css to your bulb icon:
text-shadow: 0px 0px 20px rgba(255, 255, 255, 1);
Where 20px is the blur radius, 255,255,255 is a white color, and 1 is the opacity.
Glow-Icons

1 Like

oeh! i like your style :slight_smile:
care to share? (so i can copy it shamelessly?)

@DeepBlueNine
Forgive me, i’m a very complete beginner with CSS etc.
Where do i add the code? in the UI template or someplace else?

@tmaniac
You can get my CSS here : Custom Node-Red CSS
Yes, add the CSS in your UI Template, in my example, I’m using the “fa-user” icon, so I’ve added this code in my UI Template :
.fa-user:hover { text-shadow: 0px 0px 20px rgba(255, 255, 255, 1); }

Hi @DeepBlueNine,
This is for hovering only. But how can I make the icon glowing when then light is on, and not-glowing when the light is off? Is this even possible?
Thanks for your valuable contributions!

Hi all,
I have installed node red in docker on my NAS.
Does anyone know how I can get node red platform upgrades installed, should they arrive?
Thanks!

Hi @RogerSt
Yes, that’s possible, you just need to create a function like this, before the UI Template :

var label;
var color;
var icon;
var classportail;

if(msg.payload === true){
 label = "OUVERT";
 color = "red";
 icon = "fa 3x fa-unlock";
 classportail = "gate-open";
}
else{
 label = "FERMÉ";
 color = "green";
 icon = "fa 3x fa-lock";
 classportail = "gate-closed";
}

msg = {cportail:classportail, topic:label, background:color, status:icon};
return msg;

And the code for the UI Template :
<div class="{msg.cportail}}">{{msg.topic}}</div>

The CSS code must be something like that, where text-shadow is the glowing effect :
.gate-open { text-shadow: 0px 0px 20px rgba(255, 255, 255, 1); }

It work’s fine in my dashboard.
Glow-FX

2 Likes

Thanks, this works where I use different icons for different states. Where I use the same icon but a different icon color, this is not a solution.
I will first try to find a solution myself.
Superb feedback for you Eric.

1 Like

How have you incorporated the icon in your UI template?
I already had a class=“msg.icon” and now I need to add a class=“msg.cportail” to the icon.
This does not seem to work.

My message:

pl="Doorbell";
icnColor="#FFAA00"; 
icon="fa fa-bell-o";
classportal = "bell-o-glow";
msg = {cportal:classportal, payload:pl, Iconcolor:icnColor, IconShape:icon};

My UI template:

<span style="vertical-align:middle; font-size:25px; color: rgb(255, 255, 255); text-align: center; " class="fr-class-transparency">
   <div class="{{msg.cportal}}"> <i style="color:{{msg.Iconcolor}}!important;" class="{{msg.IconShape}}" aria-hidden="true"></i></div>&nbsp;
<span>{{msg.payload}}</span>
</span>

My CSS:

.fa-bell-o-glow { text-shadow: 0px 0px 20px rgba(255, 255, 255, 1); }
.fa-bell-o-noglow { text-shadow: 0px 0px 0px rgba(255, 255, 255, 1);}

No glowing happens… Sorry still quite new on this…

In the Hub app settings, there us a button “Broadcast” which will publish the state of all devices on demand. No automated solution unfortunately…

@RogerSt A ‘birth message’ can be used to automatically trigger a broadcast.