KNX IP BAOS Indication Listener
Connects and listens to an Weinzierl KNX IP BAOS IP interface to get so called "Indications" from the ip interface. New revision with slightly optimized session indication handling.
[{"id":"08d7d8e8d36d55eb","type":"subflow","name":"KNX BAOS","info":"","category":"","in":[{"x":100,"y":200,"wires":[{"id":"fd0edce42b99d180"}]}],"out":[{"x":1920,"y":640,"wires":[{"id":"0a3c269af422ffd7","port":0}]}],"env":[{"name":"interfaceIp","type":"str","value":"0"},{"name":"areaId","type":"str","value":"0"},{"name":"dataPointCount","type":"str","value":"250"}],"meta":{"module":"KNX IP BAOS","version":"0.0.1","author":"Gökhan Sirin <[email protected]>","desc":"Verbindet sich mit einem KNX IP BAOS Gerät und empfängt Änderungen an Datenpunkten","keywords":"KNX, BAOS, Weinzierl, IP"},"color":"#C7E9C0","icon":"font-awesome/fa-chain","status":{"x":300,"y":760,"wires":[{"id":"e158a50e6d6f03c1","port":0}]}},{"id":"fd0edce42b99d180","type":"delay","z":"08d7d8e8d36d55eb","name":"delay","pauseType":"random","timeout":"5","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"5","randomLast":"10","randomUnits":"seconds","drop":false,"allowrate":false,"outputs":1,"x":230,"y":200,"wires":[["6cc55093fb1d3741"]]},{"id":"297a191af61447d1","type":"http request","z":"08d7d8e8d36d55eb","name":"start session","method":"GET","ret":"txt","paytoqs":"ignore","url":"http://{{payload.interfaceIp}}/baos/StartIndicationSession","tls":"","persist":false,"proxy":"","insecureHTTPParser":false,"authType":"","senderr":false,"headers":[],"x":330,"y":380,"wires":[["fdeb787018ca61a5"]]},{"id":"fdeb787018ca61a5","type":"switch","z":"08d7d8e8d36d55eb","name":"","property":"payload","propertyType":"msg","rules":[{"t":"istype","v":"json","vt":"json"},{"t":"else"}],"checkall":"false","repair":false,"outputs":2,"x":490,"y":380,"wires":[["79b80cac2d9b4c2c"],["af8ab0433328257b"]]},{"id":"79b80cac2d9b4c2c","type":"json","z":"08d7d8e8d36d55eb","name":"toJSON","property":"payload","action":"","pretty":false,"x":660,"y":380,"wires":[["0e9f855b72e15495"]]},{"id":"0e9f855b72e15495","type":"switch","z":"08d7d8e8d36d55eb","name":"","property":"payload['Result']","propertyType":"msg","rules":[{"t":"true"},{"t":"else"}],"checkall":"false","repair":false,"outputs":2,"x":810,"y":380,"wires":[["d0d18982ce3d046a"],["af8ab0433328257b"]]},{"id":"d0d18982ce3d046a","type":"function","z":"08d7d8e8d36d55eb","name":"","func":"flow.set('listenerSessionId', msg.payload['Data']['SessionId']);\n\nvar newMsg = {\"payload\":\n {\n 'areaId':flow.get('areaId'),\n 'interfaceIp':flow.get('interfaceIp'),\n 'sessionId':flow.get('listenerSessionId'),\n 'data':null\n }\n}\nreturn newMsg;\n","outputs":1,"timeout":"","noerr":0,"initialize":"","finalize":"","libs":[],"x":980,"y":380,"wires":[["e158a50e6d6f03c1"]]},{"id":"e158a50e6d6f03c1","type":"http request","z":"08d7d8e8d36d55eb","name":"listen","method":"GET","ret":"txt","paytoqs":"ignore","url":"http://{{payload.interfaceIp}}/baos/GetIndication?SessionId={{payload.sessionId}}&Timeout=30&Format=Default","tls":"","persist":false,"proxy":"","insecureHTTPParser":false,"authType":"","senderr":false,"headers":[],"x":150,"y":540,"wires":[["699a72de765c65ad"]]},{"id":"699a72de765c65ad","type":"switch","z":"08d7d8e8d36d55eb","name":"","property":"payload","propertyType":"msg","rules":[{"t":"istype","v":"json","vt":"json"},{"t":"else"}],"checkall":"false","repair":false,"outputs":2,"x":290,"y":540,"wires":[["24a0c07b6f61e1e3"],["267543ecff8a975d"]]},{"id":"24a0c07b6f61e1e3","type":"json","z":"08d7d8e8d36d55eb","name":"toJSON","property":"payload","action":"","pretty":false,"x":460,"y":540,"wires":[["62ca6a9218bf4a1c"]]},{"id":"91d5212f4ff7a002","type":"function","z":"08d7d8e8d36d55eb","name":"","func":"var newMsg = {\n \"payload\":\n {\n 'areaId':flow.get('areaId'),\n 'interfaceIp':flow.get('interfaceIp'),\n 'sessionId':flow.get('listenerSessionId'),\n 'knx_data':msg.payload['Data']\n }\n}\nreturn newMsg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":840,"y":540,"wires":[["3d0b8322734fdc05"]]},{"id":"62ca6a9218bf4a1c","type":"function","z":"08d7d8e8d36d55eb","name":"","func":"\n// ausgang 1 wenn die 30 sekunden request timeout abgelaufen sind\n// -> neuen \"listen\"-request ausführen\nif (typeof msg.payload.Error !== 'undefined' && msg.payload.Error == 'IndTimeout'){\n return [msg, null];\n}\n\n// ausgang 1 wenn eine nachricht ankam\nif (msg.payload.Result === true){\n return [msg, null];\n}\n\n\nvar newMsg = {\n \"payload\":\n {\n 'areaId': flow.get('areaId'),\n 'interfaceIp': flow.get('interfaceIp'),\n 'sessionId': flow.get('listenerSessionId'),\n 'data': null\n }\n}\n\n\n// prüfen ob indication session beendet wurde dann neue session starten\n// ausgang 3\nif (msg.payload.Result === false && msg.payload.Error == 'IndStopped')\n{\nreturn [null, null, newMsg];\n}\n\n// ansonsten\n// ausgang 2 bestehende session neu abfragen\nreturn [null, newMsg];\n","outputs":3,"timeout":"","noerr":0,"initialize":"","finalize":"","libs":[],"x":620,"y":540,"wires":[["91d5212f4ff7a002"],["e158a50e6d6f03c1"],["af8ab0433328257b"]]},{"id":"3d0b8322734fdc05","type":"function","z":"08d7d8e8d36d55eb","name":"hasData","func":"\n// ausgang 1 wenn daten vorhanden sind\nif (typeof msg.payload.knx_data !== 'undefined'){\n return [msg, null];\n}\n\n// ausgang 2 für keine daten\nreturn [null, msg];\n","outputs":2,"timeout":"","noerr":0,"initialize":"","finalize":"","libs":[],"x":1000,"y":540,"wires":[["e158a50e6d6f03c1","eb9e693efa1b45e9"],["e158a50e6d6f03c1"]]},{"id":"0fdf35ebaee58b7c","type":"comment","z":"08d7d8e8d36d55eb","name":"BAOS IP Interface über HTTP IndicatinoSession abhören","info":"","x":250,"y":40,"wires":[]},{"id":"6cc55093fb1d3741","type":"function","z":"08d7d8e8d36d55eb","name":"set context vars","func":"flow.set('listenerSessionId', 0);\nflow.set('interfaceIp', env.get('interfaceIp'));\nflow.set('areaId', env.get('areaId'));\nflow.set('dataPointCount', env.get('dataPointCount'));\n\nmsg = {\n \"payload\":\n {\n 'areaId':flow.get('areaId'),\n 'interfaceIp':flow.get('interfaceIp'),\n 'sessionId':flow.get('listenerSessionId'),\n 'dataPointCount':flow.get('dataPointCount'),\n 'data':null\n }\n}\nreturn msg;","outputs":1,"timeout":"","noerr":0,"initialize":"","finalize":"","libs":[],"x":400,"y":200,"wires":[["fb6663b7e441f348"]]},{"id":"eb9e693efa1b45e9","type":"function","z":"08d7d8e8d36d55eb","name":"","func":"// var fieldName = flow.get('areaId') +'_'+ msg.payload.knx_data[0].Datapoint;\n// var rawValue = msg.payload.knx_data[0].Value;\n// var niceValue = msg.payload.knx_data[0].Value;\n// if (rawValue === true) niceValue = 1;\n// if (rawValue === false) niceValue = 0;\n\nvar newMsg = {\n \"payload\":\n {\n 'areaId': flow.get('areaId'),\n 'knxData': msg.payload.knx_data\n }\n}\nreturn newMsg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1340,"y":640,"wires":[["e1cddf7125761b1c"]]},{"id":"37f08b99dde9286a","type":"comment","z":"08d7d8e8d36d55eb","name":"001 Umgebungsvariabeln mappen und BAOS Datenpunkt-Beschreibungen auslesen. Bei Fehler mit Verzögerung von vorne beginnen","info":"","x":530,"y":140,"wires":[]},{"id":"fb6663b7e441f348","type":"http request","z":"08d7d8e8d36d55eb","name":"","method":"GET","ret":"txt","paytoqs":"ignore","url":"http://{{payload.interfaceIp}}/baos/GetDescriptionString?DatapointStart=1&DatapointCount={{payload.dataPointCount}}","tls":"","persist":false,"proxy":"","authType":"","x":750,"y":200,"wires":[["89b1cc9ff0cf60e5"]]},{"id":"89b1cc9ff0cf60e5","type":"switch","z":"08d7d8e8d36d55eb","name":"","property":"payload","propertyType":"msg","rules":[{"t":"istype","v":"json","vt":"json"},{"t":"else"}],"checkall":"false","repair":false,"outputs":2,"x":910,"y":200,"wires":[["4aea95b8432b1a55"],["fd0edce42b99d180"]]},{"id":"4aea95b8432b1a55","type":"json","z":"08d7d8e8d36d55eb","name":"","property":"payload","action":"","pretty":false,"x":1070,"y":200,"wires":[["197708eddeef14a1"]]},{"id":"f5de925b8a24a4de","type":"function","z":"08d7d8e8d36d55eb","name":"","func":"var msgToJoin = {\n \"payload\": msg.payload.Data\n}\n\nvar msgToContinue = {\n \"payload\":\n {\n 'areaId':flow.get('areaId'),\n 'interfaceIp':flow.get('interfaceIp'),\n 'sessionId':flow.get('listenerSessionId'),\n 'data':null\n }\n}\nreturn [msgToJoin,msgToContinue];","outputs":2,"timeout":"","noerr":0,"initialize":"","finalize":"","libs":[],"x":1400,"y":200,"wires":[["b76bd04be6492928"],["297a191af61447d1"]]},{"id":"b76bd04be6492928","type":"split","z":"08d7d8e8d36d55eb","name":"","splt":"\\n","spltType":"str","arraySplt":1,"arraySpltType":"len","stream":false,"addname":"","x":1570,"y":180,"wires":[["bf4310e4950f1ded"]]},{"id":"bf4310e4950f1ded","type":"function","z":"08d7d8e8d36d55eb","name":"set describer var","func":"var niceString = msg.payload.Description;\nniceString = niceString.replace(/\\s+/g, '');\nif (msg.payload.Description != '') flow.set('datapointDescriber_'+msg.payload.Datapoint, niceString);","outputs":1,"timeout":"","noerr":0,"initialize":"","finalize":"","libs":[],"x":1750,"y":180,"wires":[[]]},{"id":"197708eddeef14a1","type":"switch","z":"08d7d8e8d36d55eb","name":"","property":"payload['Result']","propertyType":"msg","rules":[{"t":"true"},{"t":"else"}],"checkall":"false","repair":false,"outputs":2,"x":1210,"y":200,"wires":[["f5de925b8a24a4de"],["fd0edce42b99d180"]]},{"id":"5e25109b0ff2a9f2","type":"comment","z":"08d7d8e8d36d55eb","name":"002 BAOS Session starten. Sparsam umgehen da Gerät vollläuft. Daher gelangt man hierher nur zurück, wenn die Meldung empfangen wird, dass die Session beendet wurde.","info":"","x":650,"y":320,"wires":[]},{"id":"00727e56ae048a8c","type":"comment","z":"08d7d8e8d36d55eb","name":"003 BAOS Session Listener loopen mit immer gleichen Session ID. Falls die Meldung empfangen wird, dass die Session beendet wurde dann neue Session starten. Ansonsten bleiben wir dauerhaft auf dieser Stufe","info":"","x":770,"y":500,"wires":[]},{"id":"0a3c269af422ffd7","type":"function","z":"08d7d8e8d36d55eb","name":"","func":"//var rawValue = msg.payload.Value;\n//var niceValue = msg.payload.Value;\n\n//if (rawValue === '.') niceValue = 0;\n//if (rawValue === false) niceValue = 0;\n//if (rawValue === true) niceValue = 1;\n\n\nvar newMsg = {\n \"measurement\": msg.areaId,\n \"payload\":\n {\n 'area': msg.areaId,\n 'datapoint': msg.payload.Datapoint,\n 'datapointDescr': flow.get('datapointDescriber_'+msg.payload.Datapoint),\n 'value': msg.payload.Value\n }\n}\nreturn newMsg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1800,"y":640,"wires":[[]]},{"id":"e1cddf7125761b1c","type":"function","z":"08d7d8e8d36d55eb","name":"","func":"var newMsg = {\n \"areaId\": msg.payload.areaId,\n \"payload\": msg.payload.knxData\n}\nreturn newMsg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1500,"y":640,"wires":[["5bcca36fc6fe0bfb"]]},{"id":"5bcca36fc6fe0bfb","type":"split","z":"08d7d8e8d36d55eb","name":"","splt":"\\n","spltType":"str","arraySplt":1,"arraySpltType":"len","stream":false,"addname":"","x":1650,"y":640,"wires":[["0a3c269af422ffd7"]]},{"id":"9d12fd0f53a6eaee","type":"comment","z":"08d7d8e8d36d55eb","name":"003a Ergebnis verarbeiten (1-N Rückgabewerte)","info":"","x":1460,"y":600,"wires":[]},{"id":"af8ab0433328257b","type":"delay","z":"08d7d8e8d36d55eb","name":"delay","pauseType":"random","timeout":"5","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"10","randomLast":"15","randomUnits":"seconds","drop":false,"allowrate":false,"outputs":1,"x":130,"y":380,"wires":[["297a191af61447d1"]]},{"id":"267543ecff8a975d","type":"function","z":"08d7d8e8d36d55eb","name":"","func":"var newMsg = {\n \"payload\":\n {\n 'areaId': flow.get('areaId'),\n 'interfaceIp': flow.get('interfaceIp'),\n 'sessionId': flow.get('listenerSessionId'),\n 'data': null\n }\n}\n\nreturn newMsg;","outputs":1,"timeout":"","noerr":0,"initialize":"","finalize":"","libs":[],"x":500,"y":660,"wires":[["e158a50e6d6f03c1"]]},{"id":"b9e4ebcbdbf250d2","type":"comment","z":"08d7d8e8d36d55eb","name":"Kein JSON dann mit bestehender Session erneut versuchen","info":"","x":660,"y":620,"wires":[]},{"id":"f0f0ef097dffda3b","type":"comment","z":"08d7d8e8d36d55eb","name":"Ergebnis von listen http request in subflow-Status schreiben","info":"","x":500,"y":720,"wires":[]}]