From bb54ce30bf440f2f72b5285939c316214ea6391b Mon Sep 17 00:00:00 2001 From: Adrien van den Bossche <vandenbo@univ-tlse2.fr> Date: Sun, 5 Jul 2020 15:24:59 +0200 Subject: [PATCH] Many changes - encoders (header, GNSS and LocRef) - change casse on Node Names to respect Node-RED convention - bug on frameofref_id deconding --- .../decode_locally_referenced_packet.html | 8 +- .../decode_locally_referenced_packet.js | 11 ++- .../decode_locapack_header.html | 10 +-- .../decode_locapack_header.js | 6 +- .../decode_universal_gnss_packet.html | 8 +- .../decode_universal_gnss_packet.js | 4 +- .../encode_locally_referenced_packet.html | 26 ++++++ .../encode_locally_referenced_packet.js | 61 ++++++++++++++ .../encode_locapack_header.html | 27 +++++++ .../encode_locapack_header.js | 81 +++++++++++++++++++ .../encode_universal_gnss_packet.html | 26 ++++++ .../encode_universal_gnss_packet.js | 50 ++++++++++++ nodered/package.json | 7 +- 13 files changed, 301 insertions(+), 24 deletions(-) create mode 100644 nodered/encode_locally_referenced_packet/encode_locally_referenced_packet.html create mode 100644 nodered/encode_locally_referenced_packet/encode_locally_referenced_packet.js create mode 100644 nodered/encode_locapack_header/encode_locapack_header.html create mode 100644 nodered/encode_locapack_header/encode_locapack_header.js create mode 100644 nodered/encode_universal_gnss_packet/encode_universal_gnss_packet.html create mode 100644 nodered/encode_universal_gnss_packet/encode_universal_gnss_packet.js diff --git a/nodered/decode_locally_referenced_packet/decode_locally_referenced_packet.html b/nodered/decode_locally_referenced_packet/decode_locally_referenced_packet.html index 313c074..35fa572 100644 --- a/nodered/decode_locally_referenced_packet/decode_locally_referenced_packet.html +++ b/nodered/decode_locally_referenced_packet/decode_locally_referenced_packet.html @@ -1,5 +1,5 @@ <script type="text/javascript"> - RED.nodes.registerType('Decode LocRef',{ + RED.nodes.registerType('decode LocRef',{ category: 'locapack', color: '#d06b5f', defaults: { @@ -9,18 +9,18 @@ outputs:1, icon: "file.png", label: function() { - return this.name||"Decode LocRef"; + return this.name||"decode LocRef"; } }); </script> -<script type="text/html" data-template-name="Decode LocRef"> +<script type="text/html" data-template-name="decode LocRef"> <div class="form-row"> <label for="node-input-name"><i class="icon-tag"></i> Name</label> <input type="text" id="node-input-name" placeholder="Name"> </div> </script> -<script type="text/html" data-help-name="Decode LocRef"> +<script type="text/html" data-help-name="decode LocRef"> <p>A node that decodes Locapack type 2 payloads (Locally Referenced)</p> </script> diff --git a/nodered/decode_locally_referenced_packet/decode_locally_referenced_packet.js b/nodered/decode_locally_referenced_packet/decode_locally_referenced_packet.js index 15807e6..58dbcb0 100644 --- a/nodered/decode_locally_referenced_packet/decode_locally_referenced_packet.js +++ b/nodered/decode_locally_referenced_packet/decode_locally_referenced_packet.js @@ -1,5 +1,5 @@ module.exports = function(RED) { - function DecodeLocallyReferencedPacketNode(config) { + function decodeLocallyReferencedPacketNode(config) { RED.nodes.createNode(this,config); var node = this; node.on('input', function(msg) { @@ -39,8 +39,11 @@ module.exports = function(RED) { // If the message contains the frameofref_id field if (p.header.frameofref_id_presence_flag ) { - p.frameofref_id = 0; //buff.readBigInt64LE(len); - len += 8; + var lsB = buff.readUInt32LE(len); // 32-bit LSB + len += 4; + var msB = buff.readUInt32LE(len); // 32-bit MSB + len += 4; + p.frameofref_id = lsB + msB * Math.pow(2, 32); } msg.payload.LocaPack["locallyReferencedPacket"] = p; @@ -48,5 +51,5 @@ module.exports = function(RED) { node.send(msg); }); } - RED.nodes.registerType("Decode LocRef",DecodeLocallyReferencedPacketNode); + RED.nodes.registerType("decode LocRef",decodeLocallyReferencedPacketNode); } diff --git a/nodered/decode_locapack_header/decode_locapack_header.html b/nodered/decode_locapack_header/decode_locapack_header.html index 82968ff..c5cc1b2 100644 --- a/nodered/decode_locapack_header/decode_locapack_header.html +++ b/nodered/decode_locapack_header/decode_locapack_header.html @@ -1,5 +1,5 @@ <script type="text/javascript"> - RED.nodes.registerType('Decode Header',{ + RED.nodes.registerType('decode header',{ category: 'locapack', color: '#e06b5f', defaults: { @@ -9,19 +9,19 @@ outputs:1, icon: "file.png", label: function() { - return this.name||"Decode Header"; + return this.name||"decode header"; } }); </script> -<script type="text/html" data-template-name="Decode Header"> +<script type="text/html" data-template-name="decode header"> <div class="form-row"> <label for="node-input-name"><i class="icon-tag"></i> Name</label> <input type="text" id="node-input-name" placeholder="Name"> </div> </script> -<script type="text/html" data-help-name="Decode Header"> - <p>A simple node that converts the message payloads...</p> +<script type="text/html" data-help-name="decode header"> + <p>A node that decodes a LocaPack message header.</p> </script> diff --git a/nodered/decode_locapack_header/decode_locapack_header.js b/nodered/decode_locapack_header/decode_locapack_header.js index 9e404a4..81fa86a 100644 --- a/nodered/decode_locapack_header/decode_locapack_header.js +++ b/nodered/decode_locapack_header/decode_locapack_header.js @@ -1,5 +1,5 @@ module.exports = function(RED) { - function DecodeLocaPackHeaderNode(config) { + function decodeLocaPackHeaderNode(config) { RED.nodes.createNode(this,config); var node = this; node.on('input', function(msg) { @@ -8,7 +8,7 @@ module.exports = function(RED) { var buff = msg.payload.LocaPack.inputBuffer; var len = 0; - // Get Header Field (hdr) + // Get header Field (hdr) var hdr = {}; var hdr_raw = buff.readUInt16LE(len); hdr.protocol_version = (hdr_raw & 0xF000) >> 12 ; @@ -54,5 +54,5 @@ module.exports = function(RED) { node.send(msg); }); } - RED.nodes.registerType("Decode Header",DecodeLocaPackHeaderNode); + RED.nodes.registerType("decode header",decodeLocaPackHeaderNode); } diff --git a/nodered/decode_universal_gnss_packet/decode_universal_gnss_packet.html b/nodered/decode_universal_gnss_packet/decode_universal_gnss_packet.html index df3912c..ae303a7 100644 --- a/nodered/decode_universal_gnss_packet/decode_universal_gnss_packet.html +++ b/nodered/decode_universal_gnss_packet/decode_universal_gnss_packet.html @@ -1,5 +1,5 @@ <script type="text/javascript"> - RED.nodes.registerType('Decode GNSS',{ + RED.nodes.registerType('decode GNSS',{ category: 'locapack', color: '#d06b5f', defaults: { @@ -9,18 +9,18 @@ outputs:1, icon: "file.png", label: function() { - return this.name||"Decode GNSS"; + return this.name||"decode GNSS"; } }); </script> -<script type="text/html" data-template-name="Decode GNSS"> +<script type="text/html" data-template-name="decode GNSS"> <div class="form-row"> <label for="node-input-name"><i class="icon-tag"></i> Name</label> <input type="text" id="node-input-name" placeholder="Name"> </div> </script> -<script type="text/html" data-help-name="Decode GNSS"> +<script type="text/html" data-help-name="decode GNSS"> <p>A node that decodes Locapack type 1 payloads (Universal GNSS)</p> </script> diff --git a/nodered/decode_universal_gnss_packet/decode_universal_gnss_packet.js b/nodered/decode_universal_gnss_packet/decode_universal_gnss_packet.js index b6ef6cc..3138297 100644 --- a/nodered/decode_universal_gnss_packet/decode_universal_gnss_packet.js +++ b/nodered/decode_universal_gnss_packet/decode_universal_gnss_packet.js @@ -1,5 +1,5 @@ module.exports = function(RED) { - function DecodeUniversalGnssPacketNode(config) { + function decodeUniversalGnssPacketNode(config) { RED.nodes.createNode(this,config); var node = this; node.on('input', function(msg) { @@ -41,5 +41,5 @@ module.exports = function(RED) { node.send(msg); }); } - RED.nodes.registerType("Decode GNSS",DecodeUniversalGnssPacketNode); + RED.nodes.registerType("decode GNSS",decodeUniversalGnssPacketNode); } diff --git a/nodered/encode_locally_referenced_packet/encode_locally_referenced_packet.html b/nodered/encode_locally_referenced_packet/encode_locally_referenced_packet.html new file mode 100644 index 0000000..19ffbf2 --- /dev/null +++ b/nodered/encode_locally_referenced_packet/encode_locally_referenced_packet.html @@ -0,0 +1,26 @@ +<script type="text/javascript"> + RED.nodes.registerType('encode LocRef',{ + category: 'locapack', + color: '#d06b5f', + defaults: { + name: {value:""} + }, + inputs:1, + outputs:1, + icon: "file.png", + label: function() { + return this.name||"encode LocRef"; + } + }); +</script> + +<script type="text/html" data-template-name="encode LocRef"> + <div class="form-row"> + <label for="node-input-name"><i class="icon-tag"></i> Name</label> + <input type="text" id="node-input-name" placeholder="Name"> + </div> +</script> + +<script type="text/html" data-help-name="encode LocRef"> + <p>A node that encodes Locapack type 2 payloads (Locally Referenced)</p> +</script> diff --git a/nodered/encode_locally_referenced_packet/encode_locally_referenced_packet.js b/nodered/encode_locally_referenced_packet/encode_locally_referenced_packet.js new file mode 100644 index 0000000..b10a097 --- /dev/null +++ b/nodered/encode_locally_referenced_packet/encode_locally_referenced_packet.js @@ -0,0 +1,61 @@ +module.exports = function(RED) { + function encodeLocallyReferencedPacketNode(config) { + RED.nodes.createNode(this,config); + var node = this; + node.on('input', function(msg) { + + const buff = Buffer.alloc(128); + var len = 0; + var z_presence_flag = false; + var dop_presence_flag = false; + var frameofref_id_presence_flag = false; + + // Check mandatory fields + if (typeof msg.payload.x === 'undefined') return; + if (typeof msg.payload.y === 'undefined') return; + + // Check optional fields + if (typeof msg.payload.z !== 'undefined') z_presence_flag = true; + if (typeof msg.payload.dop !== 'undefined') dop_presence_flag = true; + if (typeof msg.payload.frameofref_id !== 'undefined') frameofref_id_presence_flag = true; + + // Make header + if (z_presence_flag) buff[len] |= 0x80; + if (dop_presence_flag) buff[len] |= 0x40; + if (frameofref_id_presence_flag) buff[len] |= 0x20; + len += 1; + + // Make x and y fields + buff.writeFloatLE(msg.payload.x, len); + len += 4; + buff.writeFloatLE(msg.payload.y, len); + len += 4; + + // Make z field if present + if ( z_presence_flag ) { + buff.writeFloatLE(msg.payload.z, len); + len += 4; + } + + // Make dop field if present + if ( dop_presence_flag ) { + buff.writeFloatLE(msg.payload.dop, len); + len += 4; + } + + // Make frameofref_id field if present + if ( frameofref_id_presence_flag ) { + buff.writeUInt32LE(msg.payload.frameofref_id%Math.pow(2, 32), len); // 32-bit LSB + len += 4; + buff.writeUInt32LE(msg.payload.frameofref_id/Math.pow(2, 32), len); // 32-bit MSB + len += 4; + } + + msg.payload["LocaPack"] = {}; + msg.payload["LocaPack"]["locallyReferencedPacket"] = {}; + msg.payload["LocaPack"]["locallyReferencedPacket"]["buffer"] = buff.subarray(0, len); + node.send(msg); + }); + } + RED.nodes.registerType("encode LocRef",encodeLocallyReferencedPacketNode); +} diff --git a/nodered/encode_locapack_header/encode_locapack_header.html b/nodered/encode_locapack_header/encode_locapack_header.html new file mode 100644 index 0000000..26220b4 --- /dev/null +++ b/nodered/encode_locapack_header/encode_locapack_header.html @@ -0,0 +1,27 @@ +<script type="text/javascript"> + RED.nodes.registerType('encode header',{ + category: 'locapack', + color: '#e06b5f', + defaults: { + name: {value:""} + }, + inputs:1, + outputs:1, + icon: "file.png", + label: function() { + return this.name||"encode header"; + } + }); +</script> + +<script type="text/html" data-template-name="encode header"> + <div class="form-row"> + <label for="node-input-name"><i class="icon-tag"></i> Name</label> + <input type="text" id="node-input-name" placeholder="Name"> + </div> +</script> + +<script type="text/html" data-help-name="encode header"> + <p>A node that encodes a LocaPack message header.</p> +</script> + diff --git a/nodered/encode_locapack_header/encode_locapack_header.js b/nodered/encode_locapack_header/encode_locapack_header.js new file mode 100644 index 0000000..986ce93 --- /dev/null +++ b/nodered/encode_locapack_header/encode_locapack_header.js @@ -0,0 +1,81 @@ +module.exports = function(RED) { + function encodeLocaPackHeaderNode(config) { + RED.nodes.createNode(this,config); + var node = this; + node.on('input', function(msg) { + + const buff = Buffer.alloc(128); + var len = 0; + var header = 0; + var altitude_presence_flag = false; + var dop_presence_flag = false; + var packet_type; + + // Check mandatory fields + if (typeof msg.payload.sequence_number === 'undefined') return; + + // Check optional fields + if (typeof msg.payload.timestamp !== 'undefined') timestamp_presence_flag = true; + if (typeof msg.payload.movement_id !== 'undefined') movement_id_presence_flag = true; + if (typeof msg.payload.device_id !== 'undefined') { + // device_id_size is mandatory if a device_id is given + if (typeof msg.payload.device_id_size === 'undefined') return; + device_id_presence_flag = true; + } + + // Determine packet_type or exit + if (typeof msg.payload.LocaPack.universalGnssPacket !== 'undefined') packet_type = 1; + if (typeof msg.payload.LocaPack.locallyReferencedPacket !== 'undefined') packet_type = 2; + if (packet_type === 'undefined') return; + + // Make header + header |= 1 << 12; // Protocol version 1 + header |= msg.payload.device_id_size << 8; + header |= packet_type << 4; + if (movement_id_presence_flag) header |= 0x0008; + if (device_id_presence_flag) header |= 0x0004; + buff.writeUInt16LE(header, len); + len += 2; + + // Make sequence number field + buff.writeUInt16LE(msg.payload.sequence_number, len); + len += 2; + + // Make timestamp field if present (5 bytes) + if ( timestamp_presence_flag ) { + buff.writeUIntLE(msg.payload.timestamp, len, 5); + len += 5; + } + + // Make movement_id field if present + if ( movement_id_presence_flag ) { + buff[len] = msg.payload.movement_id; + len += 1; + } + + // Make device_id field if present + if ( device_id_presence_flag ) { + buff.writeUIntLE(msg.payload.device_id, len, msg.payload.device_id_size); + len += msg.payload.device_id_size; + } + + // Add payload len and payload + if ( packet_type == 1 ) { + payload_len = msg.payload.LocaPack.universalGnssPacket.buffer.length; + buff[len] = payload_len + len += 1; + var header_buff_universalGnssPacket = buff.subarray(0, len); + msg.payload["LocaPack"]["outputBuffer"] = Buffer.concat([header_buff_universalGnssPacket, msg.payload.LocaPack.universalGnssPacket.buffer], len + payload_len); + } else if ( packet_type == 2 ) { + payload_len = msg.payload.LocaPack.locallyReferencedPacket.buffer.length; + buff[len] = payload_len + len += 1; + var header_buff_locallyReferencedPacket = buff.subarray(0, len); + msg.payload["LocaPack"]["outputBuffer"] = Buffer.concat([header_buff_locallyReferencedPacket, msg.payload.LocaPack.locallyReferencedPacket.buffer], len + payload_len); + } else return; + + node.send(msg); + }); + } + RED.nodes.registerType("encode header",encodeLocaPackHeaderNode); +} diff --git a/nodered/encode_universal_gnss_packet/encode_universal_gnss_packet.html b/nodered/encode_universal_gnss_packet/encode_universal_gnss_packet.html new file mode 100644 index 0000000..70a3a11 --- /dev/null +++ b/nodered/encode_universal_gnss_packet/encode_universal_gnss_packet.html @@ -0,0 +1,26 @@ +<script type="text/javascript"> + RED.nodes.registerType('encode GNSS',{ + category: 'locapack', + color: '#d06b5f', + defaults: { + name: {value:""} + }, + inputs:1, + outputs:1, + icon: "file.png", + label: function() { + return this.name||"encode GNSS"; + } + }); +</script> + +<script type="text/html" data-template-name="encode GNSS"> + <div class="form-row"> + <label for="node-input-name"><i class="icon-tag"></i> Name</label> + <input type="text" id="node-input-name" placeholder="Name"> + </div> +</script> + +<script type="text/html" data-help-name="encode GNSS"> + <p>A node that encodes Locapack type 1 payloads (Universal GNSS)</p> +</script> diff --git a/nodered/encode_universal_gnss_packet/encode_universal_gnss_packet.js b/nodered/encode_universal_gnss_packet/encode_universal_gnss_packet.js new file mode 100644 index 0000000..7d1c016 --- /dev/null +++ b/nodered/encode_universal_gnss_packet/encode_universal_gnss_packet.js @@ -0,0 +1,50 @@ +module.exports = function(RED) { + function encodeUniversalGnssPacketNode(config) { + RED.nodes.createNode(this,config); + var node = this; + node.on('input', function(msg) { + + const buff = Buffer.alloc(128); + var len = 0; + var altitude_presence_flag = false; + var dop_presence_flag = false; + + // Check mandatory fields + if (typeof msg.payload.latitude === 'undefined') return; + if (typeof msg.payload.longitude === 'undefined') return; + + // Check optional fields + if (typeof msg.payload.altitude !== 'undefined') altitude_presence_flag = true; + if (typeof msg.payload.dop !== 'undefined') dop_presence_flag = true; + + // Make header + if (altitude_presence_flag) buff[len] |= 0x80; + if (dop_presence_flag) buff[len] |= 0x40; + len += 1; + + // Make latitude and longitude fields + buff.writeFloatLE(msg.payload.latitude, len); + len += 4; + buff.writeFloatLE(msg.payload.longitude, len); + len += 4; + + // Make altitude field if present + if ( altitude_presence_flag ) { + buff.writeFloatLE(msg.payload.altitude, len); + len += 4; + } + + // Make dop field if present + if ( dop_presence_flag ) { + buff.writeFloatLE(msg.payload.dop, len); + len += 4; + } + + msg.payload["LocaPack"] = {}; + msg.payload["LocaPack"]["universalGnssPacket"] = {}; + msg.payload["LocaPack"]["universalGnssPacket"]["buffer"] = buff.subarray(0, len); + node.send(msg); + }); + } + RED.nodes.registerType("encode GNSS",encodeUniversalGnssPacketNode); +} diff --git a/nodered/package.json b/nodered/package.json index 57e7d68..54a7b6f 100644 --- a/nodered/package.json +++ b/nodered/package.json @@ -1,7 +1,7 @@ { "name": "node-red-contrib-locapack", - "version": "0.0.4", - "description": "A node to interact with LocaPack devices using the LocaPack protocol", + "version": "0.0.5", + "description": "Some nodes to interact with LocaPack devices using the LocaPack protocol", "dependencies": { }, "keywords": [ "node-red", "localisation", "protocol" ], @@ -13,8 +13,11 @@ "license": "GPLv3", "node-red" : { "nodes": { + "EncodeLocapackHeader": "encode_locapack_header/encode_locapack_header.js", "DecodeLocapackHeader": "decode_locapack_header/decode_locapack_header.js", + "EncodeUniversalGnssPacket": "encode_universal_gnss_packet/encode_universal_gnss_packet.js", "DecodeUniversalGnssPacket": "decode_universal_gnss_packet/decode_universal_gnss_packet.js", + "EncodeLocallyReferencedPacket": "encode_locally_referenced_packet/encode_locally_referenced_packet.js", "DecodeLocallyReferencedPacket": "decode_locally_referenced_packet/decode_locally_referenced_packet.js" } } -- GitLab