MQTT garage door opener with Node-RED

Super Thanks Dave.

I’m gonna try this today itself in my lab. Don’t know how to say I’d love to learn this just don’t know how to start.

This is incredible stuff. Tons of Thanks.

I've just spotted a 'typo' in the FSM block that handles the relay outputs. A new flow has been uploaded.

1 Like

not sure what was wrong but when you created the first flow there was those indicators and telling me more about it.

in this second flow, i've tried to add some mqtt in/out nodes and switch nodes but there's no indication telling the gate opening or closing. modified i guess ? i'm still gonna try this again

The FSM function node should indicate what state the 'state regsiter' is in (Stopped, Opening or Closing).

You'll need to get an input from the MQTT nodes into the appropriate flow variable. Probably the easiest way is to copy the section, from my first flow, and replace the UI-buttons with your MQTT-In node.

As a quick test you could insert some 'inject' nodes where the UI-buttons are to see if the state machine moves from one state to another.

I'm busy for the next hour, but when I have a break I'll 'cobble' a flow together for you with test inputs from the buttons and limit switches. I also forgot I should have initialised the flow variables in the second flow.

Post the flow you have created so far and I'll take a look at it.

1 Like

sharing the current flow i am certain it's terribly messed up

removed the flow sharing fresh

Dave,

Also, i've been trying to correct some of my dumb errors, modified flow couple times

i think i found my mistake with Broker configuration but there are errors still.

Edited the reply with the flow

now when i press open it opens
when i press close it closes
when i press stop it stops

but the issue i think is in a sscenario if i press open and the gate is opening and i press close it stops which means without stop it's also ok...but again that's not the right way...but mqtt i think i have corrected. please comment Because what I am observing it that stop switch is dictating when open means clockwise or anti-clockwise rotation for the motor

[{"id":"2d687f9e.53cf5","type":"mqtt out","z":"2c33d65b.2afe62","name":"","topic":"cmnd/EastGate/POWER8","qos":"","retain":"","broker":"b650332e.d12ee","x":1230,"y":380,"wires":[]},{"id":"b650332e.d12ee","type":"mqtt-broker","z":"","name":"pi","broker":"192.168.1.9","port":"1883","clientid":"","usetls":false,"compatmode":false,"keepalive":"60","cleansession":true,"birthTopic":"","birthQos":"0","birthPayload":"","closeTopic":"","closeQos":"0","closePayload":"","willTopic":"","willQos":"0","willPayload":""}]

Try this TEST flow that I've quickly constructed.

[{"id":"95cf852c.51e278","type":"function","z":"626334cf.48a844","name":"real_gate_fsm","func":"// It is assumed the two relays are used as follows\n// RLA controls the motor On/Off\n// RLB controls direction of rotation\n\n//  RLA     RLB     Action\n//  ---     ---     ------\n//  off      -      Motor stopped\n//  on      off     Motor turns clockwise >> opening the gate\n//  on      on      Motor turns anti-clockwise >> closing the gate\n\n\nvar fsm_state = flow.get(\"gate_fsm_state_register\") || \"stopped\";\n\nvar closed_limit_switch = flow.get(\"closed_limit_switch\") || \"activated\";\nvar opened_limit_switch = flow.get(\"opened_limit_switch\") || \"activated\";\n\nvar button_pressed = flow.get(\"button_pressed\") || \"stopped\";\n\nswitch (fsm_state)\n   {\n        case \"stopped\":\n        if ( (button_pressed == \"open\") && (opened_limit_switch == \"inactive\") ) {\n            fsm_state = \"opening\";\n            node.status({text:\"State register = Opening\"});\n            node.send( [{payload: \"on\"},{payload: \"off\"}] );       // These outputs operate the relays \n        }\n        else if ( (button_pressed == \"close\") && (closed_limit_switch == \"inactive\") ) {\n            fsm_state = \"closing\";\n            node.status({text:\"State register = Closing\"});\n            node.send( [{payload: \"on\"},{payload: \"on\"}] );       // These outputs operate the relays \n        }\n        break;\n       \n        case \"opening\":\n        if  ( (button_pressed == \"stop\") || (opened_limit_switch == \"activated\") ) {\n            fsm_state = \"stopped\";\n            node.status({text:\"State register = Stopped\"});\n            node.send( [{payload: \"off\"},{payload: \"off\"}] );       // These outputs operate the relays \n            flow.set(\"button_pressed\",\"stop\");\n        }\n        else {  \n            fsm_state = \"opening\";\n            node.status({text:\"State register = Opening\"});\n            node.send( [{payload: \"on\"},{payload: \"off\"}] );       // These outputs operate the relays \n        }\n        break;\n       \n        case \"closing\":\n        if  ( (button_pressed == \"stop\") || (closed_limit_switch == \"activated\") ) {\n            fsm_state = \"stopped\";\n            node.status({text:\"State register = stopped\"});\n            node.send( [{payload: \"off\"},{payload: \"off\"}] );       // These outputs operate the relays \n            flow.set(\"button_pressed\",\"stop\");\n        }\n        else {\n            fsm_state = \"closing\";\n            node.status({text:\"State register = Closing\"});\n            node.send( [{payload: \"on\"},{payload: \"on\"}] );       // These outputs operate the relays \n        }\n        break;\n   }\n\nflow.set(\"gate_fsm_state_register\", fsm_state);\n\n","outputs":2,"noerr":0,"initialize":"","finalize":"","x":660,"y":260,"wires":[["b61287d6.e77c4"],["a995b147.5c41"]],"inputLabels":["Sys_clk"],"outputLabels":["RLA","RLB"]},{"id":"905d686b.774a18","type":"inject","z":"626334cf.48a844","name":"Clock Pulse Generator","props":[{"p":"payload"}],"repeat":"1","crontab":"","once":true,"onceDelay":"1","topic":"","payload":"1","payloadType":"num","x":430,"y":260,"wires":[["95cf852c.51e278"]]},{"id":"20ee1289.69eba6","type":"debug","z":"626334cf.48a844","name":"Relay_A","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":1140,"y":220,"wires":[]},{"id":"9afda566.12f15","type":"debug","z":"626334cf.48a844","name":"Relay_B","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":1140,"y":300,"wires":[]},{"id":"82d93c7d.1e9ec8","type":"comment","z":"626334cf.48a844","name":"ReadMe... Details about the FSM","info":"The FSM has five inputs...\n\nBtn_Open\nBtn_Close\nBtn_STOP\n\nClose_limit_switch\nOpen_limit_switch\n\nThe FSM also has a system clock (Frequency = 1Hz)\nThe frequency can be reduced to 2Hz, 3Hz etc...\n\nThe FSM has two outputs...\n\nRelay_A\nRelay_B\n\nThese two relays switch the motor on/off and \nalso define the direction of rotation (clockwise or anticlock) \n","x":650,"y":320,"wires":[]},{"id":"6aa52c5a.d82724","type":"comment","z":"626334cf.48a844","name":"Inputs come in via MQTT or Telegram","info":"","x":210,"y":300,"wires":[]},{"id":"bac75513.0afcd","type":"comment","z":"626334cf.48a844","name":"Outputs go out via MQTT or Telegram","info":"","x":1070,"y":180,"wires":[]},{"id":"af200e82.88424","type":"inject","z":"626334cf.48a844","name":"Set initial conditions","props":[{"p":"payload"}],"repeat":"","crontab":"","once":true,"onceDelay":0.1,"topic":"","payload":"1","payloadType":"num","x":420,"y":180,"wires":[["f6e03621.490018","d50b2735.98336"]]},{"id":"f6e03621.490018","type":"function","z":"626334cf.48a844","name":"Set initail conditions","func":"flow.set(\"position\",0);\n\nflow.set(\"gate_fsm_state_register\",\"stopped\");\n\nflow.set(\"button_pressed\",\"stop\");\n\n// flow.set(\"simulation_status\",\"stopped\");\n\nmsg.payload = 100;\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":660,"y":180,"wires":[["bd4a43fa.eaaf78"]]},{"id":"48c7477b.c9f498","type":"ui_button","z":"626334cf.48a844","name":"Open","group":"876a6d6.be7489","order":2,"width":"3","height":"1","passthru":false,"label":"Open","tooltip":"","color":"","bgcolor":"{{msg.background}}","icon":"","payload":"btn_open","payloadType":"str","topic":"","x":570,"y":440,"wires":[["5f7447cb.e50b58"]]},{"id":"9be81b21.503b2","type":"ui_button","z":"626334cf.48a844","name":"Close","group":"876a6d6.be7489","order":3,"width":"3","height":"1","passthru":false,"label":"Close","tooltip":"","color":"","bgcolor":"{{msg.background}}","icon":"","payload":"btn_close","payloadType":"str","topic":"","x":570,"y":540,"wires":[["3b7af108.c194f6"]]},{"id":"8cadddb4.3d9c68","type":"ui_button","z":"626334cf.48a844","name":"STOP","group":"876a6d6.be7489","order":5,"width":"3","height":"1","passthru":false,"label":"STOP","tooltip":"","color":"","bgcolor":"{{msg.background}}","icon":"","payload":"btn_stop","payloadType":"str","topic":"","x":570,"y":660,"wires":[["7dbee31d.5c1a14"]]},{"id":"5f7447cb.e50b58","type":"function","z":"626334cf.48a844","name":"","func":"var opened_limit_switch = flow.get(\"opened_limit_switch\") || \"activated\";\n\nif (opened_limit_switch == \"inactive\") {\n    var button_pressed = flow.get(\"button_pressed\") || \"stop\";\n    if (button_pressed == \"close\") {\n        flow.set(\"button_pressed\", \"stop\");\n    }\n    else {\n        flow.set(\"button_pressed\",\"open\");\n    }\n}\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":720,"y":400,"wires":[["bd4a43fa.eaaf78"]]},{"id":"3b7af108.c194f6","type":"function","z":"626334cf.48a844","name":"","func":"var closed_limit_switch = flow.get(\"closed_limit_switch\") || \"activated\";\n\nif (closed_limit_switch == \"inactive\") {\n    var button_pressed = flow.get(\"button_pressed\") || \"stop\";\n    if (button_pressed == \"open\") {\n        flow.set(\"button_pressed\", \"stop\");\n    }\n    else {\n        flow.set(\"button_pressed\",\"close\");\n    }\n}\nreturn msg;\n","outputs":1,"noerr":0,"initialize":"","finalize":"","x":720,"y":520,"wires":[["bd4a43fa.eaaf78"]]},{"id":"7dbee31d.5c1a14","type":"function","z":"626334cf.48a844","name":"","func":"flow.set(\"button_pressed\",\"stop\");\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":720,"y":640,"wires":[["bd4a43fa.eaaf78"]]},{"id":"bd4a43fa.eaaf78","type":"function","z":"626334cf.48a844","name":"","func":"var button_pressed = flow.get(\"button_pressed\") || \"stop\";\n\nif (button_pressed == \"open\") {\n    node.send( [{background:\"red\"},{background:\"#097479\"},{background:\"#097479\"}] );\n}\nelse if (button_pressed == \"close\") {\n    node.send( [{background: \"#097479\"},{background:\"red\"},{background: \"#097479\"}] );\n}\nelse if (button_pressed == \"stop\") {\n    node.send( [{background: \"#097479\"},{background: \"#097479\"},{background:\"red\"}] );\n}\n","outputs":3,"noerr":0,"initialize":"","finalize":"","x":960,"y":440,"wires":[["48c7477b.c9f498"],["9be81b21.503b2"],["8cadddb4.3d9c68"]]},{"id":"f116d7e7.5325a","type":"inject","z":"626334cf.48a844","name":"Simulate Open Button","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"1","payloadType":"num","x":200,"y":340,"wires":[["5f7447cb.e50b58"]]},{"id":"264aee7.8e27692","type":"inject","z":"626334cf.48a844","name":"Simulate Close Button","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"1","payloadType":"num","x":200,"y":400,"wires":[["3b7af108.c194f6"]]},{"id":"69b834dc.8299ec","type":"inject","z":"626334cf.48a844","name":"Simulate STOP Button","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"1","payloadType":"num","x":200,"y":460,"wires":[["7dbee31d.5c1a14"]]},{"id":"b61287d6.e77c4","type":"function","z":"626334cf.48a844","name":"Show RLA state","func":"node.status({text:\"RLA = \"+msg.payload});\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":940,"y":220,"wires":[["20ee1289.69eba6"]]},{"id":"a995b147.5c41","type":"function","z":"626334cf.48a844","name":"Show RLB state","func":"node.status({text:\"RLB = \"+msg.payload});\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":940,"y":300,"wires":[["9afda566.12f15"]]},{"id":"ba72e647.2f75d8","type":"inject","z":"626334cf.48a844","name":"Toggle Open_Limit_switch","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"1","payloadType":"num","x":210,"y":540,"wires":[["3120e8ee.d93778"]]},{"id":"3120e8ee.d93778","type":"function","z":"626334cf.48a844","name":"Toggle opened_limit_switch","func":"var opened_limit_switch = flow.get(\"opened_limit_switch\");\n\nif (opened_limit_switch == \"activated\") {\n    flow.set(\"opened_limit_switch\",\"inactive\");\n    node.status({text:\"opened_limit_switch = inactive\"});\n}\nelse {\n    flow.set(\"opened_limit_switch\",\"activated\");\n    node.status({text:\"opened_limit_switch = activated\"});\n}\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":280,"y":600,"wires":[[]]},{"id":"d50b2735.98336","type":"function","z":"626334cf.48a844","name":"For testing only >> set limit switches","func":"flow.set(\"closed_limit_switch\",\"inactive\");\nflow.set(\"opened_limit_switch\",\"inactive\");\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":710,"y":120,"wires":[[]]},{"id":"3f8e6804.d7232","type":"inject","z":"626334cf.48a844","name":"Toggle Closed_Limit_switch","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"1","payloadType":"num","x":220,"y":660,"wires":[["2b7392ce.8c9c4e"]]},{"id":"2b7392ce.8c9c4e","type":"function","z":"626334cf.48a844","name":"Toggle closed_limit_switch","func":"var closed_limit_switch = flow.get(\"closed_limit_switch\");\n\nif (closed_limit_switch == \"activated\") {\n    flow.set(\"closed_limit_switch\",\"inactive\");\n    node.status({text:\"closed_limit_switch = inactive\"});\n}\nelse {\n    flow.set(\"closed_limit_switch\",\"activated\");\n    node.status({text:\"closed_limit_switch = activated\"});\n}\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":280,"y":720,"wires":[[]]},{"id":"876a6d6.be7489","type":"ui_group","z":"","name":"Simulation control buttons","tab":"58343703.f0abb8","order":3,"disp":true,"width":"12","collapse":false},{"id":"58343703.f0abb8","type":"ui_tab","z":"","name":"Gate simulation","icon":"dashboard","order":41,"disabled":false,"hidden":false}]

I'll take a look at your flow later.

1 Like

i added my mqtt in/out nodes. tested works but few doubts

1-there is one second delay, not sure it there's specific purpose
2-also there is no indication to movement with motor current state or gate position.

[{"id":"3cf3b676.f10bba","type":"mqtt in","z":"7fe3365e.0b5be8","name":"","topic":"stat/EastGate/POWER7","qos":"2","datatype":"auto","broker":"b650332e.d12ee","x":140,"y":140,"wires":[["b80917ac.deac1"]]},{"id":"b650332e.d12ee","type":"mqtt-broker","z":"","name":"pi","broker":"192.168.1.9","port":"1883","clientid":"","usetls":false,"compatmode":false,"keepalive":"60","cleansession":true,"birthTopic":"","birthQos":"0","birthPayload":"","closeTopic":"","closeQos":"0","closePayload":"","willTopic":"","willQos":"0","willPayload":""}]

there's something wrong, when i press open nothing happens
and the moment i press close the flow is triggering multiple instant messages (see below picture) debug section

Also when i press STOP or CLOSE the red color appears on those buttons after i tap the latest one.
but not with OPEN button..it stays as is. motor is not moving because of constant messages sent by function nodes

Can I ask what's coming in on the two MQTT-In nodes?? They shouldn't be connected to the FSM.

pasting below logs from my syslog server
basically it's reporting the status for the mqtt

Sep 24 18:09:51 192.168.1.246 EastGate ESP-MQT: stat/EastGate/POWER7 = ON
Sep 24 18:09:51 192.168.1.246 EastGate ESP-SRC: MQTT
Sep 24 18:09:51 192.168.1.246 EastGate ESP-RSL: Received Topic cmnd/EastGate/POWER8, Data Size 2, Data on
Sep 24 18:09:51 192.168.1.246 EastGate ESP-RSL: Group 0, Index 8, Command POWER, Data on
Sep 24 18:09:51 192.168.1.246 EastGate ESP-MQT: stat/EastGate/RESULT = {"POWER8":"ON"}
EastGate ESP-SRC: MQTT
Sep 24 18:09:54 192.168.1.246 EastGate ESP-RSL: Received Topic cmnd/EastGate/POWER8, Data Size 2, Data on
Sep 24 18:09:54 192.168.1.246 EastGate ESP-RSL: Group 0, Index 8, Command POWER, Data on
Sep 24 18:09:54 192.168.1.246 EastGate ESP-MQT: stat/EastGate/RESULT = {"POWER8":"ON"}
Sep 24 18:09:54 192.168.1.246 EastGate ESP-MQT: stat/EastGate/POWER8 = ON

The constant messages are because the FSM is triggered every 'second'. You could re-code the 'Show RLx state' node so it only sends a MQTT-Out message if there has been a change.

I didn' think you would be connecting it to a motor until you had got the test flow working (debugged).

OK - that looks like the feedback from Tasmota (SonOff) indicating the status of 'POWER'.
Please can you disconnect it from the input of the FSM.

it's nothing major just a car power-window motor on my desk in a plastic tray...i refer as my lab

anyway i've removed the MQTT stat nodes which were connected to the FSM

now i'm trying to find the every-second trigger code out

here's the actual flow

[{"id":"7fe3365e.0b5be8","type":"tab","label":"Flow 2","disabled":false,"info":""},{"id":"b80917ac.deac1","type":"function","z":"7fe3365e.0b5be8","name":"real_gate_fsm","func":"// It is assumed the two relays are used as follows\n// RLA controls the motor On/Off\n// RLB controls direction of rotation\n\n//  RLA     RLB     Action\n//  ---     ---     ------\n//  off      -      Motor stopped\n//  on      off     Motor turns clockwise >> opening the gate\n//  on      on      Motor turns anti-clockwise >> closing the gate\n\n\nvar fsm_state = flow.get(\"gate_fsm_state_register\") || \"stopped\";\n\nvar closed_limit_switch = flow.get(\"closed_limit_switch\") || \"activated\";\nvar opened_limit_switch = flow.get(\"opened_limit_switch\") || \"activated\";\n\nvar button_pressed = flow.get(\"button_pressed\") || \"stopped\";\n\nswitch (fsm_state)\n   {\n        case \"stopped\":\n        if ( (button_pressed == \"open\") && (opened_limit_switch == \"inactive\") ) {\n            fsm_state = \"opening\";\n            node.status({text:\"State register = Opening\"});\n            node.send( [{payload: \"on\"},{payload: \"off\"}] );       // These outputs operate the relays \n        }\n        else if ( (button_pressed == \"close\") && (closed_limit_switch == \"inactive\") ) {\n            fsm_state = \"closing\";\n            node.status({text:\"State register = Closing\"});\n            node.send( [{payload: \"on\"},{payload: \"on\"}] );       // These outputs operate the relays \n        }\n        break;\n       \n        case \"opening\":\n        if  ( (button_pressed == \"stop\") || (opened_limit_switch == \"activated\") ) {\n            fsm_state = \"stopped\";\n            node.status({text:\"State register = Stopped\"});\n            node.send( [{payload: \"off\"},{payload: \"off\"}] );       // These outputs operate the relays \n            flow.set(\"button_pressed\",\"stop\");\n        }\n        else {  \n            fsm_state = \"opening\";\n            node.status({text:\"State register = Opening\"});\n            node.send( [{payload: \"on\"},{payload: \"off\"}] );       // These outputs operate the relays \n        }\n        break;\n       \n        case \"closing\":\n        if  ( (button_pressed == \"stop\") || (closed_limit_switch == \"activated\") ) {\n            fsm_state = \"stopped\";\n            node.status({text:\"State register = stopped\"});\n            node.send( [{payload: \"off\"},{payload: \"off\"}] );       // These outputs operate the relays \n            flow.set(\"button_pressed\",\"stop\");\n        }\n        else {\n            fsm_state = \"closing\";\n            node.status({text:\"State register = Closing\"});\n            node.send( [{payload: \"on\"},{payload: \"on\"}] );       // These outputs operate the relays \n        }\n        break;\n   }\n\nflow.set(\"gate_fsm_state_register\", fsm_state);\n\n","outputs":2,"noerr":0,"x":620,"y":260,"wires":[["c0cad7a4.f6544"],["b636383a.671fd"]],"inputLabels":["Sys_clk"],"outputLabels":["RLA","RLB"]},{"id":"b4fe3d0.eb869c","type":"inject","z":"7fe3365e.0b5be8","name":"Clock Pulse Generator","topic":"","payload":"1","payloadType":"num","repeat":"1","crontab":"","once":true,"onceDelay":"1","x":190,"y":260,"wires":[["b80917ac.deac1"]]},{"id":"5b34c79e.c2ccc","type":"debug","z":"7fe3365e.0b5be8","name":"Relay_A","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","x":1100,"y":220,"wires":[]},{"id":"a8e026a1.68f948","type":"debug","z":"7fe3365e.0b5be8","name":"Relay_B","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","x":1100,"y":300,"wires":[]},{"id":"1a91bdc1.ed1802","type":"comment","z":"7fe3365e.0b5be8","name":"ReadMe... Details about the FSM","info":"The FSM has five inputs...\n\nBtn_Open\nBtn_Close\nBtn_STOP\n\nClose_limit_switch\nOpen_limit_switch\n\nThe FSM also has a system clock (Frequency = 1Hz)\nThe frequency can be reduced to 2Hz, 3Hz etc...\n\nThe FSM has two outputs...\n\nRelay_A\nRelay_B\n\nThese two relays switch the motor on/off and \nalso define the direction of rotation (clockwise or anticlock) \n","x":610,"y":320,"wires":[]},{"id":"24031acb.a44b3e","type":"comment","z":"7fe3365e.0b5be8","name":"Inputs come in via MQTT or Telegram","info":"","x":190,"y":60,"wires":[]},{"id":"69918325.e36d5c","type":"comment","z":"7fe3365e.0b5be8","name":"Outputs go out via MQTT or Telegram","info":"","x":1050,"y":60,"wires":[]},{"id":"cc3366f7.a3fff8","type":"inject","z":"7fe3365e.0b5be8","name":"Set initial conditions","topic":"","payload":"1","payloadType":"num","repeat":"","crontab":"","once":true,"onceDelay":0.1,"x":380,"y":120,"wires":[["3662ef83.fbd66","fe9448.6a604bb8"]]},{"id":"3662ef83.fbd66","type":"function","z":"7fe3365e.0b5be8","name":"Set initail conditions","func":"flow.set(\"position\",0);\n\nflow.set(\"gate_fsm_state_register\",\"stopped\");\n\nflow.set(\"button_pressed\",\"stop\");\n\n// flow.set(\"simulation_status\",\"stopped\");\n\nmsg.payload = 100;\nreturn msg;","outputs":1,"noerr":0,"x":620,"y":120,"wires":[["d671cbc8.57863"]]},{"id":"ffab170f.ba7f","type":"ui_button","z":"7fe3365e.0b5be8","name":"Open","group":"c7057e27.c3c908","order":2,"width":"3","height":"1","passthru":false,"label":"Open","tooltip":"","color":"","bgcolor":"{{msg.background}}","icon":"","payload":"btn_open","payloadType":"str","topic":"","x":530,"y":440,"wires":[["6ca93d7e.2e7214"]]},{"id":"afcf3f4.736f74","type":"ui_button","z":"7fe3365e.0b5be8","name":"Close","group":"c7057e27.c3c908","order":3,"width":"3","height":"1","passthru":false,"label":"Close","tooltip":"","color":"","bgcolor":"{{msg.background}}","icon":"","payload":"btn_close","payloadType":"str","topic":"","x":530,"y":540,"wires":[["2fd354e6.cfab54"]]},{"id":"73142367.7e836c","type":"ui_button","z":"7fe3365e.0b5be8","name":"STOP","group":"c7057e27.c3c908","order":5,"width":"3","height":"1","passthru":false,"label":"STOP","tooltip":"","color":"","bgcolor":"{{msg.background}}","icon":"","payload":"btn_stop","payloadType":"str","topic":"","x":530,"y":660,"wires":[["84b2e78a.f142"]]},{"id":"6ca93d7e.2e7214","type":"function","z":"7fe3365e.0b5be8","name":"","func":"var opened_limit_switch = flow.get(\"opened_limit_switch\") || \"activated\";\n\nif (opened_limit_switch == \"inactive\") {\n    var button_pressed = flow.get(\"button_pressed\") || \"stop\";\n    if (button_pressed == \"close\") {\n        flow.set(\"button_pressed\", \"stop\");\n    }\n    else {\n        flow.set(\"button_pressed\",\"open\");\n    }\n}\nreturn msg;","outputs":1,"noerr":0,"x":680,"y":400,"wires":[["d671cbc8.57863"]]},{"id":"2fd354e6.cfab54","type":"function","z":"7fe3365e.0b5be8","name":"","func":"var closed_limit_switch = flow.get(\"closed_limit_switch\") || \"activated\";\n\nif (closed_limit_switch == \"inactive\") {\n    var button_pressed = flow.get(\"button_pressed\") || \"stop\";\n    if (button_pressed == \"open\") {\n        flow.set(\"button_pressed\", \"stop\");\n    }\n    else {\n        flow.set(\"button_pressed\",\"close\");\n    }\n}\nreturn msg;\n","outputs":1,"noerr":0,"x":680,"y":520,"wires":[["d671cbc8.57863"]]},{"id":"84b2e78a.f142","type":"function","z":"7fe3365e.0b5be8","name":"","func":"flow.set(\"button_pressed\",\"stop\");\nreturn msg;","outputs":1,"noerr":0,"x":680,"y":640,"wires":[["d671cbc8.57863"]]},{"id":"d671cbc8.57863","type":"function","z":"7fe3365e.0b5be8","name":"","func":"var button_pressed = flow.get(\"button_pressed\") || \"stop\";\n\nif (button_pressed == \"open\") {\n    node.send( [{background:\"red\"},{background:\"#097479\"},{background:\"#097479\"}] );\n}\nelse if (button_pressed == \"close\") {\n    node.send( [{background: \"#097479\"},{background:\"red\"},{background: \"#097479\"}] );\n}\nelse if (button_pressed == \"stop\") {\n    node.send( [{background: \"#097479\"},{background: \"#097479\"},{background:\"red\"}] );\n}\n","outputs":3,"noerr":0,"x":920,"y":440,"wires":[["ffab170f.ba7f"],["afcf3f4.736f74"],["73142367.7e836c"]]},{"id":"dca95b27.874dc8","type":"inject","z":"7fe3365e.0b5be8","name":"Simulate Open Button","topic":"","payload":"1","payloadType":"num","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":160,"y":340,"wires":[["6ca93d7e.2e7214"]]},{"id":"21b61de9.71fee2","type":"inject","z":"7fe3365e.0b5be8","name":"Simulate Close Button","topic":"","payload":"1","payloadType":"num","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":160,"y":400,"wires":[["2fd354e6.cfab54"]]},{"id":"e825243d.6a1a58","type":"inject","z":"7fe3365e.0b5be8","name":"Simulate STOP Button","topic":"","payload":"1","payloadType":"num","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":160,"y":460,"wires":[["84b2e78a.f142"]]},{"id":"c0cad7a4.f6544","type":"function","z":"7fe3365e.0b5be8","name":"Show RLA state","func":"node.status({text:\"RLA = \"+msg.payload});\nreturn msg;","outputs":1,"noerr":0,"x":900,"y":220,"wires":[["5b34c79e.c2ccc","5ed274cb.cdcbfc"]]},{"id":"b636383a.671fd","type":"function","z":"7fe3365e.0b5be8","name":"Show RLB state","func":"node.status({text:\"RLB = \"+msg.payload});\nreturn msg;","outputs":1,"noerr":0,"x":900,"y":300,"wires":[["a8e026a1.68f948","f5fa0947.80194"]]},{"id":"a38298c9.10a46","type":"inject","z":"7fe3365e.0b5be8","name":"Toggle Open_Limit_switch","topic":"","payload":"1","payloadType":"num","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":170,"y":540,"wires":[["4ad4319d.f389c"]]},{"id":"4ad4319d.f389c","type":"function","z":"7fe3365e.0b5be8","name":"Toggle opened_limit_switch","func":"var opened_limit_switch = flow.get(\"opened_limit_switch\");\n\nif (opened_limit_switch == \"activated\") {\n    flow.set(\"opened_limit_switch\",\"inactive\");\n    node.status({text:\"opened_limit_switch = inactive\"});\n}\nelse {\n    flow.set(\"opened_limit_switch\",\"activated\");\n    node.status({text:\"opened_limit_switch = activated\"});\n}\nreturn msg;","outputs":1,"noerr":0,"x":240,"y":600,"wires":[[]]},{"id":"fe9448.6a604bb8","type":"function","z":"7fe3365e.0b5be8","name":"For testing only >> set limit switches","func":"flow.set(\"closed_limit_switch\",\"inactive\");\nflow.set(\"opened_limit_switch\",\"inactive\");\n\nreturn msg;","outputs":1,"noerr":0,"x":670,"y":60,"wires":[[]]},{"id":"e58b3ea8.de8ce8","type":"inject","z":"7fe3365e.0b5be8","name":"Toggle Closed_Limit_switch","topic":"","payload":"1","payloadType":"num","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":180,"y":660,"wires":[["f1ad716b.27e7d8"]]},{"id":"f1ad716b.27e7d8","type":"function","z":"7fe3365e.0b5be8","name":"Toggle closed_limit_switch","func":"var closed_limit_switch = flow.get(\"closed_limit_switch\");\n\nif (closed_limit_switch == \"activated\") {\n    flow.set(\"closed_limit_switch\",\"inactive\");\n    node.status({text:\"closed_limit_switch = inactive\"});\n}\nelse {\n    flow.set(\"closed_limit_switch\",\"activated\");\n    node.status({text:\"closed_limit_switch = activated\"});\n}\nreturn msg;","outputs":1,"noerr":0,"x":240,"y":720,"wires":[[]]},{"id":"5ed274cb.cdcbfc","type":"mqtt out","z":"7fe3365e.0b5be8","name":"","topic":"cmnd/EastGate/POWER7","qos":"","retain":"","broker":"b650332e.d12ee","x":1110,"y":160,"wires":[]},{"id":"f5fa0947.80194","type":"mqtt out","z":"7fe3365e.0b5be8","name":"","topic":"cmnd/EastGate/POWER8","qos":"","retain":"","broker":"b650332e.d12ee","x":1110,"y":360,"wires":[]},{"id":"c7057e27.c3c908","type":"ui_group","z":"","name":"Simulation control buttons","tab":"6fb95799.b88e3","order":3,"disp":true,"width":"12","collapse":false},{"id":"b650332e.d12ee","type":"mqtt-broker","z":"","name":"pi","broker":"192.168.1.9","port":"1883","clientid":"","usetls":false,"compatmode":false,"keepalive":"60","cleansession":true,"birthTopic":"","birthQos":"0","birthPayload":"","closeTopic":"","closeQos":"0","closePayload":"","willTopic":"","willQos":"0","willPayload":""},{"id":"6fb95799.b88e3","type":"ui_tab","z":"","name":"Gate simulation","icon":"dashboard","order":41,"disabled":false,"hidden":false}]

Is it possible for you to remove all the automatic triggering via scripts, keeping it purely manual operated.

I’m testing all with limit switches and buttons manually with the motor in a safe plastic tray

It looks like you have a number of garage-door flows in your workspace. I suggest you disable the ones you don't need or you're not working on. You should also change the debug settings (top-right of Node-RED screen) to be 'Current Flow' otherwise you might end-up chasing your tail (as the 'on' messages could be coming from more than one flow).

I've just tried the test-flow on my PC and I get a series of 'on' messages - but they stop once I click the appropriate limit_switch.

Well I'm sure you could have a go at doing that. Don't forget to keep your original flow (e.g. export it to NR library).

Sure will do. I’m sitting at it again and again for few minutes. Have Straight 10 hours to deal with it.

Here are two modified RLx nodes that should only output ONCE when there is a change..

[{"id":"d7c96b7b.839e58","type":"function","z":"c00250c7.18a848","name":"Show RLA state","func":"var RLA_status = flow.get(\"rla_status\") || \"off\";\n\nif (msg.payload != RLA_status) {\n    flow.set(\"rla_status\",msg.payload)\n    node.status({text:\"RLA = \"+msg.payload});\n    return msg;\n}\n","outputs":1,"noerr":0,"initialize":"","finalize":"","x":900,"y":220,"wires":[["744384b8.fefe44"]]},{"id":"3f5fc38f.be4a14","type":"function","z":"c00250c7.18a848","name":"Show RLB state","func":"var RLB_status = flow.get(\"rlb_status\") || \"off\";\n\nif (msg.payload != RLB_status) {\n    flow.set(\"rlb_status\",msg.payload)\n    node.status({text:\"RLB = \"+msg.payload});\n    return msg;\n}\n","outputs":1,"noerr":0,"initialize":"","finalize":"","x":900,"y":300,"wires":[["e361315a.44e0b"]]}]

PS: This will make a great project, once you get it working. Could then post in 'Share Your Projects'.

Please could you edit the log-listing above (reduce its length) as it will put people off reading this thread.