Most cases the best way to figure out reasons to this kind of issues is to use browser dev tools.
For your httpStatic
setting to work, you need to point at the absolute pathname to the directory (so “/home/pi”) – when you don’t start it with a slash, you are telling it to use a directory called “home” under the current node-red directory, which probably does not exist.
Also, one other “gotcha” is that you will need to have either an httpAdmin
or httpRoot
prefix defined in your settings.js, since enabling httpStatic
means that the URL “/” now gets intercepted by the static file service. Once you are able to type the URL http://localhost:1880/Pictures/clock.jpg
into your browser and see the image, your background template should work…
I would also strong recommend not setting httpStatic
to just /home/pi
- as that will expose your entire home directory and all its contents.
I suggest you create a directory just for this purpose and use that - for example /home/pi/node-red-static
Thanks again both.
I am setting httpStatic to /home/pi for now because I am just playing with pictures (etc) - well actually only pictures - and don’t want to have multiple copies of them here and there.
Also the machine is not on the net (96% of the time) and so isn’t that much likely to be hacked.
I shall work in changing that at some time when it is more … needed?
But I do get the flaw in what I am doing.
Something like this? Can be done also with a function directly but with nodes fomr palette is also easy.
[{"id":"82689cc3.2322b","type":"ui_button","z":"3a79879.af7b678","name":"","group":"b55f6d5b.83d05","order":0,"width":0,"height":0,"passthru":false,"label":"unlock","color":"","bgcolor":"","icon":"","payload":"","payloadType":"str","topic":"unlock","x":160,"y":2680,"wires":[["fa87c63e.5dfbd8"]]},{"id":"34f094b2.0d5fcc","type":"ui_button","z":"3a79879.af7b678","name":"","group":"b55f6d5b.83d05","order":0,"width":0,"height":0,"passthru":false,"label":"button","color":"","bgcolor":"","icon":"","payload":"set","payloadType":"str","topic":"","x":170,"y":2740,"wires":[["f74da7eb.39c238"]]},{"id":"fa87c63e.5dfbd8","type":"trigger","z":"3a79879.af7b678","op1":"true","op2":"false","op1type":"bool","op2type":"bool","duration":"2","extend":false,"units":"s","reset":"","bytopic":"all","name":"","x":320,"y":2680,"wires":[["d3583814.de9a38"]]},{"id":"8a9150cb.f14b7","type":"change","z":"3a79879.af7b678","name":"","rules":[{"t":"set","p":"unlock","pt":"global","to":"unlocked","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":630,"y":2660,"wires":[[]]},{"id":"f74da7eb.39c238","type":"switch","z":"3a79879.af7b678","name":"","property":"unlock","propertyType":"global","rules":[{"t":"eq","v":"unlocked","vt":"str"}],"checkall":"true","repair":false,"outputs":1,"x":330,"y":2740,"wires":[["2fa30573.c5e9aa","9673bb0.b681b48","496c1215.3052fc"]]},{"id":"2fa30573.c5e9aa","type":"debug","z":"3a79879.af7b678","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":510,"y":2740,"wires":[]},{"id":"d3583814.de9a38","type":"switch","z":"3a79879.af7b678","name":"","property":"payload","propertyType":"msg","rules":[{"t":"true"},{"t":"false"}],"checkall":"true","repair":false,"outputs":2,"x":450,"y":2680,"wires":[["8a9150cb.f14b7"],["eff06a4f.29a578"]]},{"id":"eff06a4f.29a578","type":"change","z":"3a79879.af7b678","name":"","rules":[{"t":"set","p":"unlock","pt":"global","to":"locked","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":630,"y":2700,"wires":[[]]},{"id":"9673bb0.b681b48","type":"ui_switch","z":"3a79879.af7b678","name":"","label":"switch","group":"b55f6d5b.83d05","order":0,"width":0,"height":0,"passthru":false,"decouple":"true","topic":"button","style":"","onvalue":"true","onvalueType":"bool","onicon":"","oncolor":"","offvalue":"false","offvalueType":"bool","officon":"","offcolor":"","x":170,"y":2820,"wires":[["f74da7eb.39c238"]]},{"id":"496c1215.3052fc","type":"ui_text","z":"3a79879.af7b678","group":"b55f6d5b.83d05","order":0,"width":0,"height":0,"name":"","label":"debug","format":"{{msg.payload}}","layout":"row-spread","x":520,"y":2800,"wires":[]},{"id":"b55f6d5b.83d05","type":"ui_group","z":"","name":"test","tab":"32649d72.d1e1b2","disp":true,"width":"6","collapse":false},{"id":"32649d72.d1e1b2","type":"ui_tab","z":"","name":"test","icon":"dashboard"}]
Yes. Like that.
I did post my version of that though?
One thing I am now noticing with buttons, that when you press them, they turn white and STAY white.
With yours, the text area on the dashboard doesn’t wipe. (just mentioning) And I am not seeing the switch toggle indicating the “enabled” state. I suspect with a quick look it is the names used. But I understand that it is easy to get confused with all the names.
But thanks for the effort. Though as I mentioned, I am sure I put something like that up already.
Anyway, do you know what is going on with the buttons staying white when pressed?
This is what I have - maybe slightly better done now:
[{"id":"e300107f.8667e8","type":"ui_button","z":"fb549e2f.4d026","name":"","group":"5a16edf3.798c04","order":3,"width":0,"height":0,"passthru":true,"label":"Reset All!","color":"","bgcolor":"","icon":"","payload":"RESET","payloadType":"str","topic":"","x":680,"y":250,"wires":[["1f5cca83.8f19c5"]]},{"id":"f18e898d.b5f0a8","type":"inject","z":"fb549e2f.4d026","name":"Wipe","topic":"","payload":"true","payloadType":"bool","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":670,"y":290,"wires":[["e300107f.8667e8"]]},{"id":"1f5cca83.8f19c5","type":"function","z":"fb549e2f.4d026","name":"EN","func":"if (msg.topic === \"ENABLE\")\n{\n //\n if (msg.payload === 'true')\n {\n node.status({fill:\"yellow\",shape:\"dot\",text:\"ENABLED\"});\n context.set('enable',1);\n }\n //if (msg.payload === 'false')\n else\n {\n context.set('enable',0);\n// context.enable = 0;\n// context.set('enable',enable_topic);\n node.status({fill:\"red\",shape:\"dot\",text:\"DISABLED\"});\n }\n}\nif (msg.topic != \"ENABLE\")\n{\n if (context.get('enable') == 1)\n {\n //\n node.status({fill:\"green\",shape:\"dot\",text:\"On-line\"});\n return msg;\n }\n}\n","outputs":1,"noerr":0,"x":830,"y":250,"wires":[["2205799b.d99d3e","5bb56ab7.6882ac","e1f2b034.e7e33","297a07ec.e91a38"]]},{"id":"99fc784c.cb71b8","type":"function","z":"fb549e2f.4d026","name":"Set Topic","func":"msg.topic=\"ENABLE\";\nreturn msg;","outputs":1,"noerr":0,"x":820,"y":150,"wires":[["9f1b1a02.1ab5"]]},{"id":"14983a82.e709bd","type":"ui_button","z":"fb549e2f.4d026","name":"","group":"5a16edf3.798c04","order":1,"width":0,"height":0,"passthru":true,"label":"Enable","color":"","bgcolor":"","icon":"","payload":"true","payloadType":"str","topic":"","x":680,"y":150,"wires":[["99fc784c.cb71b8"]]},{"id":"9f1b1a02.1ab5","type":"timeouttrigger","z":"fb549e2f.4d026","ontimeouttype":"bool","ontimeoutval":"false","duration":"2","units":"s","name":"","x":690,"y":190,"wires":[["1f5cca83.8f19c5","f81b8be4.ad3f7"]]},{"id":"f81b8be4.ad3f7","type":"ui_switch","z":"fb549e2f.4d026","name":"","label":"Enabled","group":"5a16edf3.798c04","order":2,"width":0,"height":0,"passthru":true,"decouple":"false","topic":"","style":"","onvalue":"true","onvalueType":"str","onicon":"","oncolor":"","offvalue":"false","offvalueType":"bool","officon":"","offcolor":"","x":830,"y":190,"wires":[["4d56bc1b.f1220c"]]},{"id":"4d56bc1b.f1220c","type":"debug","z":"fb549e2f.4d026","name":"Junk","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","x":960,"y":190,"wires":[]},{"id":"88ae8fe4.52d99","type":"inject","z":"fb549e2f.4d026","name":"Enable","topic":"","payload":"true","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":670,"y":110,"wires":[["14983a82.e709bd"]]},{"id":"297a07ec.e91a38","type":"debug","z":"fb549e2f.4d026","name":"Wipe message","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","x":1120,"y":250,"wires":[]},{"id":"5a16edf3.798c04","type":"ui_group","z":"","name":"Wipe all Graphs","tab":"cababfc5.7b2f6","order":4,"disp":true,"width":"4","collapse":false},{"id":"cababfc5.7b2f6","type":"ui_tab","z":"","name":"Control Display","icon":"dashboard","order":6}]
I have injection points too for testing.
Ups you have one node that I don’t have and will have to install it, right now I can’t I will try on another moment because my testing raspi is disconnected now and don’t wnat to start installing now stuff on the one is on use controlling home.
Just a couple of things… on the “enable” button why you set a function afterwards to change the topic while you can set directy the topic on the button config itself?
Other one, on the “enabled” button one payload is a boolean and the other one a string, this kind of things can give you troubles depending what you do later on.
Regards
Being very new to node red, I stumbled across the sample flow that you shared and liked it a lot. Of course I am looking for the type of flow you added as an image, but at my current stage I am not competent to transfer one to the other. What I HAVE managed is to extract status from my MQTT topic so I know whether my physical button is True or False. What I'd love to be able to do is to use your flow and send a on/off payload depending on current state. I also want the button to change state if the physical button and is pushed, thereby changing the state.
So question is - how do i go from your post #17 to the one drawn out in post #20?
Best regards,
Ranur
There is another thread where you can find more examples about this.
Explore and try them out and if no luck then let's deal with more specific questions based on where you exactly stuck
Cool! Actually I was looking at and have copied that specific thread. AND - Lord and behold - I have manged to make it work. (Proud Newbie!) The challenge is that I will be using 12 buttons, so I thought I'd copy each sequence over and over and - yeah you get it.
Unfortunately that doesn't seem to work. When starting from button 1 ->4 it works, but I can not seem to be able to turn off 1 again before i've turned off the higher number ones.
I think it is the global variable lightstate that creates the problem. Unfortunately, I'm too newbie to understand what I should do. Changing the name lightstate to lighstate1, ls2, ls3... didn't work so I need help.
The input from the mqtt from my Shelly RGBW switch is
ison: t/f
mode: "white"
brightness: nn
power: nn
overpower: t/f
Thankful for any assistance or pointers in this project!
[{"id":"932c9a5e.6c66f8","type":"tab","label":"Flow 6","disabled":false,"info":""},{"id":"cd8ee5a7.6a6d48","type":"mqtt out","z":"932c9a5e.6c66f8","name":"","topic":"","qos":"","retain":"","broker":"c86985b9.a9ab78","x":846,"y":70,"wires":[]},{"id":"e298b010.3eff","type":"template","z":"932c9a5e.6c66f8","name":"","field":"payload","fieldType":"msg","format":"handlebars","syntax":"mustache","template":"{\"brightness\" :{{payload}}}","output":"str","x":616,"y":70,"wires":[["cd8ee5a7.6a6d48","5db7e0e5.e58de"]]},{"id":"5db7e0e5.e58de","type":"debug","z":"932c9a5e.6c66f8","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":846,"y":110,"wires":[]},{"id":"27598731.c5b6f8","type":"change","z":"932c9a5e.6c66f8","name":"Brightness","rules":[{"t":"move","p":"payload.brightness","pt":"msg","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":266,"y":70,"wires":[["5bade9f2.8815a8"]]},{"id":"64bdea3d.42a334","type":"json","z":"932c9a5e.6c66f8","name":"","property":"payload","action":"","pretty":false,"x":106,"y":110,"wires":[["27598731.c5b6f8","e5a8e727.96e478"]]},{"id":"12ab70a3.8bcd0f","type":"mqtt in","z":"932c9a5e.6c66f8","name":"Status 1_1","topic":"shellies/shellyrgbw2-B0D733/white/0/status","qos":"2","broker":"c86985b9.a9ab78","x":96,"y":50,"wires":[["64bdea3d.42a334"]]},{"id":"e5a8e727.96e478","type":"change","z":"932c9a5e.6c66f8","name":"On/off Status","rules":[{"t":"move","p":"payload.ison","pt":"msg","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":266,"y":110,"wires":[["bdc56e85.850af"]]},{"id":"4da04575.f9b24c","type":"mqtt out","z":"932c9a5e.6c66f8","name":"S1_1 On/off","topic":"shellies/shellyrgbw2-B0D733/white/0/command","qos":"","retain":"","broker":"761dfb74.752d64","x":826,"y":150,"wires":[]},{"id":"8796405f.b5d5f","type":"change","z":"932c9a5e.6c66f8","name":"","rules":[{"t":"change","p":"payload","pt":"msg","from":"true","fromt":"bool","to":"off","tot":"str"},{"t":"change","p":"payload","pt":"msg","from":"false","fromt":"bool","to":"on","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":636,"y":150,"wires":[["4da04575.f9b24c"]]},{"id":"7b70b363.12362c","type":"ui_button","z":"932c9a5e.6c66f8","name":"on/off","group":"c6364af0.be9fe8","order":1,"width":3,"height":1,"passthru":false,"label":"{{msg.topic}}","tooltip":"","color":"","bgcolor":"{{msg.background}}","icon":"","payload":"lightstate","payloadType":"global","topic":"shellies/shellyrgbw2-B0D733/white/0/command","x":326,"y":150,"wires":[["d3896a5f.0c44a8","8796405f.b5d5f","e0188c68.fdae4"]]},{"id":"d3896a5f.0c44a8","type":"function","z":"932c9a5e.6c66f8","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 = \"1\";\n color = \"red\";\n}\nelse{\n // current state is false (light is off) lets turn it on \n label = \"1\";\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\n//msg.payload = \"here I need to way to set an on/off payload depending on state...\"\n\nreturn [buttonstate,msg];","outputs":"2","noerr":0,"x":476,"y":150,"wires":[["7b70b363.12362c"],[]],"inputLabels":["input"],"outputLabels":["to button","to proccessing"]},{"id":"795c95f.d0f286c","type":"function","z":"932c9a5e.6c66f8","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 = \"1\";\n color = \"darkorange\";\n}\nelse{\n // state is false (lets make button red)\n label = \"1\";\n color = \"mediumgray\";\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":156,"y":150,"wires":[["7b70b363.12362c"]]},{"id":"a4c990e2.05ea4","type":"function","z":"932c9a5e.6c66f8","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":656,"y":110,"wires":[["795c95f.d0f286c"]]},{"id":"5bade9f2.8815a8","type":"ui_slider","z":"932c9a5e.6c66f8","name":"slider S1_1","label":"slider S1_1","group":"c6364af0.be9fe8","order":2,"width":9,"height":1,"passthru":true,"topic":"shellies/shellyrgbw2-B0D733/white/0/set","min":0,"max":"100","step":"5","x":446,"y":70,"wires":[["e298b010.3eff"]]},{"id":"bdc56e85.850af","type":"change","z":"932c9a5e.6c66f8","name":"","rules":[{"t":"change","p":"payload","pt":"msg","from":"true","fromt":"bool","to":"true","tot":"str"},{"t":"change","p":"payload","pt":"msg","from":"false","fromt":"bool","to":"false","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":456,"y":110,"wires":[["a4c990e2.05ea4"]]},{"id":"30840bae.a97b74","type":"mqtt out","z":"932c9a5e.6c66f8","name":"S1_2 On/off","topic":"shellies/shellyrgbw2-B0D733/white/1/command","qos":"","retain":"","broker":"761dfb74.752d64","x":826,"y":310,"wires":[]},{"id":"893c9409.723278","type":"change","z":"932c9a5e.6c66f8","name":"","rules":[{"t":"change","p":"payload","pt":"msg","from":"true","fromt":"bool","to":"off","tot":"str"},{"t":"change","p":"payload","pt":"msg","from":"false","fromt":"bool","to":"on","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":656,"y":310,"wires":[["30840bae.a97b74"]]},{"id":"1263cf58.a3b441","type":"ui_button","z":"932c9a5e.6c66f8","name":"on/off","group":"c6364af0.be9fe8","order":3,"width":3,"height":1,"passthru":false,"label":"{{msg.topic}}","color":"","bgcolor":"{{msg.background}}","icon":"","payload":"lightstate","payloadType":"global","topic":"shellies/shellyrgbw2-B0D733/white/1/command","x":326,"y":310,"wires":[["5fe1a98a.1d9d48","893c9409.723278","a16579e1.d31c78"]]},{"id":"5fe1a98a.1d9d48","type":"function","z":"932c9a5e.6c66f8","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 = \"2\";\n color = \"red\";\n}\nelse{\n // current state is false (light is off) lets turn it on \n label = \"2\";\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\n//msg.payload = \"here I need to way to set an on/off payload depending on state...\"\n\nreturn [buttonstate,msg];","outputs":"2","noerr":0,"x":476,"y":310,"wires":[["1263cf58.a3b441"],[]],"inputLabels":["input"],"outputLabels":["to button","to proccessing"]},{"id":"6bb1c44c.fb56bc","type":"function","z":"932c9a5e.6c66f8","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 = \"2\";\n color = \"darkorange\";\n}\nelse{\n // state is false (lets make button red)\n label = \"2\";\n color = \"mediumgray\";\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":156,"y":310,"wires":[["1263cf58.a3b441"]]},{"id":"ee6489b4.7b97f8","type":"function","z":"932c9a5e.6c66f8","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":656,"y":270,"wires":[["6bb1c44c.fb56bc"]]},{"id":"abfbee5c.b1c6f","type":"change","z":"932c9a5e.6c66f8","name":"","rules":[{"t":"change","p":"payload","pt":"msg","from":"true","fromt":"bool","to":"true","tot":"str"},{"t":"change","p":"payload","pt":"msg","from":"false","fromt":"bool","to":"false","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":456,"y":270,"wires":[["ee6489b4.7b97f8"]]},{"id":"109224ab.0a311b","type":"change","z":"932c9a5e.6c66f8","name":"On/off Status","rules":[{"t":"move","p":"payload.ison","pt":"msg","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":266,"y":270,"wires":[["abfbee5c.b1c6f"]]},{"id":"ee86c2ab.f0251","type":"json","z":"932c9a5e.6c66f8","name":"","property":"payload","action":"","pretty":false,"x":106,"y":270,"wires":[["6c97f925.9a2828","109224ab.0a311b"]]},{"id":"6c97f925.9a2828","type":"change","z":"932c9a5e.6c66f8","name":"Brightness","rules":[{"t":"move","p":"payload.brightness","pt":"msg","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":266,"y":230,"wires":[["82a647ca.4b8f68"]]},{"id":"ad69712.850479","type":"mqtt in","z":"932c9a5e.6c66f8","name":"Status 1_2","topic":"shellies/shellyrgbw2-B0D733/white/1/status","qos":"2","broker":"c86985b9.a9ab78","x":96,"y":210,"wires":[["ee86c2ab.f0251"]]},{"id":"82a647ca.4b8f68","type":"ui_slider","z":"932c9a5e.6c66f8","name":"slider S1_2","label":"slider S1_2","group":"c6364af0.be9fe8","order":4,"width":9,"height":1,"passthru":true,"topic":"shellies/shellyrgbw2-B0D733/white/1/set","min":0,"max":"100","step":"5","x":446,"y":230,"wires":[["29371b43.65e7e4"]]},{"id":"29371b43.65e7e4","type":"template","z":"932c9a5e.6c66f8","name":"","field":"payload","fieldType":"msg","format":"handlebars","syntax":"mustache","template":"{\"brightness\" :{{payload}}}","output":"str","x":616,"y":230,"wires":[["24cc6d1f.95fc32","75137cf2.5b0534"]]},{"id":"24cc6d1f.95fc32","type":"mqtt out","z":"932c9a5e.6c66f8","name":"","topic":"","qos":"","retain":"","broker":"c86985b9.a9ab78","x":846,"y":230,"wires":[]},{"id":"75137cf2.5b0534","type":"debug","z":"932c9a5e.6c66f8","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":846,"y":270,"wires":[]},{"id":"a16579e1.d31c78","type":"debug","z":"932c9a5e.6c66f8","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":486,"y":350,"wires":[]},{"id":"e0188c68.fdae4","type":"debug","z":"932c9a5e.6c66f8","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":466,"y":190,"wires":[]},{"id":"230664c5.d45d2c","type":"mqtt out","z":"932c9a5e.6c66f8","name":"S1_3 On/off","topic":"shellies/shellyrgbw2-B0D733/white/2/command","qos":"","retain":"","broker":"761dfb74.752d64","x":826,"y":470,"wires":[]},{"id":"3f219df9.3f0802","type":"change","z":"932c9a5e.6c66f8","name":"","rules":[{"t":"change","p":"payload","pt":"msg","from":"true","fromt":"bool","to":"off","tot":"str"},{"t":"change","p":"payload","pt":"msg","from":"false","fromt":"bool","to":"on","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":636,"y":470,"wires":[["230664c5.d45d2c"]]},{"id":"c89b69a9.b0a1a8","type":"ui_button","z":"932c9a5e.6c66f8","name":"on/off","group":"c6364af0.be9fe8","order":5,"width":3,"height":1,"passthru":false,"label":"{{msg.topic}}","color":"","bgcolor":"{{msg.background}}","icon":"","payload":"lightstate","payloadType":"global","topic":"shellies/shellyrgbw2-B0D733/white/2/command","x":326,"y":470,"wires":[["53d50749.8b3cd8","3f219df9.3f0802","2acea899.86a798"]]},{"id":"53d50749.8b3cd8","type":"function","z":"932c9a5e.6c66f8","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 = \"3\";\n color = \"red\";\n}\nelse{\n // current state is false (light is off) lets turn it on \n label = \"3\";\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\n//msg.payload = \"here I need to way to set an on/off payload depending on state...\"\n\nreturn [buttonstate,msg];","outputs":"2","noerr":0,"x":476,"y":470,"wires":[["c89b69a9.b0a1a8"],[]],"inputLabels":["input"],"outputLabels":["to button","to proccessing"]},{"id":"3a45d750.bb0578","type":"function","z":"932c9a5e.6c66f8","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 = \"3\";\n color = \"darkorange\";\n}\nelse{\n // state is false (lets make button red)\n label = \"3\";\n color = \"mediumgray\";\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":156,"y":470,"wires":[["c89b69a9.b0a1a8"]]},{"id":"2acea899.86a798","type":"debug","z":"932c9a5e.6c66f8","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":466,"y":510,"wires":[]},{"id":"199a9a13.0a4076","type":"function","z":"932c9a5e.6c66f8","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":656,"y":430,"wires":[["3a45d750.bb0578"]]},{"id":"885a6776.943e38","type":"change","z":"932c9a5e.6c66f8","name":"","rules":[{"t":"change","p":"payload","pt":"msg","from":"true","fromt":"bool","to":"true","tot":"str"},{"t":"change","p":"payload","pt":"msg","from":"false","fromt":"bool","to":"false","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":456,"y":430,"wires":[["199a9a13.0a4076"]]},{"id":"16b0b10f.c9589f","type":"change","z":"932c9a5e.6c66f8","name":"On/off Status","rules":[{"t":"move","p":"payload.ison","pt":"msg","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":266,"y":430,"wires":[["885a6776.943e38"]]},{"id":"75ba85d7.2a7f2c","type":"json","z":"932c9a5e.6c66f8","name":"","property":"payload","action":"","pretty":false,"x":106,"y":430,"wires":[["a0e79d88.3a49e","16b0b10f.c9589f"]]},{"id":"a0e79d88.3a49e","type":"change","z":"932c9a5e.6c66f8","name":"Brightness","rules":[{"t":"move","p":"payload.brightness","pt":"msg","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":266,"y":390,"wires":[["22485e30.2d8b92"]]},{"id":"95083081.157c7","type":"mqtt in","z":"932c9a5e.6c66f8","name":"Status 1_3","topic":"shellies/shellyrgbw2-B0D733/white/2/status","qos":"2","broker":"c86985b9.a9ab78","x":96,"y":370,"wires":[["75ba85d7.2a7f2c"]]},{"id":"22485e30.2d8b92","type":"ui_slider","z":"932c9a5e.6c66f8","name":"slider S1_3","label":"slider S1_3","group":"c6364af0.be9fe8","order":6,"width":9,"height":1,"passthru":true,"topic":"shellies/shellyrgbw2-B0D733/white/2/set","min":0,"max":"100","step":"5","x":446,"y":390,"wires":[["ed4114b4.150248"]]},{"id":"ed4114b4.150248","type":"template","z":"932c9a5e.6c66f8","name":"","field":"payload","fieldType":"msg","format":"handlebars","syntax":"mustache","template":"{\"brightness\" :{{payload}}}","output":"str","x":616,"y":390,"wires":[["a3804ed9.6f47a","bf4cffe3.5bb88"]]},{"id":"a3804ed9.6f47a","type":"mqtt out","z":"932c9a5e.6c66f8","name":"","topic":"","qos":"","retain":"","broker":"c86985b9.a9ab78","x":846,"y":390,"wires":[]},{"id":"bf4cffe3.5bb88","type":"debug","z":"932c9a5e.6c66f8","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":846,"y":430,"wires":[]},{"id":"b6715d55.c552e","type":"mqtt out","z":"932c9a5e.6c66f8","name":"S1_4 On/off","topic":"shellies/shellyrgbw2-B0D733/white/3/command","qos":"","retain":"","broker":"761dfb74.752d64","x":824,"y":633,"wires":[]},{"id":"b5aac05.c2b954","type":"change","z":"932c9a5e.6c66f8","name":"","rules":[{"t":"change","p":"payload","pt":"msg","from":"true","fromt":"bool","to":"off","tot":"str"},{"t":"change","p":"payload","pt":"msg","from":"false","fromt":"bool","to":"on","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":634,"y":633,"wires":[["b6715d55.c552e"]]},{"id":"5b21a3cc.b8f66c","type":"ui_button","z":"932c9a5e.6c66f8","name":"on/off","group":"c6364af0.be9fe8","order":7,"width":3,"height":1,"passthru":false,"label":"{{msg.topic}}","color":"","bgcolor":"{{msg.background}}","icon":"","payload":"lightstate","payloadType":"global","topic":"shellies/shellyrgbw2-B0D733/white/3/command","x":324,"y":633,"wires":[["e8e8ad71.3e2c7","b5aac05.c2b954","ed5b9cbd.383c1"]]},{"id":"e8e8ad71.3e2c7","type":"function","z":"932c9a5e.6c66f8","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 = \"4\";\n color = \"red\";\n}\nelse{\n // current state is false (light is off) lets turn it on \n label = \"4\";\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\n//msg.payload = \"here I need to way to set an on/off payload depending on state...\"\n\nreturn [buttonstate,msg];","outputs":"2","noerr":0,"x":474,"y":633,"wires":[["5b21a3cc.b8f66c"],[]],"inputLabels":["input"],"outputLabels":["to button","to proccessing"]},{"id":"ed5b9cbd.383c1","type":"debug","z":"932c9a5e.6c66f8","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":464,"y":673,"wires":[]},{"id":"26a90a47.0dc9c6","type":"function","z":"932c9a5e.6c66f8","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 = \"4\";\n color = \"darkorange\";\n}\nelse{\n // state is false (lets make button red)\n label = \"4\";\n color = \"mediumgray\";\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":154,"y":633,"wires":[["5b21a3cc.b8f66c"]]},{"id":"c90ba206.29967","type":"function","z":"932c9a5e.6c66f8","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":654,"y":593,"wires":[["26a90a47.0dc9c6"]]},{"id":"3191abbd.355684","type":"change","z":"932c9a5e.6c66f8","name":"","rules":[{"t":"change","p":"payload","pt":"msg","from":"true","fromt":"bool","to":"true","tot":"str"},{"t":"change","p":"payload","pt":"msg","from":"false","fromt":"bool","to":"false","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":454,"y":593,"wires":[["c90ba206.29967"]]},{"id":"2f3c1bb0.1da084","type":"change","z":"932c9a5e.6c66f8","name":"On/off Status","rules":[{"t":"move","p":"payload.ison","pt":"msg","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":264,"y":593,"wires":[["3191abbd.355684"]]},{"id":"e19335fe.9b8228","type":"json","z":"932c9a5e.6c66f8","name":"","property":"payload","action":"","pretty":false,"x":104,"y":593,"wires":[["a3e3c4da.f537f8","2f3c1bb0.1da084"]]},{"id":"a3e3c4da.f537f8","type":"change","z":"932c9a5e.6c66f8","name":"Brightness","rules":[{"t":"move","p":"payload.brightness","pt":"msg","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":264,"y":553,"wires":[["39c54957.6406f6"]]},{"id":"316822e7.007d7e","type":"mqtt in","z":"932c9a5e.6c66f8","name":"Status 1_4","topic":"shellies/shellyrgbw2-B0D733/white/3/status","qos":"2","broker":"c86985b9.a9ab78","x":94,"y":533,"wires":[["e19335fe.9b8228"]]},{"id":"39c54957.6406f6","type":"ui_slider","z":"932c9a5e.6c66f8","name":"slider S1_4","label":"slider S1_3","group":"c6364af0.be9fe8","order":8,"width":9,"height":1,"passthru":true,"topic":"shellies/shellyrgbw2-B0D733/white/3/set","min":0,"max":"100","step":"5","x":444,"y":553,"wires":[["1c5ee82a.cab098"]]},{"id":"1c5ee82a.cab098","type":"template","z":"932c9a5e.6c66f8","name":"","field":"payload","fieldType":"msg","format":"handlebars","syntax":"mustache","template":"{\"brightness\" :{{payload}}}","output":"str","x":614,"y":553,"wires":[["3a516240.5b51ae","4afae4da.a0009c"]]},{"id":"3a516240.5b51ae","type":"mqtt out","z":"932c9a5e.6c66f8","name":"","topic":"","qos":"","retain":"","broker":"c86985b9.a9ab78","x":844,"y":553,"wires":[]},{"id":"4afae4da.a0009c","type":"debug","z":"932c9a5e.6c66f8","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":844,"y":593,"wires":[]},{"id":"c86985b9.a9ab78","type":"mqtt-broker","z":"","name":"","broker":"localhost","port":"1883","clientid":"","usetls":false,"compatmode":false,"keepalive":"60","cleansession":true,"birthTopic":"","birthQos":"0","birthPayload":"","closeTopic":"","closeQos":"0","closePayload":"","willTopic":"","willQos":"0","willPayload":""},{"id":"761dfb74.752d64","type":"mqtt-broker","z":"","name":"","broker":"localhost","port":"1883","clientid":"","usetls":false,"compatmode":true,"keepalive":"60","cleansession":true,"birthTopic":"","birthQos":"0","birthPayload":"","closeTopic":"","closePayload":"","willTopic":"","willQos":"0","willPayload":""},{"id":"c6364af0.be9fe8","type":"ui_group","z":"","name":"Light","tab":"7be54798.217718","disp":true,"width":"12","collapse":false},{"id":"7be54798.217718","type":"ui_tab","z":"","name":"Home","icon":"dashboard","order":1}]```
You have four different lights (devices). For every one of them you'll need to use unique variable to store the state of that unique light. (can be combined into one variable but let's keep things simple for now) So in every flow (from mqtt input to mqtt output) you'll use only one of those unique flow variables to identfy and store state of this light.
From button you'll need only one wire to go to button handler. Inside button handler determine current state and make decision for outoing messages.
2 messages going out. One goes back to button and the other goes to device (mqtt out)
buttonHandler
//this function runs when you are pressing the button.
// read current state of light.
// for every light it will be needed to define unique variable
//and store it in flow context (or global context)
// used number 4 here, but should be unique for each flow (device) stream
var state = global.get("lightstate_4") || false;
var label;
var color;
var command;
if(state === true){
// current state is true (light is on) lets turn it off
label = "4";
color = "red";
command = "off"
}
else{
// current state is false (light is off) lets turn it on
label = "4";
color = "green";
command = "on"
}
// buttonstate is message, which goes straight back to button. It disables button.
// button stays disabled until MQTT message comes in and tells to node-red
// what is actual state of that light
var buttonstate = {enabled:false, background:color, topic:label};
msg.payload = command
return [buttonstate,msg];
Thanks you! It seemed the obvious easy way out right? I made the change and replaced the "lightstate" for "lightstate_n" for the other button functions as well. However it doesn't work. The MQTT messages are sent as they are supposed to and the Shelly does its magic, but the button hangs in limbo. In my determinebuttonstate function - which is the one that should change AFTER the MQTT msg has confirmed an actual switch change, I have defined the button as orange/gray. It never changes to these colors, but stays at green, which is a color defined in button handler, and as I interpret it - it is the color that is supposed to show between button push and actual confirmation of state.
So what do I try next? Is there a place where the global variables are set where I need to add lightstate_n?
Share the flow again. But not entire flow but only select one stream from end to end.
Here is one flow. I also came across the last post of the link you sent previously. Will se if I can make that work as it is cleaner with less nodes. I guess I still need the variable_1 setup though
. ```
[{"id":"4da04575.f9b24c","type":"mqtt out","z":"932c9a5e.6c66f8","name":"S1_1 On/off","topic":"shellies/shellyrgbw2-B0D733/white/0/command","qos":"","retain":"","broker":"761dfb74.752d64","x":826,"y":150,"wires":[]},{"id":"8796405f.b5d5f","type":"change","z":"932c9a5e.6c66f8","name":"","rules":[{"t":"change","p":"payload","pt":"msg","from":"true","fromt":"bool","to":"off","tot":"str"},{"t":"change","p":"payload","pt":"msg","from":"false","fromt":"bool","to":"on","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":636,"y":150,"wires":[["4da04575.f9b24c"]]},{"id":"7b70b363.12362c","type":"ui_button","z":"932c9a5e.6c66f8","name":"on/off","group":"c6364af0.be9fe8","order":1,"width":3,"height":2,"passthru":false,"label":"{{msg.topic}}","tooltip":"","color":"","bgcolor":"{{msg.background}}","icon":"","payload":"lightstate","payloadType":"global","topic":"shellies/shellyrgbw2-B0D733/white/0/command","x":326,"y":150,"wires":[["d3896a5f.0c44a8","8796405f.b5d5f","e0188c68.fdae4"]]},{"id":"d3896a5f.0c44a8","type":"function","z":"932c9a5e.6c66f8","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 = \"1\";\n color = \"red\";\n}\nelse{\n // current state is false (light is off) lets turn it on \n label = \"1\";\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\n//msg.payload = \"here I need to way to set an on/off payload depending on state...\"\n\nreturn [buttonstate,msg];","outputs":"2","noerr":0,"x":476,"y":150,"wires":[["7b70b363.12362c"],[]],"inputLabels":["input"],"outputLabels":["to button","to proccessing"]},{"id":"e0188c68.fdae4","type":"debug","z":"932c9a5e.6c66f8","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":466,"y":190,"wires":[]},{"id":"795c95f.d0f286c","type":"function","z":"932c9a5e.6c66f8","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 = \"1\";\n color = \"darkorange\";\n}\nelse{\n // state is false (lets make button red)\n label = \"1\";\n color = \"mediumgray\";\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":156,"y":150,"wires":[["7b70b363.12362c"]]},{"id":"a4c990e2.05ea4","type":"function","z":"932c9a5e.6c66f8","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":656,"y":110,"wires":[["795c95f.d0f286c"]]},{"id":"bdc56e85.850af","type":"change","z":"932c9a5e.6c66f8","name":"","rules":[{"t":"change","p":"payload","pt":"msg","from":"true","fromt":"bool","to":"true","tot":"str"},{"t":"change","p":"payload","pt":"msg","from":"false","fromt":"bool","to":"false","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":456,"y":110,"wires":[["a4c990e2.05ea4"]]},{"id":"e5a8e727.96e478","type":"change","z":"932c9a5e.6c66f8","name":"On/off Status","rules":[{"t":"move","p":"payload.ison","pt":"msg","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":266,"y":110,"wires":[["bdc56e85.850af"]]},{"id":"64bdea3d.42a334","type":"json","z":"932c9a5e.6c66f8","name":"","property":"payload","action":"","pretty":false,"x":106,"y":110,"wires":[["27598731.c5b6f8","e5a8e727.96e478"]]},{"id":"27598731.c5b6f8","type":"change","z":"932c9a5e.6c66f8","name":"Brightness","rules":[{"t":"move","p":"payload.brightness","pt":"msg","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":266,"y":70,"wires":[["5bade9f2.8815a8"]]},{"id":"12ab70a3.8bcd0f","type":"mqtt in","z":"932c9a5e.6c66f8","name":"Status 1_1","topic":"shellies/shellyrgbw2-B0D733/white/0/status","qos":"2","broker":"c86985b9.a9ab78","x":96,"y":50,"wires":[["64bdea3d.42a334"]]},{"id":"5bade9f2.8815a8","type":"ui_slider","z":"932c9a5e.6c66f8","name":"slider S1_1","label":"slider S1_1","tooltip":"","group":"c6364af0.be9fe8","order":2,"width":9,"height":2,"passthru":true,"outs":"all","topic":"shellies/shellyrgbw2-B0D733/white/0/set","min":0,"max":"100","step":"5","x":446,"y":70,"wires":[["e298b010.3eff"]]},{"id":"e298b010.3eff","type":"template","z":"932c9a5e.6c66f8","name":"","field":"payload","fieldType":"msg","format":"handlebars","syntax":"mustache","template":"{\"brightness\" :{{payload}}}","output":"str","x":616,"y":70,"wires":[["cd8ee5a7.6a6d48","5db7e0e5.e58de"]]},{"id":"cd8ee5a7.6a6d48","type":"mqtt out","z":"932c9a5e.6c66f8","name":"","topic":"","qos":"","retain":"","broker":"c86985b9.a9ab78","x":846,"y":70,"wires":[]},{"id":"5db7e0e5.e58de","type":"debug","z":"932c9a5e.6c66f8","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":846,"y":110,"wires":[]},{"id":"761dfb74.752d64","type":"mqtt-broker","z":"","name":"","broker":"localhost","port":"1883","clientid":"","usetls":false,"compatmode":true,"keepalive":"60","cleansession":true,"birthTopic":"","birthQos":"0","birthPayload":"","closeTopic":"","closePayload":"","willTopic":"","willQos":"0","willPayload":""},{"id":"c6364af0.be9fe8","type":"ui_group","z":"","name":"Light","tab":"7be54798.217718","order":1,"disp":true,"width":13,"collapse":false},{"id":"c86985b9.a9ab78","type":"mqtt-broker","z":"","name":"","broker":"localhost","port":"1883","clientid":"","usetls":false,"compatmode":false,"keepalive":"60","cleansession":true,"birthTopic":"","birthQos":"0","birthPayload":"","closeTopic":"","closeQos":"0","closePayload":"","willTopic":"","willQos":"0","willPayload":""},{"id":"7be54798.217718","type":"ui_tab","z":"","name":"Home","icon":"dashboard","order":2}]```
It seems to be working now. Here's what I am doing:
Copy every button flow one by one into notepad, then do a search/replace for lightstate/lighstate_n.
Done two and it seems like I've overlooked one or two when messing around with the manual _n addon.
Thanks for encouragement!
Here is my final attempt at this. I have buttons that switches color when they are pushed and when MQTT sends a confirmation on state change. The ON is further enhanced by a LED which turns on (green in this case). Furthermore I've added a slider that can control the dimming function of the Shelly RGBW2's I am using, and for clarity I've added a text field to show the dimming value.
I've attached a flow with 4 butons/sliders. In order to expand, the global lightstat_1_n function needs to be incremented to avoid confusion between buttons. I am currently running 12 and it works like a charm. Merry Christmas and thanks to "Santas helpers" for pointing in the right direction!
Here is the flow:
[{"id":"932c9a5e.6c66f8","type":"tab","label":"Shelly 2","disabled":false,"info":""},{"id":"da78fb05.006388","type":"mqtt out","z":"932c9a5e.6c66f8","name":"S2_1 On/off","topic":"shellies/shellyrgbw2-B082AB/white/0/command","qos":"","retain":"","broker":"c46b305c.d08b3","x":837,"y":145,"wires":[]},{"id":"e8f0637f.6e4f6","type":"change","z":"932c9a5e.6c66f8","name":"","rules":[{"t":"change","p":"payload","pt":"msg","from":"true","fromt":"bool","to":"off","tot":"str"},{"t":"change","p":"payload","pt":"msg","from":"false","fromt":"bool","to":"on","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":647,"y":145,"wires":[["da78fb05.006388"]]},{"id":"eb29fdb3.57cf6","type":"ui_button","z":"932c9a5e.6c66f8","name":"on/off","group":"c6364af0.be9fe8","order":17,"width":3,"height":1,"passthru":false,"label":"{{msg.topic}}","tooltip":"Tänder ljuset i akterkojen","color":"#030303","bgcolor":"{{msg.background}}","icon":"","payload":"lightstate_2_1","payloadType":"global","topic":"shellies/shellyrgbw2-B082AB/white/0/command","x":337,"y":145,"wires":[["bccb057e.6869b8","e8f0637f.6e4f6","874d11a1.d8385","61c33cb5.28a7d4"]]},{"id":"bccb057e.6869b8","type":"function","z":"932c9a5e.6c66f8","name":"buttonHandler","func":"//this function runs when you are pressing the button.\n\n// read current state of light\nvar state = global.get(\"lightstate_2_1\") || false;\n\nvar label;\nvar color;\n\nif(state === true){\n // current state is true (light is on) lets turn it off \n label = \"Akterkoj\";\n color = \"#f79f28\";\n}\nelse{\n // current state is false (light is off) lets turn it on \n label = \"Akterkoj\";\n color = \"#e3be8d\";\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\n//msg.payload = \"here I need to way to set an on/off payload depending on state...\"\n\nreturn [buttonstate,msg];","outputs":"2","noerr":0,"x":487,"y":145,"wires":[["eb29fdb3.57cf6"],[]],"inputLabels":["input"],"outputLabels":["to button","to proccessing"]},{"id":"874d11a1.d8385","type":"debug","z":"932c9a5e.6c66f8","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":636,"y":189,"wires":[]},{"id":"61c33cb5.28a7d4","type":"ui_led","z":"932c9a5e.6c66f8","group":"c6364af0.be9fe8","order":20,"width":1,"height":1,"label":"","labelPlacement":"left","labelAlignment":"left","colorForValue":[{"color":"green","value":"true","valueType":"bool"},{"color":"","value":"false","valueType":"bool"}],"allowColorForValueInMessage":false,"name":"","x":462,"y":187,"wires":[]},{"id":"c4615c46.19a2b","type":"function","z":"932c9a5e.6c66f8","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_2_1\") || false;\nvar label;\nvar color;\n\nif(state === true){\n// state is true (lets make button green)\n label = \"Akterkoj\";\n color = \"#e3be8d\";\n}\nelse{\n // state is false (lets make button red)\n label = \"Akterkoj\";\n color = \"#f79f28\";\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":167,"y":145,"wires":[["eb29fdb3.57cf6"]]},{"id":"80caea4b.50e5c8","type":"function","z":"932c9a5e.6c66f8","name":"store the state of light","func":"// read current state of light \nvar lightstate_2_1 = global.get(\"lightstate_2_1\") || undefined\nif(msg.payload === \"true\"){\n lightstate_2_1 = true\n}\nelse{\n lightstate_2_1 = false \n}\n// write state to global context, so we can read it where ever the state is needed\nglobal.set(\"lightstate_2_1\",lightstate_2_1)\n\n\n// return last known state (we dont use it but the flow must continue)\nmsg.payload = lightstate_2_1\nmsg.topic = \"state-of-light-changed\"\nreturn msg;","outputs":1,"noerr":0,"x":667,"y":105,"wires":[["c4615c46.19a2b"]]},{"id":"a9f30ddb.07403","type":"change","z":"932c9a5e.6c66f8","name":"","rules":[{"t":"change","p":"payload","pt":"msg","from":"true","fromt":"bool","to":"true","tot":"str"},{"t":"change","p":"payload","pt":"msg","from":"false","fromt":"bool","to":"false","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":467,"y":105,"wires":[["80caea4b.50e5c8"]]},{"id":"46bb1adf.bf18d4","type":"change","z":"932c9a5e.6c66f8","name":"On/off Status","rules":[{"t":"move","p":"payload.ison","pt":"msg","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":277,"y":105,"wires":[["a9f30ddb.07403"]]},{"id":"3331dfb9.c04c3","type":"json","z":"932c9a5e.6c66f8","name":"","property":"payload","action":"","pretty":false,"x":117,"y":105,"wires":[["e91a7939.37f2a8","46bb1adf.bf18d4"]]},{"id":"e91a7939.37f2a8","type":"change","z":"932c9a5e.6c66f8","name":"Brightness","rules":[{"t":"move","p":"payload.brightness","pt":"msg","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":277,"y":65,"wires":[["33f0b48b.f0cf9c"]]},{"id":"9f78968b.0741a8","type":"mqtt in","z":"932c9a5e.6c66f8","name":"Status 2_1","topic":"shellies/shellyrgbw2-B082AB/white/0/status","qos":"2","broker":"c46b305c.d08b3","x":107,"y":45,"wires":[["3331dfb9.c04c3"]]},{"id":"33f0b48b.f0cf9c","type":"ui_slider","z":"932c9a5e.6c66f8","name":"slider S2_1","label":"","tooltip":"","group":"c6364af0.be9fe8","order":18,"width":9,"height":1,"passthru":true,"outs":"all","topic":"shellies/shellyrgbw2-B082AB/white/0/set","min":0,"max":"100","step":"5","x":457,"y":65,"wires":[["6d760d84.8f7d84","e49f52ab.f8ed8"]]},{"id":"6d760d84.8f7d84","type":"template","z":"932c9a5e.6c66f8","name":"","field":"payload","fieldType":"msg","format":"handlebars","syntax":"mustache","template":"{\"brightness\" :{{payload}}}","output":"str","x":627,"y":65,"wires":[["455ada38.733de4","ea690184.a11b6"]]},{"id":"455ada38.733de4","type":"mqtt out","z":"932c9a5e.6c66f8","name":"","topic":"","qos":"","retain":"","broker":"c46b305c.d08b3","x":857,"y":65,"wires":[]},{"id":"ea690184.a11b6","type":"debug","z":"932c9a5e.6c66f8","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":857,"y":105,"wires":[]},{"id":"13c5fa83.5a65a5","type":"mqtt out","z":"932c9a5e.6c66f8","name":"S2_2 On/off","topic":"shellies/shellyrgbw2-B082AB/white/1/command","qos":"","retain":"","broker":"c46b305c.d08b3","x":840,"y":336,"wires":[]},{"id":"e4724694.770f38","type":"change","z":"932c9a5e.6c66f8","name":"","rules":[{"t":"change","p":"payload","pt":"msg","from":"true","fromt":"bool","to":"off","tot":"str"},{"t":"change","p":"payload","pt":"msg","from":"false","fromt":"bool","to":"on","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":650,"y":336,"wires":[["13c5fa83.5a65a5"]]},{"id":"c3173a8d.f0fe98","type":"ui_button","z":"932c9a5e.6c66f8","name":"on/off","group":"c6364af0.be9fe8","order":21,"width":3,"height":1,"passthru":false,"label":"{{msg.topic}}","tooltip":"Tänder ljus i pentry","color":"#030303","bgcolor":"{{msg.background}}","icon":"","payload":"lightstate_2_2","payloadType":"global","topic":"shellies/shellyrgbw2-B082AB/white/1/command","x":340,"y":336,"wires":[["3d017b43.7a7d34","e4724694.770f38","9f6916c3.5ee6f8","5de42dff.ba3ea4"]]},{"id":"3d017b43.7a7d34","type":"function","z":"932c9a5e.6c66f8","name":"buttonHandler","func":"//this function runs when you are pressing the button.\n\n// read current state of light\nvar state = global.get(\"lightstate_2_2\") || false;\n\nvar label;\nvar color;\n\nif(state === true){\n // current state is true (light is on) lets turn it off \n label = \"Pentry\";\n color = \"#f79f28\";\n}\nelse{\n // current state is false (light is off) lets turn it on \n label = \"Pentry\";\n color = \"#e3be8d\";\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\n//msg.payload = \"here I need to way to set an on/off payload depending on state...\"\n\nreturn [buttonstate,msg];","outputs":"2","noerr":0,"x":490,"y":336,"wires":[["c3173a8d.f0fe98"],[]],"inputLabels":["input"],"outputLabels":["to button","to proccessing"]},{"id":"9f6916c3.5ee6f8","type":"debug","z":"932c9a5e.6c66f8","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":639,"y":380,"wires":[]},{"id":"5de42dff.ba3ea4","type":"ui_led","z":"932c9a5e.6c66f8","group":"c6364af0.be9fe8","order":24,"width":1,"height":1,"label":"","labelPlacement":"left","labelAlignment":"left","colorForValue":[{"color":"green","value":"true","valueType":"bool"},{"color":"","value":"false","valueType":"bool"}],"allowColorForValueInMessage":false,"name":"","x":465,"y":378,"wires":[]},{"id":"1fb7bdbb.5617e2","type":"function","z":"932c9a5e.6c66f8","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_2_2\") || false;\nvar label;\nvar color;\n\nif(state === true){\n// state is true (lets make button green)\n label = \"Pentry\";\n color = \"#e3be8d\";\n}\nelse{\n // state is false (lets make button red)\n label = \"Pentry\";\n color = \"#f79f28\";\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":170,"y":336,"wires":[["c3173a8d.f0fe98"]]},{"id":"1a272ab1.cf1085","type":"function","z":"932c9a5e.6c66f8","name":"store the state of light","func":"// read current state of light \nvar lightstate_2_2 = global.get(\"lightstate_2_2\") || undefined\nif(msg.payload === \"true\"){\n lightstate_2_2 = true\n}\nelse{\n lightstate_2_2 = false \n}\n// write state to global context, so we can read it where ever the state is needed\nglobal.set(\"lightstate_2_2\",lightstate_2_2)\n\n\n// return last known state (we dont use it but the flow must continue)\nmsg.payload = lightstate_2_2\nmsg.topic = \"state-of-light-changed\"\nreturn msg;","outputs":1,"noerr":0,"x":670,"y":296,"wires":[["1fb7bdbb.5617e2"]]},{"id":"c1b0fd88.7f1f9","type":"change","z":"932c9a5e.6c66f8","name":"","rules":[{"t":"change","p":"payload","pt":"msg","from":"true","fromt":"bool","to":"true","tot":"str"},{"t":"change","p":"payload","pt":"msg","from":"false","fromt":"bool","to":"false","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":470,"y":296,"wires":[["1a272ab1.cf1085"]]},{"id":"ca5fa623.c5da18","type":"change","z":"932c9a5e.6c66f8","name":"On/off Status","rules":[{"t":"move","p":"payload.ison","pt":"msg","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":280,"y":296,"wires":[["c1b0fd88.7f1f9"]]},{"id":"d5ef45bc.2a4858","type":"json","z":"932c9a5e.6c66f8","name":"","property":"payload","action":"","pretty":false,"x":120,"y":296,"wires":[["b7b29f50.4d33a","ca5fa623.c5da18"]]},{"id":"b7b29f50.4d33a","type":"change","z":"932c9a5e.6c66f8","name":"Brightness","rules":[{"t":"move","p":"payload.brightness","pt":"msg","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":280,"y":256,"wires":[["1ad756ad.6131a9"]]},{"id":"fb5beb32.10a5c8","type":"mqtt in","z":"932c9a5e.6c66f8","name":"Status 2_2","topic":"shellies/shellyrgbw2-B082AB/white/1/status","qos":"2","broker":"c46b305c.d08b3","x":110,"y":236,"wires":[["d5ef45bc.2a4858"]]},{"id":"1ad756ad.6131a9","type":"ui_slider","z":"932c9a5e.6c66f8","name":"slider S2_2","label":"","tooltip":"","group":"c6364af0.be9fe8","order":22,"width":9,"height":1,"passthru":true,"outs":"all","topic":"shellies/shellyrgbw2-B082AB/white/1/set","min":0,"max":"100","step":"5","x":460,"y":256,"wires":[["dcf9b47b.0df888","f41a665c.d63da8"]]},{"id":"dcf9b47b.0df888","type":"template","z":"932c9a5e.6c66f8","name":"","field":"payload","fieldType":"msg","format":"handlebars","syntax":"mustache","template":"{\"brightness\" :{{payload}}}","output":"str","x":630,"y":256,"wires":[["77d8f764.751428","c0e9e2d7.d0fea"]]},{"id":"77d8f764.751428","type":"mqtt out","z":"932c9a5e.6c66f8","name":"","topic":"","qos":"","retain":"","broker":"c46b305c.d08b3","x":860,"y":256,"wires":[]},{"id":"c0e9e2d7.d0fea","type":"debug","z":"932c9a5e.6c66f8","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":860,"y":296,"wires":[]},{"id":"c7d0db93.02b5c8","type":"mqtt out","z":"932c9a5e.6c66f8","name":"S2_3 On/off","topic":"shellies/shellyrgbw2-B082AB/white/2/command","qos":"","retain":"","broker":"c46b305c.d08b3","x":835,"y":531,"wires":[]},{"id":"eedf418d.d96c5","type":"change","z":"932c9a5e.6c66f8","name":"","rules":[{"t":"change","p":"payload","pt":"msg","from":"true","fromt":"bool","to":"off","tot":"str"},{"t":"change","p":"payload","pt":"msg","from":"false","fromt":"bool","to":"on","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":645,"y":531,"wires":[["c7d0db93.02b5c8"]]},{"id":"42c468d8.550878","type":"ui_button","z":"932c9a5e.6c66f8","name":"on/off","group":"c6364af0.be9fe8","order":25,"width":3,"height":1,"passthru":false,"label":"{{msg.topic}}","tooltip":"Tänder ljus i motorrummet","color":"#030303","bgcolor":"{{msg.background}}","icon":"","payload":"lightstate_2_3","payloadType":"global","topic":"shellies/shellyrgbw2-B082AB/white/2/command","x":335,"y":531,"wires":[["b614a034.69aa4","eedf418d.d96c5","edeff632.909928","3fd86ec9.0651a2"]]},{"id":"b614a034.69aa4","type":"function","z":"932c9a5e.6c66f8","name":"buttonHandler","func":"//this function runs when you are pressing the button.\n\n// read current state of light\nvar state = global.get(\"lightstate_2_3\") || false;\n\nvar label;\nvar color;\n\nif(state === true){\n // current state is true (light is on) lets turn it off \n label = \"Motorrum\";\n color = \"#f79f28\";\n}\nelse{\n // current state is false (light is off) lets turn it on \n label = \"Motorrum\";\n color = \"#e3be8d\";\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\n//msg.payload = \"here I need to way to set an on/off payload depending on state...\"\n\nreturn [buttonstate,msg];","outputs":"2","noerr":0,"x":485,"y":531,"wires":[["42c468d8.550878"],[]],"inputLabels":["input"],"outputLabels":["to button","to proccessing"]},{"id":"edeff632.909928","type":"debug","z":"932c9a5e.6c66f8","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":634,"y":575,"wires":[]},{"id":"3fd86ec9.0651a2","type":"ui_led","z":"932c9a5e.6c66f8","group":"c6364af0.be9fe8","order":28,"width":1,"height":1,"label":"","labelPlacement":"left","labelAlignment":"left","colorForValue":[{"color":"green","value":"true","valueType":"bool"},{"color":"","value":"false","valueType":"bool"}],"allowColorForValueInMessage":false,"name":"","x":460,"y":573,"wires":[]},{"id":"c1049626.a5caf8","type":"function","z":"932c9a5e.6c66f8","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_2_3\") || false;\nvar label;\nvar color;\n\nif(state === true){\n// state is true (lets make button green)\n label = \"Motorrum\";\n color = \"#e3be8d\";\n}\nelse{\n // state is false (lets make button red)\n label = \"Motorrum\";\n color = \"#f79f28\";\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":165,"y":531,"wires":[["42c468d8.550878"]]},{"id":"20b00bbd.b86804","type":"function","z":"932c9a5e.6c66f8","name":"store the state of light","func":"// read current state of light \nvar lightstate_2_3 = global.get(\"lightstate_2_3\") || undefined\nif(msg.payload === \"true\"){\n lightstate_2_3 = true\n}\nelse{\n lightstate_2_3 = false \n}\n// write state to global context, so we can read it where ever the state is needed\nglobal.set(\"lightstate_2_3\",lightstate_2_3)\n\n\n// return last known state (we dont use it but the flow must continue)\nmsg.payload = lightstate_2_3\nmsg.topic = \"state-of-light-changed\"\nreturn msg;","outputs":1,"noerr":0,"x":665,"y":491,"wires":[["c1049626.a5caf8"]]},{"id":"f015c3.8900fa4","type":"change","z":"932c9a5e.6c66f8","name":"","rules":[{"t":"change","p":"payload","pt":"msg","from":"true","fromt":"bool","to":"true","tot":"str"},{"t":"change","p":"payload","pt":"msg","from":"false","fromt":"bool","to":"false","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":465,"y":491,"wires":[["20b00bbd.b86804"]]},{"id":"dd6eeffa.80545","type":"change","z":"932c9a5e.6c66f8","name":"On/off Status","rules":[{"t":"move","p":"payload.ison","pt":"msg","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":275,"y":491,"wires":[["f015c3.8900fa4"]]},{"id":"cdc9e020.e11fe","type":"json","z":"932c9a5e.6c66f8","name":"","property":"payload","action":"","pretty":false,"x":115,"y":491,"wires":[["2dd3c07b.bbbbc","dd6eeffa.80545"]]},{"id":"2dd3c07b.bbbbc","type":"change","z":"932c9a5e.6c66f8","name":"Brightness","rules":[{"t":"move","p":"payload.brightness","pt":"msg","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":275,"y":451,"wires":[["f810481e.a3eec8"]]},{"id":"da8e0c75.4e2a4","type":"mqtt in","z":"932c9a5e.6c66f8","name":"Status 2_3","topic":"shellies/shellyrgbw2-B082AB/white/2/status","qos":"2","broker":"c46b305c.d08b3","x":105,"y":431,"wires":[["cdc9e020.e11fe"]]},{"id":"f810481e.a3eec8","type":"ui_slider","z":"932c9a5e.6c66f8","name":"slider S2_3","label":"","tooltip":"","group":"c6364af0.be9fe8","order":26,"width":9,"height":1,"passthru":true,"outs":"all","topic":"shellies/shellyrgbw2-B082AB/white/2/set","min":0,"max":"100","step":"5","x":455,"y":451,"wires":[["ad8af91e.7bcd08","f438acba.0d719"]]},{"id":"ad8af91e.7bcd08","type":"template","z":"932c9a5e.6c66f8","name":"","field":"payload","fieldType":"msg","format":"handlebars","syntax":"mustache","template":"{\"brightness\" :{{payload}}}","output":"str","x":625,"y":451,"wires":[["2240aef0.922962","695f9bcd.c1b804"]]},{"id":"2240aef0.922962","type":"mqtt out","z":"932c9a5e.6c66f8","name":"","topic":"","qos":"","retain":"","broker":"c46b305c.d08b3","x":855,"y":451,"wires":[]},{"id":"695f9bcd.c1b804","type":"debug","z":"932c9a5e.6c66f8","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":855,"y":491,"wires":[]},{"id":"e49f52ab.f8ed8","type":"ui_text","z":"932c9a5e.6c66f8","group":"c6364af0.be9fe8","order":19,"width":1,"height":1,"name":"2_1","label":"","format":"{{msg.payload}}","layout":"row-center","x":755,"y":41,"wires":[]},{"id":"f41a665c.d63da8","type":"ui_text","z":"932c9a5e.6c66f8","group":"c6364af0.be9fe8","order":23,"width":1,"height":1,"name":"2_2","label":"","format":"{{msg.payload}}","layout":"row-center","x":751,"y":234,"wires":[]},{"id":"f438acba.0d719","type":"ui_text","z":"932c9a5e.6c66f8","group":"c6364af0.be9fe8","order":27,"width":1,"height":1,"name":"2_3","label":"","format":"{{msg.payload}}","layout":"row-center","x":749,"y":430,"wires":[]},{"id":"82b542b8.f4b97","type":"debug","z":"932c9a5e.6c66f8","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":640,"y":777,"wires":[]},{"id":"b2dc4e6a.23c17","type":"ui_button","z":"932c9a5e.6c66f8","name":"on/off","group":"c6364af0.be9fe8","order":29,"width":3,"height":1,"passthru":false,"label":"{{msg.topic}}","tooltip":"Tänder ljus i över kartbordet","color":"#030303","bgcolor":"{{msg.background}}","icon":"","payload":"lightstate_2_4","payloadType":"global","topic":"shellies/shellyrgbw2-B082AB/white/3/command","x":341,"y":733,"wires":[["5dbd16dc.4a4708","c3eb8459.516b08","82b542b8.f4b97","9d2f2207.56d01"]]},{"id":"5dbd16dc.4a4708","type":"function","z":"932c9a5e.6c66f8","name":"buttonHandler","func":"//this function runs when you are pressing the button.\n\n// read current state of light\nvar state = global.get(\"lightstate_2_4\") || false;\n\nvar label;\nvar color;\n\nif(state === true){\n // current state is true (light is on) lets turn it off \n label = \"Kartbord\";\n color = \"#f79f28\";\n}\nelse{\n // current state is false (light is off) lets turn it on \n label = \"Kartbord\";\n color = \"#e3be8d\";\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\n//msg.payload = \"here I need to way to set an on/off payload depending on state...\"\n\nreturn [buttonstate,msg];","outputs":"2","noerr":0,"x":491,"y":733,"wires":[["b2dc4e6a.23c17"],[]],"inputLabels":["input"],"outputLabels":["to button","to proccessing"]},{"id":"c3eb8459.516b08","type":"change","z":"932c9a5e.6c66f8","name":"","rules":[{"t":"change","p":"payload","pt":"msg","from":"true","fromt":"bool","to":"off","tot":"str"},{"t":"change","p":"payload","pt":"msg","from":"false","fromt":"bool","to":"on","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":651,"y":733,"wires":[["7dfd724f.aa877c"]]},{"id":"9d2f2207.56d01","type":"ui_led","z":"932c9a5e.6c66f8","group":"c6364af0.be9fe8","order":32,"width":1,"height":1,"label":"","labelPlacement":"left","labelAlignment":"left","colorForValue":[{"color":"green","value":"true","valueType":"bool"},{"color":"","value":"false","valueType":"bool"}],"allowColorForValueInMessage":false,"name":"","x":466,"y":775,"wires":[]},{"id":"c7463f33.3e261","type":"function","z":"932c9a5e.6c66f8","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_2_4\") || false;\nvar label;\nvar color;\n\nif(state === true){\n// state is true (lets make button green)\n label = \"Kartbord\";\n color = \"#e3be8d\";\n}\nelse{\n // state is false (lets make button red)\n label = \"Kartbord\";\n color = \"#f79f28\";\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":171,"y":733,"wires":[["b2dc4e6a.23c17"]]},{"id":"7dfd724f.aa877c","type":"mqtt out","z":"932c9a5e.6c66f8","name":"S2_4 On/off","topic":"shellies/shellyrgbw2-B082AB/white/3/command","qos":"","retain":"","broker":"c46b305c.d08b3","x":841,"y":733,"wires":[]},{"id":"714c0598.7cdf4c","type":"function","z":"932c9a5e.6c66f8","name":"store the state of light","func":"// read current state of light \nvar lightstate_2_4 = global.get(\"lightstate_2_4\") || undefined\nif(msg.payload === \"true\"){\n lightstate_2_4 = true\n}\nelse{\n lightstate_2_4 = false \n}\n// write state to global context, so we can read it where ever the state is needed\nglobal.set(\"lightstate_2_4\",lightstate_2_4)\n\n\n// return last known state (we dont use it but the flow must continue)\nmsg.payload = lightstate_2_4\nmsg.topic = \"state-of-light-changed\"\nreturn msg;","outputs":1,"noerr":0,"x":671,"y":693,"wires":[["c7463f33.3e261"]]},{"id":"f52481f3.36bc5","type":"change","z":"932c9a5e.6c66f8","name":"","rules":[{"t":"change","p":"payload","pt":"msg","from":"true","fromt":"bool","to":"true","tot":"str"},{"t":"change","p":"payload","pt":"msg","from":"false","fromt":"bool","to":"false","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":471,"y":693,"wires":[["714c0598.7cdf4c"]]},{"id":"f34f28ee.5c8dd8","type":"change","z":"932c9a5e.6c66f8","name":"On/off Status","rules":[{"t":"move","p":"payload.ison","pt":"msg","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":281,"y":693,"wires":[["f52481f3.36bc5"]]},{"id":"78b2d4fe.3a4afc","type":"json","z":"932c9a5e.6c66f8","name":"","property":"payload","action":"","pretty":false,"x":121,"y":693,"wires":[["69358fc6.2736d","f34f28ee.5c8dd8"]]},{"id":"69358fc6.2736d","type":"change","z":"932c9a5e.6c66f8","name":"Brightness","rules":[{"t":"move","p":"payload.brightness","pt":"msg","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":281,"y":653,"wires":[["24947c10.d04d34"]]},{"id":"4a5b92b8.6f270c","type":"mqtt in","z":"932c9a5e.6c66f8","name":"Status 2_4","topic":"shellies/shellyrgbw2-B082AB/white/3/status","qos":"2","broker":"c46b305c.d08b3","x":111,"y":633,"wires":[["78b2d4fe.3a4afc"]]},{"id":"24947c10.d04d34","type":"ui_slider","z":"932c9a5e.6c66f8","name":"slider S2_4","label":"","tooltip":"","group":"c6364af0.be9fe8","order":30,"width":9,"height":1,"passthru":true,"outs":"all","topic":"shellies/shellyrgbw2-B082AB/white/3/set","min":0,"max":"100","step":"5","x":461,"y":653,"wires":[["52f91279.1a9e3c","f1cc190f.50cc98"]]},{"id":"52f91279.1a9e3c","type":"template","z":"932c9a5e.6c66f8","name":"","field":"payload","fieldType":"msg","format":"handlebars","syntax":"mustache","template":"{\"brightness\" :{{payload}}}","output":"str","x":631,"y":653,"wires":[["9f06ea78.c85a68","1ae828e9.2af187"]]},{"id":"f1cc190f.50cc98","type":"ui_text","z":"932c9a5e.6c66f8","group":"c6364af0.be9fe8","order":31,"width":1,"height":1,"name":"2_4","label":"","format":"{{msg.payload}}","layout":"row-center","x":755,"y":632,"wires":[]},{"id":"9f06ea78.c85a68","type":"mqtt out","z":"932c9a5e.6c66f8","name":"","topic":"","qos":"","retain":"","broker":"c46b305c.d08b3","x":861,"y":653,"wires":[]},{"id":"1ae828e9.2af187","type":"debug","z":"932c9a5e.6c66f8","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":861,"y":693,"wires":[]},{"id":"c46b305c.d08b3","type":"mqtt-broker","z":"","name":"","broker":"10.10.10.1","port":"1883","clientid":"","usetls":false,"compatmode":true,"keepalive":"60","cleansession":true,"birthTopic":"","birthQos":"0","birthPayload":"","closeTopic":"","closePayload":"","willTopic":"","willQos":"0","willPayload":""},{"id":"c6364af0.be9fe8","type":"ui_group","z":"","name":"Normalljus","tab":"7be54798.217718","order":1,"disp":true,"width":14,"collapse":false},{"id":"7be54798.217718","type":"ui_tab","z":"","name":"Lampor","icon":"dashboard","order":2,"disabled":false,"hidden":false}]
Sorry @Ranur all there is in the flow is just a single function node.
Is that what you intended to post?
Thank you Sir! No that was not my intention! The post is edited and the entire flow should be included. Ahh - the challenges of being a Node Red Virgin...
The drawback compared to my original post is that I have changed a bit in the color scheme to match my needs and changed text to Scandinavian - but hey - if I can work out code ANYONE can figure out some Scandinavian terms...
Thanks again for the heads up!
Hi @Ranur - so nice to hear from someone in Scandinavia.
I had many wonderful trips to Copenhagen, Stockholm, Goteborg and Oslo years ago when I was conducting technical training sessions in Scandinavia.