Title Edit: Dashboard Switch Node bug found

I am having an issue with a dashboard switch node that I have been unable to resolve. I have successfully used the disable/enable message on the input of a switch to prevent a toggle if it occurs within a certain amount of time after the last change. In this particular case I am turning a video projector on and off and need to allow warm up and cooldown times before making another change, but that's really besides the point.

Now when I set enable to False, it also sets the switch to Off. This means I cannot send an Off command, because after the switch is enabled again it sends the On command again the next time it is toggled.

I added a debug node after the change node and thought that was the issue because I am getting a msg.payload of "undefined" when I believe I should not have been getting any msg.payload at all. I even added an explicit msg.payload Delete and still get and undefined msg.payload passed through.

However, I made another switch and injected the msg.enabled True and False and although the undefined payload is gone the dashboard switch behavior is the same.

Here is a simple example. Is this a bug or am I just missing something obvious?

I am running Buster on an RPi3B

[info] Node-RED version: v0.20.7
[info] Node.js version: v10.16.0
[info] Linux 4.19.58-v7+ arm LE

[{"id":"b7ce1316.fba4b8","type":"debug","z":"94a49731.2d9ba8","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","x":810,"y":280,"wires":[]},{"id":"40f5c1cc.3e6c28","type":"ui_switch","z":"94a49731.2d9ba8","name":"","label":"switch","tooltip":"","group":"6ad83db.c98ed44","order":20,"width":0,"height":0,"passthru":false,"decouple":"false","topic":"","style":"","onvalue":"projSystemOn","onvalueType":"str","onicon":"","oncolor":"","offvalue":"projSystemOff","offvalueType":"str","officon":"","offcolor":"","x":390,"y":240,"wires":[["7c2b7503.fd7d7c"]]},{"id":"8026106.7e5f17","type":"change","z":"94a49731.2d9ba8","name":"","rules":[{"t":"move","p":"payload","pt":"msg","to":"enabled","tot":"msg"},{"t":"delete","p":"payload","pt":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":460,"y":300,"wires":[["fd0cbe4d.822658","b7ce1316.fba4b8","40f5c1cc.3e6c28"]]},{"id":"fd0cbe4d.822658","type":"debug","z":"94a49731.2d9ba8","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"enabled","targetType":"msg","x":810,"y":320,"wires":[]},{"id":"7c2b7503.fd7d7c","type":"trigger","z":"94a49731.2d9ba8","op1":"false","op2":"true","op1type":"bool","op2type":"bool","duration":"5","extend":false,"units":"s","reset":"","bytopic":"all","name":"","x":260,"y":300,"wires":[["8026106.7e5f17"]]},{"id":"bc19148f.0e864","type":"debug","z":"94a49731.2d9ba8","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","x":810,"y":400,"wires":[]},{"id":"dc1ded8b.a26c4","type":"ui_switch","z":"94a49731.2d9ba8","name":"","label":"switch","tooltip":"","group":"6ad83db.c98ed44","order":20,"width":0,"height":0,"passthru":false,"decouple":"false","topic":"","style":"","onvalue":"projSystemOn","onvalueType":"str","onicon":"","oncolor":"","offvalue":"projSystemOff","offvalueType":"str","officon":"","offcolor":"","x":590,"y":400,"wires":[["bc19148f.0e864"]]},{"id":"44aeed9d.acc3bc","type":"debug","z":"94a49731.2d9ba8","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"enabled","targetType":"msg","x":610,"y":460,"wires":[]},{"id":"a078746b.602588","type":"inject","z":"94a49731.2d9ba8","name":"Enable Switch","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":150,"y":380,"wires":[["167e0e37.ac4282"]]},{"id":"c6566488.58f848","type":"inject","z":"94a49731.2d9ba8","name":"Disable Switch","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":160,"y":420,"wires":[["4742104d.9c9548"]]},{"id":"167e0e37.ac4282","type":"change","z":"94a49731.2d9ba8","name":"Enabled is True","rules":[{"t":"set","p":"enabled","pt":"msg","to":"true","tot":"bool"}],"action":"","property":"","from":"","to":"","reg":false,"x":400,"y":380,"wires":[["dc1ded8b.a26c4","44aeed9d.acc3bc"]]},{"id":"4742104d.9c9548","type":"change","z":"94a49731.2d9ba8","name":"Enabled is False","rules":[{"t":"set","p":"enabled","pt":"msg","to":"false","tot":"bool"}],"action":"","property":"","from":"","to":"","reg":false,"x":390,"y":420,"wires":[["dc1ded8b.a26c4","44aeed9d.acc3bc"]]},{"id":"6ad83db.c98ed44","type":"ui_group","z":"","name":"Projector","tab":"fb2aadc5.d87d1","disp":true,"width":"6","collapse":false},{"id":"fb2aadc5.d87d1","type":"ui_tab","z":"","name":"Home AV","icon":"dashboard"}]

That's neat.

Couple of things:

1 - add a delay just after the switch node. 1 second should suffice.
There may not be enough time for the message to get through. (Yeah, ok. It probably will, but doing this will help you see the next problem)
2 - Where is the message you are sending from the switch node going?
If you are wanting to send the payload projSystemOn, you kinda shot yourself in the foot.
That gets destroyed by the trigger node which turns it into true/false.
Take the output from the switch straight to the next part you want to control

That will really help with the problem you have.

Remember:
The payload you make in the switch is overwritten (destroyed) by the trigger. So you will never see it appear in the debug node.

Good luck.

Oh, just to be clear: There is still a bug.

Here is the flow as I describe it above: with an added text node so you can see the output to the next stage.

[{"id":"bcbbc7e3.e0d938","type":"debug","z":"b86527b7.8c79f","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","x":610,"y":1830,"wires":[]},{"id":"3e3f4a9a.d0ecd6","type":"ui_switch","z":"b86527b7.8c79f","name":"","label":"switch","tooltip":"","group":"445b24cf.0744ec","order":20,"width":0,"height":0,"passthru":false,"decouple":"false","topic":"","style":"","onvalue":"projSystemOn","onvalueType":"str","onicon":"","oncolor":"","offvalue":"projSystemOff","offvalueType":"str","officon":"","offcolor":"","x":200,"y":1830,"wires":[["fb58f065.5e69f8","e1a17624.d7c518"]]},{"id":"f26e224e.9c45d8","type":"change","z":"b86527b7.8c79f","name":"","rules":[{"t":"move","p":"payload","pt":"msg","to":"enabled","tot":"msg"},{"t":"delete","p":"payload","pt":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":390,"y":1910,"wires":[["b2804b4.e12e3b8","3e3f4a9a.d0ecd6"]]},{"id":"b2804b4.e12e3b8","type":"debug","z":"b86527b7.8c79f","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"enabled","targetType":"msg","x":610,"y":1910,"wires":[]},{"id":"2513983.4f7b0e8","type":"trigger","z":"b86527b7.8c79f","op1":"false","op2":"true","op1type":"bool","op2type":"bool","duration":"5","extend":false,"units":"s","reset":"","bytopic":"all","name":"","x":190,"y":1910,"wires":[["f26e224e.9c45d8"]]},{"id":"fb58f065.5e69f8","type":"delay","z":"b86527b7.8c79f","name":"","pauseType":"delay","timeout":"2","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"x":410,"y":1830,"wires":[["2513983.4f7b0e8","bcbbc7e3.e0d938"]]},{"id":"e1a17624.d7c518","type":"ui_text","z":"b86527b7.8c79f","group":"445b24cf.0744ec","order":1,"width":0,"height":0,"name":"","label":"text","format":"{{msg.payload}}","layout":"row-spread","x":400,"y":1790,"wires":[]},{"id":"445b24cf.0744ec","type":"ui_group","z":"","name":"Projector","tab":"5c6c34bf.6a57fc","disp":true,"width":"6","collapse":false},{"id":"5c6c34bf.6a57fc","type":"ui_tab","z":"","name":"Home AV","icon":"dashboard"}]

I'm not that good with the switch node. I can see what you are trying to do with the enable part, but because it is disabled there is a problem with where/how the switch is set after the enable command is received.

I am suspicious you are going to need a function node in here somewhere, or a change node to store a flow/context/global variable.

Thanks for the reply. I guess I got too carried away stripping out what I thought was unnecessary to show the issue.

In the actual flow I am trying to build the switch node also outputs to another node that takes the string and does a number of things with it, lowering a projection screen, setting a default volume, turning on the projector, and making a default video route. The trigger node has a delay of about 3 minutes on it.

When I select the switch on the dashboard the projSystemOn payload gets where it's supposed to go and does what it's supposed to do. Unfortunately, the switch immediately disables itself and stays in the Off position, so after the trigger node re-enables the switch, selecting it again sends projSystemOn again, which is useless of course because I need to send projSystemOff to shut the system down again.

I have several outlets that I used this exact same logic with to prevent powering a device off again before it booted up, and that worked fine. However, I replaced those with function nodes because I also wanted to do some other state tracking and a function node was cleaner and neater than a series of default nodes so I cannot directly compare any more.

I also have used this process with other Pi units where I am toggling the file system between read-only and read-write. Those units are working fine. I was able to remote into one of them and noticed that the switch is sending Boolean values for On and Off.

I did some further experimentation and found that if the switch node sends a Boolean or Buffer this logic works. If it sends a number or string it fails as seen here.

I believe this must be a bug unless there's a good reason for this behavior I am not aware of.

For now I just added a change node to convert the Boolean values to the strings I need. Here is a flow showing the working and not working flows. Based on what I find in the docs there is no reason the simpler flow should have this issue. Both switch nodes are identical except for the payload type.

[{"id":"40f5c1cc.3e6c28","type":"ui_switch","z":"94a49731.2d9ba8","name":"","label":"switch","tooltip":"","group":"6ad83db.c98ed44","order":2,"width":0,"height":0,"passthru":false,"decouple":"false","topic":"","style":"","onvalue":"true","onvalueType":"bool","onicon":"","oncolor":"","offvalue":"false","offvalueType":"bool","officon":"","offcolor":"","x":350,"y":100,"wires":[["7c2b7503.fd7d7c","356c7431.bfa6c4"]]},{"id":"8026106.7e5f17","type":"change","z":"94a49731.2d9ba8","name":"","rules":[{"t":"move","p":"payload","pt":"msg","to":"enabled","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":430,"y":160,"wires":[["40f5c1cc.3e6c28"]]},{"id":"7c2b7503.fd7d7c","type":"trigger","z":"94a49731.2d9ba8","op1":"false","op2":"true","op1type":"bool","op2type":"bool","duration":"5","extend":false,"units":"s","reset":"","bytopic":"all","name":"","x":220,"y":160,"wires":[["8026106.7e5f17"]]},{"id":"356c7431.bfa6c4","type":"change","z":"94a49731.2d9ba8","name":"","rules":[{"t":"change","p":"payload","pt":"msg","from":"true","fromt":"bool","to":"projSystemOn","tot":"str"},{"t":"change","p":"payload","pt":"msg","from":"false","fromt":"bool","to":"projSystemOff","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":520,"y":100,"wires":[["162b6a82.cb2905","a3e13e82.26d09"]]},{"id":"5415eb12.85ede4","type":"ui_switch","z":"94a49731.2d9ba8","name":"","label":"switch","tooltip":"","group":"6ad83db.c98ed44","order":4,"width":0,"height":0,"passthru":false,"decouple":"false","topic":"","style":"","onvalue":"true","onvalueType":"str","onicon":"","oncolor":"","offvalue":"false","offvalueType":"str","officon":"","offcolor":"","x":350,"y":200,"wires":[["bc69bb13.010eb","228535db.95853a"]]},{"id":"63abedb0.155434","type":"change","z":"94a49731.2d9ba8","name":"","rules":[{"t":"move","p":"payload","pt":"msg","to":"enabled","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":430,"y":260,"wires":[["5415eb12.85ede4"]]},{"id":"bc69bb13.010eb","type":"trigger","z":"94a49731.2d9ba8","op1":"false","op2":"true","op1type":"bool","op2type":"bool","duration":"5","extend":false,"units":"s","reset":"","bytopic":"all","name":"","x":220,"y":260,"wires":[["63abedb0.155434"]]},{"id":"228535db.95853a","type":"debug","z":"94a49731.2d9ba8","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":600,"y":200,"wires":[]},{"id":"a3e13e82.26d09","type":"debug","z":"94a49731.2d9ba8","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":730,"y":100,"wires":[]},{"id":"6ad83db.c98ed44","type":"ui_group","z":"","name":"Projector","tab":"fb2aadc5.d87d1","disp":true,"width":"6","collapse":false},{"id":"fb2aadc5.d87d1","type":"ui_tab","z":"","name":"Home AV","icon":"dashboard"}]

Please export your flow again and use the following format:

```
your code
```

I think this shows the problem @kocherjj mentions about the switch node.

[{"id":"af765dbd.9f3518","type":"ui_switch","z":"b86527b7.8c79f","name":"","label":"A","tooltip":"","group":"445b24cf.0744ec","order":20,"width":0,"height":0,"passthru":false,"decouple":"false","topic":"","style":"","onvalue":"projSystemOn","onvalueType":"str","onicon":"","oncolor":"","offvalue":"projSystemOff","offvalueType":"str","officon":"","offcolor":"","x":530,"y":2110,"wires":[["297cd4cb.a0a864"]]},{"id":"297cd4cb.a0a864","type":"ui_text","z":"b86527b7.8c79f","group":"445b24cf.0744ec","order":1,"width":0,"height":0,"name":"","label":"text","format":"{{msg.payload}}","layout":"row-spread","x":680,"y":2110,"wires":[]},{"id":"57f8bdf1.315304","type":"ui_button","z":"b86527b7.8c79f","name":"EN","group":"445b24cf.0744ec","order":6,"width":0,"height":0,"passthru":false,"label":"EN","tooltip":"","color":"","bgcolor":"","icon":"","payload":"true","payloadType":"bool","topic":"","x":160,"y":2070,"wires":[["a1c4aaed.4f20c8"]]},{"id":"a1c4aaed.4f20c8","type":"change","z":"b86527b7.8c79f","name":"","rules":[{"t":"move","p":"payload","pt":"msg","to":"enabled","tot":"msg"},{"t":"delete","p":"payload","pt":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":330,"y":2110,"wires":[["af765dbd.9f3518"]]},{"id":"10b06713.c7bee9","type":"ui_button","z":"b86527b7.8c79f","name":"DIS","group":"445b24cf.0744ec","order":6,"width":0,"height":0,"passthru":false,"label":"DIS","tooltip":"","color":"","bgcolor":"","icon":"","payload":"false","payloadType":"bool","topic":"","x":166,"y":2149,"wires":[["a1c4aaed.4f20c8"]]},{"id":"445b24cf.0744ec","type":"ui_group","z":"","name":"Projector","tab":"5c6c34bf.6a57fc","disp":true,"width":"6","collapse":false},{"id":"5c6c34bf.6a57fc","type":"ui_tab","z":"","name":"Home AV","icon":"dashboard"}]

You press the EN button and toggle the switch. Press the DIS button.

If you move the switch from off to on, when you press the DIS button, the switch is put to the OFF position. Ok let's let that slip. But when you EN the switch again, it stays in the OFF position.

Sorry I haven't looked at your code, but this is something I think may do what you want.

Of course I have "over simplified" it, but I want to only show you an alternative.

I've made it all on the GUI side so you can see things rather than having to switch from EDIT to GUI screens.

(P.S. Yeah, looked at it. Am not getting it.)
Suggestion: Like I did, add a text node to show the output on the same screen so I don't have to keep switching screens to see the debug output.

Good luck with it though. Hang in there.

[{"id":"eff26284.7961","type":"ui_button","z":"b86527b7.8c79f","name":"","group":"445b24cf.0744ec","order":8,"width":0,"height":0,"passthru":false,"label":"New button","tooltip":"","color":"","bgcolor":"","icon":"","payload":"true","payloadType":"bool","topic":"","x":250,"y":2490,"wires":[["777ac8ac.78b13","ceab6d3.a8f059","895ea950.79588"]]},{"id":"280a7349.be370c","type":"ui_text","z":"b86527b7.8c79f","group":"445b24cf.0744ec","order":1,"width":0,"height":0,"name":"","label":"New text","format":"{{msg.payload}}","layout":"row-spread","x":570,"y":2450,"wires":[]},{"id":"ceab6d3.a8f059","type":"trigger","z":"b86527b7.8c79f","op1":"false","op2":"true","op1type":"bool","op2type":"bool","duration":"5","extend":false,"units":"s","reset":"","bytopic":"all","name":"","x":240,"y":2530,"wires":[["30497141.552aee"]]},{"id":"30497141.552aee","type":"change","z":"b86527b7.8c79f","name":"","rules":[{"t":"move","p":"payload","pt":"msg","to":"enabled","tot":"msg"},{"t":"delete","p":"payload","pt":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":440,"y":2530,"wires":[["eff26284.7961"]]},{"id":"895ea950.79588","type":"debug","z":"b86527b7.8c79f","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","x":430,"y":2490,"wires":[]},{"id":"777ac8ac.78b13","type":"function","z":"b86527b7.8c79f","name":"","func":"var state = context.get(\"STATE\")||0;\nif (msg.payload === true)\n{\n    state = (state + 1) % 2;\n    context.set(\"STATE\",state);\n}\nif (state === 0)\n{\n    //\n    msg.payload = \"projSystemOn\";\n} else\n{\n    //\n    msg.payload = \"projSystemOff\";\n}\nreturn msg;","outputs":1,"noerr":0,"x":410,"y":2450,"wires":[["280a7349.be370c"]]},{"id":"445b24cf.0744ec","type":"ui_group","z":"","name":"Projector","tab":"5c6c34bf.6a57fc","disp":true,"width":"6","collapse":false},{"id":"5c6c34bf.6a57fc","type":"ui_tab","z":"","name":"Home AV","icon":"dashboard"}]

Hi @kocherjj
your concept should work - I'll have a look later. Thanks

Interesting bug you have found there :slight_smile:

I have pushed a fix to the master branch on github - not yet on npm

Thanks for looking, and I'm glad to know I wasn't missing something obvious. Using the Change Node is working for me, I just like to keep things as minimal as possible.

I appreciate all the effort you put into this program and am still impressed and amazed that this kind of thing is available for free. My background is in Crestron control systems and I'm just beginning to explore the possibilities of open source control!