[ { "id": "7c62624c.845dcc", "type": "function", "z": "f3ab6910.2495f8", "name": "Set url", "func": "//msg.payload contain the command input from snips and realknx.\n//\nmsg.device = msg.payload; \nmsg.payload =[];\nfor(var i = 0; i < msg.device.length ; i++){\n var uid = msg.device[i].uid;\n msg.payload[i] ={\n \"url\" : \"http://localhost:1880/api/v1/values/\" + uid + \"?token=dEAUv4WaS2N6CvbLmz2Y8pvRIEamK6gv\"\n };\n}\nreturn msg;", "outputs": 1, "noerr": 0, "x": 1270, "y": 440, "wires": [ [ "1f35079f.cfc658" ] ] }, { "id": "ac20706d.4511b", "type": "http request", "z": "f3ab6910.2495f8", "name": "GET", "method": "GET", "ret": "txt", "paytoqs": false, "url": "", "tls": "", "proxy": "", "authType": "", "x": 1630, "y": 440, "wires": [ [ "4e2f75fb.26878c" ] ] }, { "id": "1f35079f.cfc658", "type": "split", "z": "f3ab6910.2495f8", "name": "split", "splt": "\\n", "spltType": "str", "arraySplt": 1, "arraySpltType": "len", "stream": false, "addname": "", "x": 1390, "y": 440, "wires": [ [ "2cb36cfc.25b894" ] ] }, { "id": "4e2f75fb.26878c", "type": "join", "z": "f3ab6910.2495f8", "name": "", "mode": "auto", "build": "string", "property": "payload", "propertyType": "msg", "key": "topic", "joiner": "\\n", "joinerType": "str", "accumulate": false, "timeout": "", "count": "", "reduceRight": false, "reduceExp": "", "reduceInit": "", "reduceInitType": "", "reduceFixup": "", "x": 1750, "y": 440, "wires": [ [ "dfe36398.9367b" ] ] }, { "id": "2cb36cfc.25b894", "type": "change", "z": "f3ab6910.2495f8", "name": "set", "rules": [ { "t": "set", "p": "url", "pt": "msg", "to": "payload.url", "tot": "msg" } ], "action": "", "property": "", "from": "", "to": "", "reg": false, "x": 1510, "y": 440, "wires": [ [ "ac20706d.4511b" ] ] }, { "id": "cecdb958.d45478", "type": "function", "z": "f3ab6910.2495f8", "name": "Set url", "func": "msg.device = msg.payload;\nmsg.payload =[];\nfor(var i = 0; i < msg.device.length ; i++){\n var uid = msg.device[i].uid;\n msg.payload[i] ={\n \"url\" : \"http://localhost:1880/api/v1/values/\" + uid + \"?token=dEAUv4WaS2N6CvbLmz2Y8pvRIEamK6gv\", \n \"value\": { \"value\" : msg.device[i].value }\n };\n}\nreturn msg;", "outputs": 1, "noerr": 0, "x": 1270, "y": 600, "wires": [ [ "3182f168.77a9be" ] ] }, { "id": "4c9b9f5e.7ddc4", "type": "http request", "z": "f3ab6910.2495f8", "name": "PUT", "method": "PUT", "ret": "txt", "paytoqs": false, "url": "", "tls": "", "proxy": "", "authType": "", "x": 1630, "y": 600, "wires": [ [ "a49c0245.0c5ff" ] ] }, { "id": "3182f168.77a9be", "type": "split", "z": "f3ab6910.2495f8", "name": "split", "splt": "\\n", "spltType": "str", "arraySplt": 1, "arraySpltType": "len", "stream": false, "addname": "", "x": 1390, "y": 600, "wires": [ [ "b746cd95.07f38" ] ] }, { "id": "b746cd95.07f38", "type": "change", "z": "f3ab6910.2495f8", "name": "set", "rules": [ { "t": "set", "p": "url", "pt": "msg", "to": "payload.url", "tot": "msg" }, { "t": "set", "p": "payload", "pt": "msg", "to": "payload.value", "tot": "msg" } ], "action": "", "property": "", "from": "", "to": "", "reg": false, "x": 1510, "y": 600, "wires": [ [ "4c9b9f5e.7ddc4" ] ] }, { "id": "a49c0245.0c5ff", "type": "join", "z": "f3ab6910.2495f8", "name": "", "mode": "auto", "build": "string", "property": "payload", "propertyType": "msg", "key": "topic", "joiner": "\\n", "joinerType": "str", "accumulate": false, "timeout": "", "count": "", "reduceRight": false, "reduceExp": "", "reduceInit": "", "reduceInitType": "", "reduceFixup": "", "x": 1750, "y": 600, "wires": [ [ "c022bd76.fb9f8" ] ] }, { "id": "dfe36398.9367b", "type": "function", "z": "f3ab6910.2495f8", "name": "**Respond from Jung**", "func": "//From the server respond, put it in this format\n//For more than one devices\n//\n//\n // [{\n // \"Data\" : [{ \n // \"Value\" : 100,\n // \"uid\" : \"\" \n // }],\n // \"Result\":true\n // },\n // {\n // \"Data\" : [{ \n // \"Value\" : 50,\n // \"type\" : \"\"\n // }],\n // \"Result\":true\n // }] \nfunction isJson(str) {\n try {\n JSON.parse(str);\n } catch (e) {\n return false;\n }\n return true;\n}\n\nmsg.states = [];\nfor(var i = 0 ; i < msg.payload.length ; i++){\n msg.payload[i] = JSON.parse(msg.payload[i]);\n // if(msg.device[i].name === \"TargetTemperature\"){\n // msg.states[i] = { \n // \"Data\" : [{\n // \"Value\" : msg.payload[i].values[0].value,\n // \"uid\" : msg.payload[i].values[0].uid\n // }]\n // };\n // if(msg.states[i].Data[0].Value !== undefined){\n // msg.states[i].Result=true;\n // }else{\n // msg.states[i].Result=false;\n // }\n // }else if(msg.device[i].name === \"CurrentTemperature\"){\n // msg.states[i] = { \n // \"Data\" : [{\n // \"Value\" : msg.payload[i].values[0].currentValue,\n // \"uid\" : msg.payload[i].values[0].uid\n // }]\n // };\n // if(msg.states[i].Data[0].Value !== undefined){\n // msg.states[i].Result=true;\n // }else{\n // msg.states[i].Result=false;\n // }\n // }else{\n msg.states[i] = { \n \"Data\" : [{\n \"Value\" : msg.payload[i].values[0].value,\n \"uid\" : msg.payload[i].values[0].uid\n }]\n };\n if(msg.states[i].Data[0].Value !== undefined){\n msg.states[i].Result=true;\n }else{\n msg.states[i].Result=false;\n } \n //}\n}\n\nmsg.payload=msg.states;\ndelete msg.states;\nreturn msg;", "outputs": 1, "noerr": 0, "x": 1930, "y": 440, "wires": [ [ "46d199d5.2856c8" ] ] }, { "id": "c022bd76.fb9f8", "type": "function", "z": "f3ab6910.2495f8", "name": "**Respond from Jung**", "func": "msg.result = [];\nfor(var i = 0 ; i < msg.payload.length ; i++){\n if(msg.payload[i] === \"\"){\n msg.result[i] = {\"Result\" : true};\n }else{\n msg.result[i] = {\"Result\" : false, \"messageError\" : msg.payload};\n }\n}\n\nmsg.payload=msg.result;\ndelete msg.result;\nreturn msg;", "outputs": 1, "noerr": 0, "x": 1930, "y": 600, "wires": [ [ "56b766f0.168948" ] ] }, { "id": "7ab6c2fe.f22acc", "type": "inject", "z": "f3ab6910.2495f8", "name": "Inject description file - JUNG", "topic": "", "payload": "{\"functions\":[{\"displayName\":\"Wall\",\"functionType\":\"dimmers\",\"zone\":\"Home Cinema\",\"commands\":[{\"name\":\"On\",\"uid\":\"knxcom_function_20190902090905369\",\"value\":100},{\"name\":\"Off\",\"uid\":\"knxcom_function_20190902090905369\",\"value\":0},{\"name\":\"Brightness\",\"uid\":\"knxcom_function_20190902090905369\",\"valueMin\":0,\"valueMax\":100}],\"currentStates\":[{\"name\":\"CurrentBrightness\",\"uid\":\"knxcom_function_20190902090905369\",\"valueMin\":0,\"valueMax\":100}]},{\"displayName\":\"Table\",\"functionType\":\"lights\",\"zone\":\"Home Cinema\",\"commands\":[{\"name\":\"On\",\"uid\":\"knxcom_function_20190812133320520\",\"value\":\"ON\"},{\"name\":\"Off\",\"uid\":\"knxcom_function_20190812133320520\",\"value\":\"OFF\"}],\"currentStates\":[{\"name\":\"CurrentState\",\"uid\":\"knxcom_function_20190812133320520\",\"valueMin\":\"ON\",\"valueMax\":\"OFF\"}]},{\"displayName\":\"Shutter\",\"functionType\":\"blinds\",\"zone\":\"Bedroom\",\"commands\":[{\"name\":\"On\",\"uid\":\"knxcom_function_20190825141254236\",\"value\":50},{\"name\":\"Off\",\"uid\":\"knxcom_function_20190825141254236\",\"value\":100},{\"name\":\"Position\",\"uid\":\"knxcom_function_20190825141254236\",\"valueMin\":0,\"valueMax\":100}],\"currentStates\":[{\"name\":\"CurrentPosition\",\"uid\":\"knxcom_function_20190825141254236\",\"valueMin\":0,\"valueMax\":100}]},{\"displayName\":\"Thermostat\",\"functionType\":\"heating\",\"zone\":\"Home Cinema\",\"commands\":[{\"name\":\"TargetTemperature\",\"uid\":\"knxcom_function_20190825162919913\",\"valueMin\":18,\"valueMax\":28}],\"currentStates\":[{\"name\":\"TargetTemperature\",\"uid\":\"knxcom_function_20190825162919913target\",\"valueMin\":18,\"valueMax\":28},{\"name\":\"CurrentTemperature\",\"uid\":\"knxcom_function_20190825162919913\",\"valueMin\":18,\"valueMax\":28}]},{\"displayName\":\"Cosy\",\"functionType\":\"scenes\",\"zone\":\"Home Cinema\",\"commands\":[{\"name\":\"On\",\"uid\":\"knxcom_function_20190827114812865\",\"value\":1}]},{\"displayName\":\"Total Energy\",\"functionType\":\"sensor\",\"zone\":\"Home Cinema\",\"unit\":\"Watt\",\"currentStates\":[{\"name\":\"CurrentValue\",\"uid\":\"knxcom_function_20190901155806602\"}]},{\"displayName\":\"Other functions\",\"functionType\":\"aux\",\"zone\":\"Bedroom\",\"commands\":[{\"name\":\"On\",\"uid\":\"knxcom_function_20190825141255490\",\"value\":50},{\"name\":\"Off\",\"uid\":\"knxcom_function_20190825141255490\",\"value\":100},{\"name\":\"Value\",\"uid\":\"knxcom_function_20190825141255490\",\"valueMin\":0,\"valueMax\":100}]}]}", "payloadType": "json", "repeat": "", "crontab": "", "once": false, "onceDelay": 0.1, "x": 1300, "y": 320, "wires": [ [ "15e2d356.d6a43d" ] ] }, { "id": "15e2d356.d6a43d", "type": "change", "z": "f3ab6910.2495f8", "name": "**IP Address for SVS Jung**", "rules": [ { "t": "set", "p": "gatewayName", "pt": "global", "to": "jung", "tot": "str" }, { "t": "set", "p": "svsIP", "pt": "global", "to": "192.168.9.93", "tot": "str" } ], "action": "", "property": "", "from": "", "to": "", "reg": false, "x": 1560, "y": 320, "wires": [ [ "72efd0bf.65a02" ] ] }, { "id": "c5a20db5.0217", "type": "comment", "z": "f3ab6910.2495f8", "name": "======= SAMPLE GATEWAY COMMUNICATION MODULE ========", "info": "# Exemple implementation of the Gateway Communication Module.\nIn this part, you will have to implement Gateway Communication code.\nThere are two parts, hence two handlers\n 1. Generic Query - to GET the value\n 2. Generic Command - absolute SET and realtive SET value (increase/decrease)\n\n## Generic Query\nThis handler is called when the Snips application needs to get the current value of a device (temperature, brightness, shutters position, sensors etc)\nIt receives an array of commands & UID of the devices as input. \nThe command name is as well as the UID are defined by **you** in the GGDF.\n\nSample input to receive (type Object):\n`[\n {\n \"name\":\"CurrentState\",\n \"uid\":\"knxcom_function_20190812133320520\"\n },\n {\n \"name\":\"CurrentBrightness\",\n \"uid\":\"knxcom_function_20190902090905369\"\n }\n]`\n\nThis input is a list of object query from the description list you provided. \n\nIf the Gateway communication module uses a Web API (http), you can re-use the sample flow. You will need to adapt the\nby changing SET node. Else, you have to replace all the nodes between two links in the handler.\nIf you intend to keep the flow, you can make a copy and detach it from the flow.\n\n\nBefore sending out the response from the gateway server to the link out of generic query, you should put it \nin a Object format that can be read by realKNX.\n\nSample output to send (type Object):\n`[{\n \"Data\": [{\n \"Value\": \"OFF\",\n \"uid\": \"knxcom_function_20190812133320520\"\n }\n ],\n \"Result\": true\n }, {\n \"Data\": [{\n \"Value\": 46.3,\n \"uid\": \"knxcom_function_20190902090905369\"\n }\n ],\n \"Result\": true\n }\n]`\n\n# Generic command\nThis handler is called to get the current value of the device (on,off,decrease,set etc)\nThe link in node of the generic command is also connected to Snips application. It receive \ncommands of devices as input. It could be one command or an array of commands at a time.\nSample input to receive (type Object):\n`[\n {\n \"name\":\"On\",\n \"uid\":\"knxcom_function_20190812133320520\",\n \"value\":\"ON\"\n },\n {\n \"name\":\"On\",\n \"uid\":\"knxcom_function_20190902090905369\",\n \"value\":100\n }\n]\n`\nThis input is a list of object command from the description list you provided. \n \nBefore send out the response from the gateway server to the link out of generic query, you should put it \nin a Object format that can be read by realknx.\nSample output to send (type Object):\n`[\n {\n \"Result\":true\n },\n {\n \"Result\":false\n }\n]`\ntrue is when the server repond correctly, otherwise, Result is false ", "x": 1410, "y": 380, "wires": [] }, { "id": "66448e12.bb0b9", "type": "comment", "z": "f3ab6910.2495f8", "name": "GGDF - GATEWAY DESCRIPTION FILES EXAMPLES", "info": "# Sample GGDF (Generic Gateway Definition File)\nThe three sample GGDF uses the same format. If you have on of these Gateway availble,\nyou can test it using the following steps:\n1. Edit the green:ish node (name : **IP Address for ..**) and set the IP address of the gateway (without http)\n2. Don't forget to put the url to the description file in realKNX main UI (top left)\n3. Then, click the blue inject button (name : Inject description file - ...) to generate a file & notifcation to Snips engine.\n4. In Sample Implementations of Gateway Communication nodes, connect the corresponding **Respond from ..... UNIFI API** \n to the flow. \n5. Then, start testing the voice control command \"Hey Snips, turn on the light\".\n\nTo create your GGDF, just edit one of the inject nodes.\n\n# Description file's content\nIn the description file, there are type of functions\n1. lights\n2. dimmers\n3. blinds\n4. heating\n5. scenes\n6. sensor\n7. aux (other)\n", "x": 1360, "y": 280, "wires": [] } ]