How to Process16bit to bool Binary Alarms with Buffer-Parser Right

Hi all,

@Steve-Mcl thank you for your amazing work on the buffer-parser. I have a feeling that I got something wrong, but if you could please assist me, that would be greatly appreciated!

I'm processing some binary Modbus alarms (if bit x is raised, then the alarm is on) with the following flow (this subflow is an example of how I've approached this):

[
    {
        "id": "e4c264bf156ed21c",
        "type": "subflow",
        "name": "Sample Bit16 (be) to Bool Flow",
        "info": "",
        "category": "",
        "in": [
            {
                "x": 220,
                "y": 280,
                "wires": [
                    {
                        "id": "86f303ce2f0b0bbb"
                    }
                ]
            }
        ],
        "out": [],
        "env": [],
        "meta": {},
        "color": "#DDAA99"
    },
    {
        "id": "b81cf00b0f816964",
        "type": "buffer-parser",
        "z": "e4c264bf156ed21c",
        "name": "Process Sample Modbus Registers",
        "data": "payload",
        "dataType": "msg",
        "specification": "spec",
        "specificationType": "ui",
        "items": [
            {
                "type": "16bitbe",
                "name": "Reg1",
                "offset": 0,
                "length": 1,
                "offsetbit": 0,
                "scale": "1",
                "mask": ""
            },
            {
                "type": "16bitbe",
                "name": "Reg2",
                "offset": 2,
                "length": 1,
                "offsetbit": 0,
                "scale": "1",
                "mask": ""
            }
        ],
        "swap1": "",
        "swap2": "",
        "swap3": "",
        "swap1Type": "swap",
        "swap2Type": "swap",
        "swap3Type": "swap",
        "msgProperty": "payload",
        "msgPropertyType": "str",
        "resultType": "object",
        "resultTypeType": "return",
        "multipleResult": true,
        "fanOutMultipleResult": true,
        "setTopic": true,
        "outputs": 2,
        "x": 620,
        "y": 280,
        "wires": [
            [
                "c92862b2260ba848",
                "6eb455381b119990"
            ],
            [
                "2ed8f572bd8239c9",
                "1939b2ea295e7641"
            ]
        ]
    },
    {
        "id": "c92862b2260ba848",
        "type": "buffer-parser",
        "z": "e4c264bf156ed21c",
        "name": "Process Binary Alarms",
        "data": "payload.value",
        "dataType": "msg",
        "specification": "spec",
        "specificationType": "ui",
        "items": [
            {
                "type": "bool",
                "name": "Continue",
                "offset": 0,
                "length": 1,
                "offsetbit": 0,
                "scale": "1",
                "mask": ""
            },
            {
                "type": "bool",
                "name": "Hold",
                "offset": 0,
                "length": 1,
                "offsetbit": 1,
                "scale": "1",
                "mask": ""
            },
            {
                "type": "bool",
                "name": "Off",
                "offset": 0,
                "length": 1,
                "offsetbit": 2,
                "scale": "1",
                "mask": ""
            },
            {
                "type": "bool",
                "name": "Start Over",
                "offset": 0,
                "length": 1,
                "offsetbit": 3,
                "scale": "1",
                "mask": ""
            }
        ],
        "swap1": "",
        "swap2": "",
        "swap3": "",
        "swap1Type": "swap",
        "swap2Type": "swap",
        "swap3Type": "swap",
        "msgProperty": "payload",
        "msgPropertyType": "str",
        "resultType": "keyvalue",
        "resultTypeType": "return",
        "multipleResult": false,
        "fanOutMultipleResult": false,
        "setTopic": true,
        "outputs": 1,
        "x": 900,
        "y": 220,
        "wires": [
            [
                "244c868b8e3dc1ce"
            ]
        ]
    },
    {
        "id": "244c868b8e3dc1ce",
        "type": "debug",
        "z": "e4c264bf156ed21c",
        "name": "Debug SF",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "payload",
        "targetType": "msg",
        "statusVal": "",
        "statusType": "auto",
        "x": 1120,
        "y": 220,
        "wires": []
    },
    {
        "id": "6eb455381b119990",
        "type": "debug",
        "z": "e4c264bf156ed21c",
        "name": "msg.payload",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "payload",
        "targetType": "msg",
        "statusVal": "",
        "statusType": "auto",
        "x": 850,
        "y": 140,
        "wires": []
    },
    {
        "id": "2ed8f572bd8239c9",
        "type": "buffer-parser",
        "z": "e4c264bf156ed21c",
        "name": "Process Binary Alarms",
        "data": "payload.value",
        "dataType": "msg",
        "specification": "spec",
        "specificationType": "ui",
        "items": [
            {
                "type": "bool",
                "name": "Pass",
                "offset": 0,
                "length": 1,
                "offsetbit": 0,
                "scale": "1",
                "mask": ""
            },
            {
                "type": "bool",
                "name": "Drop",
                "offset": 0,
                "length": 1,
                "offsetbit": 1,
                "scale": "1",
                "mask": ""
            },
            {
                "type": "bool",
                "name": "Off",
                "offset": 0,
                "length": 1,
                "offsetbit": 2,
                "scale": "1",
                "mask": ""
            },
            {
                "type": "bool",
                "name": "Restart",
                "offset": 0,
                "length": 1,
                "offsetbit": 3,
                "scale": "1",
                "mask": ""
            }
        ],
        "swap1": "",
        "swap2": "",
        "swap3": "",
        "swap1Type": "swap",
        "swap2Type": "swap",
        "swap3Type": "swap",
        "msgProperty": "payload",
        "msgPropertyType": "str",
        "resultType": "keyvalue",
        "resultTypeType": "return",
        "multipleResult": false,
        "fanOutMultipleResult": false,
        "setTopic": true,
        "outputs": 1,
        "x": 900,
        "y": 300,
        "wires": [
            [
                "ad83ef7138325218"
            ]
        ]
    },
    {
        "id": "ad83ef7138325218",
        "type": "debug",
        "z": "e4c264bf156ed21c",
        "name": "Debug SF",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "payload",
        "targetType": "msg",
        "statusVal": "",
        "statusType": "auto",
        "x": 1120,
        "y": 300,
        "wires": []
    },
    {
        "id": "1939b2ea295e7641",
        "type": "debug",
        "z": "e4c264bf156ed21c",
        "name": "msg.payload",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "payload",
        "targetType": "msg",
        "statusVal": "",
        "statusType": "auto",
        "x": 870,
        "y": 380,
        "wires": []
    },
    {
        "id": "86f303ce2f0b0bbb",
        "type": "function",
        "z": "e4c264bf156ed21c",
        "name": "4-Byte-Buffer",
        "func": "let buf = [10, 8]\n\nmsg.payload = buf;\nreturn msg;",
        "outputs": 1,
        "timeout": 0,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 370,
        "y": 280,
        "wires": [
            [
                "b81cf00b0f816964"
            ]
        ]
    },
    {
        "id": "eb37a9689c2c24f3",
        "type": "global-config",
        "env": [],
        "modules": {
            "node-red-contrib-buffer-parser": "3.2.2"
        }
    }
]

The injected message for this bit is simply msg.payload. Since the buffer includes bits in 0 and 3 offset positions, I'd expect the final array to contain 1-2 "True" values; however, despite the raised '1's, there are no true values. What am I doing wrong?

Thank you in advance!

can you post code as well as the screenshot?

Hi @gerry!

I believe I already did:

You should be able to toggle between the flow and the source code, and you can either copy the flow to the clipboard or download it. Let me know if I missed something. Thanks!

I don't believe that's how this works. You can't toggle a screenshot. Only do that inside node red

What I attached in my first (intro) post is a flow and what I just posted above is a screenshot. Can you please try it out? If you still can't get it to work, I'll re-post the code manually. Thanks!

you need to copy the code then paste it here inside tick marks

code here

some where there is a tutorial but I can't find it right now, it looks like you posted a picture,
Sorry

No worries, I can re-post it manually. Does this work well then?

[{"id":"e4c264bf156ed21c","type":"subflow","name":"Sample Bit16 (be) to Bool Flow","info":"","category":"","in":[{"x":220,"y":280,"wires":[{"id":"86f303ce2f0b0bbb"}]}],"out":[],"env":[],"meta":{},"color":"#DDAA99"},{"id":"b81cf00b0f816964","type":"buffer-parser","z":"e4c264bf156ed21c","name":"Process Sample Modbus Registers","data":"payload","dataType":"msg","specification":"spec","specificationType":"ui","items":[{"type":"16bitbe","name":"Reg1","offset":0,"length":1,"offsetbit":0,"scale":"1","mask":""},{"type":"16bitbe","name":"Reg2","offset":2,"length":1,"offsetbit":0,"scale":"1","mask":""}],"swap1":"","swap2":"","swap3":"","swap1Type":"swap","swap2Type":"swap","swap3Type":"swap","msgProperty":"payload","msgPropertyType":"str","resultType":"object","resultTypeType":"return","multipleResult":true,"fanOutMultipleResult":true,"setTopic":true,"outputs":2,"x":620,"y":280,"wires":[["c92862b2260ba848","6eb455381b119990"],["2ed8f572bd8239c9","1939b2ea295e7641"]]},{"id":"c92862b2260ba848","type":"buffer-parser","z":"e4c264bf156ed21c","name":"Process Binary Alarms","data":"payload.value","dataType":"msg","specification":"spec","specificationType":"ui","items":[{"type":"bool","name":"Continue","offset":0,"length":1,"offsetbit":0,"scale":"1","mask":""},{"type":"bool","name":"Hold","offset":0,"length":1,"offsetbit":1,"scale":"1","mask":""},{"type":"bool","name":"Off","offset":0,"length":1,"offsetbit":2,"scale":"1","mask":""},{"type":"bool","name":"Start Over","offset":0,"length":1,"offsetbit":3,"scale":"1","mask":""}],"swap1":"","swap2":"","swap3":"","swap1Type":"swap","swap2Type":"swap","swap3Type":"swap","msgProperty":"payload","msgPropertyType":"str","resultType":"keyvalue","resultTypeType":"return","multipleResult":false,"fanOutMultipleResult":false,"setTopic":true,"outputs":1,"x":900,"y":220,"wires":[["244c868b8e3dc1ce"]]},{"id":"244c868b8e3dc1ce","type":"debug","z":"e4c264bf156ed21c","name":"Debug SF","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":1120,"y":220,"wires":[]},{"id":"6eb455381b119990","type":"debug","z":"e4c264bf156ed21c","name":"msg.payload","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":850,"y":140,"wires":[]},{"id":"2ed8f572bd8239c9","type":"buffer-parser","z":"e4c264bf156ed21c","name":"Process Binary Alarms","data":"payload.value","dataType":"msg","specification":"spec","specificationType":"ui","items":[{"type":"bool","name":"Pass","offset":0,"length":1,"offsetbit":0,"scale":"1","mask":""},{"type":"bool","name":"Drop","offset":0,"length":1,"offsetbit":1,"scale":"1","mask":""},{"type":"bool","name":"Off","offset":0,"length":1,"offsetbit":2,"scale":"1","mask":""},{"type":"bool","name":"Restart","offset":0,"length":1,"offsetbit":3,"scale":"1","mask":""}],"swap1":"","swap2":"","swap3":"","swap1Type":"swap","swap2Type":"swap","swap3Type":"swap","msgProperty":"payload","msgPropertyType":"str","resultType":"keyvalue","resultTypeType":"return","multipleResult":false,"fanOutMultipleResult":false,"setTopic":true,"outputs":1,"x":900,"y":300,"wires":[["ad83ef7138325218"]]},{"id":"ad83ef7138325218","type":"debug","z":"e4c264bf156ed21c","name":"Debug SF","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":1120,"y":300,"wires":[]},{"id":"1939b2ea295e7641","type":"debug","z":"e4c264bf156ed21c","name":"msg.payload","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":870,"y":380,"wires":[]},{"id":"86f303ce2f0b0bbb","type":"function","z":"e4c264bf156ed21c","name":"4-Byte-Buffer","func":"let buf = [10, 8]\n\nmsg.payload = buf;\nreturn msg;","outputs":1,"timeout":0,"noerr":0,"initialize":"","finalize":"","libs":[],"x":370,"y":280,"wires":[["b81cf00b0f816964"]]},{"id":"eb37a9689c2c24f3","type":"global-config","env":[],"modules":{"node-red-contrib-buffer-parser":"3.2.2"}}]

that got it

need to see how your input data is formatted, can you post a sample?

The subflow I shared is representative of what I have. The 4 bytes of data simply become x bytes (>60), but the workflow is the same. This is the smallest possible (and self-contained) example that reproduces my issue.

If you look at the debug output after the "Process Sample Modbus Registers", then you'll see this:

Bit 1 and Bit 3 are both '1'; however, if you look at the debug output of the "Process Binary Alarm", you'll see the following:

That node is defined this way, which, to my best understanding, should be "processing" the array right (Hold and Start Over should be true in the above output due to bit offsets):

Does this help explain the issue?

You can download the flow from his first post - which is not a screenshot but a rendered flow.

@gerry the first post is a code block with the flows modifier. It is a REAL flow just rendered in the browser to look like a picture. The buttons on that flow viewer are active & clickable giving you access to the flow posted by the OP

Entering the below


```flows
[
   {"id": "123", "type": "inject", "x": 100, "y": 200, "z": "abc"}
]
```

results in an interactive flow

[
   {"id": "123", "type": "inject", "x": 100, "y": 200, "z": "abc"}
]

Try clicking the buttons on the bottom right of the flow viewer

Hi Nikos, welcome to the forum and thanks for the kind words.

Yeah, you are not taking care to pass a valid value into the 2nd parser


On to the fix - there are a few ways. Here is 1

Here is another:

Supporting flows:

[{"id":"41801a922c5b3027","type":"buffer-parser","z":"63cca1d6941cd160","name":"Process Binary Alarms","data":"payload","dataType":"msg","specification":"spec","specificationType":"ui","items":[{"type":"bool","name":"Continue","offset":0,"length":1,"offsetbit":0,"scale":"1","mask":""},{"type":"bool","name":"Hold","offset":0,"length":1,"offsetbit":1,"scale":"1","mask":""},{"type":"bool","name":"Off","offset":0,"length":1,"offsetbit":2,"scale":"1","mask":""},{"type":"bool","name":"Start Over","offset":0,"length":1,"offsetbit":3,"scale":"1","mask":""}],"swap1":"swap16","swap2":"","swap3":"","swap1Type":"swap","swap2Type":"swap","swap3Type":"swap","msgProperty":"payload","msgPropertyType":"str","resultType":"keyvalue","resultTypeType":"return","multipleResult":false,"fanOutMultipleResult":false,"setTopic":true,"outputs":1,"x":860,"y":260,"wires":[["3fd6980837a06860"]]},{"id":"3fd6980837a06860","type":"debug","z":"63cca1d6941cd160","name":"Debug SF","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":1080,"y":260,"wires":[]},{"id":"eee696788c33eff7","type":"buffer-parser","z":"63cca1d6941cd160","name":"Process Binary Alarms","data":"payload","dataType":"msg","specification":"spec","specificationType":"ui","items":[{"type":"bool","name":"Pass","offset":2,"length":1,"offsetbit":0,"scale":"1","mask":""},{"type":"bool","name":"Drop","offset":2,"length":1,"offsetbit":1,"scale":"1","mask":""},{"type":"bool","name":"Off","offset":2,"length":1,"offsetbit":2,"scale":"1","mask":""},{"type":"bool","name":"Restart","offset":2,"length":1,"offsetbit":3,"scale":"1","mask":""}],"swap1":"swap16","swap2":"","swap3":"","swap1Type":"swap","swap2Type":"swap","swap3Type":"swap","msgProperty":"payload","msgPropertyType":"str","resultType":"keyvalue","resultTypeType":"return","multipleResult":false,"fanOutMultipleResult":false,"setTopic":true,"outputs":1,"x":860,"y":340,"wires":[["8c51a859d16cc5f8"]]},{"id":"8c51a859d16cc5f8","type":"debug","z":"63cca1d6941cd160","name":"Debug SF","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":1080,"y":340,"wires":[]},{"id":"b173fc8a626eb9ab","type":"function","z":"63cca1d6941cd160","name":"4-Byte-Buffer","func":"let buf = [10, 8]\n\nmsg.payload = buf;\nreturn msg;","outputs":1,"timeout":0,"noerr":0,"initialize":"","finalize":"","libs":[],"x":630,"y":300,"wires":[["41801a922c5b3027","eee696788c33eff7"]]},{"id":"aafa4d9a23ab6c0b","type":"inject","z":"63cca1d6941cd160","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":460,"y":300,"wires":[["b173fc8a626eb9ab"]]},{"id":"6bdfc37bd049af8a","type":"buffer-parser","z":"63cca1d6941cd160","name":"Process Binary Alarms","data":"payload","dataType":"msg","specification":"spec","specificationType":"ui","items":[{"type":"bool","name":"wd0=>continue","offset":0,"length":1,"offsetbit":0,"scale":"1","mask":""},{"type":"bool","name":"wd0=>hold","offset":0,"length":1,"offsetbit":1,"scale":"1","mask":""},{"type":"bool","name":"wd0=>off","offset":0,"length":1,"offsetbit":2,"scale":"1","mask":""},{"type":"bool","name":"wd0=>start_over","offset":0,"length":1,"offsetbit":3,"scale":"1","mask":""},{"type":"bool","name":"wd2=>pass","offset":2,"length":1,"offsetbit":0,"scale":"1","mask":""},{"type":"bool","name":"wd2=>drop","offset":2,"length":1,"offsetbit":1,"scale":"1","mask":""},{"type":"bool","name":"wd2=>off","offset":2,"length":1,"offsetbit":2,"scale":"1","mask":""},{"type":"bool","name":"wd2=>restart","offset":2,"length":1,"offsetbit":3,"scale":"1","mask":""}],"swap1":"swap16","swap2":"","swap3":"","swap1Type":"swap","swap2Type":"swap","swap3Type":"swap","msgProperty":"payload","msgPropertyType":"str","resultType":"keyvalue","resultTypeType":"return","multipleResult":false,"fanOutMultipleResult":false,"setTopic":true,"outputs":1,"x":860,"y":440,"wires":[["469289a42f8df5b5"]]},{"id":"56500f69e7f7d3d9","type":"function","z":"63cca1d6941cd160","name":"4-Byte-Buffer","func":"let buf = [10, 8]\n\nmsg.payload = buf;\nreturn msg;","outputs":1,"timeout":0,"noerr":0,"initialize":"","finalize":"","libs":[],"x":650,"y":440,"wires":[["6bdfc37bd049af8a"]]},{"id":"469289a42f8df5b5","type":"debug","z":"63cca1d6941cd160","name":"Debug","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":1070,"y":440,"wires":[]},{"id":"60bf16c1e15c819c","type":"inject","z":"63cca1d6941cd160","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":480,"y":440,"wires":[["56500f69e7f7d3d9"]]},{"id":"0de6c2a055c987b0","type":"global-config","env":[],"modules":{"node-red-contrib-buffer-parser":"3.2.2"}}]

Notes:

  • Avoid spaces in names - stick with camelCase naming (you will thank me later :wink: )
  • Avoid subflows unless you are templating functionality. This particular code would be more suited to the link-call subroutine pattern.

To hijack this for a moment, figured out how to get to the flow in the op's post, can someone explain how to post that ?

Steve showed how in post #12

Thanks, missed it

Thank you! That helped (and thanks for the tips)!

I see, my mistake was assuming that all arrays would work (in this case, a bit array), but you're right, the docs do indeed say "integer array".

One question:

I assumed sub-flows are sort of sub-routines or akin to sub-VIs? I'll search the forum, but if you can quickly link as to what you're specifically talking about, I'd appreciate it!

Also, to expand on templating vs sub-routines, if I have x identical devices (PLCs) from which I'm getting the exact same data and I want to, for the most part, process, display, and store that data in the same exact way for each one of them, would you still not recommend using sub-flows? Thanks!