Garage Door Opener
Updated March 12, 2022 by ShaquuUUID: 00000041-0000-1000-8000-0026BB765291
Characteristics
Name | Required |
---|---|
LockCurrentState | ✕ |
LockTargetState | ✕ |
Name | ✕ |
CurrentDoorState | ✓ |
TargetDoorState | ✓ |
ObstructionDetected | ✓ |
Synopsis
Garage door is dangerous because it can lock you inside or damage your car. That’s why it is a good idea to have at least 3 sensors:
- Door fully opened
- Door fully closed
- Obstruction sensor
Motion sensor or button inside to open it manually also is optional.
Examples
Garage door with initial state and simple open/close logics.
[{"id":"5534366a.7ef91","type":"homekit-service","z":"75848247.7201a4","isParent":true,"bridge":"1f4da0a9.4023c7","parentService":"","name":"Garage Door","serviceName":"GarageDoorOpener","topic":"","filter":false,"manufacturer":"ptath","model":"Default Model","serialNo":"0001","characteristicProperties":"{\n \"CurrentDoorState\":1\n}","x":518,"y":256,"wires":[["14d4bf27.4db229","745cd5b8.149d1c","d12ee2b5.67db6"]]},{"id":"14d4bf27.4db229","type":"debug","z":"75848247.7201a4","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":894,"y":256,"wires":[]},{"id":"f0a87280.f66ea","type":"inject","z":"75848247.7201a4","name":"TargetDoorState 0 To Open","topic":"","payload":"{\"TargetDoorState\": 0}","payloadType":"json","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":142,"y":40,"wires":[["5534366a.7ef91"]]},{"id":"2f0bb109.cee4ee","type":"inject","z":"75848247.7201a4","name":"TargetDoorState 1 To Close","topic":"","payload":"{\"TargetDoorState\":1}","payloadType":"json","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":152,"y":80,"wires":[["5534366a.7ef91"]]},{"id":"26ef612d.04cd86","type":"inject","z":"75848247.7201a4","name":"CurrentDoorState 0 opened","topic":"","payload":"{\"CurrentDoorState\":0}","payloadType":"json","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":152,"y":168,"wires":[["5534366a.7ef91"]]},{"id":"1dcedc5c.cc1004","type":"inject","z":"75848247.7201a4","name":"CurrentDoorState 1 closed","topic":"","payload":"{\"CurrentDoorState\":1}","payloadType":"json","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":142,"y":208,"wires":[["5534366a.7ef91"]]},{"id":"75402de5.d52d84","type":"inject","z":"75848247.7201a4","name":"ObstructionDetected 1 true","topic":"","payload":"{\"ObstructionDetected\":1}","payloadType":"json","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":152,"y":400,"wires":[["5534366a.7ef91"]]},{"id":"70fdf078.8d2b48","type":"inject","z":"75848247.7201a4","name":"ObstructionDetected 0 false","topic":"","payload":"{\"ObstructionDetected\":0}","payloadType":"json","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":152,"y":440,"wires":[["5534366a.7ef91"]]},{"id":"ea0e73a2.6eba48","type":"inject","z":"75848247.7201a4","name":"CurrentDoorState 4 stopped in the middle","topic":"","payload":"{\"CurrentDoorState\":4}","payloadType":"json","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":192,"y":328,"wires":[["5534366a.7ef91"]]},{"id":"d12ee2b5.67db6","type":"function","z":"75848247.7201a4","name":"Save STATE","func":"var GD1 = global.get(\"GD1\");\n\nif (msg.payload.TargetDoorState !== undefined) {\n global.set(\"GD1.TargetState\", msg.payload.TargetDoorState);\n // 0 - want to open, 1 — want to close\n}\n\n//node.warn(GD1);\nreturn msg;","outputs":1,"noerr":0,"x":718,"y":296,"wires":[[]]},{"id":"d9b75532.233b28","type":"function","z":"75848247.7201a4","name":"Set GD1 — initial state (from sensors)","func":"var GD1 = {\n SensorState: 1, // set real init state according to sensor\n RunTime: 20, // time in seconds to fully open/close door (not implemented here)\n ObstructionDetected: false // set real init state according to sensor\n}\n\nglobal.set(\"GD1\", GD1);\n\n//node.warn(GD1);\n\nreturn [GD1];","outputs":1,"noerr":0,"x":686,"y":40,"wires":[[]]},{"id":"a45db63a.eb474","type":"inject","z":"75848247.7201a4","name":"Set initial state","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":true,"onceDelay":0.1,"x":432,"y":40,"wires":[["d9b75532.233b28"]]},{"id":"745cd5b8.149d1c","type":"function","z":"75848247.7201a4","name":"Main Logic","func":"var GD1 = global.get(\"GD1\");\n\nif ((msg.payload.TargetDoorState === 1) && \n (GD1.ObstructionDetected === false) && \n (GD1.CurrentState === 0)) {\n // real command to close here\n return {\"payload\": \"CLOSE COMMAND\"}\n}\n\nif (msg.payload.TargetDoorState === 0) {\n // real command to open here\n return {\"payload\": \"OPEN COMMAND\"}\n}","outputs":1,"noerr":0,"x":718,"y":336,"wires":[["14d4bf27.4db229"]]},{"id":"c53b5c5a.49826","type":"function","z":"75848247.7201a4","name":"Set initial HomeKit state","func":"var GD1 = global.get(\"GD1\");\n\nif (GD1.SensorState === 1) {\n var newMsg = {\"payload\": {\n \"TargetDoorState\":1,\n \"CurrentDoorState\":1 }\n }\n //node.warn(newMsg);\n return newMsg\n}\n\nif (GD1.SensorState === 0) {\n var newMsg = {\"payload\": {\n \"TargetDoorState\":0,\n \"CurrentDoorState\":0 }\n }\n //node.warn(newMsg);\n return newMsg\n}","outputs":1,"noerr":0,"x":726,"y":80,"wires":[["5534366a.7ef91"]]},{"id":"38b37223.7302b6","type":"inject","z":"75848247.7201a4","name":"Send initial state to HomeKit","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":true,"onceDelay":"0.5","x":472,"y":80,"wires":[["c53b5c5a.49826"]]},{"id":"35daf933.b31bae","type":"inject","z":"75848247.7201a4","name":"CurrentDoorState 2 opening","topic":"","payload":"{\"CurrentDoorState\":2}","payloadType":"json","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":152,"y":248,"wires":[[]]},{"id":"ab4940dd.c6e4f","type":"inject","z":"75848247.7201a4","name":"CurrentDoorState 3 closing","topic":"","payload":"{\"CurrentDoorState\":3}","payloadType":"json","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":142,"y":288,"wires":[[]]},{"id":"d3e3a15f.775f","type":"inject","z":"75848247.7201a4","name":"Sensor Closed","topic":"1","payload":"SensorState","payloadType":"global","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":432,"y":432,"wires":[["dcae49cf.d24648"]]},{"id":"d57c187.234f768","type":"inject","z":"75848247.7201a4","name":"Sensor Opened","topic":"0","payload":"SensorState","payloadType":"global","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":432,"y":472,"wires":[["c37a0663.e9b01"]]},{"id":"c37a0663.e9b01","type":"function","z":"75848247.7201a4","name":"","func":"// sensor send opened state\n\nvar GD1 = global.get(\"GD1\");\nglobal.set(\"GD1.CurrentState\", 0);\nvar newMsg = {\"payload\": {\"CurrentDoorState\":0 }}\nreturn newMsg;","outputs":1,"noerr":0,"x":586,"y":472,"wires":[["5534366a.7ef91"]]},{"id":"dcae49cf.d24648","type":"function","z":"75848247.7201a4","name":"","func":"// sensor send closed state\n\nvar GD1 = global.get(\"GD1\");\nglobal.set(\"GD1.CurrentState\", 1);\nvar newMsg = {\"payload\": {\"CurrentDoorState\":1 }}\nreturn newMsg;","outputs":1,"noerr":0,"x":586,"y":432,"wires":[["5534366a.7ef91"]]},{"id":"b49fbf5e.c23e08","type":"inject","z":"75848247.7201a4","name":"Sensor Unknown","topic":"0","payload":"SensorState","payloadType":"global","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":432,"y":512,"wires":[["91fbd029.4be268"]]},{"id":"91fbd029.4be268","type":"function","z":"75848247.7201a4","name":"","func":"// sensor send unknown (not closed and not opened) state\n\nvar GD1 = global.get(\"GD1\");\n\nif (GD1.TargetState === 0) {\n var newMsg = {\"payload\": {\"CurrentDoorState\":2 }}\n} else if (GD1.TargetState === 1) {\n var newMsg = {\"payload\": {\"CurrentDoorState\":3 }}\n} else {\n var newMsg = {\"payload\": {\"CurrentDoorState\":4 }}\n}\n\n// dunno what to do with this info =)\nreturn newMsg;","outputs":1,"noerr":0,"x":586,"y":512,"wires":[["5534366a.7ef91"]]},{"id":"1f4da0a9.4023c7","type":"homekit-bridge","z":"","bridgeName":"villa-test","pinCode":"111-11-111","port":"","allowInsecureRequest":false,"manufacturer":"ptath","model":"raspberry pi zeroW","serialNo":"12345678"}]
Advanced Garage door setup
Based on #33. Using Sonoff-Tasmota and mqtt in real case: NodeMCU with two magnetic sensors (to check open/close position) and one relay (to control Garage door). In this case relay should blink (Power 3
in sonoff-tasmota) once to send signal to the door, please check this before running IRL!
[{"id":"69226b8c.22ab04","type":"homekit-service","z":"3e0d11cf.29e996","isParent":true,"bridge":"56f83ee1.f0bbd","parentService":"","name":"Ptath","serviceName":"GarageDoorOpener","topic":"","filter":false,"manufacturer":"Default Manufacturer","model":"Default Model","serialNo":"Default Serial Number","characteristicProperties":"{}","x":890,"y":1000,"wires":[["81e26608.9dcf1"]]},{"id":"7ba4d5eb.9d83ec","type":"mqtt in","z":"3e0d11cf.29e996","name":"TELE Sensors","topic":"tele/garage/SENSOR","qos":"1","datatype":"json","broker":"8de2bd93.86c898","x":210,"y":1060,"wires":[["564864bb.b1601c","1a3938a1.19889f"]]},{"id":"15ff5e5a.1ac742","type":"mqtt out","z":"3e0d11cf.29e996","name":"cmnd/garage/Power 3","topic":"cmnd/garage/Power","qos":"1","retain":"","broker":"8de2bd93.86c898","x":1300,"y":960,"wires":[]},{"id":"81e26608.9dcf1","type":"function","z":"3e0d11cf.29e996","name":"Main Logic","func":"if (msg.hap !== undefined && msg.hap.context !== undefined) {\n var GarageDoor = global.get(\"GarageDoor\");\n var command;\n \n if (msg.payload.TargetDoorState === 1) {\n if (GarageDoor.CurrentState === \"OPENED\") {\n // Normal close command\n if (GarageDoor.Obstruction !== \"TRUE\") {\n // Close if no obstruction\n command = {\"payload\": \"3\"};\n node.warn (\"CLOSING...\");\n GarageDoor.CurrentState = \"CLOSING\";\n } else {\n // Do not close if obstruction detected\n node.warn (\"Obstruction! Clear the door area!\");\n command = null;\n }\n } else if (GarageDoor.CurrentState === \"OPENING\") {\n // Stop door while opening\n command = {\"payload\": \"3\"};\n node.warn (\"STOPPING...\");\n GarageDoor.LastState = \"STOPPED\";\n GarageDoor.CurrentState = \"STOPPED\";\n } else if (GarageDoor.CurrentState === \"STOPPED\") {\n // Restart door from stopped\n if (GarageDoor.Obstruction !== \"TRUE\") {\n // Close if no obstruction\n command = {\"payload\": \"3\"};\n node.warn (\"CLOSING...\");\n GarageDoor.LastState = \"OPENED\"\n GarageDoor.CurrentState = \"CLOSING\";\n } else {\n // Do not close if obstruction detected\n node.warn (\"Obstruction! Clear the door area!\");\n command = null;\n }\n }\n } else if (msg.payload.TargetDoorState === 0) {\n if (GarageDoor.CurrentState === \"CLOSED\") {\n // Normal open command\n command = {\"payload\": \"3\"};\n node.warn (\"OPENING...\");\n // GarageDoor.LastState = \"CLOSED\";\n GarageDoor.CurrentState = \"OPENING\";\n } else if (GarageDoor.CurrentState === \"CLOSING\") {\n // Stop door while closing\n command = {\"payload\": \"3\"};\n node.warn (\"STOPPING...\");\n GarageDoor.LastState = \"STOPPED\";\n GarageDoor.CurrentState = \"STOPPED\";\n } else if (GarageDoor.CurrentState === \"STOPPED\") {\n // Restart door from stopped, assume it's going to close.\n if (GarageDoor.Obstruction !== \"TRUE\") {\n // Close if no obstruction\n command = {\"payload\": \"3\"};\n node.warn (\"CLOSING...\");\n GarageDoor.LastState = \"OPENED\"\n GarageDoor.CurrentState = \"CLOSING\";\n } else {\n // Do not close if obstruction detected\n node.warn (\"Obstruction! Clear the door area!\");\n command = null;\n }\n }\n }\n return [command, {\"payload\": GarageDoor.CurrentState}]\n}","outputs":2,"noerr":0,"x":1070,"y":1000,"wires":[["15ff5e5a.1ac742"],["76c85a60.bd0004"]]},{"id":"564864bb.b1601c","type":"function","z":"3e0d11cf.29e996","name":"State Handler","func":"var GarageDoor = global.get(\"GarageDoor\") || {}; // load \"GarageDoor\" or set to empty\n\nif (msg.payload.Switch1 == \"ON\" && msg.payload.Switch2 == \"OFF\") {\n // The door is fully opened\n GarageDoor.LastState = \"OPENED\";\n GarageDoor.CurrentState = \"OPENED\";\n}\n\nif (msg.payload.Switch1 == \"OFF\" && msg.payload.Switch2 == \"ON\") {\n // The door is fully closed\n GarageDoor.LastState = \"CLOSED\";\n GarageDoor.CurrentState = \"CLOSED\";\n}\n\nif (msg.payload.Switch1 == \"OFF\" && msg.payload.Switch2 == \"OFF\") {\n // The door is in the middle\n if (GarageDoor.LastState == \"OPENED\") GarageDoor.CurrentState = \"CLOSING\";\n if (GarageDoor.LastState == \"CLOSED\") GarageDoor.CurrentState = \"OPENING\";\n if (GarageDoor.LastState == \"STOPPED\") GarageDoor.CurrentState = \"STOPPED\";\n}\n\nvar moving = false;\nif (GarageDoor.CurrentState == \"OPENING\" || GarageDoor.CurrentState == \"CLOSING\") moving = true;\n\nglobal.set(\"GarageDoor\", GarageDoor);\n\nif (moving){\n return [{\"payload\": GarageDoor.CurrentState}, {\"payload\": 1}]\n} else {\n return [{\"payload\": GarageDoor.CurrentState}, {\"payload\": \"RESET\"}]\n}\n","outputs":2,"noerr":0,"x":500,"y":1060,"wires":[["fb761eae.a5ef8"],["d1438336.ad7238"]]},{"id":"d1438336.ad7238","type":"trigger","z":"3e0d11cf.29e996","op1":"","op2":"","op1type":"nul","op2type":"date","duration":"30","extend":false,"units":"s","reset":"RESET","bytopic":"all","name":"Trigger","x":730,"y":1220,"wires":[["97dd7cf5.c6075"]]},{"id":"97dd7cf5.c6075","type":"function","z":"3e0d11cf.29e996","name":"Set stopped","func":"var GarageDoor = global.get(\"GarageDoor\") || {};\nGarageDoor.CurrentState = \"STOPPED\";\nGarageDoor.LastState = \"STOPPED\";\nglobal.set(\"GarageDoor\", GarageDoor);","outputs":0,"noerr":0,"x":910,"y":1220,"wires":[]},{"id":"81d3c123.834598","type":"inject","z":"3e0d11cf.29e996","name":"Neither","topic":"","payload":"{\"Switch1\":\"OFF\",\"Switch2\":\"OFF\"}","payloadType":"json","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":230,"y":840,"wires":[["c18468e.fdde518"]]},{"id":"ef6c6ca4.618ae","type":"inject","z":"3e0d11cf.29e996","name":"Opened","topic":"","payload":"{\"Switch1\":\"ON\",\"Switch2\":\"OFF\"}","payloadType":"json","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":230,"y":880,"wires":[["c18468e.fdde518"]]},{"id":"1ed91362.10f605","type":"inject","z":"3e0d11cf.29e996","name":"Closed","topic":"","payload":"{\"Switch1\":\"OFF\",\"Switch2\":\"ON\"}","payloadType":"json","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":230,"y":920,"wires":[["c18468e.fdde518"]]},{"id":"fb761eae.a5ef8","type":"function","z":"3e0d11cf.29e996","name":"To HomeKit","func":"var GarageDoor = global.get(\"GarageDoor\");\nvar output = {};\n\nif (GarageDoor.CurrentState == \"OPENED\") {\n output = {\n \"payload\": {\n \"TargetDoorState\": 0,\n \"CurrentDoorState\": 0\n }\n }\n}\nelse if (GarageDoor.CurrentState == \"CLOSED\") {\n output = {\n \"payload\": {\n \"TargetDoorState\": 1,\n \"CurrentDoorState\": 1\n }\n }\n}\nelse if (GarageDoor.CurrentState == \"OPENING\") {\n output = {\n \"payload\": {\n \"TargetDoorState\": 0,\n \"CurrentDoorState\": 3\n }\n }\n}\nelse if (GarageDoor.CurrentState == \"CLOSING\") {\n output = {\n \"payload\": {\n \"TargetDoorState\": 1,\n \"CurrentDoorState\": 2\n }\n }\n}\nelse if (GarageDoor.CurrentState == \"STOPPED\") {\n output = {\n \"payload\": {\n \"TargetDoorState\": 0,\n \"CurrentDoorState\": 4\n }\n }\n}\n\nreturn output;","outputs":1,"noerr":0,"x":710,"y":1020,"wires":[["69226b8c.22ab04"]]},{"id":"c18468e.fdde518","type":"mqtt out","z":"3e0d11cf.29e996","name":"Simulator","topic":"tele/garage/SENSOR","qos":"1","retain":"","broker":"8de2bd93.86c898","x":500,"y":720,"wires":[]},{"id":"1450ca78.249d8e","type":"function","z":"3e0d11cf.29e996","name":"Simulator","func":"var Newmsg = {};\nNewmsg.hap = {\"context\":\"defined\"};\nNewmsg.payload = {\"TargetDoorState\":msg.payload};\nreturn Newmsg;\n","outputs":1,"noerr":0,"x":860,"y":720,"wires":[["81e26608.9dcf1"]]},{"id":"4eb7eeb2.56b25","type":"inject","z":"3e0d11cf.29e996","name":"Close","topic":"","payload":"1","payloadType":"num","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":710,"y":720,"wires":[["1450ca78.249d8e"]]},{"id":"3d998491.e2daac","type":"inject","z":"3e0d11cf.29e996","name":"Open","topic":"","payload":"0","payloadType":"num","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":710,"y":760,"wires":[["1450ca78.249d8e"]]},{"id":"152449f6.bcaece","type":"inject","z":"3e0d11cf.29e996","name":"OBSTRUCTION","topic":"","payload":"{\"Switch3\":\"ON\"}","payloadType":"json","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":260,"y":720,"wires":[["c18468e.fdde518"]]},{"id":"e359a895.408258","type":"inject","z":"3e0d11cf.29e996","name":"All clear","topic":"","payload":"{\"Switch3\":\"OFF\"}","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":230,"y":760,"wires":[["c18468e.fdde518"]]},{"id":"d2add466.b69c98","type":"function","z":"3e0d11cf.29e996","name":"Obstruction Handler","func":"GarageDoor = global.get(\"GarageDoor\");\nvar output = {};\n\nif (msg.payload.Switch3 === \"ON\") {\n if (GarageDoor.CurrentState !== \"CLOSED\"){\n output = {\n \"payload\": {\n \"ObstructionDetected\": true\n }\n }\n GarageDoor.Obstruction = \"TRUE\"\n } else {\n output = {\n \"payload\": {\n \"ObstructionDetected\": false\n }\n }\n }\n} else {\n output = {\n \"payload\": {\n \"ObstructionDetected\": false\n }\n }\n GarageDoor.Obstruction = \"FALSE\"\n}\nglobal.set(\"GarageDoor\", GarageDoor);\n\nreturn output;\n","outputs":1,"noerr":0,"x":680,"y":960,"wires":[["69226b8c.22ab04"]]},{"id":"a09fe844.ef8af","type":"comment","z":"3e0d11cf.29e996","name":"Obstruction simulator","info":"","x":260,"y":680,"wires":[]},{"id":"1a3938a1.19889f","type":"delay","z":"3e0d11cf.29e996","name":"","pauseType":"delay","timeout":"10","timeoutUnits":"milliseconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"x":490,"y":960,"wires":[["d2add466.b69c98"]]},{"id":"7e1c4b.927f33b4","type":"comment","z":"3e0d11cf.29e996","name":"Teleperiod simulator","info":"","x":250,"y":800,"wires":[]},{"id":"97e48d59.73d608","type":"comment","z":"3e0d11cf.29e996","name":"HomeKit simulator","info":"","x":730,"y":680,"wires":[]},{"id":"b67bb3a5.19e1f8","type":"link in","z":"3e0d11cf.29e996","name":"","links":["76c85a60.bd0004"],"x":555,"y":1000,"wires":[["fb761eae.a5ef8"]]},{"id":"76c85a60.bd0004","type":"link out","z":"3e0d11cf.29e996","name":"","links":["b67bb3a5.19e1f8"],"x":1215,"y":1040,"wires":[]},{"id":"b7e5025d.e11e58","type":"mqtt in","z":"3e0d11cf.29e996","name":"SwitchTopic (on=opened off=closing)","topic":"cmnd/SwitchTopic/POWER1","qos":"1","datatype":"auto","broker":"8de2bd93.86c898","x":230,"y":1180,"wires":[["81eb9be3.c25088"]]},{"id":"6c47141f.43b344","type":"mqtt in","z":"3e0d11cf.29e996","name":"SwitchTopic (on=closed off=opening)","topic":"cmnd/SwitchTopic/POWER2","qos":"1","datatype":"auto","broker":"8de2bd93.86c898","x":230,"y":1240,"wires":[["5d350244.59bd4c"]]},{"id":"81eb9be3.c25088","type":"function","z":"3e0d11cf.29e996","name":"Opened Handler","func":"var GarageDoor = global.get(\"GarageDoor\") || {}; // load \"GarageDoor\" or set to empty\n\nif (msg.payload == \"ON\") {\n // Sensor just turned on = door is fully opened\n GarageDoor.LastState = \"OPENED\";\n GarageDoor.CurrentState = \"OPENED\";\n} else if (msg.payload == \"OFF\" && GarageDoor.LastState == \"OPENED\") {\n // Sensor just turned off == door is starting to close\n GarageDoor.CurrentState = \"CLOSING\";\n}\n\nvar moving = false;\nif (GarageDoor.CurrentState == \"OPENING\" || GarageDoor.CurrentState == \"CLOSING\") moving = true;\n\nglobal.set(\"GarageDoor\", GarageDoor);\n\nif (moving){\n return [{\"payload\": GarageDoor.CurrentState}, {\"payload\": 1}]\n} else {\n return [{\"payload\": GarageDoor.CurrentState}, {\"payload\": \"RESET\"}]\n}","outputs":2,"noerr":0,"x":480,"y":1180,"wires":[["fb761eae.a5ef8"],["d1438336.ad7238"]]},{"id":"5d350244.59bd4c","type":"function","z":"3e0d11cf.29e996","name":"Closed Handler","func":"var GarageDoor = global.get(\"GarageDoor\") || {}; // load \"GarageDoor\" or set to empty\n\nif (msg.payload == \"ON\") {\n // Sensor just turned on = door is fully opened\n GarageDoor.LastState = \"CLOSED\";\n GarageDoor.CurrentState = \"CLOSED\";\n} else if (msg.payload == \"OFF\" && GarageDoor.LastState == \"CLOSED\") {\n // Sensor just turned off == door is starting to close\n GarageDoor.CurrentState = \"OPENING\";\n}\n\nvar moving = false;\nif (GarageDoor.CurrentState == \"OPENING\" || GarageDoor.CurrentState == \"CLOSING\") moving = true;\n\nglobal.set(\"GarageDoor\", GarageDoor);\n\nif (moving){\n return [{\"payload\": GarageDoor.CurrentState}, {\"payload\": 1}]\n} else {\n return [{\"payload\": GarageDoor.CurrentState}, {\"payload\": \"RESET\"}]\n}","outputs":2,"noerr":0,"x":480,"y":1240,"wires":[["fb761eae.a5ef8"],["d1438336.ad7238"]]},{"id":"37c95a46.9afdb6","type":"inject","z":"3e0d11cf.29e996","name":"opened = ON","topic":"cmnd/SwitchTopic/POWER1","payload":"ON","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":1070,"y":720,"wires":[["77d679b2.662be"]]},{"id":"f8407fd2.2cef88","type":"inject","z":"3e0d11cf.29e996","name":"Closing = OFF","topic":"cmnd/SwitchTopic/POWER1","payload":"OFF","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":1070,"y":760,"wires":[["77d679b2.662be"]]},{"id":"1fd925ac.3d202a","type":"inject","z":"3e0d11cf.29e996","name":"Closed = ON","topic":"cmnd/SwitchTopic/POWER2","payload":"ON","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":1070,"y":820,"wires":[["77d679b2.662be"]]},{"id":"4894bcad.103fec","type":"inject","z":"3e0d11cf.29e996","name":"Opening = OFF","topic":"cmnd/SwitchTopic/POWER2","payload":"OFF","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":1080,"y":860,"wires":[["77d679b2.662be"]]},{"id":"77d679b2.662be","type":"mqtt out","z":"3e0d11cf.29e996","name":"state change","topic":"","qos":"1","retain":"false","broker":"8de2bd93.86c898","x":1310,"y":720,"wires":[]},{"id":"facbd911.62551","type":"comment","z":"3e0d11cf.29e996","name":"Instant feedback simulator","info":"","x":1090,"y":680,"wires":[]},{"id":"c2c8c131.b76c48","type":"inject","z":"3e0d11cf.29e996","name":"Obstruction","topic":"cmnd/SwitchTopic/POWER3","payload":"ON","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":1310,"y":820,"wires":[["77d679b2.662be"]]},{"id":"38ae5250.c50d16","type":"inject","z":"3e0d11cf.29e996","name":"Clear","topic":"cmnd/SwitchTopic/POWER3","payload":"OFF","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":1290,"y":860,"wires":[["77d679b2.662be"]]},{"id":"56f83ee1.f0bbd","type":"homekit-bridge","z":"","bridgeName":"villa-test","pinCode":"111-11-111","port":"","allowInsecureRequest":false,"manufacturer":"ptath","model":"raspberry pi zeroW","serialNo":"12345678","customMdnsConfig":false,"mdnsMulticast":true,"mdnsInterface":"","mdnsPort":"","mdnsIp":"","mdnsTtl":"","mdnsLoopback":true,"mdnsReuseAddr":true},{"id":"8de2bd93.86c898","type":"mqtt-broker","z":"","name":"villa","broker":"192.168.100.10","port":"1883","clientid":"","usetls":false,"compatmode":true,"keepalive":"60","cleansession":true,"birthTopic":"","birthQos":"0","birthRetain":"false","birthPayload":"","closeTopic":"","closeQos":"0","closeRetain":"false","closePayload":"","willTopic":"","willQos":"0","willRetain":"false","willPayload":""}]