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

I believe there are numerous weather service nodes that you can install. But I just use an Aqara Zigbee temperature / humidity sensor outside.

Anyone tested this Node-RED library since MQTT Hub is supporting Homie convention https://flows.nodered.org/node/node-red-contrib-homie-convention

I am trying to make a button instead of a switch. I think it looks nicer. I have made something with the help from someone on the Node Red forum but I can’t seem to make it work all the way…
The button switches now from on to off when I control my light through homey. When I want to control it through the NR dashboard it only switches on.
My intention was to make it work and share it here but it looks like I need some help :relaxed:
Can someone here have a look?

[{"id":"12bc164d.44fefa","type":"ui_button","z":"e185900c.bdc37","name":"on/off test1","group":"c09ef81b.346968","order":5,"width":6,"height":1,"passthru":false,"label":"{{msg.topic}}","tooltip":"","color":"","bgcolor":"{{msg.background}}","icon":"","payload":"lightstate","payloadType":"global","topic":"homie/homey-topic/gang-beneden/onoff/set","x":770,"y":1200,"wires":[["512a9b9.572d264"]]},{"id":"512a9b9.572d264","type":"function","z":"e185900c.bdc37","name":"buttonHandler","func":"//this function runs when you are pressing the button.\n\n// read current state of light\nvar state = global.get(\"lightstate\") || false;\n\nvar label;\nvar color;\n\nif(state === true){\n  // current state is true (light is on) lets turn it off \n    label = \"OFF\";\n    color = \"red\";\n}\nelse {\n    // current state is false (light is off) lets turn it on \n    label = \"ON\";\n    color = \"green\";\n}\n\n// buttonstate is message, which goes straight back to button. It disables button. \n// button stays disabled until MQTT message comes in and tells to node-red \n// what is actual state of that light\nvar buttonstate = {enabled:false, background:color, topic:label};\n\n\n// I dont know anything about your mqtt commands\n// usually the commands are created by using msg topic for device select and and msg payload for command\n// Find info about it from your device documentation \n// if the command onoff/set does the toggle action, then it may work\n// but if not, then you must create the command with correct action (on or off)\n\nmsg.payload = \"true\"\n\nreturn [buttonstate,msg];","outputs":"2","noerr":0,"x":890,"y":1260,"wires":[["12bc164d.44fefa"],["326f19bd.0bee86","df991750.4f1028"]],"inputLabels":["input"],"outputLabels":["to button","to proccessing"]},{"id":"efdd2bf0.f76278","type":"function","z":"e185900c.bdc37","name":"determineButtonState","func":"// this function runs every time the MQTT message is arrived (previous node changed the state of light).\n// read the state (if not set somehow, let assume it is false)\nvar state = global.get(\"lightstate\") || false;\nvar label;\nvar color;\n\nif(state === true){\n// state is true (lets make button green)\n label = \"ON\";\n color = \"green\";\n}\nelse{\n    // state is false (lets make button red)\n label = \"OFF\";\n color = \"red\";\n}\n\n// send out message to button, this outgoing message only changes button visuals\nmsg = {enabled:true, topic:label, background:color};\nreturn msg;","outputs":1,"noerr":0,"x":540,"y":1180,"wires":[["12bc164d.44fefa"]]},{"id":"57fd577b.0d4378","type":"mqtt in","z":"e185900c.bdc37","name":"MQTT receiver","topic":"homie/homey-topic/gang-beneden/onoff","qos":"2","datatype":"auto","broker":"ff171d3b.1cac1","x":80,"y":1300,"wires":[["bb8d1607.9edff8"]]},{"id":"bb8d1607.9edff8","type":"function","z":"e185900c.bdc37","name":"store the state of light","func":"// read current state of light \nvar lightstate = global.get(\"lightstate\") || undefined\nif(msg.payload === \"true\"){\n   lightstate = true\n}\nelse{\n   lightstate = false \n}\n// write state to global context, so we can read it where ever the state is needed\nglobal.set(\"lightstate\",lightstate)\n\n\n// return last known state (we dont use it but the flow must continue)\nmsg.payload = lightstate\nmsg.topic = \"state-of-light-changed\"\nreturn msg;","outputs":1,"noerr":0,"x":350,"y":1300,"wires":[["efdd2bf0.f76278","45e16198.c0745"]]},{"id":"326f19bd.0bee86","type":"mqtt out","z":"e185900c.bdc37","name":"MQTT Light transmit","topic":"","qos":"","retain":"","broker":"ff171d3b.1cac1","x":1140,"y":1340,"wires":[]},{"id":"45e16198.c0745","type":"debug","z":"e185900c.bdc37","name":"FROM MQTT","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","x":750,"y":1360,"wires":[]},{"id":"df991750.4f1028","type":"debug","z":"e185900c.bdc37","name":"TO MQTT","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","x":1080,"y":1260,"wires":[]},{"id":"c09ef81b.346968","type":"ui_group","z":"","name":"Test tab","tab":"d8ed3d29.d7b81","disp":true,"width":"6","collapse":false},{"id":"ff171d3b.1cac1","type":"mqtt-broker","z":"","name":"Homey MQTT","broker":"192.168.1.22","port":"1883","clientid":"","usetls":false,"compatmode":true,"keepalive":"60","cleansession":true,"birthTopic":"","birthQos":"0","birthPayload":"","closeTopic":"","closeQos":"0","closePayload":"","willTopic":"","willQos":"0","willPayload":""},{"id":"d8ed3d29.d7b81","type":"ui_tab","z":"","name":"Testing","icon":"dashboard","order":3,"disabled":false,"hidden":false}]

Hello @Satoer

This idea with Nodred is GREAT !!!

I wanted to ask you a question,

What screen do you use for the board?

Thank you very much and great work !!!

I think you made it way too complicated. I’ve adjusted your example:

First you receive the MQTT light message.

Than you store the state of light in a global, or in my case I changed to a flow variable (flow variables only exist on the flow page, if you don’t need it global I suggest you don’t use it global)

var lightstate = flow.get("lightstate") || undefined;
var label;
var color;
    if(msg.payload === "true"){
      // state is true (lets make button green)
       label = "ON";
       color = "green";
       lightstate = true;
    }
    else{
        // state is false (lets make button red)
       label = "OFF";
       color = "red";
       lightstate = false;
    }

    flow.set("lightstate",lightstate);
    msg = {enabled:true, topic:label, background:color};
    return msg;

This the only thing you need to set the color for the switch. If you switch the button, the outgoing MQTT message will return from homey setting the color to the right color (on / off).

Feed this into the switch.

Output the switch to this piece of script:

//this function runs when you are pressing the button.
// read current state of light
var lightstate = flow.get("lightstate") || false;

//Payload is NOT (!) the lightstate. inverts the boolean (true / false)
msg.payload =  !lightstate;

return msg;

And output that to the MQTT handler.

Full Json (Remember to select your own Homey MQTT server and topic!)

[{"id":"3d6f3a0c.eedda6","type":"ui_button","z":"48744450.148de4","name":"on/off test1","group":"bec4a4a3.5c9928","order":5,"width":6,"height":1,"passthru":false,"label":"{{msg.topic}}","tooltip":"","color":"","bgcolor":"{{msg.background}}","icon":"","payload":"lightstate","payloadType":"global","topic":"homie/homey-topic/binnenring/onoff/set","x":630,"y":1360,"wires":[["37ff796.3faf406"]]},{"id":"37ff796.3faf406","type":"function","z":"48744450.148de4","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,"x":840,"y":1360,"wires":[["1b5eb5fe.366b72"]],"inputLabels":["input"],"outputLabels":["to button"]},{"id":"83ca39da.0824f","type":"mqtt in","z":"48744450.148de4","name":"MQTT receiver","topic":"homie/homey-topic/binnenring/onoff","qos":"2","datatype":"auto","broker":"d776df12.63afa","x":160,"y":1360,"wires":[["8236aac3.d4838"]]},{"id":"8236aac3.d4838","type":"function","z":"48744450.148de4","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 color = \"green\";\n lightstate = true;\n}\nelse{\n // state is false (lets make button red)\n label = \"OFF\";\n color = \"red\";\n lightstate = false;\n}\n\nflow.set(\"lightstate\",lightstate);\nmsg = {enabled:true, topic:label, background:color};\nreturn msg;","outputs":1,"noerr":0,"x":400,"y":1360,"wires":[["3d6f3a0c.eedda6"]]},{"id":"1b5eb5fe.366b72","type":"mqtt out","z":"48744450.148de4","name":"MQTT Light transmit","topic":"","qos":"","retain":"","broker":"d776df12.63afa","x":1080,"y":1360,"wires":[]},{"id":"bec4a4a3.5c9928","type":"ui_group","z":"","name":"test","tab":"c63b7d19.a7f4f","disp":true,"width":"6","collapse":false},{"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":"c63b7d19.a7f4f","type":"ui_tab","z":"","name":"Homey Dashboard 2","icon":"dashboard","order":2,"disabled":false,"hidden":false}]

1 Like

I’ve modded an old iPad 2 (not the Air 2) and put it inside the wall (It’s actually a really large hatch, the back of the wall is accessible).


Used an esp 8266 with Homeyduino to wake up the screen with homey (based on a motion sensor) when someone is in the room. A simpler solution is to do this wireless with Bluetooth (But the iPad 2 ios 9 does not support BLE, so I couldn’t use it for that).

Made a tutorial for Bluetooth solution:
https://community.homey.app/t/homey-esp32-bluetooth-keyboard-firmware-can-lock-unlock-ipad-remotely-dev-review-needed

5 Likes

What a great job @Satoer !!!

Just a question from my ignorance.

The graphic control board, do you launch it through the ipad web browser connected to the same network as homey?

Thank you very much in advance

I use this one, Samsung QB13R (wifi), integrated in wall, with no access from behind! It has remote and a touch-panel version (T)

1 Like

Thanks @Tangodelta!!!

Samsung’s screen is very cool. I guess how to enter you choose web browser.

Is that right?

Thanks!!!

Yes, I use the web browser, it enters full screen automatic, with preconfigured ip-adress! Have 7, one for every room in the house, with a dedicated node red page for each, and in addition one in the hallway for general information like weather and forecast, energy use and basement info! Can recommend these screens!

Hi @Satoer, Ofcourse I made it to complicated! :rofl: Thanks for this and also for taking the time to explain it. I tried so many different things but I could not get it to work.

greetings

My dash so far… And I’m proud of it😊

4 Likes

A question.

How could you put the size of the largest date without changing the rest of the texts?

Thanks!!!

i’m not sure what you mean. The date and the time are two separate fields en therefore u can give them seperate sizes of text.

1 Like

Yes. I have already seen how you created two fields, one for the date and one for the time.

But, where can you change the font size each of them ?.

I know it’s a rookie question …

i.m not home at the moment. tommorow i make a printscreen en show it.

Some info from the web

2 Likes

Thank you very much in advance!!!

Yes. I have seen that post. But, in the case of the date and time it does not work. Or at least I have been unable to make it work.

Grateful for the help.

1 Like

I’ve also been struggling with the font sizes of a text node. Somehow I only could set about 3 sizes. Eventually I just use a template node and put a piece of html inside it. Just as easy:
<p style="font-size:70px; text-align: center; font-weight: bold;">{{msg.payload}}</p>