[{"id":"75679700.c053a8","type":"tab","label":"Zigate API","disabled":false,"info":""},{"id":"8f50bdda.84b77","type":"tab","label":"Zigate UI","disabled":false,"info":""},{"id":"2a3adfb4.0cce2","type":"tab","label":"Zigate Read Serial","disabled":false,"info":""},{"id":"c733c6b6.ada328","type":"subflow","name":"Zigate Send Telegram","info":"# Description\nGenerate a Zigate frame based on a command received in input.\n`\nmsg.payload = {\n msgType : 0x0010,\n data : []\n}\n`\n# Functions\nThe procedure generate the frame, transcode it and send it to the serial port.\n\n# Remarks\nIn some cases, we store the information in the database.\nFor example, when we send an On/Off command, we already set the value to On/Off in the database because the Zigate (or the device) doesn't send a response with the current value.","category":"Zigate","in":[{"x":60,"y":160,"wires":[{"id":"47762663.380738"}]}],"out":[{"x":1300,"y":280,"wires":[{"id":"608f2f64.6a555","port":0}]}],"env":[],"icon":"font-awesome/fa-wifi"},{"id":"2ed89ec0.b5f5b2","type":"subflow","name":"Zigate Decode Response","info":"# Description\nDecode the frame's response from the Zigate and store the needed information in the database.\n\n# Remarks\nWhen we received a \"Device List Response\", we remove the unused devices from the database in order to have something clear.","category":"Zigate","in":[{"x":40,"y":320,"wires":[{"id":"59d08afb.903b94"}]}],"out":[{"x":2160,"y":340,"wires":[{"id":"c7fc1977.b5c188","port":0}]}],"env":[],"icon":"font-awesome/fa-wifi"},{"id":"8e737be3.b45a58","type":"subflow","name":"Zigate Discover Device","info":"# Description\nSend the needed commands to discover a powered device.\nFor \"battery device\", generally, you have to \"clic\" on the device to send the needed information to the zigate.\nIn that case, we'll decode it via the bloc \"Zigate Decode Response\"","category":"Zigate","in":[{"x":60,"y":320,"wires":[{"id":"4d776546.a99b8c"}]}],"out":[{"x":920,"y":680,"wires":[{"id":"65d13696.b19588","port":0}]}],"env":[],"icon":"font-awesome/fa-wifi"},{"id":"ade00219.436f6","type":"subflow","name":"Zigate Send and Receive","info":"# Description\nCombine the bloc \"Zigate Send Telegram\" and \"Zigate Decode Response\" in one bloc.","category":"Zigate","in":[{"x":40,"y":120,"wires":[{"id":"cfd86985.493b28"}]}],"out":[{"x":680,"y":120,"wires":[{"id":"2e6f4291.ca79ae","port":0}]}],"env":[],"icon":"font-awesome/fa-wifi"},{"id":"8bf91d15.7f53a","type":"serial-port","z":"","serialport":"/dev/ttyAMA0","serialbaud":"115200","databits":"8","parity":"none","stopbits":"1","waitfor":"0x01","newline":"200","bin":"bin","out":"time","addchar":"","responsetimeout":"1000"},{"id":"875df393.5dcfe","type":"json-db-collection","z":"","name":"Zigate Devices","collection":"zigate","save":true},{"id":"82321b1d.abb5b8","type":"http in","z":"75679700.c053a8","name":"","url":"/zigate/version","method":"get","upload":false,"swaggerDoc":"","x":130,"y":80,"wires":[["507cf5fc.ace7fc"]]},{"id":"2fb00a56.901086","type":"http response","z":"75679700.c053a8","name":"Response to user","statusCode":"200","headers":{},"x":1290,"y":480,"wires":[]},{"id":"507cf5fc.ace7fc","type":"function","z":"75679700.c053a8","name":"Version Command","func":"msg.payload = {\n msgType : 0x0010,\n data : []\n}\n\n\nreturn msg;","outputs":1,"noerr":0,"x":630,"y":80,"wires":[["4a9c7f57.0baca"]]},{"id":"938c1bd8.ee2ae8","type":"comment","z":"75679700.c053a8","name":"Zigate Send and Receive","info":"","x":990,"y":40,"wires":[]},{"id":"841f9a90.5a0b48","type":"comment","z":"75679700.c053a8","name":"API Routes (Zigate)","info":"","x":227,"y":38,"wires":[]},{"id":"695958fe.2c4b28","type":"comment","z":"75679700.c053a8","name":"API Response","info":"","x":1290,"y":40,"wires":[]},{"id":"f6ccea37.1df108","type":"function","z":"75679700.c053a8","name":"Permit Join Command","func":"msg.payload = {\n msgType : 0x0049,\n data : [0xFF,0xFC,30,0x00]\n}\n\n\nreturn msg;","outputs":1,"noerr":0,"x":639.5,"y":120,"wires":[["4a9c7f57.0baca"]]},{"id":"44b8a3b7.16046c","type":"http in","z":"75679700.c053a8","name":"","url":"/zigate/permitjoin","method":"get","upload":false,"swaggerDoc":"","x":140,"y":120,"wires":[["f6ccea37.1df108"]]},{"id":"fa662a28.323b48","type":"http in","z":"75679700.c053a8","name":"","url":"/zigate/deviceslist","method":"get","upload":false,"swaggerDoc":"","x":140,"y":160,"wires":[["ca641b35.cb0a68"]]},{"id":"ca641b35.cb0a68","type":"function","z":"75679700.c053a8","name":"Devices List Command","func":"msg.payload = {\n msgType : 0x0015,\n data : []\n}\n\n\nreturn msg;","outputs":1,"noerr":0,"x":649.5,"y":160,"wires":[["4a9c7f57.0baca"]]},{"id":"2e8d063d.efd11a","type":"http in","z":"75679700.c053a8","name":"","url":"/zigate/setLedOn","method":"get","upload":false,"swaggerDoc":"","x":140,"y":320,"wires":[["e41c8a02.07ae58"]]},{"id":"e41c8a02.07ae58","type":"function","z":"75679700.c053a8","name":"Set Led On Command","func":"msg.payload = {\n msgType : 0x0018,\n data : [1]\n}\n\n\nreturn msg;","outputs":1,"noerr":0,"x":639.5,"y":320,"wires":[["4a9c7f57.0baca"]]},{"id":"5e61612a.82af6","type":"http in","z":"75679700.c053a8","name":"","url":"/zigate/setLedOff","method":"get","upload":false,"swaggerDoc":"","x":140,"y":360,"wires":[["83eb765.7dc4088"]]},{"id":"83eb765.7dc4088","type":"function","z":"75679700.c053a8","name":"Set Led Off Command","func":"msg.payload = {\n msgType : 0x0018,\n data : [0]\n}\n\n\nreturn msg;","outputs":1,"noerr":0,"x":639.5,"y":360,"wires":[["4a9c7f57.0baca"]]},{"id":"2093aa9.ab86556","type":"http in","z":"75679700.c053a8","name":"","url":"/zigate/reset","method":"get","upload":false,"swaggerDoc":"","x":120,"y":400,"wires":[["70449cf5.75e3a4"]]},{"id":"70449cf5.75e3a4","type":"function","z":"75679700.c053a8","name":"Reset Command","func":"msg.payload = {\n msgType : 0x0011,\n data : []\n}\n\n\nreturn msg;","outputs":1,"noerr":0,"x":629.5,"y":400,"wires":[["4a9c7f57.0baca"]]},{"id":"293706b7.cbfc9a","type":"http in","z":"75679700.c053a8","name":"","url":"/zigate/startnetworkscan","method":"get","upload":false,"swaggerDoc":"","x":160,"y":440,"wires":[["839fa7b6.5482d8"]]},{"id":"839fa7b6.5482d8","type":"function","z":"75679700.c053a8","name":"Start Network Scan Command","func":"msg.payload = {\n msgType : 0x0025,\n data : []\n}\n\n\nreturn msg;","outputs":1,"noerr":0,"x":669.5,"y":440,"wires":[["4a9c7f57.0baca"]]},{"id":"562b95f9.b0977c","type":"http in","z":"75679700.c053a8","name":"","url":"/zigate/startnetwork","method":"get","upload":false,"swaggerDoc":"","x":150,"y":480,"wires":[["c1e57a28.e05fd8"]]},{"id":"c1e57a28.e05fd8","type":"function","z":"75679700.c053a8","name":"Start Network Command","func":"msg.payload = {\n msgType : 0x0024,\n data : []\n}\n\n\nreturn msg;","outputs":1,"noerr":0,"x":649.5,"y":480,"wires":[["4a9c7f57.0baca"]]},{"id":"754e09c5.8c0d78","type":"http in","z":"75679700.c053a8","name":"","url":"/zigate/on/:shortAddress/:endpoint","method":"get","upload":false,"swaggerDoc":"","x":190,"y":520,"wires":[["569cd90d.687428"]]},{"id":"e2ea8eac.a0638","type":"http in","z":"75679700.c053a8","name":"","url":"/zigate/off/:shortAddress/:endpoint","method":"get","upload":false,"swaggerDoc":"","x":190,"y":560,"wires":[["3229b74b.e8cdd8"]]},{"id":"3229b74b.e8cdd8","type":"function","z":"75679700.c053a8","name":"Off Command","func":"var shortAddress = msg.req.params.shortAddress;\nvar endpoint = msg.req.params.endpoint;\nmsg.payload = {\n msgType : 0x0092,\n data : [0x02, parseInt(shortAddress.substr(0,2), 16), parseInt(shortAddress.substr(2,2), 16), 0x01, parseInt(endpoint, 16), 0x00]\n}\n\nreturn msg;","outputs":1,"noerr":0,"x":619.5,"y":560,"wires":[["4a9c7f57.0baca"]]},{"id":"569cd90d.687428","type":"function","z":"75679700.c053a8","name":"On Command","func":"var shortAddress = msg.req.params.shortAddress;\nvar endpoint = msg.req.params.endpoint;\nmsg.payload = {\n msgType : 0x0092,\n data : [0x02, parseInt(shortAddress.substr(0,2), 16), parseInt(shortAddress.substr(2,2), 16), 0x01, parseInt(endpoint, 16), 0x01]\n}\n\nreturn msg;","outputs":1,"noerr":0,"x":619.5,"y":520,"wires":[["4a9c7f57.0baca"]]},{"id":"4292764d.0bc208","type":"http in","z":"75679700.c053a8","name":"","url":"/zigate/activeEndpoint/:shortAddress","method":"get","upload":false,"swaggerDoc":"","x":200,"y":200,"wires":[["5ad4dc9e.5a1eb4"]]},{"id":"5ad4dc9e.5a1eb4","type":"function","z":"75679700.c053a8","name":"Active EndPoint Command","func":"var shortAddress = msg.req.params.shortAddress;\nmsg.payload = {\n msgType : 0x0045,\n data : [parseInt(shortAddress.substr(0,2), 16), parseInt(shortAddress.substr(2,2), 16)]\n}\nreturn msg;","outputs":1,"noerr":0,"x":659.5,"y":200,"wires":[["4a9c7f57.0baca"]]},{"id":"e72757fe.dcbad8","type":"http in","z":"75679700.c053a8","name":"","url":"/zigate/clusters/:shortAddress/:endpoint","method":"get","upload":false,"swaggerDoc":"","x":210,"y":280,"wires":[["11011f5a.d494d1"]]},{"id":"11011f5a.d494d1","type":"function","z":"75679700.c053a8","name":"Simple Descriptor Command","func":"var shortAddress = msg.req.params.shortAddress;\nvar endpoint = msg.req.params.endpoint;\nmsg.payload = {\n msgType : 0x0043,\n data : [parseInt(shortAddress.substr(0,2), 16), parseInt(shortAddress.substr(2,2), 16), parseInt(endpoint, 16)]\n}\nreturn msg;","outputs":1,"noerr":0,"x":659.5,"y":280,"wires":[["4a9c7f57.0baca"]]},{"id":"244dc7a5.b39a58","type":"function","z":"75679700.c053a8","name":"Database Device Query","func":"msg.datapath = \"/devices\";\nreturn msg;","outputs":1,"noerr":0,"x":630,"y":1060,"wires":[["5929d0d9.70fb4"]]},{"id":"5929d0d9.70fb4","type":"DataOut","z":"75679700.c053a8","collection":"875df393.5dcfe","name":"Zigate Devices DB","path":"/","error":false,"x":950,"y":1080,"wires":[["2fb00a56.901086"]]},{"id":"dbb2834d.d1a2a","type":"http in","z":"75679700.c053a8","name":"","url":"/zigate/devices","method":"get","upload":false,"swaggerDoc":"","x":110.5,"y":1060,"wires":[["244dc7a5.b39a58"]]},{"id":"ea64119.6c019f","type":"http in","z":"75679700.c053a8","name":"","url":"/zigate/devices/:shortAddress","method":"get","upload":false,"swaggerDoc":"","x":160.5,"y":1100,"wires":[["9e0cae96.91ffe"]]},{"id":"9e0cae96.91ffe","type":"function","z":"75679700.c053a8","name":"Database Device Query","func":"msg.datapath = \"/devices/\" + msg.req.params.shortAddress.toLowerCase();\nreturn msg;","outputs":1,"noerr":0,"x":630,"y":1100,"wires":[["5929d0d9.70fb4"]]},{"id":"cafa58b4.d70438","type":"comment","z":"75679700.c053a8","name":"API Routes (DB)","info":"","x":220,"y":980,"wires":[]},{"id":"326b4b0.9daacb6","type":"function","z":"2ed89ec0.b5f5b2","name":"Network joined / formed Response","func":"var r = msg.payload;\nr.status = parseInt(r.payload.slice(0,1).toString(\"hex\"),16);\nr.shortAddress = r.payload.slice(1,3).toString(\"hex\");\nr.extendedAddress = r.payload.slice(3,11).toString(\"hex\");\nr.channel = r.payload.slice(11,12).toString(\"hex\");\ndelete r.payload;\n\nmsg.payload = r;\nreturn msg;","outputs":1,"noerr":0,"x":980,"y":240,"wires":[["8e12f490.0ee5f8"]]},{"id":"8e12f490.0ee5f8","type":"function","z":"2ed89ec0.b5f5b2","name":"Set last telegram as complete","func":"if(flow.get(\"counter\") === flow.get(\"telegrams_total\") ){\n msg.complete = true;\n}\nreturn msg;","outputs":1,"noerr":0,"x":1350,"y":340,"wires":[["77642274.585d9c"]]},{"id":"e113ead8.6ec498","type":"function","z":"2ed89ec0.b5f5b2","name":"Active Endpoint Response","func":"var r = msg.payload;\nr.sequenceNumber = parseInt(r.payload.slice(0,1).toString(\"hex\"),16);\nr.status = parseInt(r.payload.slice(1,2).toString(\"hex\"),16);\nr.shortAddress = r.payload.slice(2,4).toString(\"hex\");\nr.endpointCount = parseInt(r.payload.slice(4,5).toString(\"hex\"), 16);\nr.endpoints = [];\n\nfor(let i = 0; i < r.endpointCount; i ++){\n r.endpoints.push(r.payload.slice((5+i),(6+i)).toString(\"hex\"))\n}\n\ndelete r.payload;\n\nmsg.payload = r;\nreturn msg;","outputs":1,"noerr":0,"x":960,"y":280,"wires":[["8e12f490.0ee5f8","98015b7.939f6a8"]]},{"id":"c893ff4f.5d194","type":"function","z":"2ed89ec0.b5f5b2","name":"APS Data Confirm Fail Response","func":"var r = msg.payload;\nr.status = parseInt(r.payload.slice(0,1).toString(\"hex\"),16);\nr.srcEndpoint = r.payload.slice(1,2).toString(\"hex\");\nr.dstEndpoint = r.payload.slice(2,3).toString(\"hex\");\nr.dstAddressMode = r.payload.slice(3,4).toString(\"hex\");\nr.dstAddress = r.payload.slice(4,12).toString(\"hex\");\nr.sequenceNumber = parseInt(r.payload.slice(12,13).toString(\"hex\"), 16);\n\ndelete r.payload;\n\nmsg.payload = r;\nreturn msg;","outputs":1,"noerr":0,"x":980,"y":320,"wires":[["8e12f490.0ee5f8"]]},{"id":"b6fb1d3f.3f3d9","type":"function","z":"2ed89ec0.b5f5b2","name":"Simple Descriptor Response","func":"var r = msg.payload;\nr.sequenceNumber = parseInt(r.payload.slice(0,1).toString(\"hex\"),16);\nr.status = parseInt(r.payload.slice(1,2).toString(\"hex\"),16);\nr.nwkAddress = r.payload.slice(2,4).toString(\"hex\");\nr.length = parseInt(r.payload.slice(4,5).toString(\"hex\"),16);\nr.endpoint = r.payload.slice(5,6).toString(\"hex\");\nr.profile = r.payload.slice(6,8).toString(\"hex\");\nr.deviceId = r.payload.slice(8,10).toString(\"hex\");\nr.bitFields = r.payload.slice(10,11).toString(\"hex\");\nr.inClusterCount = parseInt(r.payload.slice(11,12).toString(\"hex\"),16);\n\nr.inClusterList = [];\n\nvar from = 12;\nfor(let i = 0; i < r.inClusterCount; i++){\n r.inClusterList.push(r.payload.slice((from),(from+2)).toString(\"hex\"));\n from = from + 2;\n}\nfrom = 12 + (r.inClusterCount * 2);\nr.outClusterCount = parseInt(r.payload.slice(from,from+1).toString(\"hex\"),16);\nfrom = from + 1;\nr.outClusterList = [];\n\nfor(let i = 0; i < r.outClusterCount; i++){\n r.outClusterList.push(r.payload.slice((from),(from+2)).toString(\"hex\"));\n from = from + 2;\n}\n\ndelete r.payload;\n\nmsg.payload = r;\nreturn msg;","outputs":1,"noerr":0,"x":960,"y":360,"wires":[["8e12f490.0ee5f8","80a2a5da.ae2e58"]]},{"id":"6435ee35.5630c","type":"function","z":"2ed89ec0.b5f5b2","name":"Insert/Update device query","func":"\nmsg.datapath = \"/devices/\" + msg.payload.shortAddress;\n\ndelete msg.payload.rssi;\ndelete msg.payload.length;\ndelete msg.payload.checksum;\ndelete msg.payload.code;\n\nreturn msg;","outputs":1,"noerr":0,"x":1640,"y":440,"wires":[["11220606.be9eaa"]]},{"id":"98015b7.939f6a8","type":"function","z":"2ed89ec0.b5f5b2","name":"Insert/Update device endpoint query","func":"\nmsg.datapath = \"/devices/\" + msg.payload.shortAddress;\n\nlet endpoints = {};\n\nmsg.payload.endpoints.map(x => {\n endpoints[x] = {};\n})\nmsg.payload.endpoints = endpoints;\ndelete msg.payload.endpointCount;\ndelete msg.payload.rssi;\ndelete msg.payload.sequenceNumber;\ndelete msg.payload.status;\ndelete msg.payload.length;\ndelete msg.payload.checksum;\ndelete msg.payload.code;\n\n\nreturn msg;","outputs":1,"noerr":0,"x":1670,"y":480,"wires":[["11220606.be9eaa"]]},{"id":"80a2a5da.ae2e58","type":"function","z":"2ed89ec0.b5f5b2","name":"Insert/Update device cluster query","func":"\nmsg.datapath = \"/devices/\" + msg.payload.nwkAddress+\"/endpoints/\" + msg.payload.endpoint;\n\n\nmsg.payload.clusters = {};\n/*\n\nlet inClusters = {};\nlet outClusters = {};\n*/\nmsg.payload.inClusterList.map(x => {\n //inClusters[x] = {};\n msg.payload.clusters[x] = {};\n})\n/*\nmsg.payload.inClusters = inClusters;\n\nmsg.payload.outClusterList.map(x => {\n outClusters[x] = {};\n})\nmsg.payload.outClusters = outClusters;*/\n\n\n\n\ndelete msg.payload.sequenceNumber;\ndelete msg.payload.status;\ndelete msg.payload.nwkAddress;\ndelete msg.payload.endpoint;\ndelete msg.payload.profile;\ndelete msg.payload.inClusterCount;\ndelete msg.payload.inClusterList;\ndelete msg.payload.outClusterCount;\ndelete msg.payload.outClusterList;\ndelete msg.payload.rssi;\ndelete msg.payload.length;\ndelete msg.payload.checksum;\ndelete msg.payload.code;\nreturn msg;","outputs":1,"noerr":0,"x":1660,"y":520,"wires":[["11220606.be9eaa"]]},{"id":"a75eb05d.512a5","type":"function","z":"2ed89ec0.b5f5b2","name":"Device List Response","func":"var r = msg.payload;\nlet devices = [];\nfor(var i = 0; i < Math.round((msg.payload.length / 13)); i ++){\n let offset = 13 * i;\n let d = {};\n d.id = r.payload.slice(offset,offset + 1).toString(\"hex\");\n d.shortAddress = r.payload.slice(offset +1,offset +3).toString(\"hex\");\n d.IEEEAddress = r.payload.slice(offset +3,offset +11).toString(\"hex\");\n d.powerSource = r.payload.slice(offset +11,offset +12).toString(\"hex\");\n d.linkQuality = parseInt(r.payload.slice(offset +12,offset +13).toString(\"hex\"), 16); \n \n devices.push(d);\n} \ndelete r.payload;\n\nmsg.payload = devices;\nreturn msg;","outputs":1,"noerr":0,"x":940,"y":200,"wires":[["8e12f490.0ee5f8","e47d43bc.1703b","b3207b17.68b9d8"]]},{"id":"2a22281c.923a68","type":"function","z":"2ed89ec0.b5f5b2","name":"Status Response","func":"var r = msg.payload;\nr.status = parseInt(r.payload.slice(0,1).toString(\"hex\"),16);\nr.sequence = parseInt(r.payload.slice(1,2).toString(\"hex\"),16);\nr.packetType = parseInt(r.payload.slice(2,4).toString(\"hex\"),16);\ndelete r.payload;\nr.statusCode = r.status;\n\nif(r.status === 0){\n r.status = \"Success\";\n}else if(r.status === 1){\n r.status = \"Incorrect parameters\";\n}else if(r.status === 2){\n r.status = \"Unhandled command\";\n}else if(r.status === 3){\n r.status = \"Command failed\";\n}else if(r.status === 4){\n r.status = \"Busy\";\n}else if(r.status === 5){\n r.status = \"Stack already started\";\n}else if(r.status >= 128){\n r.status = \"Failed (ZigBee event codes)\";\n} \n\nmsg.payload = r;\n\nreturn msg;","outputs":1,"noerr":0,"x":930,"y":160,"wires":[["8e12f490.0ee5f8"]]},{"id":"64a1cdd4.558474","type":"function","z":"2ed89ec0.b5f5b2","name":"Version List Response","func":"var r = msg.payload;\nr.majorVersion = r.payload.slice(0,2).toString(\"hex\");\nr.installerVersion = r.payload.slice(2,4).toString(\"hex\");\n//r.channel = r.payload.slice(4,5).toString(\"hex\");\ndelete r.payload;\n\nmsg.payload = r;\n\nreturn msg;","outputs":1,"noerr":0,"x":940,"y":120,"wires":[["8e12f490.0ee5f8"]]},{"id":"77642274.585d9c","type":"join","z":"2ed89ec0.b5f5b2","name":"Merge Payloads","mode":"custom","build":"array","property":"payload","propertyType":"msg","key":"topic","joiner":"\\n","joinerType":"str","accumulate":false,"timeout":"","count":"","reduceRight":false,"reduceExp":"","reduceInit":"","reduceInitType":"num","reduceFixup":"","x":1600,"y":340,"wires":[["c7fc1977.b5c188"]]},{"id":"11220606.be9eaa","type":"DataIn","z":"2ed89ec0.b5f5b2","collection":"875df393.5dcfe","name":"ZIgate Devices DB","update":true,"path":"/","x":2190,"y":500,"wires":[]},{"id":"da160378.c6125","type":"switch","z":"2ed89ec0.b5f5b2","name":"Generate the response by code","property":"payload.code","propertyType":"msg","rules":[{"t":"eq","v":"8010","vt":"str"},{"t":"eq","v":"8000","vt":"str"},{"t":"eq","v":"8015","vt":"str"},{"t":"eq","v":"8024","vt":"str"},{"t":"eq","v":"8045","vt":"str"},{"t":"eq","v":"8702","vt":"str"},{"t":"eq","v":"8043","vt":"str"},{"t":"eq","v":"004d","vt":"str"},{"t":"eq","v":"8048","vt":"str"},{"t":"eq","v":"8009","vt":"str"},{"t":"eq","v":"8042","vt":"str"},{"t":"eq","v":"8102","vt":"str"}],"checkall":"false","repair":false,"outputs":12,"x":550,"y":340,"wires":[["64a1cdd4.558474"],["2a22281c.923a68"],["a75eb05d.512a5"],["326b4b0.9daacb6"],["e113ead8.6ec498"],["c893ff4f.5d194"],["b6fb1d3f.3f3d9"],["93b09afd.b52828"],["a75fbd4.f632b4"],["8ace1a1a.ea96d8"],["420a3085.863bf"],["c148378e.6d0348"]]},{"id":"96aae0bb.a655f","type":"function","z":"2ed89ec0.b5f5b2","name":"Parse Telegram","func":"let result = {\n \"code\" : undefined,\n \"length\" : undefined,\n \"checksum\" : undefined,\n \"payload\" : undefined,\n \"rssi\" : undefined\n}\n\n\nresult.code = msg.payload.slice(1,3).toString(\"hex\");\nresult.length = parseInt(msg.payload.slice(3,5).toString(\"hex\"),16);\nresult.checksum = msg.payload.slice(5,6).toString(\"hex\");\nresult.payload = msg.payload.slice(6,(6+result.length));\nresult.rssi = parseInt(result.payload[result.payload.length-1],16);\n\nmsg.payload = result;\n\n//node.warn(result);\nreturn msg;","outputs":1,"noerr":0,"x":200,"y":420,"wires":[["da160378.c6125"]]},{"id":"b00e23f9.b5be6","type":"function","z":"2ed89ec0.b5f5b2","name":"Unescape Telegram","func":"let unescapeData =\tfunction(data) {\n var decodedLength = 0;\n var decodedData = Buffer.alloc(data.length);\n var i=0;\n while (i0) {\n \t\treturn unescapeData(data.slice(i));\n \t}\n \telse if (data[i] === 0x02) {\n \t\tif ((i+1) {\n if(x == 0x03){\n total ++;\n }\n});\nflow.set(\"counter\", 0);\nflow.set(\"telegrams_total\", total);\nreturn msg;","outputs":1,"noerr":0,"x":230,"y":240,"wires":[["94abbd64.8a2ef"]]},{"id":"93b09afd.b52828","type":"function","z":"2ed89ec0.b5f5b2","name":"Device Announce Response","func":"var r = msg.payload;\nr.shortAddress = r.payload.slice(0,2).toString(\"hex\");\nr.IEEEAddress = r.payload.slice(2,10).toString(\"hex\");\nr.MACCapability = r.payload.slice(10,11).toString(\"hex\");\nr.alternatePANCoordinator = (\"00000000\" + parseInt(r.payload.slice(10,11).toString(\"hex\"),16).toString(2)).substr(-8).substr(0,1);\nr.deviceType = (\"00000000\" + parseInt(r.payload.slice(10,11).toString(\"hex\"),16).toString(2)).substr(-8).substr(1,1);\nr.powerSource = parseInt((\"00000000\" + parseInt(r.payload.slice(10,11).toString(\"hex\"),16).toString(2)).substr(-8).substr(2,1));\nr.receiverOnWhenIdle = (\"00000000\" + parseInt(r.payload.slice(10,11).toString(\"hex\"),16).toString(2)).substr(-8).substr(3,1);\nr.securityCapability = (\"00000000\" + parseInt(r.payload.slice(10,11).toString(\"hex\"),16).toString(2)).substr(-8).substr(6,1);\nr.allocateAddress = (\"00000000\" + parseInt(r.payload.slice(10,11).toString(\"hex\"),16).toString(2)).substr(-8).substr(7,1);\ndelete r.payload;\n\nmsg.payload = r;\nreturn msg;","outputs":1,"noerr":0,"x":960,"y":400,"wires":[["8e12f490.0ee5f8","6435ee35.5630c"]]},{"id":"da913c8c.b1682","type":"http in","z":"75679700.c053a8","name":"","url":"/zigate/remove/:shortAddress/:extendedAddress","method":"get","upload":false,"swaggerDoc":"","x":230,"y":600,"wires":[["3ae4e337.1ec95c"]]},{"id":"3ae4e337.1ec95c","type":"function","z":"75679700.c053a8","name":"Remove Command","func":"msg.payload = {\n msgType : 0x0026,\n data : [ parseInt(msg.req.params.shortAddress.substr(0,2), 16), \n parseInt(msg.req.params.shortAddress.substr(2,2), 16),\n parseInt(msg.req.params.extendedAddress.substr(0,2), 16),\n parseInt(msg.req.params.extendedAddress.substr(2,2), 16),\n parseInt(msg.req.params.extendedAddress.substr(4,2), 16),\n parseInt(msg.req.params.extendedAddress.substr(6,2), 16),\n parseInt(msg.req.params.extendedAddress.substr(8,2), 16),\n parseInt(msg.req.params.extendedAddress.substr(10,2), 16),\n parseInt(msg.req.params.extendedAddress.substr(12,2), 16),\n parseInt(msg.req.params.extendedAddress.substr(14,2), 16)\n ]\n}\n\nreturn msg;","outputs":1,"noerr":0,"x":629.5,"y":600,"wires":[["4a9c7f57.0baca"]]},{"id":"a75fbd4.f632b4","type":"function","z":"2ed89ec0.b5f5b2","name":"Leave Indication Response","func":"var r = msg.payload;\nr.extendedAddress = r.payload.slice(0,8).toString(\"hex\");\nr.rejoinStatus = r.payload.slice(8,9).toString(\"hex\");\n\ndelete r.payload;\n\nmsg.payload = r;\nreturn msg;","outputs":1,"noerr":0,"x":960,"y":440,"wires":[["8e12f490.0ee5f8"]]},{"id":"6f8616be.bea608","type":"http in","z":"75679700.c053a8","name":"","url":"/zigate/networkState","method":"get","upload":false,"swaggerDoc":"","x":150,"y":640,"wires":[["e872fd1b.19d22"]]},{"id":"e872fd1b.19d22","type":"function","z":"75679700.c053a8","name":"Get Network State Command","func":"msg.payload = {\n msgType : 0x0009,\n data : [ ]\n}\n\nreturn msg;","outputs":1,"noerr":0,"x":659.5,"y":640,"wires":[["4a9c7f57.0baca"]]},{"id":"8ace1a1a.ea96d8","type":"function","z":"2ed89ec0.b5f5b2","name":"Network State Response","func":"var r = msg.payload;\nr.shortAddress = r.payload.slice(0,2).toString(\"hex\");\nr.extendedAddress = r.payload.slice(2,10).toString(\"hex\");\nr.PANId = r.payload.slice(10,12).toString(\"hex\");\nr.ExtPANId = r.payload.slice(12,14).toString(\"hex\");\nr.channel = r.payload.slice(14,15).toString(\"hex\");\n\ndelete r.payload;\n\nmsg.payload = r;\nreturn msg;","outputs":1,"noerr":0,"x":950,"y":480,"wires":[["8e12f490.0ee5f8"]]},{"id":"3e26dab9.f5f2a6","type":"http in","z":"75679700.c053a8","name":"","url":"/zigate/nodeDescriptor/:shortAddress","method":"get","upload":false,"swaggerDoc":"","x":200,"y":240,"wires":[["3e48c916.025ec6"]]},{"id":"3e48c916.025ec6","type":"function","z":"75679700.c053a8","name":"Node Descriptor Command","func":"var shortAddress = msg.req.params.shortAddress;\nmsg.payload = {\n msgType : 0x0042,\n data : [parseInt(shortAddress.substr(0,2), 16), parseInt(shortAddress.substr(2,2), 16)]\n}\nreturn msg;","outputs":1,"noerr":0,"x":659.5,"y":240,"wires":[["4a9c7f57.0baca"]]},{"id":"420a3085.863bf","type":"function","z":"2ed89ec0.b5f5b2","name":"Node Descriptor Response","func":"var r = msg.payload;\nr.sequenceNumber = parseInt(r.payload.slice(0,1).toString(\"hex\"), 16);\nr.status = parseInt(r.payload.slice(1,2).toString(\"hex\"), 16);\nr.networkAddress = r.payload.slice(2,4).toString(\"hex\");\nr.manufacturerCode = r.payload.slice(4,6).toString(\"hex\");\nr.maxRxSize = r.payload.slice(6,8).toString(\"hex\");\nr.maxTxSize = r.payload.slice(8,10).toString(\"hex\");\nr.serverMask = r.payload.slice(10,12).toString(\"hex\");\nr.descriptorCapability = r.payload.slice(12,13).toString(\"hex\");\nr.macFlags = r.payload.slice(13,14).toString(\"hex\");\nr.maxBufferSizz = r.payload.slice(14,15).toString(\"hex\");\nr.bitsFields = r.payload.slice(15,17).toString(\"hex\");\n\ndelete r.payload;\n\nmsg.payload = r;\nreturn msg;","outputs":1,"noerr":0,"x":960,"y":520,"wires":[["8e12f490.0ee5f8"]]},{"id":"c7fc1977.b5c188","type":"function","z":"2ed89ec0.b5f5b2","name":"Generate JSON Response","func":"let r = {\n \"status\" : {\n \"value\" : \"Success\",\n \"code\" : 0\n },\n \"response\" : []\n};\n\nmsg.payload.map(t => {\n if(t.code === \"8000\"){\n r.status.value = t.status;\n r.status.code = t.statusCode;\n }else{\n if(t.code === \"8702\"){\n r.status.value = \"APS Data Confirm Fail\";\n r.status.code = 3;\n }\n delete t.checksum;\n delete t.length;\n //delete t.code;\n r.response.push(t);\n }\n})\n\nif(r.response.length === 0){\n delete r.response;\n}\n\nmsg.payload = r;\nmsg.topic = \"zigate_response\";\n\nreturn msg;","outputs":1,"noerr":0,"x":1860,"y":340,"wires":[[]]},{"id":"424b9b90.3995c4","type":"http in","z":"75679700.c053a8","name":"","url":"/zigate/erasepersistentdata","method":"get","upload":false,"swaggerDoc":"","x":170,"y":680,"wires":[["7ae611ff.28bd8"]]},{"id":"7ae611ff.28bd8","type":"function","z":"75679700.c053a8","name":"Erase Persistent Data Command","func":"msg.payload = {\n msgType : 0x0012,\n data : [ ]\n}\n\nreturn msg;","outputs":1,"noerr":0,"x":679.5,"y":680,"wires":[["4a9c7f57.0baca"]]},{"id":"b3207b17.68b9d8","type":"split","z":"2ed89ec0.b5f5b2","name":"","splt":"\\n","spltType":"str","arraySplt":1,"arraySpltType":"len","stream":false,"addname":"","x":1270,"y":500,"wires":[["6435ee35.5630c"]]},{"id":"d4d1b43a.5aa278","type":"http in","z":"75679700.c053a8","name":"","url":"/zigate/attribute/:shortAddress/:endpoint/:cluster/:attribute","method":"get","upload":false,"swaggerDoc":"","x":260,"y":720,"wires":[["d28ea56b.2c2468"]]},{"id":"d28ea56b.2c2468","type":"function","z":"75679700.c053a8","name":"Attribute Command","func":"var shortAddress = msg.req.params.shortAddress;\nvar endpoint = msg.req.params.endpoint;\nvar cluster = msg.req.params.cluster;\nvar attribute = msg.req.params.attribute;\nmsg.payload = {\n msgType : 0x0100,\n data : [\n 0x02,\n parseInt(shortAddress.substr(0,2), 16),\n parseInt(shortAddress.substr(2,2), 16),\n 0x01,\n parseInt(endpoint.substr(0,2), 16),\n parseInt(cluster.substr(0,2), 16),\n parseInt(cluster.substr(2,2), 16),\n 0x00,\n 0x00,\n 0x00,\n 0x00,\n Math.round((attribute.length / 4))\n ]\n}\n\n\nfor(let i = 0;i < Math.round((attribute.length / 4)); i ++){\n msg.payload.data.push(parseInt(attribute.substr(0 + (i * 4),2), 16))\n msg.payload.data.push(parseInt(attribute.substr(2 + (i * 4),2), 16))\n}\n\nreturn msg;","outputs":1,"noerr":0,"x":630,"y":720,"wires":[["4a9c7f57.0baca"]]},{"id":"c148378e.6d0348","type":"function","z":"2ed89ec0.b5f5b2","name":"Report Individual Attribute Response","func":"let hex_to_ascii = function(str1)\n {\n\tvar hex = str1.toString();\n\tvar str = '';\n\tfor (var n = 0; n < hex.length; n += 2) {\n\t\tstr += String.fromCharCode(parseInt(hex.substr(n, 2), 16));\n\t}\n\treturn str;\n }\n\n\nvar r = msg.payload;\nr.sequenceNumber = parseInt(r.payload.slice(0,1).toString(\"hex\"), 16);\nr.srcAddress = r.payload.slice(1,3).toString(\"hex\");\nr.endpoint = r.payload.slice(3,4).toString(\"hex\");\nr.clusterId = r.payload.slice(4,6).toString(\"hex\");\nr.attributeEnum = r.payload.slice(6,8).toString(\"hex\");\nr.attributeStatus = r.payload.slice(8,9).toString(\"hex\");\nr.attributeDataType = parseInt(r.payload.slice(9,10).toString(\"hex\"), 16);\nr.sizeOfAttribute = parseInt(r.payload.slice(10,12).toString(\"hex\"), 16);\n\nr.dataByte = r.payload.slice(12, 12 + r.sizeOfAttribute).toString(\"hex\");\n\nif (r.attributeDataType == 16 || r.attributeDataType == 32){\n r.dataByte = parseInt(r.dataByte, 16);\n}else if (r.attributeDataType == 66){\n r.dataByte = hex_to_ascii(r.dataByte);\n}else if (r.attributeDataType == 41 || r.attributeDataType == 33){\n if(r.clusterId === \"0402\" || r.clusterId === \"0405\"){\n r.dataByte = parseInt(r.dataByte, 16)/100; \n }else{\n r.dataByte = parseInt(r.dataByte, 16); \n }\n\n}else if (r.attributeDataType == 24){\n r.dataByte = parseFloat(r.dataByte, 10);\n}\n\n\n\ndelete r.payload;\n\nmsg.payload = r;\nreturn msg;","outputs":1,"noerr":0,"x":990,"y":560,"wires":[["8e12f490.0ee5f8","2ec4ac7a.d5a9e4"]]},{"id":"2ec4ac7a.d5a9e4","type":"function","z":"2ed89ec0.b5f5b2","name":"Insert/Update device attribute query","func":"let decodeCluster = function (code){\n let clustersName = {\n \"0000\" : \"Basic\",\n \"0001\" : \"Power Configuration\",\n \"0002\" : \"Device Temperature Configuration\",\n \"0003\" : \"Identify\",\n \"0004\" : \"Groups\",\n \"0005\" : \"Scenes\",\n \"0006\" : \"On/Off\",\n \"0007\" : \"On/Off Switch Configuration\",\n \"0008\" : \"Level Control\",\n \"0009\" : \"Alarms\",\n \"000a\" : \"Time\",\n \"000b\" : \"RSSI Location\",\n \"000c\" : \"Analog Input (Basic)\",\n \"000d\" : \"Analog Output (Basic)\",\n \"000e\" : \"Analog Value (Basic)\",\n \"000f\" : \"Binary Input (Basic)\",\n \"0010\" : \"Binary Output (Basic)\",\n \"0011\" : \"Binary Value (Basic)\",\n \"0012\" : \"Multistate Input (Basic)\",\n \"0013\" : \"Multistate Output (Basic)\",\n \"0014\" : \"Multistate Value (Basic)\",\n \"0015\" : \"Commissioning\",\n \"0101\" : \"Door Lock\",\n \"0201\" : \"Thermostat\",\n \"0204\" : \"Thermostat User Interface Configuration\",\n \"0300\" : \"Colour Control\",\n \"0400\" : \"Illuminance Measurement\",\n \"0401\" : \"Illuminance Level Sensing\",\n \"0402\" : \"Temperature Measurement\",\n \"0405\" : \"Relative Humidity Measurement\",\n \"0406\" : \"Occupancy Sensing\",\n \"0500\" : \"IAS Zone\",\n \"0501\" : \"IAS ACE (Ancillary Control Equipment)\",\n \"0502\" : \"IAS WD (Warning Device)\",\n }\n return clustersName[code] || code;\n}\n\nlet decodeClusterAttribute = function(cluster, code){\n let attributesName = {\n \"0000\" : {\n \"0004\" : \"ManufacturerName\",\n \"0005\" : \"ModelIdentifier\" \n },\n \"0006\" : {\n \"0000\" : \"OnOff\",\n },\n \"0402\" : {\n \"0000\" : \"Temperature\"\n },\n \"0405\" : {\n \"0000\" : \"Humidity\"\n },\n \"0406\" : {\n \"0000\" : \"Sensor\"\n },\n \"0012\" : {\n \"0055\" : \"PresentValue\"\n }\n }\n return attributesName[cluster][code] || code\n}\n\nvar cluster = msg.payload.clusterId;\n//Special for the magic cube to keep coherence between values\nif(cluster == \"000c\"){\n cluster = \"0012\"\n msg.payload.clusterId = \"0012\"\n msg.payload.endpoint = \"02\"\n}\n\nmsg.datapath = \"/devices/\" + msg.payload.srcAddress+\"/endpoints/\" + msg.payload.endpoint+\"/clusters/\"+cluster;\n\nmsg.payload.clusterName = decodeCluster(cluster);\n\n\nmsg.payload[ msg.payload.attributeEnum] = {\n \"name\" : decodeClusterAttribute(cluster, msg.payload.attributeEnum),\n \"value\" :msg.payload.dataByte,\n \"lastUpdated\" : Date.now()\n}\ndelete msg.payload.sequenceNumber;\ndelete msg.payload.status;\ndelete msg.payload.dataByte;\ndelete msg.payload.clusterId;\ndelete msg.payload.srcAddress;\ndelete msg.payload.endpoint;\ndelete msg.payload.profile;\ndelete msg.payload.attributeEnum;\ndelete msg.payload.attributeStatus;\ndelete msg.payload.attributeDataType;\ndelete msg.payload.sizeOfAttribute;\ndelete msg.payload.rssi;\ndelete msg.payload.length;\ndelete msg.payload.checksum;\ndelete msg.payload.code;\n\nreturn msg;","outputs":1,"noerr":0,"x":1660,"y":560,"wires":[["11220606.be9eaa"]]},{"id":"4d776546.a99b8c","type":"function","z":"8e737be3.b45a58","name":"Active EndPoint Command","func":"flow.set(\"shortAddress\", msg.payload.shortAddress);\nmsg.payload = {\n msgType : 0x0045,\n data : [parseInt(msg.payload.shortAddress.substr(0,2), 16), parseInt(msg.payload.shortAddress.substr(2,4), 16)]\n}\n\nreturn msg;","outputs":1,"noerr":0,"x":240,"y":320,"wires":[["15e9e141.30b94f"]]},{"id":"fff69738.8ae8f8","type":"function","z":"8e737be3.b45a58","name":"Convert Endpoints To Payload","func":"let payload = [];\nif(msg.payload.response !== undefined && msg.payload.response.length > 0){\n msg.payload.response.map(x => {\n if(x.endpoints !== undefined){\n x.endpoints.map(e => {\n payload.push(e);\n })\n }\n })\n}\n\nif(payload.length === 0){\n msg.payload = {};\n return [null, msg];\n}else{\n msg.payload = payload;\n return [msg, null];\n}","outputs":2,"noerr":0,"x":870,"y":320,"wires":[["470c7dc4.d58ff4"],["bac206bb.314958"]]},{"id":"527fdfc2.aa69a","type":"http in","z":"75679700.c053a8","name":"","url":"/zigate/autodiscover/:shortAddress","method":"get","upload":false,"swaggerDoc":"","x":190,"y":800,"wires":[["4bc5d5ef.affbbc"]]},{"id":"eec7b486.ae8d98","type":"subflow:8e737be3.b45a58","z":"75679700.c053a8","name":"","env":[],"x":990,"y":800,"wires":[["2fb00a56.901086"]]},{"id":"4bc5d5ef.affbbc","type":"function","z":"75679700.c053a8","name":"Convert To Payload","func":"msg.payload = {\n \"shortAddress\" : msg.req.params.shortAddress\n}\nreturn msg;","outputs":1,"noerr":0,"x":630,"y":800,"wires":[["eec7b486.ae8d98"]]},{"id":"470c7dc4.d58ff4","type":"split","z":"8e737be3.b45a58","name":"ForEach Endpoint","splt":"\\n","spltType":"str","arraySplt":1,"arraySpltType":"len","stream":false,"addname":"","x":1150,"y":320,"wires":[["79cd98ea.8e9fc8"]]},{"id":"79cd98ea.8e9fc8","type":"function","z":"8e737be3.b45a58","name":"Simple Descriptor Command","func":"let shortAddress = flow.get(\"shortAddress\");\nflow.set(\"endpoint\", msg.payload);\nmsg.payload = {\n msgType : 0x0043,\n data : [parseInt(shortAddress.substr(0,2), 16), parseInt(shortAddress.substr(2,4), 16), parseInt(msg.payload, 16)]\n}\nreturn msg;","outputs":1,"noerr":0,"x":240,"y":400,"wires":[["1408746b.55201c"]]},{"id":"ce4f25e1.4f7038","type":"function","z":"8e737be3.b45a58","name":"Convert Endpoints To Payload","func":"let payload = [];\nif(msg.payload.response !== undefined && msg.payload.response.length > 0){\n msg.payload.response.map(x => {\n if(x.inClusterList !== undefined){\n x.inClusterList.map(e => {\n payload.push(e);\n })\n }\n })\n}\nmsg.payload = payload;\nreturn msg;","outputs":1,"noerr":0,"x":870,"y":400,"wires":[["29fb553d.c96c2a"]]},{"id":"29fb553d.c96c2a","type":"split","z":"8e737be3.b45a58","name":"ForEach Clusters","splt":"\\n","spltType":"str","arraySplt":1,"arraySpltType":"len","stream":false,"addname":"","x":1130,"y":400,"wires":[["cab4f65f.5b92f8"]]},{"id":"bac206bb.314958","type":"function","z":"8e737be3.b45a58","name":"Database Device Query","func":"let shortAddress = flow.get(\"shortAddress\");\nmsg.datapath = \"/devices/\" + shortAddress;\nreturn msg;","outputs":1,"noerr":0,"x":1010,"y":520,"wires":[["5fe5a19a.5991b"]]},{"id":"5fe5a19a.5991b","type":"DataOut","z":"8e737be3.b45a58","collection":"875df393.5dcfe","name":"Zigate Devices DB","path":"/","error":false,"x":1250,"y":520,"wires":[["65d13696.b19588"]]},{"id":"cab4f65f.5b92f8","type":"switch","z":"8e737be3.b45a58","name":"","property":"payload","propertyType":"msg","rules":[{"t":"eq","v":"0000","vt":"str"},{"t":"eq","v":"0006","vt":"str"},{"t":"else"}],"checkall":"true","repair":false,"outputs":3,"x":170,"y":480,"wires":[["e394cced.a80e9"],["e3f15f0b.e0d5c"],[]]},{"id":"e394cced.a80e9","type":"function","z":"8e737be3.b45a58","name":"Cluster 0000 Attribute Command","func":"let shortAddress = flow.get(\"shortAddress\");\nlet endpoint = flow.get(\"endpoint\");\nlet size = 2;\nlet attributes = \"00040005\";\nmsg.payload = {\n msgType : 0x0100,\n data : [\n 0x02,\n parseInt(shortAddress.substr(0,2), 16),\n parseInt(shortAddress.substr(2,2), 16),\n 0x01,\n // parseInt(msg.req.params.endpoint.substr(0,2), 16),\n parseInt(endpoint.substr(0,2), 16),\n parseInt(msg.payload.substr(0,2), 16),\n parseInt(msg.payload.substr(2,2), 16),\n 0x00,\n 0x00,\n 0x00,\n 0x00\n ]\n}\n\nmsg.payload.data.push(size);\nfor(let i = 0;i < size; i ++){\n msg.payload.data.push(parseInt(attributes.substr(0 + (i * 4),2), 16))\n msg.payload.data.push(parseInt(attributes.substr(2 + (i * 4),2), 16))\n}\n\n\nreturn msg;","outputs":1,"noerr":0,"x":400,"y":480,"wires":[["bd306979.e6c8d8"]]},{"id":"8587c359.ca52c","type":"join","z":"8e737be3.b45a58","name":"","mode":"custom","build":"string","property":"payload","propertyType":"msg","key":"topic","joiner":"\\n","joinerType":"str","accumulate":false,"timeout":"5","count":"","reduceRight":false,"reduceExp":"","reduceInit":"","reduceInitType":"","reduceFixup":"","x":690,"y":540,"wires":[["bac206bb.314958"]]},{"id":"e3f15f0b.e0d5c","type":"function","z":"8e737be3.b45a58","name":"Cluster 0006 Attribute Command","func":"let shortAddress = flow.get(\"shortAddress\");\nlet endpoint = flow.get(\"endpoint\");\nlet size = 1;\nlet attributes = \"0000\";\nmsg.payload = {\n msgType : 0x0100,\n data : [\n 0x02,\n parseInt(shortAddress.substr(0,2), 16),\n parseInt(shortAddress.substr(2,2), 16),\n 0x01,\n // parseInt(msg.req.params.endpoint.substr(0,2), 16),\n parseInt(endpoint.substr(0,2), 16),\n parseInt(msg.payload.substr(0,2), 16),\n parseInt(msg.payload.substr(2,2), 16),\n 0x00,\n 0x00,\n 0x00,\n 0x00\n ]\n}\nmsg.payload.data.push(size);\nfor(let i = 0;i < size; i ++){\n msg.payload.data.push(parseInt(attributes.substr(0 + (i * 4),2), 16))\n msg.payload.data.push(parseInt(attributes.substr(2 + (i * 4),2), 16))\n}\n\n\nreturn msg;","outputs":1,"noerr":0,"x":400,"y":520,"wires":[["bd306979.e6c8d8"]]},{"id":"70315e2d.1fb19","type":"uibuilder","z":"8f50bdda.84b77","name":"Zigate UI","topic":"zigate_devices","url":"zigate","fwdInMessages":false,"allowScripts":false,"allowStyles":false,"copyIndex":false,"showfolder":false,"x":890,"y":120,"wires":[["ba853d9e.d2b7b"],[]]},{"id":"5f2c72d.5f2d18c","type":"DataOut","z":"8f50bdda.84b77","collection":"875df393.5dcfe","name":"Zigate Devices DB","path":"/","error":true,"x":1530,"y":580,"wires":[["c526ef86.7cde7"]]},{"id":"ba853d9e.d2b7b","type":"switch","z":"8f50bdda.84b77","name":"Commands Received From UI","property":"topic","propertyType":"msg","rules":[{"t":"cont","v":"zigate_command","vt":"str"},{"t":"eq","v":"db_update_name","vt":"str"},{"t":"eq","v":"zigate_autodiscover","vt":"str"},{"t":"eq","v":"refresh_devices","vt":"str"}],"checkall":"false","repair":false,"outputs":4,"x":130,"y":580,"wires":[["811ffbcc.58c8c8"],["34d511ff.790bee"],["63d6d8bd.d5dff8"],["1d0da9b5.2704c6"]]},{"id":"c2cb1afb.b6b498","type":"DataIn","z":"75679700.c053a8","collection":"875df393.5dcfe","name":"Save devices - No Merge","update":false,"path":"/devices","x":970,"y":1140,"wires":[]},{"id":"f6af851d.cc8d48","type":"http in","z":"75679700.c053a8","name":"","url":"/zigate/devices/db/reset","method":"get","upload":false,"swaggerDoc":"","x":140,"y":1140,"wires":[["62ceaead.f187d"]]},{"id":"62ceaead.f187d","type":"function","z":"75679700.c053a8","name":"Database Device Query","func":"msg.payload = {};\nreturn msg;","outputs":1,"noerr":0,"x":630,"y":1140,"wires":[["2fb00a56.901086","c2cb1afb.b6b498"]]},{"id":"35b82744.7cd588","type":"http in","z":"75679700.c053a8","name":"","url":"/zigate/devices/name/:shortAddress/:name","method":"get","upload":false,"swaggerDoc":"","x":200,"y":1180,"wires":[["db8e5d1a.16702"]]},{"id":"db8e5d1a.16702","type":"function","z":"75679700.c053a8","name":"Database Device Query","func":"msg.datapath = \"/devices/\" + msg.req.params.shortAddress.toLowerCase();\nmsg.payload.name = msg.req.params.name;\nreturn msg;","outputs":1,"noerr":0,"x":629.5,"y":1180,"wires":[["bdb6a2a7.43a9"]]},{"id":"bdb6a2a7.43a9","type":"DataIn","z":"75679700.c053a8","collection":"875df393.5dcfe","name":"Save device - Merge","update":true,"path":"/devices","x":960,"y":1180,"wires":[]},{"id":"fd1b2b36.4ab448","type":"DataIn","z":"8f50bdda.84b77","collection":"875df393.5dcfe","name":"Save device - Merge","update":true,"path":"/devices","x":720,"y":500,"wires":[]},{"id":"20babac1.0d6bb6","type":"DataOut","z":"8f50bdda.84b77","collection":"875df393.5dcfe","name":"Query Status","path":"/devices","error":false,"x":470,"y":700,"wires":[["7046575c.5f0a88"]]},{"id":"7046575c.5f0a88","type":"function","z":"8f50bdda.84b77","name":"Convert To Array","func":"var devices = [];\n\nfor(var shortAddress in msg.payload){\n devices.push({\"shortAddress\" : shortAddress});\n}\nmsg.payload = devices;\nreturn msg;","outputs":1,"noerr":0,"x":670,"y":700,"wires":[["4d0c4a3c.941334"]]},{"id":"4d0c4a3c.941334","type":"split","z":"8f50bdda.84b77","name":"","splt":"\\n","spltType":"str","arraySplt":1,"arraySpltType":"len","stream":false,"addname":"","x":850,"y":700,"wires":[["63d6d8bd.d5dff8"]]},{"id":"63d6d8bd.d5dff8","type":"subflow:8e737be3.b45a58","z":"8f50bdda.84b77","name":"","env":[],"x":1090,"y":580,"wires":[["47ba73cf.543aac"]]},{"id":"65d13696.b19588","type":"function","z":"8e737be3.b45a58","name":"Convert to Response Standard","func":"msg.payload = {\n \"status\" : {\n \"code\" : 0,\n \"value\" : \"Success\"\n },\n \"response\" : msg.payload\n};\n\n//node.warn(\"End Discover\");\n//node.warn(msg.payload);\nreturn msg;","outputs":1,"noerr":0,"x":1190,"y":600,"wires":[[]]},{"id":"c526ef86.7cde7","type":"function","z":"8f50bdda.84b77","name":"Add Topic","func":"msg.topic = \"zigate_devices\"\nreturn msg;","outputs":1,"noerr":0,"x":1520,"y":520,"wires":[["70315e2d.1fb19"]]},{"id":"47ba73cf.543aac","type":"function","z":"8f50bdda.84b77","name":"set datapath","func":"msg.datapath = \"/\";\nreturn msg;","outputs":1,"noerr":0,"x":1330,"y":580,"wires":[["5f2c72d.5f2d18c"]]},{"id":"cfd86985.493b28","type":"subflow:c733c6b6.ada328","z":"ade00219.436f6","name":"","x":220,"y":120,"wires":[["2e6f4291.ca79ae"]]},{"id":"2e6f4291.ca79ae","type":"subflow:2ed89ec0.b5f5b2","z":"ade00219.436f6","name":"","x":510,"y":120,"wires":[[]]},{"id":"4a9c7f57.0baca","type":"subflow:ade00219.436f6","z":"75679700.c053a8","name":"","x":1030,"y":380,"wires":[["2fb00a56.901086"]]},{"id":"811ffbcc.58c8c8","type":"subflow:ade00219.436f6","z":"8f50bdda.84b77","name":"","env":[],"x":470,"y":460,"wires":[["70315e2d.1fb19"]]},{"id":"34d511ff.790bee","type":"function","z":"8f50bdda.84b77","name":"Database Device Query","func":"msg.datapath = \"/devices/\" + msg.payload.shortAddress.toLowerCase();\nmsg.payload.name = msg.payload.name;\n\nreturn msg;","outputs":1,"noerr":0,"x":470,"y":500,"wires":[["fd1b2b36.4ab448"]]},{"id":"15e9e141.30b94f","type":"subflow:ade00219.436f6","z":"8e737be3.b45a58","name":"","x":530,"y":320,"wires":[["fff69738.8ae8f8"]]},{"id":"1408746b.55201c","type":"subflow:ade00219.436f6","z":"8e737be3.b45a58","name":"","x":550,"y":400,"wires":[["ce4f25e1.4f7038"]]},{"id":"bd306979.e6c8d8","type":"subflow:ade00219.436f6","z":"8e737be3.b45a58","name":"","x":710,"y":480,"wires":[["8587c359.ca52c"]]},{"id":"37b7d9e4.672926","type":"serial in","z":"2a3adfb4.0cce2","name":"Zigate Serial Read","serial":"8bf91d15.7f53a","x":190,"y":80,"wires":[["41b0f76a.b2f6f8"]]},{"id":"41b0f76a.b2f6f8","type":"subflow:2ed89ec0.b5f5b2","z":"2a3adfb4.0cce2","name":"","env":[],"x":450,"y":80,"wires":[["82fa4e09.51b51","f64b7655.df4508"]]},{"id":"82fa4e09.51b51","type":"debug","z":"2a3adfb4.0cce2","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":1190,"y":80,"wires":[]},{"id":"9e6524fb.7de7a8","type":"split","z":"2a3adfb4.0cce2","name":"Treat Every Responses","splt":"\\n","spltType":"str","arraySplt":1,"arraySpltType":"len","stream":false,"addname":"","x":270,"y":240,"wires":[["ef4f4c81.29c47"]]},{"id":"f64b7655.df4508","type":"function","z":"2a3adfb4.0cce2","name":"Search for Attribute Response","func":"var newPayload = [];\n\nif(msg.payload.response !== undefined){\n newPayload = msg.payload.response.filter(x => x.code == \"8102\")\n}\n\n\nmsg.payload = newPayload;\nreturn msg;","outputs":1,"noerr":0,"x":270,"y":180,"wires":[["9e6524fb.7de7a8"]]},{"id":"ab91145e.1e3e08","type":"switch","z":"2a3adfb4.0cce2","name":"Door Sensor","property":"payload.dataByte","propertyType":"msg","rules":[{"t":"eq","v":"0","vt":"str"},{"t":"eq","v":"1","vt":"num"}],"checkall":"true","repair":false,"outputs":2,"x":590,"y":260,"wires":[["d1b53f73.e496f"],["f5ca554e.abb868"]]},{"id":"4b748bca.b376c4","type":"subflow:c733c6b6.ada328","z":"2a3adfb4.0cce2","name":"","env":[],"x":1160,"y":360,"wires":[[]]},{"id":"98878b.5b3a3878","type":"http in","z":"75679700.c053a8","name":"","url":"/zigate/removedevice/:IEEAddress","method":"get","upload":false,"swaggerDoc":"","x":190,"y":760,"wires":[["ac847e1c.a290f"]]},{"id":"ac847e1c.a290f","type":"function","z":"75679700.c053a8","name":"Remove Device","func":"var IEEAddress = msg.req.params.IEEAddress;\nmsg.payload = {\n msgType : 0x004C,\n data : [\n parseInt(IEEAddress.substr(0,2), 16),\n parseInt(IEEAddress.substr(2,2), 16),\n parseInt(IEEAddress.substr(4,2), 16),\n parseInt(IEEAddress.substr(6,2), 16),\n parseInt(IEEAddress.substr(8,2), 16),\n parseInt(IEEAddress.substr(10,2), 16),\n parseInt(IEEAddress.substr(12,2), 16),\n parseInt(IEEAddress.substr(14,2), 16),\n \n \n 0x00,\n 0x01\n ]\n}\n\n\n\nreturn msg;","outputs":1,"noerr":0,"x":620,"y":760,"wires":[["4a9c7f57.0baca"]]},{"id":"3b5b73e7.8547fc","type":"switch","z":"2a3adfb4.0cce2","name":"Motion Sensor","property":"payload.dataByte","propertyType":"msg","rules":[{"t":"eq","v":"0","vt":"str"},{"t":"eq","v":"1","vt":"num"}],"checkall":"true","repair":false,"outputs":2,"x":600,"y":320,"wires":[[],["988f8f09.bde5a"]]},{"id":"86fe58ca.83bc38","type":"delay","z":"2a3adfb4.0cce2","name":"","pauseType":"delay","timeout":"90","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"x":860,"y":460,"wires":[["e7c75cd1.8982e"]]},{"id":"e7c75cd1.8982e","type":"function","z":"2a3adfb4.0cce2","name":"Command motion stop","func":"var command = {\n msgType : 0x0000,\n data : []\n}\n\nvar shortAddress = \"8bb2\";\nvar endpoint = \"03\";\ncommand.msgType = 0x0092;\ncommand.data = [0x02, parseInt(shortAddress.substr(0,2), 16), parseInt(shortAddress.substr(2,2), 16), 0x01, parseInt(endpoint, 16), 0x00]\nmsg.payload = command;\nreturn msg;","outputs":1,"noerr":0,"x":860,"y":520,"wires":[["4b748bca.b376c4"]]},{"id":"d1b53f73.e496f","type":"function","z":"2a3adfb4.0cce2","name":"Light Garage Off","func":"var command = {msgType : 0x0000, data : []};\n//Send a OFF command to a light\nvar shortAddress = \"9bb8\";\nvar endpoint = \"03\";\ncommand.msgType = 0x0092;\ncommand.data = [0x02, parseInt(shortAddress.substr(0,2), 16), parseInt(shortAddress.substr(2,2), 16), 0x01, parseInt(endpoint, 16), 0x00]\nmsg.payload = command;\nreturn msg;","outputs":1,"noerr":0,"x":840,"y":220,"wires":[["4b748bca.b376c4"]]},{"id":"988f8f09.bde5a","type":"function","z":"2a3adfb4.0cce2","name":"Light Garage On","func":"var command = {msgType : 0x0000, data : []};\n//Send a OFF command to a light\nvar shortAddress = \"9bb8\";\nvar endpoint = \"03\";\ncommand.msgType = 0x0092;\ncommand.data = [0x02, parseInt(shortAddress.substr(0,2), 16), parseInt(shortAddress.substr(2,2), 16), 0x01, parseInt(endpoint, 16), 0x01]\nmsg.payload = command;\nreturn msg;","outputs":1,"noerr":0,"x":850,"y":340,"wires":[["4b748bca.b376c4","8c4962ac.100d6"]]},{"id":"ef4f4c81.29c47","type":"switch","z":"2a3adfb4.0cce2","name":"Switch Devices","property":"payload.srcAddress","propertyType":"msg","rules":[{"t":"eq","v":"9c1e","vt":"str"},{"t":"eq","v":"857f","vt":"str"},{"t":"eq","v":"1d2a","vt":"str"}],"checkall":"true","repair":false,"outputs":3,"x":300,"y":300,"wires":[["ab91145e.1e3e08"],["3b5b73e7.8547fc"],["86c3f5fa.26f298"]]},{"id":"f5ca554e.abb868","type":"function","z":"2a3adfb4.0cce2","name":"Light Garage On","func":"var command = {msgType : 0x0000, data : []};\n//Send a OFF command to a light\nvar shortAddress = \"9bb8\";\nvar endpoint = \"03\";\ncommand.msgType = 0x0092;\ncommand.data = [0x02, parseInt(shortAddress.substr(0,2), 16), parseInt(shortAddress.substr(2,2), 16), 0x01, parseInt(endpoint, 16), 0x01]\nmsg.payload = command;\nreturn msg;","outputs":1,"noerr":0,"x":850,"y":280,"wires":[["4b748bca.b376c4"]]},{"id":"4c248eb3.b5388","type":"serial in","z":"8f50bdda.84b77","name":"","serial":"8bf91d15.7f53a","x":190,"y":120,"wires":[["44070705.89ec68"]]},{"id":"44070705.89ec68","type":"subflow:2ed89ec0.b5f5b2","z":"8f50bdda.84b77","name":"","env":[],"x":390,"y":120,"wires":[["e3876963.5ff068"]]},{"id":"e3876963.5ff068","type":"delay","z":"8f50bdda.84b77","name":"","pauseType":"delay","timeout":"2","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"x":600,"y":120,"wires":[["47ba73cf.543aac"]]},{"id":"b96bfd71.d2b8f","type":"DataOut","z":"2ed89ec0.b5f5b2","collection":"875df393.5dcfe","name":"Get all devices","path":"/","error":false,"x":1580,"y":140,"wires":[["ab6afa30.b69718"]]},{"id":"e47d43bc.1703b","type":"function","z":"2ed89ec0.b5f5b2","name":"Store devices list","func":"msg.list = msg.payload;\nmsg.datapath = \"/\"\nreturn msg;","outputs":1,"noerr":0,"x":1330,"y":160,"wires":[["b96bfd71.d2b8f"]]},{"id":"ab6afa30.b69718","type":"function","z":"2ed89ec0.b5f5b2","name":"Remove unused devices","func":"for(var shortAddress in msg.payload.devices){\n var found = false;\n msg.list.filter( x => x.shortAddress == shortAddress)\n .map( x => {\n found = true;\n });\n if(!found){\n delete msg.payload.devices[shortAddress];\n }\n}\nreturn msg;","outputs":1,"noerr":0,"x":1910,"y":140,"wires":[["11220606.be9eaa"]]},{"id":"1d0da9b5.2704c6","type":"function","z":"8f50bdda.84b77","name":"Devices List Command","func":"msg.payload = {\n msgType : 0x0015,\n data : []\n}\n\n\nreturn msg;","outputs":1,"noerr":0,"x":470,"y":620,"wires":[["b3405362.c1695"]]},{"id":"b3405362.c1695","type":"subflow:ade00219.436f6","z":"8f50bdda.84b77","name":"","x":470,"y":660,"wires":[["20babac1.0d6bb6"]]},{"id":"8c4962ac.100d6","type":"function","z":"2a3adfb4.0cce2","name":"Reset & Set delay","func":"msg1={reset:true}; \nmsg2={payload:\"Set the delay\", delay:90000}; \nreturn [[msg1,msg2]];","outputs":1,"noerr":0,"x":850,"y":400,"wires":[["86fe58ca.83bc38"]]},{"id":"b779f022.10138","type":"comment","z":"8f50bdda.84b77","name":"Update the UI when we received a message","info":"","x":370,"y":80,"wires":[]},{"id":"e5eb2c48.7a498","type":"comment","z":"8f50bdda.84b77","name":"Treat commands received from UI","info":"","x":340,"y":400,"wires":[]},{"id":"86c3f5fa.26f298","type":"switch","z":"2a3adfb4.0cce2","name":"Magic Cube","property":"payload.dataByte","propertyType":"msg","rules":[{"t":"eq","v":"0","vt":"str"},{"t":"eq","v":"3","vt":"str"},{"t":"btwn","v":"50","vt":"num","v2":"127","v2t":"num"},{"t":"gte","v":"128","vt":"str"},{"t":"cont","v":"42","vt":"str"}],"checkall":"false","repair":false,"outputs":5,"x":590,"y":640,"wires":[[],["c17af3ea.0b63c"],[],[],[]],"info":"Magic cube values :\n - 0 : Shake\n - 3 : Jeté vertical\n - between 50 to 127 : Rotation 90°\n - greater or equals 128 :Rotation 180°\n - Index of \"42\" : Rotation vertical"},{"id":"608f2f64.6a555","type":"serial request","z":"c733c6b6.ada328","name":"Send to Zigate and wait for response","serial":"8bf91d15.7f53a","x":430,"y":280,"wires":[[]]},{"id":"16c68c96.7d0ac3","type":"function","z":"c733c6b6.ada328","name":"Escape Telegram","func":"var newDataLength = 0;\nvar newDataBuf = Buffer.alloc(msg.payload.length * 2);\nmsg.payload.forEach((v, i) => {\n if (i !== 0 && i < (msg.payload.length - 1)) {\n if (v <= 0x10) {\n newDataBuf[newDataLength++] = 0x02;\n newDataBuf[newDataLength++] = v ^ 0x10;\n } else {\n newDataBuf[newDataLength++] = v;\n }\n } else {\n newDataBuf[newDataLength++] = v;\n }\n});\nvar newBuf = newDataBuf.slice(0, newDataLength);\nmsg.payload = newBuf;\n\nreturn msg;","outputs":1,"noerr":0,"x":424,"y":219,"wires":[["608f2f64.6a555"]]},{"id":"47762663.380738","type":"function","z":"c733c6b6.ada328","name":"Generate Telegram","func":"var bufLength = 7 + msg.payload.data.length;\nvar buf = Buffer.alloc(bufLength);\n\nvar checksum = 0x00;\nchecksum ^= msg.payload.msgType >> 8;\nchecksum ^= msg.payload.msgType % 256;\nchecksum ^= msg.payload.data.length >> 8;\nchecksum ^= msg.payload.data.length % 256;\n\nbuf.writeUInt8(0x01, 0);\nbuf.writeUInt16BE(msg.payload.msgType, 1);\nbuf.writeUInt16BE(msg.payload.data.length, 3);\n\nvar cpt = 6;\nmsg.payload.data.map(data => {\n checksum ^= data;\n buf.writeUInt8(data, cpt); \n cpt++;\n});\nbuf.writeUInt8(checksum, 5);\n\nbuf.writeUInt8(0x03, bufLength - 1);\nmsg.payload = buf;\n\n\n//node.warn(msg.payload);\n\nreturn msg;","outputs":1,"noerr":0,"x":410,"y":160,"wires":[["16c68c96.7d0ac3","ea929f76.59a7f"]]},{"id":"ea929f76.59a7f","type":"function","z":"c733c6b6.ada328","name":"Store in database if needed (eg : command 0092)","func":"\n/*\nThe command 0x0092 (On/Off) returns only a \"Status\" telegram\nTo have a \"standard\" behaviour, we modified our database to store the value\nIn that case, we can display the real value on the dashboard even if another device send a \"On/Off command\" (eg : via motion sensor or door sensor)\n*/\nif(msg.payload[1] == 0x00 && msg.payload[2] == 0x92){\n var shortAddress = msg.payload.slice(7,9).toString(\"hex\")\n var endpoint = msg.payload.slice(10,11).toString(\"hex\")\n var value = parseInt(msg.payload[11].toString(\"16\"))\n \n msg.datapath = \"/devices/\" + shortAddress+\"/endpoints/\" + endpoint+\"/clusters/0006\";\n\n var newValue = {\n \"0000\" : {\n \"value\" : value,\n \"lastUpdated\" : Date.now()\n }\n \n }\n msg.payload = newValue;\n return msg;\n}else{\n return undefined;\n}","outputs":1,"noerr":0,"x":790,"y":160,"wires":[["d742a8f5.754ba8"]]},{"id":"d742a8f5.754ba8","type":"DataIn","z":"c733c6b6.ada328","collection":"875df393.5dcfe","name":"ZIgate Devices DB","update":true,"path":"/","x":1130,"y":160,"wires":[]},{"id":"c17af3ea.0b63c","type":"function","z":"2a3adfb4.0cce2","name":"Light Garage Toggle","func":"var command = {msgType : 0x0000, data : []};\n//Send a OFF command to a light\nvar shortAddress = \"823a\";\nvar endpoint = \"03\";\ncommand.msgType = 0x0092;\ncommand.data = [0x02, parseInt(shortAddress.substr(0,2), 16), parseInt(shortAddress.substr(2,2), 16), 0x01, parseInt(endpoint, 16), 0x02]\nmsg.payload = command;\nreturn msg;","outputs":1,"noerr":0,"x":840,"y":620,"wires":[["4b748bca.b376c4"]]}]