Created
April 10, 2018 11:09
-
-
Save fidian/e19abe283c278adc1397d6fb9a35bc2e to your computer and use it in GitHub Desktop.
SmartThings Node Red X10 Bridge Flow
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[ | |
{ | |
"id": "a206e388.d25c7", | |
"type": "tab", | |
"label": "Smartthings X10 Connector", | |
"disabled": false, | |
"info": "" | |
}, | |
{ | |
"id": "8f319222.e6859", | |
"type": "debug", | |
"z": "a206e388.d25c7", | |
"name": "", | |
"active": false, | |
"console": "false", | |
"complete": "payload", | |
"x": 630, | |
"y": 840, | |
"wires": [] | |
}, | |
{ | |
"id": "5e396823.403508", | |
"type": "function", | |
"z": "a206e388.d25c7", | |
"name": "Parse mochad Messages", | |
"func": "msg.headers = {};\nmsg.headers['Content-Type'] = 'application/json';\nmsg.headers['X10NodeRed'] = 'DeviceUpdate';\n \nvar lastCommand = global.get(\"LastCommand\");\nlastCommand = lastCommand.toLowerCase().trim();\n//node.warn(lastCommand);\n\nconst inLines = new Buffer(msg.payload, 'hex'); \n//node.warn(inLines.toString());\nvar lastCodeSeen = context.get(\"lastCodeSeen\");\nif(typeof lastCodeSeen == \"undefined\") {\n lastCodeSeen = {\n housecode: \"x\",\n unitcode: \"0\"\n };\n context.set(\"lastCodeSeen\", lastCodeSeen);\n}\n\ntry {\n\n var eventData, m;\n \n if (m = /^\\d{2}\\/\\d{2}\\s+(?:\\d{2}:){2}\\d{2}\\s(Tx|Rx)\\s+(RF|PL)\\s+House:\\s+([a-pA-P])\\s+Func:\\s+All\\s+(units|lights)\\s+(on|off)$/m.exec(inLines)) {\n eventData = {\n protocol: m[2].toLowerCase().trim(),\n direction: m[1].toLowerCase().trim(),\n housecode: m[3].toLowerCase().trim(),\n unitcode: \"*\" + m[4].trim(),\n state: m[5].toLowerCase().trim()\n };\n \n msg.payload = JSON.stringify(eventData);\n msg.headers['eventData'] = msg.payload;\n return msg; //{payload: JSON.stringify(eventData)};\n }\n if (m = /^\\d{2}\\/\\d{2}\\s+(?:\\d{2}:){2}\\d{2}\\s(Tx|Rx)\\s+(RFSEC)\\s+Addr:\\s+([xX:0-9a-fA-F]+)(\\s+)Func:\\s+(.+)$/m.exec(inLines)) {\n eventData = {\n protocol: m[2].toLowerCase().trim(),\n direction: m[1].toLowerCase().trim(),\n housecode: m[3].toLowerCase().trim(),\n unitcode: \"*\" + m[4].trim(),\n state: m[5].toLowerCase().trim()\n };\n msg.payload = JSON.stringify(eventData);\n msg.headers['eventData'] = msg.payload;\n return msg; //{payload: JSON.stringify(eventData)};\n }\n if (m = /^\\d{2}\\/\\d{2}\\s+(?:\\d{2}:){2}\\d{2}\\s(Tx|Rx)\\s+(RF|PL)\\s+HouseUnit:\\s+([a-pA-P])(\\d{1,2})\\s+Func:\\s+(On|Off)/m.exec(inLines)) {\n eventData = {\n protocol: m[2].toLowerCase().trim(),\n direction: m[1].toLowerCase().trim(),\n housecode: m[3].toLowerCase().trim(),\n unitcode: parseInt(m[4].trim(), 10),\n state: m[5].toLowerCase().trim()\n };\n msg.payload = JSON.stringify(eventData);\n msg.headers['eventData'] = msg.payload;\n return msg; //{payload: JSON.stringify(eventData)};\n } else if (m = /^\\d{2}\\/\\d{2}\\s+(?:\\d{2}:){2}\\d{2}\\s(?:Rx)\\s+(?:RF|PL)\\s+HouseUnit:\\s+([a-pA-P])(\\d{1,2})/m.exec(inLines)) {\n lastCodeSeen.housecode = m[1].toLowerCase().trim();\n lastCodeSeen.unitcode = parseInt(m[2].trim(), 10);\n context.set(\"lastCodeSeen\", lastCodeSeen);\n }\n if (lastCodeSeen.housecode && lastCodeSeen.unitcode && (m = /\\d{2}\\/\\d{2}\\s+(?:\\d{2}:){2}\\d{2}\\s(Rx|Tx)\\s+(RF|PL)\\s+House:\\s+([a-pA-P])\\s+Func:\\s+(On|Off|Dim|Bright)$/m.exec(inLines))) {\n eventData = {\n protocol: m[2].toLowerCase().trim(),\n direction: m[1].toLowerCase().trim(),\n housecode: m[3].toLowerCase().trim(),\n unitcode: null,\n state: m[4].toLowerCase().trim()\n };\n if (eventData.housecode === lastCodeSeen.housecode) {\n eventData.unitcode = lastCodeSeen.unitcode;\n msg.payload = JSON.stringify(eventData);\n msg.headers['eventData'] = msg.payload;\n return msg; //{payload: JSON.stringify(eventData)};\n }\n }\n} \ncatch(err) {\n return null; //ignore the exception, its probably a message we don't understand\n //console.log(\"exception in parsing: \" + err.message); \n} \n \nreturn null;\n\n", | |
"outputs": 1, | |
"noerr": 0, | |
"x": 530, | |
"y": 200, | |
"wires": [ | |
[ | |
"f4e17d6f.f9033", | |
"2ebf47b8.c5f118" | |
] | |
] | |
}, | |
{ | |
"id": "54852502.0e31bc", | |
"type": "http in", | |
"z": "a206e388.d25c7", | |
"name": "/register", | |
"url": "/register", | |
"method": "get", | |
"upload": false, | |
"swaggerDoc": "", | |
"x": 80, | |
"y": 751, | |
"wires": [ | |
[ | |
"7ba3251f.24a4fc", | |
"f87a71e8.d3759" | |
] | |
] | |
}, | |
{ | |
"id": "6a2e72ce.234d6c", | |
"type": "http response", | |
"z": "a206e388.d25c7", | |
"name": "Send respone to ST", | |
"statusCode": "", | |
"headers": {}, | |
"x": 640, | |
"y": 760, | |
"wires": [] | |
}, | |
{ | |
"id": "ba53ff3f.4a99a", | |
"type": "http request", | |
"z": "a206e388.d25c7", | |
"name": "http request to ST", | |
"method": "POST", | |
"ret": "txt", | |
"url": "", | |
"tls": "", | |
"x": 850, | |
"y": 320, | |
"wires": [ | |
[] | |
] | |
}, | |
{ | |
"id": "2ebf47b8.c5f118", | |
"type": "debug", | |
"z": "a206e388.d25c7", | |
"name": "", | |
"active": false, | |
"console": "false", | |
"complete": "true", | |
"x": 810, | |
"y": 200, | |
"wires": [] | |
}, | |
{ | |
"id": "80ccf868.d26d28", | |
"type": "file in", | |
"z": "a206e388.d25c7", | |
"name": "Read ST setting after restart", | |
"filename": "/home/fidian/.red-st-connect.conf", | |
"format": "utf8", | |
"chunk": false, | |
"sendError": false, | |
"x": 366.5, | |
"y": 80, | |
"wires": [ | |
[ | |
"bdb1a3ab.ec377" | |
] | |
] | |
}, | |
{ | |
"id": "82222da6.2ea49", | |
"type": "inject", | |
"z": "a206e388.d25c7", | |
"name": "Startup", | |
"topic": "", | |
"payload": "", | |
"payloadType": "date", | |
"repeat": "", | |
"crontab": "", | |
"once": true, | |
"onceDelay": "", | |
"x": 91, | |
"y": 81, | |
"wires": [ | |
[ | |
"80ccf868.d26d28", | |
"1c8a3b01.a2a6d5" | |
] | |
] | |
}, | |
{ | |
"id": "f87a71e8.d3759", | |
"type": "file", | |
"z": "a206e388.d25c7", | |
"name": "Persist ST settings to File", | |
"filename": "/home/fidian/.red-st-connect.conf", | |
"appendNewline": false, | |
"createDir": true, | |
"overwriteFile": "true", | |
"x": 316.5, | |
"y": 719, | |
"wires": [] | |
}, | |
{ | |
"id": "86014fed.fc818", | |
"type": "comment", | |
"z": "a206e388.d25c7", | |
"name": "setup config file path", | |
"info": "If you are not running as pi or /home/pi is\nnot writable change the location of where\nthis flow will read and write ST settings\nsettings will be stored in /home/pi/.red-st-connect.conf", | |
"x": 348, | |
"y": 43, | |
"wires": [] | |
}, | |
{ | |
"id": "bdb1a3ab.ec377", | |
"type": "function", | |
"z": "a206e388.d25c7", | |
"name": "Set ST Settings in global context", | |
"func": "try {\n var STsettings = JSON.parse(msg.payload);\n if (typeof obj !== 'string' ) \n global.set(\"STsettings\", STsettings);\n global.set(\"LastCommand\", \" \");\n} catch (e) {\n // ignore errors\n}\n\nmsg.payload = \"Smartthings settings: \" + JSON.stringify (STsettings);\n\nreturn msg\n\n\n\n", | |
"outputs": 1, | |
"noerr": 0, | |
"x": 674, | |
"y": 80, | |
"wires": [ | |
[] | |
] | |
}, | |
{ | |
"id": "f4e17d6f.f9033", | |
"type": "function", | |
"z": "a206e388.d25c7", | |
"name": "Setup http request", | |
"func": "\n// if you want to hard code the url to ST uncomment these two lines and\n// delete or comment out the rest of the lines in this node\n// msg.url. = \"http://ip_address_of_Smartthings_hub:39500/\";\n// return msg;\n\nvar STsettings = global.get(\"STsettings\");\nif(typeof STsettings == \"undefined\") {\n node.error(\"Can't continue. Don't know where Smartthings hub is.\");\n return null;\n}\nnode.log(\"Please ignore the message properties override warning\");\nmsg.url =\"http://\" + STsettings.ip_for_st + \":\" + STsettings.port_for_st;\nreturn msg;\n\n\n\n\n\n", | |
"outputs": 1, | |
"noerr": 0, | |
"x": 630, | |
"y": 260, | |
"wires": [ | |
[ | |
"2ebf47b8.c5f118", | |
"ba53ff3f.4a99a" | |
] | |
] | |
}, | |
{ | |
"id": "fecd2465.c22738", | |
"type": "http in", | |
"z": "a206e388.d25c7", | |
"name": "/push", | |
"url": "/push", | |
"method": "get", | |
"upload": false, | |
"swaggerDoc": "", | |
"x": 61, | |
"y": 500, | |
"wires": [ | |
[ | |
"fc432ad6.d35fd8", | |
"898566fd.e0bd68" | |
] | |
] | |
}, | |
{ | |
"id": "7ba3251f.24a4fc", | |
"type": "function", | |
"z": "a206e388.d25c7", | |
"name": "Registration response", | |
"func": "msg.headers = {};\nmsg.headers['Content-Type'] = 'application/json';\nmsg.headers['X10NodeRed'] = 'Registered';\nmsg.payload = {\"X10NodeRed\":\"Registered\"};\nreturn msg;\n", | |
"outputs": 1, | |
"noerr": 0, | |
"x": 310, | |
"y": 792, | |
"wires": [ | |
[ | |
"6a2e72ce.234d6c", | |
"8f319222.e6859" | |
] | |
] | |
}, | |
{ | |
"id": "7e85adfe.5eb384", | |
"type": "comment", | |
"z": "a206e388.d25c7", | |
"name": "setup mochad host ip", | |
"info": "This is the mochad listener you should \nsetup the mochad host address here\n", | |
"x": 320, | |
"y": 160, | |
"wires": [] | |
}, | |
{ | |
"id": "49074972.110bb8", | |
"type": "function", | |
"z": "a206e388.d25c7", | |
"name": "parse send message", | |
"func": "var jsonText = JSON.stringify(msg.payload); \nvar obj = JSON.parse(jsonText);\n\nif (typeof obj !== 'string' ) {\n var device = obj.device.replace(/-/g, \" \");\n msg.payload = device + \" \" + obj.action+\"\\n\";\n global.set(\"LastCommand\", msg.payload);\n return msg;\n}", | |
"outputs": 1, | |
"noerr": 0, | |
"x": 300, | |
"y": 400, | |
"wires": [ | |
[ | |
"56e95236.13472c", | |
"c33ad720.a00f88", | |
"1c8a3b01.a2a6d5" | |
] | |
] | |
}, | |
{ | |
"id": "64d3c2c5.39f3bc", | |
"type": "comment", | |
"z": "a206e388.d25c7", | |
"name": "setup config file path", | |
"info": "If you are not running as pi or /home/pi is\nnot writable change the location of where\nthis flow will read and write ST settings\nsettigns will be stored in /home/pi/.red-st-connect.conf", | |
"x": 310, | |
"y": 676, | |
"wires": [] | |
}, | |
{ | |
"id": "56e95236.13472c", | |
"type": "function", | |
"z": "a206e388.d25c7", | |
"name": "OK response", | |
"func": "msg.headers = {};\nmsg.headers['Content-Type'] = 'application/json';\nmsg.payload = {\"X10NodeRed\":\"OK\"};\nreturn msg;\n", | |
"outputs": 1, | |
"noerr": 0, | |
"x": 610, | |
"y": 600, | |
"wires": [ | |
[ | |
"6a2e72ce.234d6c" | |
] | |
] | |
}, | |
{ | |
"id": "c33ad720.a00f88", | |
"type": "debug", | |
"z": "a206e388.d25c7", | |
"name": "", | |
"active": false, | |
"console": "false", | |
"complete": "payload", | |
"x": 570, | |
"y": 420, | |
"wires": [] | |
}, | |
{ | |
"id": "fc432ad6.d35fd8", | |
"type": "debug", | |
"z": "a206e388.d25c7", | |
"name": "", | |
"active": false, | |
"console": "false", | |
"complete": "payload", | |
"x": 230, | |
"y": 600, | |
"wires": [] | |
}, | |
{ | |
"id": "9c0e4d3f.247a9", | |
"type": "function", | |
"z": "a206e388.d25c7", | |
"name": "Rate Limiter", | |
"func": "var interval = (500); // minimum interval between messages (ms)\ncontext.lastTime = context.lastTime || 0;\n\nvar now = Date.now();\n\nif (now-context.lastTime > interval) {\n context.lastTime = now;\n return msg;\n} else {\n return null;\n}", | |
"outputs": 1, | |
"noerr": 0, | |
"x": 370, | |
"y": 260, | |
"wires": [ | |
[ | |
"5e396823.403508" | |
] | |
] | |
}, | |
{ | |
"id": "1c8a3b01.a2a6d5", | |
"type": "tcp request", | |
"z": "a206e388.d25c7", | |
"server": "localhost", | |
"port": "1099", | |
"out": "sit", | |
"splitc": " ", | |
"name": "mochad", | |
"x": 280, | |
"y": 200, | |
"wires": [ | |
[ | |
"9c0e4d3f.247a9" | |
] | |
] | |
}, | |
{ | |
"id": "898566fd.e0bd68", | |
"type": "delay", | |
"z": "a206e388.d25c7", | |
"name": "", | |
"pauseType": "rate", | |
"timeout": "5", | |
"timeoutUnits": "seconds", | |
"rate": "1", | |
"nbRateUnits": "1", | |
"rateUnits": "second", | |
"randomFirst": "1", | |
"randomLast": "5", | |
"randomUnits": "seconds", | |
"drop": false, | |
"x": 210, | |
"y": 480, | |
"wires": [ | |
[ | |
"49074972.110bb8" | |
] | |
] | |
} | |
] |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment