Local Control with Node-RED
Planning to purchase a Tesla vehicle and learned it has no garage door opener built-in. They have the MyQ app but... enough said. I discovered the Tailwind and installed it. I've also installed an OpenEVSE charger and plan to collect data into a raspberry PI running EmonCMS energy monitor.
I'll also want to get Tesla data (battery state of charge mostly) so I've learned Node RED and installed that on the raspberry PI also. I wrote a flow to capture Tailwind open/close data. First I used polling periodically, but seemed like a lot of data for something only changes twice a day, so I also tried the UDP notification and that works well.
Anyone wanting to learn/use Node RED I'll attach an export. (I also wrote a Door Open and Door Close flow so I could test it without having to look for my cellphone.)

-
Official comment
Thanks for posting this Russell!
Just in case it may be of further assistance with Node-RED implementations with Tailwind, we also have this resource available
https://github.com/Scott--R/Tailwind_NodeRED
Also, we've heard Tesla owners are having success using our web-based UI. They just add it to their home screen in the vehicle. web.gotailwind.com
Comment actions -
[{"id": "6dadd047a48e74c1","type": "tab","label": "Tailwind Garage","disabled": false,"info": "","env": []},{"id": "77a7b701b6101280","type": "group","z": "6dadd047a48e74c1","name": "test UDP by sending a message","style": {"label": true,"stroke": "#0070c0","fill": "#d1d1d1","color": "#001f60","fill-opacity": "0.5"},"nodes": ["d9cebbf2b02d04e2","164cdd5a3c467520","a11d73b247780747"],"x": 34,"y": 499,"w": 712,"h": 82},{"id": "ec37641847207d9f","type": "group","z": "6dadd047a48e74c1","name": "set status report URL","style": {"label": true,"stroke": "#0070c0","fill": "#d1d1d1","color": "#001f60","fill-opacity": "0.5"},"nodes": ["9fe253d6de07daba","893f0619fb586176","0c0b29b6756a958a","abc40c79d1441121"],"x": 34,"y": 399,"w": 972,"h": 82},{"id": "12816556da6fe887","type": "group","z": "6dadd047a48e74c1","name": "use UDP status report","style": {"label": true,"color": "#000000","fill": "#e3f3d3","fill-opacity": "0.52"},"nodes": ["d317dd6a31186a88","48956c77824109a9","c7293a46fb0328b0","67dd4ebcf0ac1eb7","a9dc1f70494a61b3","42205cc1e97917af","7d8aa32c4d91a4fc","41093f32eac1d917","322416e440f2c81b","56d8c3cc0d9ebde9"],"x": 34,"y": 39,"w": 932,"h": 262},{"id": "72e5d1ba983b38f8","type": "group","z": "6dadd047a48e74c1","name": "open door 1","style": {"label": true,"stroke": "#0070c0","fill": "#ffbfbf","color": "#001f60","fill-opacity": "0.5"},"nodes": ["dc0f2d3efdfcaea9","ca2a866f744fb39d","f0a18e332c51f9a3","4433b15d62fc48d3"],"x": 34,"y": 639,"w": 952,"h": 82},{"id": "2a7030623b016385","type": "group","z": "6dadd047a48e74c1","name": "close door 1","style": {"label": true,"stroke": "#0070c0","fill": "#ffbfbf","color": "#001f60","fill-opacity": "0.5"},"nodes": ["d9c5f7f2980d78c4","297c5407d55e573f","1ef7fc89cb1edafd","a00d1efd6b4ca5cb"],"x": 34,"y": 739,"w": 952,"h": 82},{"id": "9e38db963fe2994c","type": "group","z": "6dadd047a48e74c1","name": "poll the Tailwind controller","style": {"label": true,"color": "#000000"},"nodes": ["0d9a9d14bd0f8a0c","c7796a8ab8a66a11","2c05f5168fd28ff1","346ceb07fbafaf5a","c8abb1edcc0789fe","7a1933e5a13b8368","a901e87f22a4888b","71e527c93e93c73b","e919c737964cb977","47deab9c1744a41e"],"x": 34,"y": 859,"w": 932,"h": 382},{"id": "56d8c3cc0d9ebde9","type": "junction","z": "6dadd047a48e74c1","g": "12816556da6fe887","x": 700,"y": 200,"wires": [["42205cc1e97917af","a9dc1f70494a61b3"]]},{"id": "d317dd6a31186a88","type": "debug","z": "6dadd047a48e74c1","g": "12816556da6fe887","name": "UDP report","active": true,"tosidebar": true,"console": false,"tostatus": false,"complete": "payload","targetType": "msg","statusVal": "","statusType": "auto","x": 590,"y": 80,"wires": []},{"id": "48956c77824109a9","type": "debug","z": "6dadd047a48e74c1","g": "12816556da6fe887","name": "result NOT OK","active": true,"tosidebar": true,"console": false,"tostatus": false,"complete": "payload","targetType": "msg","statusVal": "","statusType": "auto","x": 580,"y": 140,"wires": []},{"id": "c7293a46fb0328b0","type": "switch","z": "6dadd047a48e74c1","g": "12816556da6fe887","name": "switch: result","property": "payload.result","propertyType": "msg","rules": [{"t": "neq","v": "OK","vt": "str"},{"t": "else"}],"checkall": "true","repair": false,"outputs": 2,"x": 350,"y": 180,"wires": [["48956c77824109a9"],["67dd4ebcf0ac1eb7"]],"inputLabels": ["UDP message"],"outputLabels": ["result != \"OK\"","result == \"OK\""]},{"id": "67dd4ebcf0ac1eb7","type": "function","z": "6dadd047a48e74c1","g": "12816556da6fe887","name": "door1 status","func": "var door1_status = msg.payload.data.door1.status;\n\nconst tailwind_status = {\n \"open\": 1,\n \"close\": 2,\n \"lock\": 3,\n \"enable\": 4,\n \"disable\": 5,\n \"reboot\": 6\n}\n\nreturn { payload: tailwind_status[door1_status] };\n\n/*\nopen Door opened\nclose Door closed\nlock Door lockup\nenable Door enabled\ndisable Door disabled\nreboot Device rebooted\n*/","outputs": 1,"timeout": 0,"noerr": 0,"initialize": "","finalize": "","libs": [],"x": 570,"y": 200,"wires": [["56d8c3cc0d9ebde9"]]},{"id": "a9dc1f70494a61b3","type": "debug","z": "6dadd047a48e74c1","g": "12816556da6fe887","name": "result OK","active": true,"tosidebar": true,"console": false,"tostatus": false,"complete": "payload","targetType": "msg","statusVal": "","statusType": "auto","x": 820,"y": 260,"wires": []},{"id": "42205cc1e97917af","type": "mqtt out","z": "6dadd047a48e74c1","g": "12816556da6fe887","name": "EmonCMS door1","topic": "emon/tailwind/door1","qos": "","retain": "","respTopic": "","contentType": "","userProps": "","correl": "","expiry": "","broker": "f61f25bb04c17f31","x": 850,"y": 200,"wires": []},{"id": "7d8aa32c4d91a4fc","type": "comment","z": "6dadd047a48e74c1","g": "12816556da6fe887","name": "Door Status Values","info": "<pre>\nopen Door opened\nclose Door closed\nlock Door lockup\nenable Door enabled\ndisable Door disabled\nreboot Device rebooted\n</pre>","x": 850,"y": 80,"wires": []},{"id": "2dd9661368df9dab","type": "debug","z": "6dadd047a48e74c1","name": "debug UDP IN","active": true,"tosidebar": true,"console": false,"tostatus": false,"complete": "payload","targetType": "msg","statusVal": "","statusType": "auto","x": 340,"y": 360,"wires": []},{"id": "d8677b94b0c4e75a","type": "udp in","z": "6dadd047a48e74c1","name": "UDP 49189","iface": "","port": "49189","ipv": "udp4","multicast": "false","group": "","datatype": "buffer","x": 110,"y": 360,"wires": [["2dd9661368df9dab"]]},{"id": "d9cebbf2b02d04e2","type": "udp out","z": "6dadd047a48e74c1","d": true,"g": "77a7b701b6101280","name": "","addr": "emonpi.local","iface": "","port": "49189","ipv": "udp4","outport": "","base64": false,"multicast": "false","x": 610,"y": 540,"wires": []},{"id": "164cdd5a3c467520","type": "change","z": "6dadd047a48e74c1","d": true,"g": "77a7b701b6101280","name": "","rules": [{"t": "set","p": "payload","pt": "msg","to": "hello","tot": "str"}],"action": "","property": "","from": "","to": "","reg": false,"x": 360,"y": 540,"wires": [["d9cebbf2b02d04e2"]]},{"id": "a11d73b247780747","type": "inject","z": "6dadd047a48e74c1","d": true,"g": "77a7b701b6101280","name": "one-shot","props": [{"p": "payload"},{"p": "topic","vt": "str"}],"repeat": "","crontab": "","once": false,"onceDelay": 0.1,"topic": "","payload": "","payloadType": "date","x": 140,"y": 540,"wires": [["164cdd5a3c467520"]]},{"id": "9fe253d6de07daba","type": "inject","z": "6dadd047a48e74c1","d": true,"g": "ec37641847207d9f","name": "one-shot","props": [{"p": "payload"},{"p": "topic","vt": "str"}],"repeat": "","crontab": "","once": false,"onceDelay": 0.1,"topic": "","payload": "","payloadType": "date","x": 140,"y": 440,"wires": [["0c0b29b6756a958a"]]},{"id": "893f0619fb586176","type": "http request","z": "6dadd047a48e74c1","d": true,"g": "ec37641847207d9f","name": "http set report URL","method": "POST","ret": "obj","paytoqs": "body","url": "http://tailwind-3ce90e6cb2d4.local/json","tls": "","persist": false,"proxy": "","insecureHTTPParser": false,"authType": "","senderr": false,"headers": [{"keyType": "other","keyValue": "TOKEN","valueType": "other","valueValue": "351348"}],"x": 610,"y": 440,"wires": [["abc40c79d1441121"]]},{"id": "0c0b29b6756a958a","type": "change","z": "6dadd047a48e74c1","d": true,"g": "ec37641847207d9f","name": "","rules": [{"t": "set","p": "payload","pt": "msg","to": "{\"product\":\"IQ3\",\"version\":\"0.1\",\"data\":{\"type\":\"set\",\"name\":\"notify_url\",\"value\":{\"url\":\"emonpi.local:49189\",\"proto\":\"udp\",\"enable\":1}}}","tot": "json"}],"action": "","property": "","from": "","to": "","reg": false,"x": 360,"y": 440,"wires": [["893f0619fb586176"]]},{"id": "abc40c79d1441121","type": "debug","z": "6dadd047a48e74c1","d": true,"g": "ec37641847207d9f","name": "debug set status URL","active": true,"tosidebar": true,"console": false,"tostatus": false,"complete": "payload","targetType": "msg","statusVal": "","statusType": "auto","x": 860,"y": 440,"wires": []},{"id": "dc0f2d3efdfcaea9","type": "inject","z": "6dadd047a48e74c1","g": "72e5d1ba983b38f8","name": "one-shot","props": [{"p": "payload"},{"p": "topic","vt": "str"}],"repeat": "","crontab": "","once": false,"onceDelay": 0.1,"topic": "","payload": "","payloadType": "date","x": 140,"y": 680,"wires": [["4433b15d62fc48d3"]]},{"id": "ca2a866f744fb39d","type": "debug","z": "6dadd047a48e74c1","g": "72e5d1ba983b38f8","name": "debug open door","active": true,"tosidebar": true,"console": false,"tostatus": false,"complete": "payload","targetType": "msg","statusVal": "","statusType": "auto","x": 850,"y": 680,"wires": []},{"id": "d9c5f7f2980d78c4","type": "inject","z": "6dadd047a48e74c1","g": "2a7030623b016385","name": "one-shot","props": [{"p": "payload"},{"p": "topic","vt": "str"}],"repeat": "","crontab": "","once": false,"onceDelay": 0.1,"topic": "","payload": "","payloadType": "date","x": 140,"y": 780,"wires": [["1ef7fc89cb1edafd"]]},{"id": "297c5407d55e573f","type": "http request","z": "6dadd047a48e74c1","g": "2a7030623b016385","name": "http tailwind","method": "POST","ret": "obj","paytoqs": "body","url": "http://tailwind-3ce90e6cb2d4.local/json","tls": "","persist": false,"proxy": "","insecureHTTPParser": false,"authType": "","senderr": false,"headers": [{"keyType": "other","keyValue": "TOKEN","valueType": "other","valueValue": "351348"}],"x": 590,"y": 780,"wires": [["a00d1efd6b4ca5cb"]]},{"id": "1ef7fc89cb1edafd","type": "change","z": "6dadd047a48e74c1","g": "2a7030623b016385","name": "close door 1","rules": [{"t": "set","p": "payload","pt": "msg","to": "{\"product\":\"iQ3\",\"version\":\"0.1\",\"data\":{\"type\":\"set\",\"name\":\"door_op\",\"value\":{\"door_idx\":0,\"cmd\":\"close\"}}}","tot": "json"}],"action": "","property": "","from": "","to": "","reg": false,"x": 350,"y": 780,"wires": [["297c5407d55e573f"]]},{"id": "a00d1efd6b4ca5cb","type": "debug","z": "6dadd047a48e74c1","g": "2a7030623b016385","name": "debug close door","active": true,"tosidebar": true,"console": false,"tostatus": false,"complete": "payload","targetType": "msg","statusVal": "","statusType": "auto","x": 850,"y": 780,"wires": []},{"id": "0d9a9d14bd0f8a0c","type": "debug","z": "6dadd047a48e74c1","d": true,"g": "9e38db963fe2994c","name": "http response","active": true,"tosidebar": true,"console": false,"tostatus": false,"complete": "payload","targetType": "msg","statusVal": "","statusType": "auto","x": 680,"y": 960,"wires": []},{"id": "c7796a8ab8a66a11","type": "http request","z": "6dadd047a48e74c1","d": true,"g": "9e38db963fe2994c","name": "http Tailwind","method": "POST","ret": "obj","paytoqs": "body","url": "http://tailwind-3ce90e6cb2d4.local/json","tls": "","persist": false,"proxy": "","insecureHTTPParser": false,"authType": "","senderr": false,"headers": [{"keyType": "other","keyValue": "TOKEN","valueType": "other","valueValue": "351348"}],"x": 450,"y": 1000,"wires": [["0d9a9d14bd0f8a0c","7a1933e5a13b8368"]]},{"id": "2c05f5168fd28ff1","type": "debug","z": "6dadd047a48e74c1","d": true,"g": "9e38db963fe2994c","name": "result NOT OK","active": true,"tosidebar": true,"console": false,"tostatus": false,"complete": "payload","targetType": "msg","statusVal": "","statusType": "auto","x": 580,"y": 1080,"wires": []},{"id": "346ceb07fbafaf5a","type": "change","z": "6dadd047a48e74c1","d": true,"g": "9e38db963fe2994c","name": "","rules": [{"t": "set","p": "payload","pt": "msg","to": "{ \"version\": \"0.1\", \"data\": { \"type\": \"get\", \"name\": \"dev_st\" } }","tot": "str"}],"action": "","property": "","from": "","to": "","reg": false,"x": 240,"y": 1000,"wires": [["c7796a8ab8a66a11"]]},{"id": "c8abb1edcc0789fe","type": "inject","z": "6dadd047a48e74c1","d": true,"g": "9e38db963fe2994c","name": "every 1 minute","props": [{"p": "payload"},{"p": "topic","vt": "str"}],"repeat": "60","crontab": "","once": false,"onceDelay": 0.1,"topic": "","payload": "","payloadType": "date","x": 160,"y": 920,"wires": [["346ceb07fbafaf5a"]]},{"id": "7a1933e5a13b8368","type": "switch","z": "6dadd047a48e74c1","d": true,"g": "9e38db963fe2994c","name": "","property": "payload.result","propertyType": "msg","rules": [{"t": "neq","v": "OK","vt": "str"},{"t": "else"}],"checkall": "true","repair": false,"outputs": 2,"x": 350,"y": 1120,"wires": [["2c05f5168fd28ff1"],["a901e87f22a4888b"]]},{"id": "a901e87f22a4888b","type": "function","z": "6dadd047a48e74c1","d": true,"g": "9e38db963fe2994c","name": "door1 status","func": "var door1_status = msg.payload.data.door1.status;\n\nconst tailwind_status = {\n \"open\": 1,\n \"close\": 2,\n \"lock\": 3,\n \"enable\": 4,\n \"disable\": 5,\n \"reboot\": 6\n}\n\nreturn { payload: tailwind_status[door1_status] };\n\n/*\nopen Door opened\nclose Door closed\nlock Door lockup\nenable Door enabled\ndisable Door disabled\nreboot Device rebooted\n*/","outputs": 1,"timeout": 0,"noerr": 0,"initialize": "","finalize": "","libs": [],"x": 570,"y": 1140,"wires": [["71e527c93e93c73b","e919c737964cb977"]]},{"id": "71e527c93e93c73b","type": "debug","z": "6dadd047a48e74c1","d": true,"g": "9e38db963fe2994c","name": "result OK","active": true,"tosidebar": true,"console": false,"tostatus": false,"complete": "payload","targetType": "msg","statusVal": "","statusType": "auto","x": 820,"y": 1200,"wires": []},{"id": "e919c737964cb977","type": "mqtt out","z": "6dadd047a48e74c1","d": true,"g": "9e38db963fe2994c","name": "EmonCMS door1","topic": "emon/tailwind/door1","qos": "","retain": "","respTopic": "","contentType": "","userProps": "","correl": "","expiry": "","broker": "f61f25bb04c17f31","x": 850,"y": 1140,"wires": []},{"id": "47deab9c1744a41e","type": "comment","z": "6dadd047a48e74c1","d": true,"g": "9e38db963fe2994c","name": "Door Status Values","info": "<pre>\nopen Door opened\nclose Door closed\nlock Door lockup\nenable Door enabled\ndisable Door disabled\nreboot Device rebooted\n</pre>","x": 850,"y": 900,"wires": []},{"id": "41093f32eac1d917","type": "udp in","z": "6dadd047a48e74c1","g": "12816556da6fe887","name": "UDP 49189","iface": "","port": "49189","ipv": "udp4","multicast": "false","group": "","datatype": "buffer","x": 130,"y": 80,"wires": [["322416e440f2c81b"]]},{"id": "322416e440f2c81b","type": "json","z": "6dadd047a48e74c1","g": "12816556da6fe887","name": "","property": "payload","action": "","pretty": false,"x": 290,"y": 80,"wires": [["c7293a46fb0328b0","d317dd6a31186a88"]]},{"id": "f0a18e332c51f9a3","type": "http request","z": "6dadd047a48e74c1","g": "72e5d1ba983b38f8","name": "http tailwind","method": "POST","ret": "obj","paytoqs": "body","url": "http://tailwind-3ce90e6cb2d4.local/json","tls": "","persist": false,"proxy": "","insecureHTTPParser": false,"authType": "","senderr": false,"headers": [{"keyType": "other","keyValue": "TOKEN","valueType": "other","valueValue": "351348"}],"x": 590,"y": 680,"wires": [["ca2a866f744fb39d"]]},{"id": "4433b15d62fc48d3","type": "change","z": "6dadd047a48e74c1","g": "72e5d1ba983b38f8","name": "open door 1","rules": [{"t": "set","p": "payload","pt": "msg","to": "{\"product\":\"iQ3\",\"version\":\"0.1\",\"data\":{\"type\":\"set\",\"name\":\"door_op\",\"value\":{\"door_idx\":0,\"cmd\":\"open\"}}}","tot": "json"}],"action": "","property": "","from": "","to": "","reg": false,"x": 350,"y": 680,"wires": [["f0a18e332c51f9a3"]]},{"id": "f61f25bb04c17f31","type": "mqtt-broker","name": "EmonCMS","broker": "emonpi.local","port": "1883","clientid": "","autoConnect": true,"usetls": false,"protocolVersion": "4","keepalive": "60","cleansession": true,"autoUnsubscribe": true,"birthTopic": "","birthQos": "0","birthRetain": "false","birthPayload": "","birthMsg": {},"closeTopic": "","closeQos": "0","closeRetain": "false","closePayload": "","closeMsg": {},"willTopic": "","willQos": "0","willRetain": "false","willPayload": "","willMsg": {},"userProps": "","sessionExpiry": ""}]
-
Thanks Scott for sharing that. And for the idea of the web interface in the Tesla (when I get one).
Though I use Android phone (Motorola) and the auto open is working GREAT for me in my F-150 and on my Can-Am Spyder. (Really useful with the Spyder since my RF opener is in the storage and I'm wearing gloves.)
-
Glad to hear it. Please be careful about a setting on newer Android OS versions. If you tap and hold on any app icon and then tap "app info" or "info" or "i", it will bring you to the settings for the app. In newer Android OS versions (I think it started in 13 - not sure) there is an option to remove permissions for unused apps, and delete data. This is turned on by default and it completely destroys the utility of any app (like Tailwind) that many people actually never open because there's almost no need to. In short, if you have any app on your Android phone that you don't use regularly, you can be assured it will stop working properly after a while if this is turned on. You'll get logged out or something will break.
Can you imagine having an app for a water leakage sensor in your basement? You never use it. It's just on your phone and is set to notify you if your basement floods. Yeah, that will not work unless you turn this "feature" off in Android settings.
I mention it because if you're like one of the many Tailwind users that never actually launch the app because you use other home automation platforms and the auto-open works by itself - then this "feature" in Android that is on by default for all apps is going to bite you sooner or later.
-
You mentioned that setting elsewhere in the setup and usage instructions for Android, and I did disable that "Pause" for unused. If you are like me (and almost nobody is) you don't even know where your phone is half the time. I carry it around in a pouch with my money and ID so it's in the vehicle with me. If you're like me (again who is) you read all the setup instructions.
I also have the widget on my phone I don't know if that makes it look "used" but again I rarely use it. When I get home I usually get out and push the button on the wall. Or use the RF remote control sometimes.
Please sign in to leave a comment.
Comments
5 comments