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

I shall share my settings:

I use a Plugwise Anna thermostat, but I think the needed syntax is about the same. Looks like this:
afbeelding
The nodes schematic looks like this:

It’s a bit overcomplicated, but I shall try to explain why I did it this way:
I use to have a slider to set the temperature. But I discovered that when using touch screens two big temperature up and down where way more convenient to set the temperature. (Just two quick touches to increase it with 1 degree). The display shows the current set temperature, but the communication of the Homey / Thermostat lags too much to see the changes in real time. (It’s annoying if you want to set the temperature and have to wait a second to see what you’ve selected) So I added a timer that instantly increases the value and shows it immediately on the display. After the time out it shows the set temperature from the thermostat again (in case you set the temperature outside of the node-red dashboard).

It also waits two seconds of “not pressing the button” to send the new temperature, otherwise the thermostat gets overwhelmed with the quick changes.

Another thing I incorporated is a little red flame and a change of colour of the thermometer icon to red when the heater is heating. (boiler status).

This is all combined in a html-node for formatting.

Like I said, it’s a bit complicated for a beginner, you could begin with the simple inc and dec (to add or subtract 0,5 degree).

Here’s the full Json if you want to try my code (or study):

[{"id":"958d3128.f703d","type":"mqtt in","z":"3fc6989f.e74748","name":"Set Temperature","topic":"homie/homey-topic/kachel/target-temperature","qos":"2","datatype":"auto","broker":"d776df12.63afa","x":120,"y":320,"wires":[["8f3a8a15.e12cc"]]},{"id":"768592fa.bd0844","type":"mqtt out","z":"3fc6989f.e74748","name":"Target kamertemperatuur","topic":"homie/homey-topic/kachel/target-temperature/set","qos":"","retain":"","broker":"d776df12.63afa","x":970,"y":180,"wires":[]},{"id":"3919e4f2.08665c","type":"ui_button","z":"3fc6989f.e74748","name":"Temperature up","group":"3468ee74.04285a","order":3,"width":3,"height":2,"passthru":false,"label":"","tooltip":"","color":"","bgcolor":"","icon":"fa-4x fa-fire","payload":"0.5","payloadType":"num","topic":"Up","x":120,"y":240,"wires":[["46913fed.3edac8"]]},{"id":"42d42408.779b24","type":"ui_button","z":"3fc6989f.e74748","name":"Temperature down","group":"3468ee74.04285a","order":2,"width":3,"height":2,"passthru":false,"label":"","tooltip":"","color":"","bgcolor":"","icon":"fa-4x fa-snowflake-o","payload":"-0.5","payloadType":"num","topic":"","x":130,"y":180,"wires":[["46913fed.3edac8"]]},{"id":"8f3a8a15.e12cc","type":"function","z":"3fc6989f.e74748","name":"Store Value Global","func":"var DelaySetTemperature=flow.get('DelaySetTemperature') || false;\n\nif (DelaySetTemperature)\n{\n    \n    \n} else\n{\n  var SetTemperature=flow.get('SetTemperature') || \"10\"; \n  flow.set('SetTemperature',msg.payload);\n  return msg;  \n}\n\n\n\n\n","outputs":1,"noerr":0,"x":370,"y":320,"wires":[["f0eb83ba.ae27b8"]]},{"id":"46913fed.3edac8","type":"function","z":"3fc6989f.e74748","name":"Inc and Dec","func":"var Temperature=flow.get('SetTemperature')|| '10'; \nvar IncDec = msg.payload; \n\n\nvar DelaySetTemperature=flow.get('DelaySetTemperature') || true;\nflow.set('DelaySetTemperature',true);\n\nmsg.payload=(parseFloat(Temperature)+IncDec).toString();\nflow.set('SetTemperature',msg.payload);\nreturn msg; // SetTemperature;","outputs":1,"noerr":0,"x":370,"y":200,"wires":[["7a8dfc1e.5a069c","b4854a8d.1c6218","f0eb83ba.ae27b8"]]},{"id":"cddd0bd7.de57f","type":"function","z":"3fc6989f.e74748","name":"Disable delay","func":"var DelaySetTemperature=flow.get('DelaySetTemperature') || false;\nflow.set('DelaySetTemperature',false);\nreturn msg;","outputs":1,"noerr":0,"x":940,"y":240,"wires":[[]]},{"id":"7a8dfc1e.5a069c","type":"stoptimer","z":"3fc6989f.e74748","duration":"4","units":"Second","payloadtype":"num","payloadval":"0","name":"","x":620,"y":240,"wires":[["cddd0bd7.de57f"],[]]},{"id":"b4854a8d.1c6218","type":"stoptimer","z":"3fc6989f.e74748","duration":"2","units":"Second","payloadtype":"num","payloadval":"0","name":"","x":620,"y":180,"wires":[["768592fa.bd0844"],[]]},{"id":"58803de2.f99984","type":"mqtt in","z":"3fc6989f.e74748","name":"Boiler status","topic":"homie/homey-topic/kachel/boiler-state","qos":"2","datatype":"auto","broker":"d776df12.63afa","x":110,"y":380,"wires":[["b67f4cf2.1e776"]]},{"id":"b67f4cf2.1e776","type":"function","z":"3fc6989f.e74748","name":"Convert String to inverted Boolean","func":"var BoilerState=global.get(\"BoilerState\") || false;\n\n\nif(msg.payload === \"true\"){\n   global.set(\"BoilerState\",true);\n}else{\n   global.set(\"BoilerState\",false);\n}\nreturn msg;","outputs":1,"noerr":0,"x":660,"y":380,"wires":[["cb755ecb.ca031"]]},{"id":"2223a1f7.ec2d1e","type":"ui_template","z":"3fc6989f.e74748","group":"3468ee74.04285a","name":"Target temperature","order":1,"width":6,"height":2,"format":"<p style=\"text-align: center\">Ingestelde temperatuur</p>\n<p class='temperature' style=\"font-size:54px; text-align: center; font-weight: bold;\">&nbsp;<i style=\"color:{{msg.Iconcolor}}!important;\" class=\"fa fa-thermometer-three-quarters\" aria-hidden=\"true\"></i>\n{{msg.payload}}°<i style=\"color:{{msg.Iconcolor}}!important; font-size:25px; \" class=\"{{msg.IconFlame}}\" aria-hidden=\"true\"></i></p>\n","storeOutMessages":true,"fwdInMessages":true,"templateScope":"local","x":1270,"y":340,"wires":[[]]},{"id":"cb755ecb.ca031","type":"function","z":"3fc6989f.e74748","name":"Set icon color and temperature","func":"var BoilerState=global.get(\"BoilerState\") || false;\nvar SetTemperature=global.get(\"SetTemperature\") || 0;\nvar flame=\"\";\n\nvar Boilercolor=\"#0094CE\";\nif (BoilerState){\n    Boilercolor=\"#CE2323\"; \n    flame=\"fa fa-fire\";\n   // flame=\" &nbsp; <i style=\\\"color:#CE2323!important;\\\" class=\\\"fa fa-fire\\\" aria-hidden=\\\"true\\\"></i>\"\n}\n\nmsg = {payload:SetTemperature, Iconcolor:Boilercolor, IconFlame:flame};\n//msg = {payload:SetTemperature, Iconcolor:Boilercolor};\nreturn msg;","outputs":1,"noerr":0,"x":990,"y":340,"wires":[["2223a1f7.ec2d1e"]]},{"id":"f0eb83ba.ae27b8","type":"function","z":"3fc6989f.e74748","name":"Store Set temperature in global","func":"var SetTemperature=global.get(\"SetTemperature\") || 0;\nglobal.set(\"SetTemperature\",msg.payload);\nreturn msg;","outputs":1,"noerr":0,"x":650,"y":320,"wires":[["cb755ecb.ca031"]]},{"id":"d776df12.63afa","type":"mqtt-broker","z":"","name":"Homey MQTT","broker":"192.168.178.26","port":"1883","clientid":"","usetls":false,"compatmode":true,"keepalive":"60","cleansession":true,"birthTopic":"","birthQos":"0","birthPayload":"","closeTopic":"","closeQos":"0","closePayload":"","willTopic":"","willQos":"0","willPayload":""},{"id":"3468ee74.04285a","type":"ui_group","z":"","name":"Klimaat","tab":"f735aa47.f5cd18","order":4,"disp":true,"width":"6","collapse":false},{"id":"f735aa47.f5cd18","type":"ui_tab","z":"","name":"Homey Dashboard","icon":"dashboard","order":1,"disabled":false,"hidden":false}]

I did all you said. This is the result:

  1. In the console of the broker on my nas I can see that the homey client is connected, the node-red is connected and the mqtt explorer is connected.
  2. The log in the homey client app states that it is connected.

In the explorer I can see the connected lights.

If I turn on a light in the homey app then I can see the output in the debug window of node-red.
If I turn on the light in the node-red dashboard I only see true or false in the debug window. No power measure and so on.

But still nothing works.

What else can I do?

1 Like

Tnx but i get a error when i want to import it

Edit: solved the problem. Now it works with my tado. The only thing i have to solve is the icon somi can see my tado is heating the room.

I want the temperature collored red when the heating is on

I finally found the stupid misstake I made!

In the MQTT hub on my homey I had the topic: homie/homey-topic/
The last forward slash in that topic should be deleted and then it works.

Thanks for all the help.

Just look what I did by injecting CSS into the template node.

Great, I was out of suggestions :sweat_smile:
Still weird that is does work with the Homey-broker.

I need some assistance because I can’t get to show my door/windows sensors to show the correct state. At this moment they show the same icon when the door is open or closed.
I tried so many options I don’t even know which options I have or haven’t tried anymore. I’m out of options.

I’m using the Xiaomi door/window sensors connected to Homey and they show the correct state when a door is opened. However in the dashboard the state does not change.
This is how it’s set up at the moment:

Thanks in advance!

The topic is without the “/onoff” at the end :wink:

Check MQTT explorer for the right address and data you can retrieve:
afbeelding

Thanks! I got it working… or at least 1 of the 2 sensors.
I found that the sensor working shows alarm-contact=false like in your sample.

However the other shows the following state contact-alarm=true


The “voordeur” sensor is working but the “balkondeursensor” is not.
If have tried to change the values in the string from true to false and false to true but the lock still does not change color when I open the door. When I open the “voordeur” the icon changes immediately.

Hope you can make any sense out of this because i’m lost.
Thanks!

I have no Idea why some one sensor works, and the other (same type one) not. Have you renamed the sensor by any change? The MQTT broker keeps old data available (it just thinks this is a new sensor and the old one is still available). When I add devices to Homey I usually restart the hub, to discover and add these devices. Try restarting the hub.

Have you tried this from the tutorial:

When you open and close the sensor, does there any information showing up in the debug window?

Tnx. Got it working and it’s great!

Here is a preview of my dasboard

The only thin i want to solve is how to control the volume of my sonos. I tried some sonos configs but i can’t get to control the volume up or down

Thanks Satoer!

After reading your reply and tried to debug the MQTT I found the sensor information was not arriving at the MQTT broker. I deleted the device from homey, restarted it and deleted the information from MQTT Explorer. After rebooting Homey and broadcasting I found the correct information was arriving again.
The values are now the same as the other sensor and it’s working like a charm.
Thanks for your patients!

Here is my first dashboard.


Still to do: blinds, security + presence, camera’s.

I can’t get the blinds to work with a slider. Has anyone some examples? Help would be great!

@pvdhelm1974

Sorry for delayed answer.

Here are an example to follow how to create one of the sliders and button to control a dimmable light.
Slider


Layout

And the example code to import in node-red

[{"id":"72e56722.d233d8","type":"homie-convention-device","z":"f6a0cce1.578a1","broker":"d2489f03.0a455","name":"","deviceID":"homey-topic","nodeID":"foraldrar-fonster","propertyID":"onoff","topic":"homey-topic/foraldrar-fonster/onoff","infoAttributes":true,"infoTiming":true,"infoError":true,"addLabel":"property","labelTopic":false,"labelPayload":true,"labelName":"","uiPlaceName":"","uiNode":"uiButton","uiControlDropdown":true,"uiControlMinMax":true,"uiColor1":"#ffffff","uiBgColor1":"#ffffff","uiColorON":"#ff0000","uiColorOFF":"#ff0000","uiColorPredicted":"#ffffff","uiUseColorPredicted":false,"uiColorPredictedOff":"#ffffff","uiUseColorPredictedOff":false,"uiFormat":false,"uiTooltip":"","uiIcon1":"fa-lightbulb-o fa-2x","uiIconON":"","uiIconOFF":"","uiSwitchPredicted":false,"uiSwitchColorPredictedON":"#aaaaaa","uiSwitchColorPredictedOFF":"#aaaaaa","uiSwitchIconPredictedON":"fa-toggle-on","uiSwitchIconPredictedOFF":"fa-toggle-off","uiFormatColor":"homieString","settable":false,"x":560,"y":2940,"wires":[["f14f7e88.0e955","367ea77c.81c798"],[]]},{"id":"84106271.7bd47","type":"homie-convention-device","z":"f6a0cce1.578a1","broker":"d2489f03.0a455","name":"","deviceID":"homey-topic","nodeID":"foraldrar-fonster","propertyID":"dim","topic":"homey-topic/foraldrar-fonster/dim","infoAttributes":true,"infoTiming":true,"infoError":true,"addLabel":"property","labelTopic":false,"labelPayload":true,"labelName":"","uiPlaceName":"","uiNode":"uiSlider","uiControlDropdown":true,"uiControlMinMax":true,"uiColor1":"#ffffff","uiBgColor1":"#ffffff","uiColorON":"#ffffff","uiColorOFF":"#ffffff","uiColorPredicted":"#ffffff","uiUseColorPredicted":false,"uiColorPredictedOff":"#ffffff","uiUseColorPredictedOff":false,"uiFormat":false,"uiTooltip":"","uiIcon1":"","uiIconON":"","uiIconOFF":"","uiSwitchPredicted":false,"uiSwitchColorPredictedON":"#aaaaaa","uiSwitchColorPredictedOFF":"#aaaaaa","uiSwitchIconPredictedON":"fa-toggle-on","uiSwitchIconPredictedOFF":"fa-toggle-off","uiFormatColor":"homieString","settable":false,"x":1500,"y":2900,"wires":[["207e8b6b.cae994","8bc034df.eb5108"],[]]},{"id":"207e8b6b.cae994","type":"ui_slider","z":"f6a0cce1.578a1","name":"","label":"","tooltip":"","group":"350d861f.e5e85a","order":3,"width":12,"height":2,"passthru":false,"outs":"all","topic":"","min":0,"max":"100","step":1,"x":1390,"y":2800,"wires":[["8313346b.166a18"]]},{"id":"c85d6a99.4acf38","type":"change","z":"f6a0cce1.578a1","name":"","rules":[{"t":"set","p":"colour","pt":"msg","to":"#333333","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":700,"y":2800,"wires":[["7aedbf38.29e5d"]]},{"id":"7aedbf38.29e5d","type":"ui_button","z":"f6a0cce1.578a1","name":"","group":"350d861f.e5e85a","order":2,"width":3,"height":3,"passthru":false,"label":"","tooltip":"","color":"","bgcolor":"{{colour}}","icon":"","payload":"press","payloadType":"str","topic":"","x":910,"y":2820,"wires":[["a4a485aa.b21058"]]},{"id":"f14f7e88.0e955","type":"switch","z":"f6a0cce1.578a1","name":"False","property":"payload","propertyType":"msg","rules":[{"t":"false"}],"checkall":"true","repair":false,"outputs":1,"x":370,"y":2800,"wires":[["71834290.71333c"]]},{"id":"367ea77c.81c798","type":"switch","z":"f6a0cce1.578a1","name":"True","property":"payload","propertyType":"msg","rules":[{"t":"true"}],"checkall":"true","repair":false,"outputs":1,"x":370,"y":2840,"wires":[["30ed9bcc.637f04"]]},{"id":"ca58f.7a331a718","type":"change","z":"f6a0cce1.578a1","name":"","rules":[{"t":"set","p":"colour","pt":"msg","to":"#205524","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":700,"y":2840,"wires":[["7aedbf38.29e5d"]]},{"id":"71834290.71333c","type":"function","z":"f6a0cce1.578a1","name":"Store State 3","func":"var state3;\n\nstate3=1;\n\nflow.set('state3',state3);\n\nreturn msg;","outputs":1,"noerr":0,"x":530,"y":2800,"wires":[["c85d6a99.4acf38"]]},{"id":"a4a485aa.b21058","type":"function","z":"f6a0cce1.578a1","name":"Change state 3","func":"\nvar state = flow.get('state3') || 0;\n\nif (state == 1) { state = true; }\n\nif (state == 2) { state = false; } \n \nmsg.payload = state\n\nreturn msg;\n\n\n","outputs":1,"noerr":0,"x":1100,"y":2820,"wires":[["72e56722.d233d8"]]},{"id":"30ed9bcc.637f04","type":"function","z":"f6a0cce1.578a1","name":"Store State 3","func":"var state3;\n\nstate3=2;\n\nflow.set('state3',state3);\n\nreturn msg;","outputs":1,"noerr":0,"x":530,"y":2840,"wires":[["ca58f.7a331a718"]]},{"id":"2522f0d0.ecaf6","type":"ui_text","z":"f6a0cce1.578a1","group":"350d861f.e5e85a","order":1,"width":12,"height":1,"name":"","label":"Föräldrar Sovrum","format":"<font size = 2> {{msg.payload}}</font><font size = 1> %</font>","layout":"row-spread","x":2070,"y":2800,"wires":[]},{"id":"8313346b.166a18","type":"trigger","z":"f6a0cce1.578a1","op1":"","op2":"","op1type":"nul","op2type":"payl","duration":"500","extend":true,"units":"ms","reset":"","bytopic":"all","name":"","x":1580,"y":2800,"wires":[["84106271.7bd47","2522f0d0.ecaf6"]]},{"id":"8bc034df.eb5108","type":"range","z":"f6a0cce1.578a1","minin":"0","maxin":"100","minout":"0","maxout":"100","action":"scale","round":true,"property":"payload","name":"Avnrunda till heltal","x":1810,"y":2880,"wires":[["2522f0d0.ecaf6"]]},{"id":"d2489f03.0a455","type":"homie-convention-broker-config","z":"","mqtt-host":"192.168.1.201","mqtt-port":"1883","usetls":false,"name":"Node-RED","homieName":"Node-RED","homieRoot":"homie","storeGlobal":false},{"id":"350d861f.e5e85a","type":"ui_group","z":"","name":"Sovrum Fönster ","tab":"472bf35c.a0808c","order":10,"disp":false,"width":15,"collapse":false},{"id":"472bf35c.a0808c","type":"ui_tab","z":"","name":"Lights","icon":"dashboard","order":4,"disabled":false,"hidden":false}]

1 Like

Wow… looks like you are in control of a nuclear power plant. :joy:

tnx this helps me a lot

Thanks for sharing @Satoer

Unfortunately Tado shows the heating-power as a number instead of boiler-status with true or false.
The heating-power number is from 0 to 100.

Can you help me how to get the function working for this?

var BoilerState=global.get("BoilerState") || false;


if(msg.payload === "true"){
   global.set("BoilerState",true);
}else{
   global.set("BoilerState",false);
}
return msg;

I have added my blinds to my dashboard with a slider. It works great.

But has anyone added a sunscreen with 3 possibilities (up/down/stop) and show it here?
I tried with the inject node and a switch node.

Thanks

If you change:

if(msg.payload === "true"){

to:

if(msg.payload > 0){

it should work. You are basically saying: "If the heating power is higher than 0 “BoilerState = true” (else false). You can change the number if you want it to activate on a higher value.

Complete code:

var BoilerState=global.get("BoilerState") || false;
if(msg.payload > 0){
   global.set("BoilerState",true);
}else{
   global.set("BoilerState",false);
}
return msg;

(The code can be optimized to two lines, but I think this is more understandable)

@Satoer That’s working. Thank you very much :slight_smile:

Wow, this looks very promising; I’m also going to try this one out! HomeyDash was a great start, but like Satoer said; a lot of presses are needed to controll the one or another. I’ve also stumbled across this beautifull theme for Home assistent, but I’ve no knowledge of it;

Is this somehow useable with Node Red @Satoer ?

1 Like