One-button garage - help

I should make an automation with node red + telegram for my garage and I ask for your help.

Basically I have a Garage of which the only control I have of it is a button which, if pressed:

When closed, it opens the garage

When open it closes it

From the state of closing / opening it stops it

(So ​​you must always have in memory the status of the garage to determine how many times to send the command
Ex: if I decide to close it while it opens, it will have to send two commands and so on)

I have a sensor (magnetic switch) that tells me if the garage door is closed (contact closed = garage closed).
I can also think of using a timer to help me send back the second command if the garage door sensor does not hear the closed position (10 seconds to open or close the entire garage).

I use tasmota (Wemos D1 mini) for sensors and control

stat / TESTLED / POWER1 = OFF led off = contact closed = garage closed
stat / TESTLED / POWER2 = ON led lit 500ms (button) time control = button opens / closes / stops garage

thanks for the reply and help

Not clear on the question. Do you want to use node red to open and close door? Fairly straight forward. Monitor position of door? Fairly straight forward. Open remotely? A little more complicated, but doable. Some clarification would help.

Thanks for the reply.
I try to be clearer.
The garage is operated by a single button, which if pressed

  • When closed, opens the garage.
  • When open it closes it.
  • From the state of opening or closing it stops it.
    so:
    if during opening or closing I press the button, it stops.
    the following action on the door closing or opening button (reverses the previous command).

I would like to open and close the garage and monitor the status (at least to know that it is open) and for this purpose I have put a sensor that signals me that it is not closed (stat / TESTLED / POWER1 = OFF). The garage is controlled via the button connected in parallel to Wemos on POWER2 (cmnd / TESTLED / POWER2 = ON) activated temporarily.

It takes 10 seconds to fully open or close (full stroke of the garage). It could be useful to know that if it is stopped in an intermediate position and 10 seconds after the closing command, the sensor does not detect the closed position, I must give a further closing command.

Another step is remote management via telegram.

Thanks for your reply and help.

I think I have a similar garage door control as you - a key-fob that opens or closes the door with the same button. I dropped the key-fob a few months ago and damaged the plastic case. However the electronics still worked. I found the pads on the PCB where the button connects and soldered a couple of wires on them. The wires go to a relay which is operated by an ESP-01 from Node-RED via MQTT. I used Alexa so I could say... "Alexa, open/close garage door" The only thing I had to do was fix a couple of microswitches to the top and bottom positions of the door's travel - so I could detect when it was at the top or bottom. Here's a link to the thread I published about it.

garage_door
I designed a Finite State Machine (FSM) to sort out the 'funny' situations, like... asking the door to open when it is already fully open; or asking it to close when it is fully closed. FSM is also used to try to track what the door is doing. e.g. opening, closing, fully-open, fully-closed.


tms = top microswitch (when closed forces the FSM to go to state S2)
bms = bottom microswitch (when closed forces the FSM to go to state S0)
ogd = Alexa command... "operate garage door"
sgd = Alexa command... "stop garage door"

Here's part of the Dashboard (I used for testing) with an animation of the roller door.
garage_dashboard
My door takes 25-secs to open or close, so I adjusted the timing in the animation accordingly.

This link has a couple of photos of the installation with my PCBs.
https://discourse.nodered.org/t/another-set-of-pcb-designs-for-wemos-d1-mini-and-esp01-s/52770/6

4 Likes

I have also garage doors that are controlled by a single button, which sends a pulse to the opener. And I have a sensor at the top and the bottom, which indicate whether the doors are fully open or closed.

But mine behaves a bit different as described in David's fsm. When the door is busy opening/closing and you then click the button again, one of the following actions occurs:

  • It stops and immediately goes back in the other direction.
  • It stops. Afterwards when you click the button again, it will move in the opposite as before.

If you have this kind of opener, it becomes more difficult to estimate the current state of your doors...

Hi Bart,
I may have confused people a bit by combining what my door does and what my FSM is trying to do.

My door works just like yours.
If the door is closed and I press the button it will start opening.
If I don't touch the button, the door will travel to its fully open position.
If, while it is opening, I click the button it will stop immediately.
If I click the button again - it will reverse its direction of travel and start closing.

The same sequence is performed (direction reversed) if the door is fully open and I click a button.

My FSM tries to mimic the above sequence.
If the door is closed, the FSM is in state S0.
If I click my virtual button, via an MQTT message, the event 'ogd' (operate garage door) is generated.
This will move the state machine to state S1 - which is called "opening" (as that's what the door is doing).
If nothing else happens, then eventually the top microswitch is triggered when the door reaches it fully open position - this forces the FSM to state S2.

If whilst the door is opening, I click my virtual button, via an MQTT message, the event 'sgd' (stop garage door) is generated. This moves the FSM to state S5 - which indicates "opening stopped".
If I was to repeatedly click my virtual button the FSM would move to S3, then S4, then S1, then S5.
This should mimic the same action that happens if the real key-fob was pressed.

The four LEDs (inside the top plastic box) shown on the following photo indicate...
four_LEDs
Green LED: Door is closed and is safe.
Yellow LED (above the green LED): Door is OPENING
Red LED: Door is open and not safe as people could steal my stuff (e.g. rip my plastic box off the wall!!).
Yellow LED (just below the red LED): Door is CLOSING.

To complicate things a little... the FSM looks for events coming from my virtual keyfob (the one with the broken case which is hidden inside the top of the plastic box) or from Alexa commands.
broken_keyfob

PS: Bart, I agree with your last statement... difficult to estimate the current state of the door.

PPS: My system could easily get confused if an Alexa command or a virtual key-fob MQTT message kicked-off the sequence and then someone pressed a button on the real remote control key-fob or pressed the large button on the main garage control box (as my FSM would not know about that manual action).

Although the above works for me, I'm open to hearing of others ways to detect and control an electric door.

Hi, David
I have read your answers very carefully and I ask you if possible to make available your FSM and the flow node red you use to be able to reproduce it and adapt it to my garage. Currently I have mounted a single sensor that signals me if the gararge is completely closed (I would also like to use it for the alarm system).
Thanks for the reply and help.

The link you put is not working.
https://discourse.nodered.org/t/another-set-of-pcb-designs-for-wemos-d1-mini-and-esp01-s/52770/6
Oops! That page doesn’t exist or is private.

Oops - sorry, I forgot that is a private area/page.The last two photos shown above are actually copies of the ones mentioned in the private link.

I've stripped the NR flow down and de-coupled it from my home automation system, so I hope it still 'sort of works' for you.

There should be an init node connected to the input of the FSM to ensure it starts in state S0.
init_node

init_reset

I've also included the animation as this was a bit of fun - no real use but it looks nice on the Dashboard.

Here's the NR flow for the above.

[{"id":"245264d194646520","type":"tab","label":"Garage Door - minimum","disabled":false,"info":"","env":[]},{"id":"a6150293cc61b97e","type":"group","z":"245264d194646520","name":"","style":{"fill":"#e3f3d3","label":true},"nodes":["29b8dabd0ee4dd3f","f2ea5ec81b09adf3","ef9e541e16f87173","1320a76202f9d9f5","1a11a41cd38305a9","7da8cd3152e38825","4766fefe5a6f3a3f","fbef7d799d2b627a","f6fc4c0af5aa9a0d"],"x":54,"y":479,"w":692,"h":302},{"id":"d14994cc7338bd14","type":"mqtt in","z":"245264d194646520","name":"","topic":"garagedoor/sensors/#","qos":"0","datatype":"json","broker":"b80c36f2.044588","nl":false,"rap":true,"rh":0,"inputs":0,"x":160,"y":280,"wires":[["3f46f2e52466b22f","caf57d0535fc9e7d","ae24791fb5773807"]]},{"id":"f8f320894fb1ee54","type":"comment","z":"245264d194646520","name":"Inputs from microswitches","info":"","x":170,"y":240,"wires":[]},{"id":"3f46f2e52466b22f","type":"function","z":"245264d194646520","name":"Detect tms","func":"if ( (msg.payload.sensor == \"top\") && (msg.payload.level == 1) ) {\n    msg.topic=\"tms\";\n    return msg;\n}\nreturn null;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":390,"y":280,"wires":[["5a2ac52663ff9f78","4e662086e45c3691"]]},{"id":"caf57d0535fc9e7d","type":"function","z":"245264d194646520","name":"Detect bms","func":"if ( (msg.payload.sensor == \"bottom\") && (msg.payload.level == 1) ) {\n    msg.topic=\"bms\";\n    return msg;\n}\nreturn null;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":390,"y":340,"wires":[["5a2ac52663ff9f78","2f824be589f71d19"]]},{"id":"5a2ac52663ff9f78","type":"link out","z":"245264d194646520","name":"Detect tms or bms","mode":"link","links":["c752bd8364c93b03"],"x":555,"y":400,"wires":[]},{"id":"ae24791fb5773807","type":"debug","z":"245264d194646520","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":390,"y":220,"wires":[]},{"id":"bfacad9b04486fda","type":"function","z":"245264d194646520","name":"FSM - State Transition Table","func":"// states\n// S0 closed    << default state\n// S1 opening\n// S2 open\n// S3 closing\n// S4 closing_stopped\n// S5 opening_stopped\n\n// inputs\n// tms top_microswitch\n// bms bottom_microswitch\n\n\nif ( (msg.topic == \"reset\") || (msg.topic == \"bms\") ) {\n    flow.set(\"state_register\", \"S0\");\n    flow.set(\"roller_pos\",0);\n    node.send( [{payload: \"S0\"}, null] );\n}\n\nif (msg.topic == \"tms\") {\n    flow.set(\"state_register\", \"S2\");\n    flow.set(\"roller_pos\",100);\n    node.send( [{payload: \"S2\"}, null] );\n}\n\nvar fsm_state = flow.get(\"state_register\") || \"S0\";\n\nswitch (fsm_state) \n   {\n        case \"S0\":\n        if (msg.topic == \"ogd\") {\n            fsm_state = \"S1\";\n            node.send( [{payload: \"S1\"}, {payload:1}] );\n        }\n        break;\n       \n        case \"S1\":\n        if (msg.topic == \"sgd\") {\n            fsm_state = \"S5\";\n            node.send( [{payload: \"S5\"}, {payload:1}] );\n        }\n        break;\n        \n        case \"S2\":\n        if (msg.topic == \"ogd\") {\n             fsm_state = \"S3\";\n            node.send( [{payload: \"S3\"}, {payload:1}] );\n        }\n        break;\n                \n        case \"S3\":\n        if (msg.topic == \"sgd\") {\n             fsm_state = \"S4\";\n            node.send( [{payload: \"S4\"}, {payload:1}] );\n        }\n        break;\n        \n        case \"S4\":\n        if (msg.topic == \"ogd\") {\n             fsm_state = \"S1\";\n            node.send( [{payload: \"S1\"}, {payload:1}] );\n        }\n        break;\n        \n        case \"S5\":\n        if (msg.topic == \"ogd\") {\n            fsm_state = \"S3\";\n            node.send( [{payload: \"S3\"}, {payload:1}] );\n        }\n        break;\n   }\n\nflow.set(\"state_register\", fsm_state);\nnode.status({text:\"State register = \" + fsm_state});\n","outputs":2,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1180,"y":240,"wires":[[],[]]},{"id":"f250df6c08e0a893","type":"alexa-remote-routine","z":"245264d194646520","name":"","account":"65fc5fb4b8d06bdd","routineNode":{"type":"speak","payload":{"type":"regular","text":{"type":"msg","value":"payload"},"devices":{"type":"msg","value":"device_name"}}},"x":1140,"y":420,"wires":[[]]},{"id":"bf6312cfb075291f","type":"mqtt out","z":"245264d194646520","name":"","topic":"garagedoor/command/cmd","qos":"2","retain":"false","respTopic":"","contentType":"","userProps":"","correl":"","expiry":"","broker":"b80c36f2.044588","x":1180,"y":340,"wires":[]},{"id":"c752bd8364c93b03","type":"link in","z":"245264d194646520","name":"FSM_IN","links":["0c414d4b211b399f","ac59d671dd2f857a","e4fbf5c0b4c1dec6","5a2ac52663ff9f78","f2ab3cd4c844fdf0","9ad85296ad697bcc"],"x":995,"y":240,"wires":[["bfacad9b04486fda"]]},{"id":"62359648ac744616","type":"link in","z":"245264d194646520","name":"Alexa_IN","links":["2b448505509f131e"],"x":995,"y":420,"wires":[["f250df6c08e0a893"]]},{"id":"c12523c640553967","type":"link in","z":"245264d194646520","name":"MQTT_IN","links":["880f3dfdd1b2c3c5","93efc9dbbc73a141","c9df95ee3ee40829","7bc49c695ec66d03"],"x":995,"y":340,"wires":[["bf6312cfb075291f"]]},{"id":"2b448505509f131e","type":"link out","z":"245264d194646520","name":"To_Alexa","mode":"link","links":["62359648ac744616"],"x":875,"y":420,"wires":[]},{"id":"f2ab3cd4c844fdf0","type":"link out","z":"245264d194646520","name":"To_FSM","mode":"link","links":["c752bd8364c93b03"],"x":875,"y":240,"wires":[]},{"id":"7bc49c695ec66d03","type":"link out","z":"245264d194646520","name":"To_MQTT","mode":"link","links":["c12523c640553967"],"x":875,"y":340,"wires":[]},{"id":"4e662086e45c3691","type":"function","z":"245264d194646520","name":"top_microswitch detected","func":"var alexa_device_name = flow.get(\"alexa_device_name\") || \"Study\";\n\n\n\n// FSM command, Alexa details, MQTT details\n\nif (msg.topic == \"tms\") {\n    // flow.set(\"roller_pos\",0);\n    node.send([null, {device_name: alexa_device_name, payload: \"Door is fully open\"}, {payload: \"event,ledcode=4\"}]);\n}\n\nreturn null;","outputs":3,"noerr":0,"initialize":"","finalize":"","libs":[],"x":650,"y":280,"wires":[["f2ab3cd4c844fdf0"],["2b448505509f131e"],["7bc49c695ec66d03"]],"outputLabels":["To FSM","To Alexa","To controller via MQTT"]},{"id":"2f824be589f71d19","type":"function","z":"245264d194646520","name":"bottom_microswitch detected","func":"var alexa_device_name = flow.get(\"alexa_device_name\") || \"Study\";\n\n\n\n// FSM command, Alexa details, MQTT details\n\nif (msg.topic == \"bms\") {\n    // flow.set(\"roller_pos\",0);\n    node.send([null, {device_name: alexa_device_name, payload: \"Door is fully closed\"}, {payload: \"event,ledcode=1\"}]);\n}\n\nreturn null;","outputs":3,"noerr":0,"initialize":"","finalize":"","libs":[],"x":660,"y":340,"wires":[["f2ab3cd4c844fdf0"],["2b448505509f131e"],["7bc49c695ec66d03"]],"outputLabels":["To FSM","To Alexa","To controller via MQTT"]},{"id":"29b8dabd0ee4dd3f","type":"ui_template","z":"245264d194646520","g":"a6150293cc61b97e","group":"273505a6.34ddaa","name":"Roller door simulation","order":1,"width":"0","height":"0","format":"<style>\n        :root {\n            --rollade-color: #097479;\n            --rollade-width: 90px;\n        }\n        .rollade__container {\n            width: var(--rollade-width);\n            overflow: hidden;\n            position: relative;\n        }\n        .rollade__fenster {\n            position: relative;\n            overflow: hidden;\n            z-index: 1;\n        }\n        .rollade__fenster path {\n            stroke: var(--rollade-color);\n            fill:none!important;\n            stroke-width:6px;\n        }\n        .rollade__rollade {\n            position: absolute;\n            width: 100%;\n            height: 100%;\n            left: 0px;\n            z-index: 10;\n            transition: all 1s;\n        }\n        .rollade__rollade path.line {\n            stroke: white;\n            fill: none;\n            stroke-width: 1.5px;\n        }\n        .rollade__rollade path.bg {\n            fill: var(--rollade-color);\n        }\n        \n    </style>\n\n    <h3>Door position</h3>\n    <div class=\"rollade__container\">\n        <svg class=\"rollade__fenster\" width=\"100%\" height=\"100%\" viewBox=\"0 0 170 188\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" xml:space=\"preserve\" xmlns:serif=\"http://www.serif.com/\" style=\"fill-rule:evenodd;clip-rule:evenodd;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.5;\">\n            <g transform=\"matrix(1,0,0,1,-15.909,-45.6212)\">\n                <g transform=\"matrix(0.989904,0,0,0.992491,4.03539,0.837446)\">\n                    <path d=\"M180.329,56.389C180.329,51.839 176.626,48.145 172.064,48.145L23.291,48.145C18.729,48.145 15.025,51.839 15.025,56.389L15.025,222.454C15.025,227.004 18.729,230.698 23.291,230.698L172.064,230.698C176.626,230.698 180.329,227.004 180.329,222.454L180.329,56.389Z\" />\n                </g>\n                <g transform=\"matrix(1,0,0,1.38253,3.04599,-37.9811)\">\n                    <path d=\"M97.589,64.432L97.589,191.286\" />\n                </g>\n                <g transform=\"matrix(1,0,0,1,2.84135,56.1777)\">\n                    <path d=\"M18.74,83.189L177.463,84.189\" />\n                </g>\n            </g>\n        </svg>\n        <svg class=\"rollade__rollade\" style=\"top: calc((-1) * {{msg.payload}}%);\" width=\"100%\" height=\"100%\" viewBox=\"0 0 181 190\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" xml:space=\"preserve\" xmlns:serif=\"http://www.serif.com/\" style=\"fill-rule:evenodd;clip-rule:evenodd;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.5;\">\n            <g transform=\"matrix(1.35281,0,0,1.35281,-45.3041,-102.109)\">\n                <path class=\"bg\" d=\"M167.134,82.161C167.134,78.473 164.14,75.479 160.452,75.479L40.171,75.479C36.483,75.479 33.489,78.473 33.489,82.161L33.489,208.93C33.489,212.618 36.483,215.612 40.171,215.612L160.452,215.612C164.14,215.612 167.134,212.618 167.134,208.93L167.134,82.161Z\"/>\n                <g transform=\"matrix(1.69574,0,0,1,18.3547,-9)\">\n                    <path class=\"line\" d=\"M13.383,95.652L84.46,95.652\" />\n                </g>\n                <g transform=\"matrix(1.69574,0,0,1,18.3547,1)\">\n                    <path class=\"line\" d=\"M13.383,95.652L84.46,95.652\" />\n                </g>\n                <g transform=\"matrix(1.69574,0,0,1,18.3547,11)\">\n                    <path class=\"line\" d=\"M13.383,95.652L84.46,95.652\" />\n                </g>\n                <g transform=\"matrix(1.69574,0,0,1,18.3547,21)\">\n                    <path class=\"line\" d=\"M13.383,95.652L84.46,95.652\" />\n                </g>\n                <g transform=\"matrix(1.69574,0,0,1,18.3547,31)\">\n                    <path class=\"line\" d=\"M13.383,95.652L84.46,95.652\" />\n                </g>\n                <g transform=\"matrix(1.69574,0,0,1,18.3547,41)\">\n                    <path class=\"line\" d=\"M13.383,95.652L84.46,95.652\" />\n                </g>\n                <g transform=\"matrix(1.69574,0,0,1,18.3547,51)\">\n                    <path class=\"line\" d=\"M13.383,95.652L84.46,95.652\" />\n                </g>\n                <g transform=\"matrix(1.69574,0,0,1,18.3547,61)\">\n                    <path class=\"line\" d=\"M13.383,95.652L84.46,95.652\" />\n                </g>\n                <g transform=\"matrix(1.69574,0,0,1,18.3547,71)\">\n                    <path class=\"line\" d=\"M13.383,95.652L84.46,95.652\" />\n                </g>\n                <g transform=\"matrix(1.69574,0,0,1,18.3547,81)\">\n                    <path class=\"line\" d=\"M13.383,95.652L84.46,95.652\" />\n                </g>\n                <g transform=\"matrix(1.69574,0,0,1,18.3547,91)\">\n                    <path class=\"line\" d=\"M13.383,95.652L84.46,95.652\" />\n                </g>\n                <g transform=\"matrix(1.69574,0,0,1,18.3547,101)\">\n                    <path class=\"line\" d=\"M13.383,95.652L84.46,95.652\" />\n                </g>\n                <g transform=\"matrix(1.69574,0,0,1,18.3547,111)\">\n                    <path class=\"line\" d=\"M13.383,95.652L84.46,95.652\" />\n                </g>\n            </g>\n        </svg>\n    </div>\n","storeOutMessages":true,"fwdInMessages":true,"resendOnRefresh":false,"templateScope":"local","className":"","x":600,"y":660,"wires":[[]]},{"id":"f2ea5ec81b09adf3","type":"inject","z":"245264d194646520","g":"a6150293cc61b97e","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":true,"onceDelay":0.1,"topic":"","payloadType":"date","x":170,"y":600,"wires":[["ef9e541e16f87173"]]},{"id":"ef9e541e16f87173","type":"trigger","z":"245264d194646520","g":"a6150293cc61b97e","name":"","op1":"1","op2":"0","op1type":"str","op2type":"str","duration":"250","extend":false,"overrideDelay":false,"units":"ms","reset":"","bytopic":"all","topic":"topic","outputs":1,"x":180,"y":660,"wires":[["1320a76202f9d9f5","7da8cd3152e38825"]]},{"id":"1320a76202f9d9f5","type":"debug","z":"245264d194646520","g":"a6150293cc61b97e","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":390,"y":720,"wires":[]},{"id":"1a11a41cd38305a9","type":"link in","z":"245264d194646520","g":"a6150293cc61b97e","name":"","links":["5d29e00c2db9c541"],"x":115,"y":740,"wires":[["ef9e541e16f87173"]]},{"id":"7da8cd3152e38825","type":"function","z":"245264d194646520","g":"a6150293cc61b97e","name":"","func":"var roller_pos = flow.get(\"roller_pos\");\n\nvar state_register = flow.get(\"state_register\") || \"S0\";\n\nif (state_register == \"S0\") {\n    flow.set(\"roller_pos\",0);\n    node.send( [{payload: 0}] );\n}\nelse if (state_register == \"S1\") {\n    if (roller_pos < 100){\n        roller_pos++;\n        flow.set(\"roller_pos\", roller_pos);\n    }\n    node.send( [{payload: roller_pos}] );\n}\n\nelse if (state_register == \"S2\") {\n    flow.set(\"roller_pos\", 100);\n    node.send( [{payload: 100}] );\n    }\n\nelse if (state_register == \"S3\") {\n    if (roller_pos > 1){\n        roller_pos--;\n        flow.set(\"roller_pos\", roller_pos);\n    }\n    node.send( [{payload: roller_pos}] );\n}\n\nreturn null;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":380,"y":660,"wires":[["29b8dabd0ee4dd3f"]]},{"id":"4766fefe5a6f3a3f","type":"comment","z":"245264d194646520","g":"a6150293cc61b97e","name":"Roller door simulation - nothing to do with controlling the door","info":"","x":300,"y":520,"wires":[]},{"id":"fbef7d799d2b627a","type":"comment","z":"245264d194646520","g":"a6150293cc61b97e","name":"Roller door simulation has 100 steps, so each step is 250ms","info":"","x":500,"y":600,"wires":[]},{"id":"f6fc4c0af5aa9a0d","type":"comment","z":"245264d194646520","g":"a6150293cc61b97e","name":"Dave's garage door takes 25-second to open or close","info":"","x":280,"y":560,"wires":[]},{"id":"b80c36f2.044588","type":"mqtt-broker","name":"Broker_156","broker":"192.168.1.156","port":"1883","clientid":"","autoConnect":true,"usetls":false,"protocolVersion":"4","keepalive":"120","cleansession":true,"birthTopic":"","birthQos":"0","birthPayload":"","birthMsg":{},"closeTopic":"","closePayload":"","closeMsg":{},"willTopic":"","willQos":"0","willPayload":"","willMsg":{},"sessionExpiry":""},{"id":"65fc5fb4b8d06bdd","type":"alexa-remote-account","name":"Amazon acct","authMethod":"proxy","proxyOwnIp":"192.168.1.156","proxyPort":"3456","cookieFile":"/home/pi/amazon_alexa.txt","refreshInterval":"3","alexaServiceHost":"alexa.amazon.co.uk","amazonPage":"amazon.co.uk","acceptLanguage":"en-GB","onKeywordInLanguage":"","userAgent":"","useWsMqtt":"on","autoInit":"on"},{"id":"273505a6.34ddaa","type":"ui_group","name":"Garage roller door","tab":"fc0f45ae.d6066","order":1,"disp":true,"width":"6","collapse":false,"className":""},{"id":"fc0f45ae.d6066","type":"ui_tab","name":"Garage roller door","icon":"dashboard","order":45,"disabled":false,"hidden":false}]

I need to explain a few things...

The state of my microswitches (top and bottom) are sensed by a Wemos D1 Mini which sends any changes via MQTT to Node-RED. These changes are fed into the FSM. To operate my garage door I send an MQTT message which is picked-up by an ESP-01S that has a relay to which my broken key-fob is attached. I also send messages to Alexa to inform me what is happening - you might want to delete these.

Hope you can adapt this for your situation. Let me know if you need any extra info.

Hi, David
thanks for the flow you gave me and congratulations on the job.
In order not to make any changes, I hope to adapt the Tasmota configuration to your work by also inserting a sensor to check the status of the fully open garage.
If you use tasmota for WEMOS you have used
% topic% /% prefix% or% prefix% /% topic%?
the full topic
garagedoor / sensors / level / stat .... is that correct?
I could not change the topic name "POWER1" to "top" or "bottom" and the payload "OFF" "ON" to "0" or "1".
Can it be done with a rule?

Thanks for your help

First of all - there are two camps of people on the forum.
Some use Tasmota for their remote slaves/sensors, other (like me) use ESPeasy.
So I haven't got an answer to your question about configuring Tasmota to send a specific topic.
There are many 'Tasmota' people on the forum that will jump-in and advise you (I'm sure).

My set-up (if you are interested) is... a Wemos D1 Mini flashed with ESPeasy with these connections...
GPIO-15 (D8) Output drives Red LED on my PCB
GPIO-13 (D7) Output drives Yellow LED on my PCB
GPIO-12 (D6) Output drives Yellow LED on my PCB
GPIO-14 (D5) Output drives Green LED on my PCB

GPIO-5 (D1) Normal switch, inverse logic signal name/level is top#level (this is top microswitch)
GPIO-4 (D1) Normal switch, inverse logic signal name/level is bottom#level (this is bottom microswitch)

This is my rule-set...

On sendSensorPosition Do
   publish,garagedoor/sensors,'{"level":[top#level],"sensor":"top"}'
   publish,garagedoor/sensors,'{"level":[bottom#level],"sensor":"bottom"}'
   // event,publishReading
EndOn

On publishReading Do
   publish,garagedoor/sensors,'{"level":[top#level],"sensor":"top"}'
   publish,garagedoor/sensors,'{"level":[bottom#level],"sensor":"bottom"}'
endOn

On top#level Do
   publish,garagedoor/sensors,'{"level":[top#level],"sensor":"top"}'
   // event,publishReading
EndOn

On bottom#level Do
   publish,garagedoor/sensors,'{"level":[bottom#level],"sensor":"bottom"}'
 // event,publishReading
EndOn

The Wemos is subscibed to... garagedoor/# and will react to the first command 'sendSensorPosition' so I can ask for the state of the microswitches. If either microswitch makes a change the appropriate part of the rule-set is triggered and the value published to Node-RED.

Other part of my set-up is an ESP-01S that has a relay (on GPIO-3, RX) connected to my virtual key-fob.

On System#Boot Do
   gpio,3,0
EndOn

On ToggleRelay Do
   gpio,3,1
   timerSet,1,2
EndOn

On Rules#Timer=1 Do
   gpio,3,0
EndOn

To simulate a key-press I simply send an MQTT command ('ToggleRelay') to the ESP-01S. As you can see in the rule-set, this operates for 2-secs [which is the same time I would need to press the real keyfob to activate the garage door].

Hope this makes sense and will be useful to you?

Just to further confuse things. I used a nodemcu tied to a rotary encoder to measure door position. Very reliable, very accurate.

1 Like

Hi, David
You were very clear.
I considered Tasmota to test some time ago with ESP01, suggested by a magazine article.
I see many now using ESPeasy. I begin to evaluate the transition, it seems easier to manage.
Do you have the schematic / pcb of the wemos adapter - Esp01?
Thanks again for all the information and advice.

Hi Gerry.
Could you share your work?
Thank you

Here's a copy of the schematic for my general purpose board (I used for my voice-operated garage door).
Schematic_General purpose board_2022-08-15.pdf (85.6 KB)
Here's a 3D view of the PCB.


Note: The two, 2-pin male headers J1 and J2 are used to select the supply voltage for the HK4100F relay as it comes in 3V and 5V versions. You can fit a jumper to match the relay that has been purchased.

The other thing to note is, U3 is a micro USB power adapter/connector I bought from China.


Let me know if this meets your requirements as I could then create the Gerber file.

Won't be near the house for seven weeks, on an extended trip so I can't access computer. But a description is I made the encoder using robot gears tied to door opener. Made the nodemcu sketch and monitored count for several open close cycles. As I remember it was about 360 counts up or down. Gives about .25 inch resolution although mechanical slop in mechanism made that a lot worse. I fed the count into a function node that did the math and displayed door open or close as a percent.

Hi, David
I thought of making an electronic assembly of a solder board, but if you have the Gerber file available I can make a PCB.
Thank you

Hi Gerry
it is interesting to know how you made the mechanical coupling and what components you used, perhaps with a photo of the assembly.
Congratulations on your accomplishment.

Sorry for the delay - been very busy this week.

Can I just recap on what sensors/controls you have in your system as I think my solution might be an "overkill". As I remember it, you just had a key-fob to operate the door and you were going to fit microswitches to detect when the door was fully-open, fully-closed. Is that correct?

I have the remote control available (or a button inside the garage that duplicates the function of the remote control). I have mounted an additional sensor that signals if the garage is closed,
If necessary, I can mount an additional sensor that signals me if the garage is completely open.