Examples of Colour change button and switch

my original example at the top still works - so maybe you need to share your flow so we can try to work out what is wrong ?

This is my current flow

[{"id":"64ac3933.070e88","type":"change","z":"24d531e9.e46a1e","name":"","rules":[{"t":"set","p":"colour","pt":"msg","to":"green","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":435,"y":102,"wires":[["9daa42d6.ac744"]]},{"id":"2a508b1c.199094","type":"inject","z":"24d531e9.e46a1e","name":"","topic":"","payload":"","payloadType":"str","repeat":"","crontab":"","once":true,"onceDelay":"","x":240,"y":102,"wires":[["2c2ce824.67da08"]]},{"id":"17b67eb3.7e2151","type":"function","z":"24d531e9.e46a1e","name":"state","func":"var state = context.state || false;\nstate = !state;\ncontext.state = state;\nif (state) { return [msg,null]; }\nelse { return [null,msg]; }\n","outputs":2,"noerr":0,"x":240,"y":147,"wires":[["64ac3933.070e88"],["2c2ce824.67da08"]]},{"id":"2c2ce824.67da08","type":"change","z":"24d531e9.e46a1e","name":"","rules":[{"t":"set","p":"colour","pt":"msg","to":"red","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":435,"y":147,"wires":[["9daa42d6.ac744"]]},{"id":"9daa42d6.ac744","type":"mui_button","z":"24d531e9.e46a1e","name":"","group":"96a86685.14e458","order":6,"width":"3","height":"2","passthru":false,"label":"Start","tooltip":"","color":"black","bgcolor":"{{colour}}","icon":"","payload":"press","payloadType":"str","topic":"Start","x":635,"y":205,"wires":[["17b67eb3.7e2151"]]},{"id":"96a86685.14e458","type":"mui_group","z":"","name":"Small","tab":"2d3eadc0.8c2392","order":2,"disp":false,"width":"10","collapse":false},{"id":"2d3eadc0.8c2392","type":"mui_tab","z":"","name":"Small Screen","icon":"dashboard","order":1}]

it looks like you are not using node-red-dashboard but another dashboard. The example provided works with node-red-dashboard.

If you want to use node-red-dashboard, you will first have to remove the other dashboard.

Hi @dceejay
I was searching for a code like yours. Sadly I am a bit lost with the thing I want to accomplish. I am rather new to Node Red. I am using it to make a dashboard for my Homey home automation.
I would like to make buttons instead of switches. I like the way they look, more tile like.
I communicate to homey through MQTT.

Can you tell me what I am doing wrong and how to solve it?
Thanks

It is hard to tell if or what you are doing wrong based on what you shared. Button colors by state of something you can find in this example also. https://flows.nodered.org/flow/cd90709d95fcba9970bd88205871c3c7

Hi @hotNipi,
Thanks for your reply. What I like to accomplish is a button to turn my lights in the living room on and off. The button should reflect the state it is in. For example, lights on button is green with a nice bulb icon that is on. Lights off the button is red with a bulb icon that is off. The node red button should communicate with the light through MQTT (with the topic I showed, this topic works with a switch).

With my switch I use the MQTT in and MQTT out node. In my switch node I have "Pass though msg if payload matches new state:" checked. If I do that now my button goes crazy :grinning:

Do you or anyone els knows how this can be done? I used the above code but need to know how to connect the MQTT to make it work.
The link you provided looks nice but even more complex :sweat_smile:

greetings

There is one old thread also about this, may be it helps

Hi @hotNipi,
Aaaargghhg, getting a bit frustrated here :crazy_face:
Tried the code in the post you gave, tried the above code, searched for other solutions but it is still not working. The best I could get is that my light turns off. So, not on again and no representation if I turn it on/off through homey. I don't understand where to connect my MQTT out and in to. And what message do I put in and where to set a light to on or off. Do you by any chance have an example with the MQTT in and out that tells the light to turn on and off?

Thanks and greetings

Share the flow with your best try. Let's try to fix it. :slight_smile:

@hotNipi
Thanks! This is what I have now. My light goes off when I press the button. On next press it does not go on. If I press the button in my home automation app the button does not show the state of the light.

[{"id":"9e1e78a2.63f928","type":"ui_button","z":"e185900c.bdc37","name":"on/off","group":"c09ef81b.346968","order":0,"width":"3","height":"2","passthru":false,"label":"{{msg.topic}}","tooltip":"","color":"","bgcolor":"{{msg.background}}","icon":"","payload":"","payloadType":"date","topic":"homie/homey-topic/gang-beneden/onoff/set","x":730,"y":480,"wires":[["e8162d5c.1afb8"]]},{"id":"e8162d5c.1afb8","type":"function","z":"e185900c.bdc37","name":"buttonHandler","func":"var state = global.get(\"devicestate\");\nvar label;\nvar color;\n\nif(state.active === true){\n state.active = false;\n label = \"OFF\";\n color = \"red\";\n}\nelse{\n state.active = true;\n label = \"ON\";\n color = \"green\";\n}\nglobal.set(\"devicestate\", state);\n\n\nvar buttonstate = {enabled:false, background:color, topic:label};\n\nmsg.payload = \"homie/homey-topic/gang-beneden/onoff/set\"\n\nreturn [buttonstate,msg];","outputs":"2","noerr":0,"x":920,"y":420,"wires":[["9e1e78a2.63f928"],["4052186d.749b38","fa6922a0.5160e"]],"inputLabels":["input"],"outputLabels":["to button","to proccessing"]},{"id":"4052186d.749b38","type":"delay","z":"e185900c.bdc37","name":"waste time to fake proccesing","pauseType":"delay","timeout":"1","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"x":950,"y":620,"wires":[["80dc1d9e.4120a"]]},{"id":"c62bdcdd.194fd","type":"function","z":"e185900c.bdc37","name":"Init","func":"var devicestate = {active:true};\nglobal.set(\"devicestate\",devicestate);\nreturn msg;","outputs":1,"noerr":0,"x":330,"y":480,"wires":[["80dc1d9e.4120a"]]},{"id":"8817181d.552828","type":"inject","z":"e185900c.bdc37","name":"Once","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":true,"onceDelay":0.1,"x":170,"y":480,"wires":[["c62bdcdd.194fd"]]},{"id":"80dc1d9e.4120a","type":"function","z":"e185900c.bdc37","name":"determineButtonState","func":"var state = global.get(\"devicestate\");\nvar label;\nvar color;\n\nif(state.active === true){\n label = \"ON\";\n color = \"green\";\n}\nelse{\n label = \"OFF\";\n color = \"red\";\n}\nmsg = {enabled:true, topic:label, background:color};\nreturn msg;","outputs":1,"noerr":0,"x":550,"y":480,"wires":[["9e1e78a2.63f928"]]},{"id":"ef643fad.f4e64","type":"mqtt in","z":"e185900c.bdc37","name":"MQTT receiver","topic":"homie/homey-topic/gang-beneden/onoff","qos":"2","datatype":"auto","broker":"49dffeeb.596af","x":160,"y":580,"wires":[["4528ad3e.cfd0f4"]]},{"id":"4528ad3e.cfd0f4","type":"function","z":"e185900c.bdc37","name":"Convert string to Boolean","func":"\nif(msg.payload === \"true\"){ msg.payload = true; }else{ msg.payload = false; } return msg;","outputs":1,"noerr":0,"x":390,"y":580,"wires":[["80dc1d9e.4120a"]]},{"id":"fa6922a0.5160e","type":"mqtt out","z":"e185900c.bdc37","name":"MQTT Light transmit","topic":"","qos":"","retain":"","broker":"49dffeeb.596af","x":1220,"y":400,"wires":[]},{"id":"c09ef81b.346968","type":"ui_group","z":"","name":"Test tab","tab":"d8ed3d29.d7b81","disp":true,"width":"6","collapse":false},{"id":"49dffeeb.596af","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}]

I think you need to read about the MQTT commands from you device documentation.
And may be also from node-red cookbook https://cookbook.nodered.org/#mqtt
I can't really help much on MQTT part.

If your device reports back the current state after switching then this flow should work.

[{"id":"36f1353e.97198a","type":"ui_button","z":"7249c977.5e05b8","name":"on/off","group":"5dd03958.98c8e8","order":0,"width":"3","height":"2","passthru":false,"label":"{{msg.topic}}","tooltip":"","color":"","bgcolor":"{{msg.background}}","icon":"","payload":"","payloadType":"date","topic":"homie/homey-topic/gang-beneden/onoff/set","x":870,"y":780,"wires":[["f519fb92.8accb8"]]},{"id":"f519fb92.8accb8","type":"function","z":"7249c977.5e05b8","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 = \"homie/homey-topic/gang-beneden/onoff/set\"\n\nreturn [buttonstate,msg];","outputs":"2","noerr":0,"x":1010,"y":840,"wires":[["36f1353e.97198a"],["b55ade5c.24e6f","da526652.99b468"]],"inputLabels":["input"],"outputLabels":["to button","to proccessing"]},{"id":"a7976faa.1b8f3","type":"function","z":"7249c977.5e05b8","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":670,"y":780,"wires":[["36f1353e.97198a"]]},{"id":"40c5bf75.70ecf","type":"mqtt in","z":"7249c977.5e05b8","name":"MQTT receiver","topic":"homie/homey-topic/gang-beneden/onoff","qos":"2","datatype":"auto","broker":"a2c147bc.6b6718","x":280,"y":880,"wires":[["d68f1916.88ed88"]]},{"id":"d68f1916.88ed88","type":"function","z":"7249c977.5e05b8","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":470,"y":880,"wires":[["a7976faa.1b8f3","9a052d9f.f611c"]]},{"id":"b55ade5c.24e6f","type":"mqtt out","z":"7249c977.5e05b8","name":"MQTT Light transmit","topic":"","qos":"","retain":"","broker":"a2c147bc.6b6718","x":1210,"y":880,"wires":[]},{"id":"9a052d9f.f611c","type":"debug","z":"7249c977.5e05b8","name":"FROM MQTT","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","x":670,"y":900,"wires":[]},{"id":"da526652.99b468","type":"debug","z":"7249c977.5e05b8","name":"TO MQTT","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","x":1200,"y":840,"wires":[]},{"id":"5dd03958.98c8e8","type":"ui_group","z":"","name":"Test tab","tab":"ad723ec.816e1c","disp":true,"width":"6","collapse":false},{"id":"a2c147bc.6b6718","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":"ad723ec.816e1c","type":"ui_tab","z":"","name":"Testing","icon":"dashboard","order":3,"disabled":false,"hidden":false}]

Almost works! When I us my home automation app the state of the button changes, great! When I press the button in the NR dashboard I can only turn it off. When I try to turn it on again it changes to the faded green and does not turn to green. The light stays off.

This is how my switch works, maybe this will make things clearer.

[{"id":"e0bdc90f.9b5bc8","type":"ui_switch","z":"de809454.b77458","name":"Woonkamer spot","label":"Woonkamer spot","tooltip":"","group":"2c6d1750.5266c8","order":1,"width":5,"height":1,"passthru":true,"decouple":"false","topic":"homie/homey-topic/woonkamer-spot/onoff/set","style":"","onvalue":"true","onvalueType":"bool","onicon":"fa-2x fa-lightbulb-o","oncolor":"#FFE400","offvalue":"false","offvalueType":"bool","officon":"fa-2x fa-lightbulb-o","offcolor":"#686441","x":670,"y":200,"wires":[["67b8512d.07884"]]},{"id":"67b8512d.07884","type":"mqtt out","z":"de809454.b77458","name":"MQTT Light transmit","topic":"homie/homey-topic/woonkamer-spot/onoff/set","qos":"","retain":"","broker":"49dffeeb.596af","x":900,"y":200,"wires":[]},{"id":"ae04b460.4d45d8","type":"mqtt in","z":"de809454.b77458","name":"MQTT receiver","topic":"homie/homey-topic/woonkamer-spot/onoff","qos":"2","datatype":"auto","broker":"49dffeeb.596af","x":200,"y":200,"wires":[["d0f75779.4d5af8"]]},{"id":"d0f75779.4d5af8","type":"function","z":"de809454.b77458","name":"Convert string to Boolean","func":"\nif(msg.payload === \"true\"){ msg.payload = true; }else{ msg.payload = false; } return msg;","outputs":1,"noerr":0,"x":430,"y":200,"wires":[["e0bdc90f.9b5bc8"]]},{"id":"2c6d1750.5266c8","type":"ui_group","z":"","name":"Lampen","tab":"11324097.cc662f","order":1,"disp":false,"width":"5","collapse":false},{"id":"49dffeeb.596af","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":"11324097.cc662f","type":"ui_tab","z":"","name":"Dash","icon":"dashboard","order":1,"disabled":false,"hidden":false}]

I think you'll need to work on outgoing MQTT message. This must be wrong. The buttonHandler is the function where you create that message.

Yes, I was digging into it :grinning:
Could it be this line: var buttonstate = {enabled:false, background:color, topic:label};
When I look in my debug window I only see the false state and not the true state.

This does not go to MQTT. this goes back to button. And yes it turns button to disabled state for purpose. As if you switch the device (light), then there must be actual switching to happen and if actual state from device comes back then by this actual state it will be made button usable again.

Still you must figure out, how to send out correct commands via MQTT to your light

Hi @hotNipi,
Thanks for al your help. I asked for help on the Homey forum and someone gave me the solution. I want to share it here also, maybe it is of use to someone else to.

[{"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}]

This is ofcourse for my situation, anyone who wants to use it has to adjust it to their needs.
Remember to select your own MQTT server and topic.

greetings

4 Likes

Nice, I see this too.

Hello,

First off thank you for sharing. I was able to import the code for the button that changes color with state. I decided to just use a switch instead though and ended up deleting these nodes. Upon doing that I can no longer deploy my flows. Any idea why that would be happening?

Ok so I got things working again. I had to delete the button I imported in, export my flows so I had a backup, and then delete everything. I was then able to then import in all my flows and deploy them. I think the issues I was having had to do with the dashboard groups I had in my workspace. When I brought in your button it clashed with something I already had.

Thanks for sharing.