node-red-contrib-buffer-parser

    3.1.7 • Public • Published

    node-red-contrib-buffer-parser

    About

    A pair of Node-RED nodes to convert values to and from buffer/array. Supports Big/Little Endian, BCD, byte swapping and much more.

    A picture is worth a thousand words

    Convert array of integers into individual topic/payload messages - ideal for sending to MQTT

    example1

    Convert a buffer into key/value items - ideal for sending to dashboard or database

    example3 example3b

    Fan out

    example3

    Scaling final values

    example3

    buffer-maker - Summary of functionality (New in V3.0)

    • Set-up a specification and convert multiple values into a buffer from...
      • int, int8, byte, uint, uint8,
      • int16, int16le, int16be, uint16, uint16le, uint16be,
      • int32, int32le, int32be, uint32, uint32le, uint32be,
      • bigint64, bigint64be, bigint64le, biguint64, biguint64be, biguint64le,
      • float, floatle, floatbe, double, doublele, doublebe,
      • 8bit, 16bit, 16bitle, 16bitbe, bool,
      • bcd, bcdle, bcdbe,
      • string, hex, ascii, utf8, utf16le, ucs2, latin1, binary, buffer
    • Specification is either configured by the built in UI or can be set by a msg/flow/global
    • Input data for each item to include in the final buffer can come from just about anywhere, making it very flexible...
      • a constant (e.g. a number, a string, a boolean, a JSON array)
      • a msg property (e.g from msg.payload.myInteger)
      • a flow property (e.g from flow.myInteger)
      • a global property (e.g from global.myInteger)
    • The final built buffer can be byte swapped one or more times. 16, 32 or 64 bit swaps are possible. The byte swaps are performed the data conversions like LE or BE functions (sometimes it is necessary to do multiple swaps)
    • The final buffer can be output to any msg property (defaults to msg.payload)
    • Built in help

    buffer-parser - Summary of functionality

    • Set-up a specification and convert multiple parts of an array or buffer to...

      • int, int8, byte, uint, uint8,
      • int16, int16le, int16be, uint16, uint16le, uint16be,
      • int32, int32le, int32be, uint32, uint32le, uint32be,
      • bigint64, bigint64be, bigint64le, biguint64, biguint64be, biguint64le,
      • float, floatle, floatbe, double, doublele, doublebe,
      • 8bit, 16bit, 16bitle, 16bitbe, bool,
      • bcd, bcdle, bcdbe,
      • string, hex, ascii, utf8, utf16le, ucs2, latin1, binary, buffer
    • Specification is either configured by the built in UI or can be set by a msg/flow/global property - permitting fully dynamic setup (e.g. via a dashboard)

    • The specification format permits random access (e.g. no need for any skips when accessing only first and last elements)

    • You can specify the same offset many times to convert the same piece of data several times

    • The data can be byte swapped one or more times. 16, 32 or 64 bit swaps are possible. The byte swaps are done prior to any data conversions like LE or BE functions (sometimes it is necessary to do multiple swaps)

    • The output can be sent in any msg property. e.g. you can send results out in msg.my.nested.property. This has the advantage of leaving the original payload in tact.

    • Input data can come from any msg property (not limited to msg.payload)

    • Input data can be a 16bit array (common plc data format) simplifying working with PLC type data arrays

    • Input data can be a hex string e.g. 1FE2D7FFBE

    • Output results can be multiple messages as topic and payload

      • ideal for taking PLC data and sending it directly to MQTT
    • Output results can be multiple messages fanned out so that each item in the specification is sent out of its own output (New in V3.1)

    • Output results can be a single msg style output

      • ideal for converting multiple different data elements into one object to pass on to perhaps a template node for preparing a SQL or HTML statement using {{mustache}} formatting
      • additionally, output results can be 1 of 4 styles...
        • "value" : the parsed values are sent in an array
        • "keyvalue" : the parsed values are sent in an object as key/value pairs. Use a fat arrow => in the name to create object.properties e.g. motor1=>power will end up in msg.payload.motor1.power.'
        • "object" : the parsed values are sent as named objects with the value set .value and other contextual properties included (like the item specification). Use a fat arrow => in the name to create object.properties e.g. motor1=>power will end up in msg.payload.motor1.power.'
        • "array" : the parsed values are sent as objects in an array, with each object containing a .value property and other contextual properties included (like the item specification)
        • "buffer" : this mode simply returns a buffer (no item processing)
    • Final values can be masked (e.g. a MASK of 0x7FFF could be used to remove the MSB or 0b1000000000000001 to keep only MSB and LSB)

      • Binary and Octal masks only available in V3.1 onwards
    • Final values can be have a Scale value or a simple Scale Equation (New in V3.1) applied...

      • e.g. Entering a Scale value of 0.01 would turn 9710 into 97.1
      • e.g. Entering a Scale value of 10 would turn 4.2 into 42
      • e.g. Entering a Scale Equation of >> 4 would bit shift the value 0x0070 to 0x0007
      • e.g. Entering a Scale Equation of + 42 would add an offset of 42 to the final value (New in V3.1)
      • Supported Scaling Equations are...
        • << e.g. <<2 would left shift the parsed value 2 places
        • >> e.g. >>2 would right shift the parsed value 2 places
        • >>> e.g. >>>2 would zero-fill right shift the parsed value 2 places (returns a 32bit unsigned value)
        • + e.g. +10 would add 10 to the parsed value
        • - e.g. -10 would deduct 10 from the parsed value
        • / e.g. /10 would divide the parsed value by 10
        • * e.g. *10 would multiply the parsed value by 10
        • ** e.g. **2 would raise the parsed value to the power of 2
        • ^ e.g. ^0xf0 would XOR the parsed value with 0xf0
        • == e.g. ==10 would result in true if the parsed value was equal to 10
        • != e.g. !=10 would result in false if the parsed value was equal to 10
        • !! e.g. !! would result in true if the parsed value was 1 (same as !!1 == true)
        • > e.g. >10 would result in true if the parsed value was greater than 10
        • < e.g. <10 would result in true if the parsed value was less than 10
      • NOTE: the scale/equation is applied AFTER the mask
    • Final values can be have a scale applied (e.g. a scale of 0.01 would turn 9710 into 97.1 or a scale of 10 would turn 50 into 500)

      • NOTE: the scale is applied AFTER the mask
    • Built in help

      help

    Examples

    Example 1 - array of data to MQTT (multiple topics / payloads)

    Screen shot - the flow

    example1a

    Screen shot - the output

    example1b

    Flow...

    [{"id":"1194a28a.49d0ad","type":"buffer-parser","z":"c70ba4a4.e7fb58","name":"","data":"payload","dataType":"msg","specification":"{\"options\":{\"byteSwap\":[\"swap16\"],\"resultType\":\"value\",\"singleResult\":false,\"msgProperty\":\"payload\"},\"items\":[{\"name\":\"plc1/production/alphabet\",\"type\":\"string\",\"offset\":0,\"length\":26},{\"name\":\"plc1/production/status/count\",\"type\":\"int\",\"offset\":25},{\"name\":\"plc1/production/status/sequence\",\"type\":\"bcd\",\"offset\":4},{\"name\":\"plc1/machine/status/runner/temperature\",\"type\":\"int16le\",\"offset\":26},{\"name\":\"plc1/machine/status/runner/speed\",\"type\":\"int16be\",\"offset\":26},{\"name\":\"plc1/machine/status/running\",\"type\":\"bool\",\"offset\":0,\"offsetbit\":0},{\"name\":\"plc1/machine/status/warning\",\"type\":\"bool\",\"offset\":0,\"offsetbit\":1},{\"name\":\"plc1/machine/status/fault\",\"type\":\"bool\",\"offset\":0,\"offsetbit\":2}]}","specificationType":"json","x":1110,"y":480,"wires":[["858b1ecf.77b58"]]},{"id":"858b1ecf.77b58","type":"debug","z":"c70ba4a4.e7fb58","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","x":1350,"y":480,"wires":[]},{"id":"c22cd2e8.52649","type":"inject","z":"c70ba4a4.e7fb58","name":"Fake PLC data 16bit Array","topic":"","payload":"[25185,25699,26213,26727,27241,27755,28013,28783,29297,29811,30325,30839,31353,256,512,768,1024,1280,1536,1792,2048,2304,2560,2816,3072,3597]","payloadType":"json","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":890,"y":480,"wires":[["1194a28a.49d0ad"]]},{"id":"970db39d.106a6","type":"comment","z":"c70ba4a4.e7fb58","name":"take a array of 16bit values, byte reverse, split out several values and transmit individual messages with topic + payload","info":"","x":1160,"y":440,"wires":[]}]
    

    Example 2 - array of data to an named objects

    Screen shot - the flow

    example2a

    Screen shot - the output

    example2b

    Flow...

    [{"id":"1523dd03.6332f3","type":"buffer-parser","z":"c70ba4a4.e7fb58","name":"","data":"payload","dataType":"msg","specification":"{\"options\":{\"byteSwap\":[\"swap16\"],\"resultType\":\"object\",\"singleResult\":true,\"msgProperty\":\"data\"},\"items\":[{\"name\":\"alphabet\",\"type\":\"string\",\"offset\":0,\"length\":26},{\"name\":\"single byte pos 4\",\"type\":\"int\",\"offset\":4},{\"name\":\"bcd equiv\",\"type\":\"bcd\",\"offset\":4,\"length\":5},{\"name\":\"Array[6] of int16le\",\"type\":\"int16le\",\"offset\":26,\"length\":6},{\"name\":\"Array[6] of int16be\",\"type\":\"int16be\",\"offset\":26,\"length\":6},{\"name\":\"32 bools\",\"type\":\"bool\",\"offset\":0,\"length\":32},{\"name\":\"Array[4] of 16bits\",\"type\":\"16bit\",\"offset\":0,\"length\":4}]}","specificationType":"json","x":1110,"y":560,"wires":[["a3051c67.b82ad"]]},{"id":"a3051c67.b82ad","type":"debug","z":"c70ba4a4.e7fb58","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"data","targetType":"msg","x":1340,"y":560,"wires":[]},{"id":"9b72f1f5.1aacc","type":"inject","z":"c70ba4a4.e7fb58","name":"Fake PLC data 16bit Array","topic":"","payload":"[25185,25699,26213,26727,27241,27755,28013,28783,29297,29811,30325,30839,31353,256,512,768,1024,1280,1536,1792,2048,2304,2560,2816,3072,3597]","payloadType":"json","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":890,"y":560,"wires":[["1523dd03.6332f3"]]},{"id":"a9a2dd4c.118f9","type":"comment","z":"c70ba4a4.e7fb58","name":"take a array of 16bit values, byte reverse, split out several values and transmit one message with named objects in msg.data","info":"","x":1180,"y":520,"wires":[]}]
    

    Install

    Pallet Manager...

    The simplest method is to install via the pallet manager in node red. Simply search for node-red-contrib-buffer-parser then click install

    Terminal...

    Run the following command in the root directory of your Node-RED install (usually ~/.node-red or %userprofile%\.node-red)

    npm install node-red-contrib-buffer-parser
    

    Or, install direct from github

    npm install steve-mcl/node-red-contrib-buffer-parser
    

    Or clone to a local folder and install using NPM

    git clone https://github.com/Steve-Mcl/node-red-contrib-buffer-parser.git
    npm install c:/source/node-red-contrib-buffer-parser
    

    Dependencies

    none 😄

    Install

    npm i node-red-contrib-buffer-parser

    DownloadsWeekly Downloads

    293

    Version

    3.1.7

    License

    MIT

    Unpacked Size

    641 kB

    Total Files

    26

    Last publish

    Collaborators

    • steve-mcl