diff --git a/doc/Tutorials/device-integration/hardware-guides/connect-teltonika-to-kaa-platform/attach/code/node-red-teltonika-tcp-flow.json b/doc/Tutorials/device-integration/hardware-guides/connect-teltonika-to-kaa-platform/attach/code/node-red-teltonika-tcp-flow.json index f28f50eca7..ced758f080 100644 --- a/doc/Tutorials/device-integration/hardware-guides/connect-teltonika-to-kaa-platform/attach/code/node-red-teltonika-tcp-flow.json +++ b/doc/Tutorials/device-integration/hardware-guides/connect-teltonika-to-kaa-platform/attach/code/node-red-teltonika-tcp-flow.json @@ -69,7 +69,7 @@ "type": "function", "z": "bde2c7d9084e1fa9", "name": "PARSE codec8_ext TCP", - "func": "var inputMsg = msg.payload;\n\nvar inputDataPtr = 0;\nvar fullPacketLength = 0;\n\nvar parsedMsg = {};\nparsedMsg.avl = [];\nvar avl = {};\n\nparseAVLfull();\n\n// create TCP response\nvar tcpResponse = createTcpResponse(parsedMsg.numberOfData, msg._session);\n\nmsg.payload = parsedMsg;\n\nreturn [msg, tcpResponse]; // response\n\n//**********************************************************************************************\n// createTcpResponse\n//**********************************************************************************************\nfunction createTcpResponse(receivedDataCount, session) {\n var countHex = dec2Hex32(receivedDataCount);\n var tcpResponse = {};\n tcpResponse._session = session;\n tcpResponse.payload = new Buffer([Number(countHex.substring(6, 8)), Number(countHex.substring(4, 6)),\n Number(countHex.substring(2, 4)), Number(countHex.substring(0, 2))]);\n\n return tcpResponse;\n}\n\n//**********************************************************************************************\n// dec2Hex32\n//**********************************************************************************************\nfunction dec2Hex32(dec) {\n return Math.abs(dec).toString(32);\n}\n\n//**********************************************************************************************\n// parseAVLfull\n//**********************************************************************************************\nfunction parseAVLfull() {\n //preamble\n var preamble = getNextInt32();\n if (preamble != 0x00000000) {\n node.warn(\"Wrong preamble\");\n return [null, null];\n }\n\n // get packet length\n parsedMsg.fullPacketLength = getNextInt32();\n\n var calculatedCrc16 = crc16(inputMsg, inputDataPtr, (inputMsg.length - inputDataPtr - 4));\n\n // AVL codec ID\n parsedMsg.codecId = getNextInt8();\n if (parsedMsg.codecId != 0x8E) {\n node.warn(\"Wrong codecId: \" + parsedMsg.codecId);\n return [null, null];\n }\n\n // AVL number of data\n parsedMsg.numberOfData = getNextInt8();\n\n // AVL Data array \n\n for (var i = 0; i < parsedMsg.numberOfData; i++) {\n parseAVLpacketDataArrayElement();\n }\n\n parsedMsg.numberOfRecords = getNextInt8();\n\n if (parsedMsg.numberOfData != parsedMsg.numberOfRecords) {\n node.warn(\"numberOfData1 not equals numberOfData2\");\n return [null, null];\n }\n\n parsedMsg.crc16 = getNextInt32();\n if (calculatedCrc16 != parsedMsg.crc16) {\n node.warn(\"Wrong crc16.\");\n return [null, null];\n }\n}\n\n//**********************************************************************************************\n// parseAVLpacketDataArrayElement\n//**********************************************************************************************\nfunction parseAVLpacketDataArrayElement() {\n avl = {};\n avl.timestamp = getTimestamp();\n avl.priority = getNextInt8();\n avl.GPS = parseGPSelement();\n parseIOelement();\n parsedMsg.avl.push(avl);\n}\n\n//**********************************************************************************************\n// parseAVLpacket\n//**********************************************************************************************\nfunction getTimestamp() {\n var timestampArray = getNextSubArray(8);\n var value = 0;\n for (var i = 0; i < timestampArray.length; i++) {\n value = (value * 256) + timestampArray[i];\n }\n return value;\n}\n\n//**********************************************************************************************\n// parseGPSelement\n//**********************************************************************************************\nfunction parseGPSelement() {\n var GPS = {};\n GPS.longitude = getCoordinate(getNextSubArray(4));\n GPS.latitude = getCoordinate(getNextSubArray(4));\n GPS.altitude = getNextInt16();\n GPS.angle = getNextInt16();\n GPS.satellites = getNextInt8();\n GPS.speed = getNextInt16();\n\n return GPS;\n}\n\n//**********************************************************************************************\n// getCoordinate\n//**********************************************************************************************\nfunction getCoordinate(array) {\n var value = 0;\n if (array[0] > 127) { //negative\n value = (array[0] << 24) + (array[1] << 16) + (array[2] << 8) + array[3];\n value -= parseInt(\"ffffffff\", 16);\n } else { //positive\n value = (array[0] << 24) + (array[1] << 16) + (array[2] << 8) + array[3];\n }\n return value / 10000000;\n}\n\n//**********************************************************************************************\n// parseIOelement\n//**********************************************************************************************\nfunction parseIOelement() {\n avl.eventIoID = getNextInt16();\n\n //if (avl.eventIoID == 385) {\n // parseBeacon();\n // getNextInt8();\n //} else {\n parseUsualIOelements();\n decodeUsualIOelements();\n //}\n}\n\n//**********************************************************************************************\n// parseBeacon\n//**********************************************************************************************\nfunction parseBeacon(array) {\n const BEACON_LENGTH = 20;\n const EDDY_LENGTH = 16;\n\n var avl = {};\n\n avl.beaconLength = array.length;\n\n var ptr = 0;\n\n // dataPart\n avl.dataPart = array[ptr++];\n avl.beaconRecordsCount = avl.dataPart & 0x0F;\n avl.recordNumber = (avl.dataPart & 0xF0) >> 4;\n\n if (avl.beaconLength < EDDY_LENGTH) {\n return avl;\n }\n\n // flags\n avl.flag = array[ptr++];\n avl.sygnalStrenghAvailable = ((avl.flag & 0x01) > 0) ? 1 : 0;\n avl.beaconDataSent = ((avl.flag & 0x20) > 0) ? 1 : 0;\n\n // beacons\n if (avl.beaconDataSent != 0) {\n // beacon data\n avl.beaconId = array.slice(ptr, ptr + BEACON_LENGTH);\n ptr += BEACON_LENGTH;\n if (avl.sygnalStrenghAvailable != 0) {\n avl.BeaconRssi = array[ptr++];\n }\n }\n\n return avl;\n}\n\n//**********************************************************************************************\n// parseUsualIOelements\n//**********************************************************************************************\nfunction parseUsualIOelements() {\n avl.nTotalIo = getNextInt16();\n avl.n1Io = getNextInt16();\n avl.ioData = new Map();\n var i = 0;\n for (i = 0; i < avl.n1Io; i++) {\n var n1IoId = getNextInt16();\n var n1IoValue = getNextInt8();\n if (n1IoValue >= 128) {\n n1IoValue = n1IoValue - 256;\n }\n avl.ioData.set(n1IoId, n1IoValue);\n }\n\n if (inputDataPtr >= parsedMsg.fullPacketLength) { return [null, null]; }\n avl.n2Io = getNextInt16();\n for (i = 0; i < avl.n2Io; i++) {\n var n2IoId = getNextInt16();\n var n2IoValue = getNextInt16();\n if (n2IoValue >= 0x8000) {\n n2IoValue = n2IoValue - 0x8000;\n }\n avl.ioData.set(n2IoId, n2IoValue);\n }\n\n if (inputDataPtr >= parsedMsg.fullPacketLength) { return [null, null]; }\n avl.n4Io = getNextInt16();\n for (i = 0; i < avl.n4Io; i++) {\n var n4IoId = getNextInt16();\n var n4IoValue = getNextInt32();\n if (n4IoValue >= 0x80000000) {\n n4IoValue = n4IoValue - 0x80000000;\n }\n avl.ioData.set(n4IoId, n4IoValue);\n }\n\n if (inputDataPtr >= parsedMsg.fullPacketLength) { return [null, null]; }\n avl.n8Io = getNextInt16();\n for (i = 0; i < avl.n8Io; i++) {\n var n8IoId = getNextInt16();\n //var n8IoSubArray = getNextSubArray(8);\n var n8IoValue = getNextInt64();\n if (n8IoValue >= 0x8000000000000000) {\n n8IoValue = n8IoValue - 0x8000000000000000;\n }\n //node.warn(n8IoValue);\n avl.ioData.set(n8IoId, n8IoValue);\n }\n avl.nxIo = getNextInt16();\n for (i = 0; i < avl.nxIo; i++) {\n var nxIoId = getNextInt16();\n var nxIoLength = getNextInt16();\n if (nxIoId == 385) {\n avl.ioData.set(nxIoId, parseBeacon(getNextSubArray(nxIoLength)));\n } else {\n avl.ioData.set(nxIoId, getNextSubArray(nxIoLength));\n }\n }\n}\n\n//**********************************************************************************************\n// decodeUsualIOelements\n//**********************************************************************************************\nfunction decodeUsualIOelements() {\n avl.axis = {};\n avl.axis.x = avl.ioData.get(17);\n avl.axis.y = avl.ioData.get(18);\n avl.axis.z = avl.ioData.get(19);\n}\n\n//**********************************************************************************************\n// getCharArray\n//**********************************************************************************************\nfunction getCharArray(array) {\n const result = [];\n for (var i = 0; i < array.length; i++) {\n result.push(String.fromCharCode(array[i]));\n }\n return result;\n}\n\n//**********************************************************************************************\n// getNextSubArray\n//**********************************************************************************************\nfunction getNextSubArray(length) {\n var subarray = inputMsg.slice(inputDataPtr, inputDataPtr + length);\n inputDataPtr += length;\n return subarray;\n}\n\n//**********************************************************************************************\n// getNextInt8\n//**********************************************************************************************\nfunction getNextInt8() {\n return inputMsg[inputDataPtr++];\n}\n\n//**********************************************************************************************\n// getNextInt16\n//**********************************************************************************************\nfunction getNextInt16() {\n var value = inputMsg[inputDataPtr++];\n value = (value << 8) + inputMsg[inputDataPtr++];\n return value;\n}\n\n//**********************************************************************************************\n// getNextInt32\n//**********************************************************************************************\nfunction getNextInt32() {\n var value = inputMsg[inputDataPtr++];\n value = (value << 8) + inputMsg[inputDataPtr++];\n value = (value << 8) + inputMsg[inputDataPtr++];\n value = (value << 8) + inputMsg[inputDataPtr++];\n return value;\n}\n\n//**********************************************************************************************\n// getNextInt64\n//**********************************************************************************************\nfunction getNextInt64() {\n var value = inputMsg[inputDataPtr++];\n value = (value << 8) + inputMsg[inputDataPtr++];\n value = (value << 8) + inputMsg[inputDataPtr++];\n value = (value << 8) + inputMsg[inputDataPtr++];\n value = (value << 8) + inputMsg[inputDataPtr++];\n value = (value << 8) + inputMsg[inputDataPtr++];\n value = (value << 8) + inputMsg[inputDataPtr++];\n value = (value << 8) + inputMsg[inputDataPtr++];\n return value;\n}\n\n//**********************************************************************************************\n// Calculates the buffers CRC-16/IBM.\n//**********************************************************************************************\nfunction crc16(buffer, startPtr, length) {\n var crc = 0;\n var odd;\n\n for (var i = 0; i < length; i++) {\n crc = crc ^ buffer[i + startPtr];\n\n var numBit = 0;\n do {\n odd = crc & 0x0001;\n crc = crc >> 1;\n if (odd == 1) {\n crc = crc ^ 0xA001;\n }\n numBit++;\n } while (numBit < 8);\n }\n\n return crc;\n};", + "func": "var inputMsg = msg.payload;\n\nvar inputDataPtr = 0;\nvar fullPacketLength = 0;\n\nvar parsedMsg = {};\nparsedMsg.avl = [];\nvar avl = {};\n\nparseAVLfull();\n\n// create TCP response\nvar tcpResponse = createTcpResponse(parsedMsg.numberOfData, msg._session);\n\nmsg.payload = parsedMsg;\n\nreturn [msg, tcpResponse]; // response\n\n//**********************************************************************************************\n// createTcpResponse\n//**********************************************************************************************\nfunction createTcpResponse(receivedDataCount, session) {\n var countHex = dec2Hex32(receivedDataCount);\n var tcpResponse = {};\n tcpResponse._session = session;\n tcpResponse.payload = new Buffer([Number(countHex.substring(6, 8)), Number(countHex.substring(4, 6)),\n Number(countHex.substring(2, 4)), Number(countHex.substring(0, 2))]);\n\n return tcpResponse;\n}\n\n//**********************************************************************************************\n// dec2Hex32\n//**********************************************************************************************\nfunction dec2Hex32(dec) {\n return Math.abs(dec).toString(32);\n}\n\n//**********************************************************************************************\n// parseAVLfull\n//**********************************************************************************************\nfunction parseAVLfull() {\n //preamble\n var preamble = getNextInt32();\n if (preamble != 0x00000000) {\n node.warn(\"Wrong preamble\");\n return [null, null];\n }\n\n // get packet length\n parsedMsg.fullPacketLength = getNextInt32();\n\n var calculatedCrc16 = crc16(inputMsg, inputDataPtr, (inputMsg.length - inputDataPtr - 4));\n\n // AVL codec ID\n parsedMsg.codecId = getNextInt8();\n if (parsedMsg.codecId != 0x8E) {\n node.warn(\"Wrong codecId: \" + parsedMsg.codecId);\n return [null, null];\n }\n\n // AVL number of data\n parsedMsg.numberOfData = getNextInt8();\n\n // AVL Data array \n\n for (var i = 0; i < parsedMsg.numberOfData; i++) {\n parseAVLpacketDataArrayElement();\n }\n\n parsedMsg.numberOfRecords = getNextInt8();\n\n if (parsedMsg.numberOfData != parsedMsg.numberOfRecords) {\n node.warn(\"numberOfData1 not equals numberOfData2\");\n return [null, null];\n }\n\n parsedMsg.crc16 = getNextInt32();\n if (calculatedCrc16 != parsedMsg.crc16) {\n node.warn(\"Wrong crc16.\");\n return [null, null];\n }\n}\n\n//**********************************************************************************************\n// parseAVLpacketDataArrayElement\n//**********************************************************************************************\nfunction parseAVLpacketDataArrayElement() {\n avl = {};\n avl.timestamp = getTimestamp();\n avl.priority = getNextInt8();\n avl.GPS = parseGPSelement();\n parseIOelement();\n parsedMsg.avl.push(avl);\n}\n\n//**********************************************************************************************\n// parseAVLpacket\n//**********************************************************************************************\nfunction getTimestamp() {\n var timestampArray = getNextSubArray(8);\n var value = 0;\n for (var i = 0; i < timestampArray.length; i++) {\n value = (value * 256) + timestampArray[i];\n }\n return value;\n}\n\n//**********************************************************************************************\n// parseGPSelement\n//**********************************************************************************************\nfunction parseGPSelement() {\n var GPS = {};\n GPS.longitude = getCoordinate(getNextSubArray(4));\n GPS.latitude = getCoordinate(getNextSubArray(4));\n GPS.altitude = getNextInt16();\n GPS.angle = getNextInt16();\n GPS.satellites = getNextInt8();\n GPS.speed = getNextInt16();\n\n return GPS;\n}\n\n//**********************************************************************************************\n// getCoordinate\n//**********************************************************************************************\nfunction getCoordinate(array) {\n // Combine the 4 bytes into a single 32-bit signed integer\n var value = (array[0] << 24) | (array[1] << 16) | (array[2] << 8) | (array[3]);\n // Adjust for JavaScript's bitwise signed 32-bit range\n if (value > 0x7FFFFFFF) {\n value -= 0x100000000;\n }\n return value / 10000000;\n}\n\n//**********************************************************************************************\n// parseIOelement\n//**********************************************************************************************\nfunction parseIOelement() {\n avl.eventIoID = getNextInt16();\n\n //if (avl.eventIoID == 385) {\n // parseBeacon();\n // getNextInt8();\n //} else {\n parseUsualIOelements();\n decodeUsualIOelements();\n //}\n}\n\n//**********************************************************************************************\n// parseBeacon\n//**********************************************************************************************\nfunction parseBeacon(array) {\n const BEACON_LENGTH = 20;\n const EDDY_LENGTH = 16;\n\n var avl = {};\n\n avl.beaconLength = array.length;\n\n var ptr = 0;\n\n // dataPart\n avl.dataPart = array[ptr++];\n avl.beaconRecordsCount = avl.dataPart & 0x0F;\n avl.recordNumber = (avl.dataPart & 0xF0) >> 4;\n\n if (avl.beaconLength < EDDY_LENGTH) {\n return avl;\n }\n\n // flags\n avl.flag = array[ptr++];\n avl.sygnalStrenghAvailable = ((avl.flag & 0x01) > 0) ? 1 : 0;\n avl.beaconDataSent = ((avl.flag & 0x20) > 0) ? 1 : 0;\n\n // beacons\n if (avl.beaconDataSent != 0) {\n // beacon data\n avl.beaconId = array.slice(ptr, ptr + BEACON_LENGTH);\n ptr += BEACON_LENGTH;\n if (avl.sygnalStrenghAvailable != 0) {\n avl.BeaconRssi = array[ptr++];\n }\n }\n\n return avl;\n}\n\n//**********************************************************************************************\n// parseUsualIOelements\n//**********************************************************************************************\nfunction parseUsualIOelements() {\n avl.nTotalIo = getNextInt16();\n avl.n1Io = getNextInt16();\n avl.ioData = new Map();\n var i = 0;\n for (i = 0; i < avl.n1Io; i++) {\n var n1IoId = getNextInt16();\n var n1IoValue = getNextInt8();\n if (n1IoValue >= 128) {\n n1IoValue = n1IoValue - 256;\n }\n avl.ioData.set(n1IoId, n1IoValue);\n }\n\n if (inputDataPtr >= parsedMsg.fullPacketLength) { return [null, null]; }\n avl.n2Io = getNextInt16();\n for (i = 0; i < avl.n2Io; i++) {\n var n2IoId = getNextInt16();\n var n2IoValue = getNextInt16();\n if (n2IoValue >= 0x8000) {\n n2IoValue = n2IoValue - 0x8000;\n }\n avl.ioData.set(n2IoId, n2IoValue);\n }\n\n if (inputDataPtr >= parsedMsg.fullPacketLength) { return [null, null]; }\n avl.n4Io = getNextInt16();\n for (i = 0; i < avl.n4Io; i++) {\n var n4IoId = getNextInt16();\n var n4IoValue = getNextInt32();\n if (n4IoValue >= 0x80000000) {\n n4IoValue = n4IoValue - 0x80000000;\n }\n avl.ioData.set(n4IoId, n4IoValue);\n }\n\n if (inputDataPtr >= parsedMsg.fullPacketLength) { return [null, null]; }\n avl.n8Io = getNextInt16();\n for (i = 0; i < avl.n8Io; i++) {\n var n8IoId = getNextInt16();\n //var n8IoSubArray = getNextSubArray(8);\n var n8IoValue = getNextInt64();\n if (n8IoValue >= 0x8000000000000000) {\n n8IoValue = n8IoValue - 0x8000000000000000;\n }\n //node.warn(n8IoValue);\n avl.ioData.set(n8IoId, n8IoValue);\n }\n avl.nxIo = getNextInt16();\n for (i = 0; i < avl.nxIo; i++) {\n var nxIoId = getNextInt16();\n var nxIoLength = getNextInt16();\n if (nxIoId == 385) {\n avl.ioData.set(nxIoId, parseBeacon(getNextSubArray(nxIoLength)));\n } else {\n avl.ioData.set(nxIoId, getNextSubArray(nxIoLength));\n }\n }\n}\n\n//**********************************************************************************************\n// decodeUsualIOelements\n//**********************************************************************************************\nfunction decodeUsualIOelements() {\n avl.axis = {};\n avl.axis.x = avl.ioData.get(17);\n avl.axis.y = avl.ioData.get(18);\n avl.axis.z = avl.ioData.get(19);\n}\n\n//**********************************************************************************************\n// getCharArray\n//**********************************************************************************************\nfunction getCharArray(array) {\n const result = [];\n for (var i = 0; i < array.length; i++) {\n result.push(String.fromCharCode(array[i]));\n }\n return result;\n}\n\n//**********************************************************************************************\n// getNextSubArray\n//**********************************************************************************************\nfunction getNextSubArray(length) {\n var subarray = inputMsg.slice(inputDataPtr, inputDataPtr + length);\n inputDataPtr += length;\n return subarray;\n}\n\n//**********************************************************************************************\n// getNextInt8\n//**********************************************************************************************\nfunction getNextInt8() {\n return inputMsg[inputDataPtr++];\n}\n\n//**********************************************************************************************\n// getNextInt16\n//**********************************************************************************************\nfunction getNextInt16() {\n var value = inputMsg[inputDataPtr++];\n value = (value << 8) + inputMsg[inputDataPtr++];\n return value;\n}\n\n//**********************************************************************************************\n// getNextInt32\n//**********************************************************************************************\nfunction getNextInt32() {\n var value = inputMsg[inputDataPtr++];\n value = (value << 8) + inputMsg[inputDataPtr++];\n value = (value << 8) + inputMsg[inputDataPtr++];\n value = (value << 8) + inputMsg[inputDataPtr++];\n return value;\n}\n\n//**********************************************************************************************\n// getNextInt64\n//**********************************************************************************************\nfunction getNextInt64() {\n var value = inputMsg[inputDataPtr++];\n value = (value << 8) + inputMsg[inputDataPtr++];\n value = (value << 8) + inputMsg[inputDataPtr++];\n value = (value << 8) + inputMsg[inputDataPtr++];\n value = (value << 8) + inputMsg[inputDataPtr++];\n value = (value << 8) + inputMsg[inputDataPtr++];\n value = (value << 8) + inputMsg[inputDataPtr++];\n value = (value << 8) + inputMsg[inputDataPtr++];\n return value;\n}\n\n//**********************************************************************************************\n// Calculates the buffers CRC-16/IBM.\n//**********************************************************************************************\nfunction crc16(buffer, startPtr, length) {\n var crc = 0;\n var odd;\n\n for (var i = 0; i < length; i++) {\n crc = crc ^ buffer[i + startPtr];\n\n var numBit = 0;\n do {\n odd = crc & 0x0001;\n crc = crc >> 1;\n if (odd == 1) {\n crc = crc ^ 0xA001;\n }\n numBit++;\n } while (numBit < 8);\n }\n\n return crc;\n};", "outputs": 2, "noerr": 0, "initialize": "", @@ -566,4 +566,4 @@ "userProps": "", "sessionExpiry": "" } -] \ No newline at end of file +]