A little bit of a flow that others may like

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}]
1 Like

Sorry @Ranur all there is in the flow is just a single function node.
Is that what you intended to post?

1 Like

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... :wink:
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.