From b26c6ded46b8816df80dc8744650d38bbfe29c34 Mon Sep 17 00:00:00 2001 From: Pavlo Anikeichyk <91755619+PavelAnikeichyk@users.noreply.github.com> Date: Thu, 8 May 2025 21:21:32 +0300 Subject: [PATCH] Fixed node-red-teltonika-udp-flow.json --- .../attach/code/node-red-teltonika-udp-flow.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/Tutorials/device-integration/hardware-guides/connect-teltonika-to-kaa-platform/attach/code/node-red-teltonika-udp-flow.json b/doc/Tutorials/device-integration/hardware-guides/connect-teltonika-to-kaa-platform/attach/code/node-red-teltonika-udp-flow.json index c20504cfd6..f35d3e7429 100644 --- a/doc/Tutorials/device-integration/hardware-guides/connect-teltonika-to-kaa-platform/attach/code/node-red-teltonika-udp-flow.json +++ b/doc/Tutorials/device-integration/hardware-guides/connect-teltonika-to-kaa-platform/attach/code/node-red-teltonika-udp-flow.json @@ -70,7 +70,7 @@ "type": "function", "z": "0f74c4179fdeaf10", "name": "PARSE codec8_ext UDP", - "func": "var inputMsg = msg.payload;\n\nvar inputDataPtr = 0;\nvar fullPacketLength = 0;\n\nvar parsedMsg = {};\nparsedMsg.avl = [];\nvar avl = {};\n\nparseAVLfull();\n\nmsg.payload = parsedMsg;\nmsg.token = parsedMsg.moduleIMEI;\n\nvar response = [];\nresponse.push(0, 5);\nresponse.push(Math.floor(parsedMsg.packetId / 256), parsedMsg.packetId % 256);\nresponse.push(1);\nresponse.push(parsedMsg.avlPacketId);\nresponse.push(parsedMsg.numberOfData);\n\nvar responseMsg = {};\nresponseMsg.ip = msg.ip;\nresponseMsg.port = msg.port;\nresponseMsg.payload = new Buffer(response);\n\n// return parsed message and UDP response\nreturn [msg, responseMsg];\n\n//**********************************************************************************************\n// parseAVLfull\n//**********************************************************************************************\nfunction parseAVLfull() {\n // get packet length\n parsedMsg.fullPacketLength = getNextInt16();\n\n // get packet ID\n parsedMsg.packetId = getNextInt16();\n\n // unused byte\n getNextInt8();\n\n // get AVL packet ID, IMEI, codec ID\n parsedMsg.avlPacketId = getNextInt8();\n\n // IMEI length & IMEI\n var imeiLength = getNextInt16();\n if (imeiLength != 15) {\n node.error(\"Wrong imei length: \" + imeiLength);\n return [null, null];\n }\n parsedMsg.moduleIMEI = toImeiString(getNextSubArray(imeiLength));\n\n // AVL Data array\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 // payload start\n for (var i = 0; i < parsedMsg.numberOfData; i++) {\n parseAVLpacketDataArrayElement();\n }\n\n // read AVL packets\n parsedMsg.numberOfRecords = getNextInt8();\n}\n\n//**********************************************************************************************\n// toImeiString\n//**********************************************************************************************\nfunction toImeiString(IMEIarray) {\n var result = \"\";\n for (var i = 0; i < IMEIarray.length; i++) {\n result += String.fromCharCode(IMEIarray[i]);\n }\n return result;\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\nmsg.payload = parsedMsg;\nmsg.token = parsedMsg.moduleIMEI;\n\nvar response = [];\nresponse.push(0, 5);\nresponse.push(Math.floor(parsedMsg.packetId / 256), parsedMsg.packetId % 256);\nresponse.push(1);\nresponse.push(parsedMsg.avlPacketId);\nresponse.push(parsedMsg.numberOfData);\n\nvar responseMsg = {};\nresponseMsg.ip = msg.ip;\nresponseMsg.port = msg.port;\nresponseMsg.payload = new Buffer(response);\n\n// return parsed message and UDP response\nreturn [msg, responseMsg];\n\n//**********************************************************************************************\n// parseAVLfull\n//**********************************************************************************************\nfunction parseAVLfull() {\n // get packet length\n parsedMsg.fullPacketLength = getNextInt16();\n\n // get packet ID\n parsedMsg.packetId = getNextInt16();\n\n // unused byte\n getNextInt8();\n\n // get AVL packet ID, IMEI, codec ID\n parsedMsg.avlPacketId = getNextInt8();\n\n // IMEI length & IMEI\n var imeiLength = getNextInt16();\n if (imeiLength != 15) {\n node.error(\"Wrong imei length: \" + imeiLength);\n return [null, null];\n }\n parsedMsg.moduleIMEI = toImeiString(getNextSubArray(imeiLength));\n\n // AVL Data array\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 // payload start\n for (var i = 0; i < parsedMsg.numberOfData; i++) {\n parseAVLpacketDataArrayElement();\n }\n\n // read AVL packets\n parsedMsg.numberOfRecords = getNextInt8();\n}\n\n//**********************************************************************************************\n// toImeiString\n//**********************************************************************************************\nfunction toImeiString(IMEIarray) {\n var result = \"\";\n for (var i = 0; i < IMEIarray.length; i++) {\n result += String.fromCharCode(IMEIarray[i]);\n }\n return result;\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": "", @@ -409,4 +409,4 @@ "userProps": "", "sessionExpiry": "" } -] \ No newline at end of file +]