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.