How can i allow join-node after captured two payloads in a datastream?

not sure how to explain this but... i got 10byte, 8bits, dec value like this:


and i use join node to split them into array.
image
but..sometimes i get glitzes in the communication and the split array just wont work...

i want to somehow watch the data-stream for
payload[0] == 171 && payload[0] == 205 and then start the "join node" to split into array.

Something like..
If(payload[0]==171 && payload[0]==205){start count payload[0]'s up to 8 and then merge into one array output}

Ok, kind of getting what you are saying, but also not. Sorry.

If there is a glitze and the array is spli I fear you have bigger problems.

But, sticking to what you say/ask:

You may need to post the actual message rather than screen shots. (May help)
Spit balling (throwing ideas to consider)
You will need two SWITCH nodes.
One set to look at payload[0] and the next to look at `payload

In your example you are testing payload[0] for two different variables.
That can't happen unless you mean check two subsequent messages and check their conditions.

Can you post a GOOD payload and then the BAD payload/s.

Where is that data coming from, and through what node?

image

as i cannot change the stream of correct values, i need to observe when value 171, 205 and then start count the rest of the string, im unsure how.
this might work if i could put all values inside one payload...

let lines = msg.payload.split(" ");
for(let i = 0; i < lines.length; i++) {
let line = lines[i].trim();
let parts = line.split(" ");
if(parts.length != 2) continue;
node.send({ topic: "byte_nr_" + parts[0], payload: parts[1]});
}
node.send({complete:true})

the 10byte value in decimal looks like this.
171 205 001 019 000 000 000 001 000 021

im trying to find a solution something like this...
image

Something like this should do it, in a Function node

let state = context.get("state") || "wait_171"
let buff = context.get("buff") || []
let count = context.get("count") || 0
const maxCount = 8  // number of additional chars to get
switch(state) {
    case "wait_171":
    if (msg.payload[0] == 171) {
        buff = [171]
        state = "wait_205"
    }
    // otherwise ignore this character
    // send nothing back 
    msg = null
    break;

    case "wait_205":
    if (msg.payload[0] == 205) {
        buff.push(205)
        state = "buffering"
        count = 0
    } else {
        // only 205 is valid here, so start again
        state = "wait_171"
    }
    msg = null
    break;
    
    default: // buffering
    buff.push(msg.payload[0])
    count++
    if (count >= maxCount) {
        // have now received a full buffer
        msg.payload = buff
        state = "wait_171"
        count = 0
    } else {
        msg = null
    }
}
context.set("state", state)
context.set("buff", buff)
context.set("count", count)
node.status({ text: `state: ${state}, count: ${count}` });
return msg;

Test flow:

[{"id":"6586e0f3363d2f8f","type":"inject","z":"e672d6322ed2b137","name":"171","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"[171]","payloadType":"bin","x":130,"y":220,"wires":[["31c19a45d4d1ba99"]]},{"id":"5eef4a3f33425859","type":"debug","z":"e672d6322ed2b137","name":"debug 47","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":540,"y":260,"wires":[]},{"id":"6915fc970d0ba5e0","type":"inject","z":"e672d6322ed2b137","name":"205","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"[205]","payloadType":"bin","x":130,"y":260,"wires":[["31c19a45d4d1ba99"]]},{"id":"2c2d25c611fb7c8f","type":"inject","z":"e672d6322ed2b137","name":"1","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"[1]","payloadType":"bin","x":130,"y":340,"wires":[["31c19a45d4d1ba99"]]},{"id":"074de7f8c91057b5","type":"inject","z":"e672d6322ed2b137","name":"22","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"[22]","payloadType":"bin","x":130,"y":380,"wires":[["31c19a45d4d1ba99"]]},{"id":"31c19a45d4d1ba99","type":"function","z":"e672d6322ed2b137","name":"Build message","func":"let state = context.get(\"state\") || \"wait_171\"\nlet buff = context.get(\"buff\") || []\nlet count = context.get(\"count\") || 0\nconst maxCount = 8  // number of additional chars to get\nswitch(state) {\n    case \"wait_171\":\n    if (msg.payload[0] == 171) {\n        buff = [171]\n        state = \"wait_205\"\n    }\n    // otherwise ignore this character\n    // send nothing back \n    msg = null\n    break;\n\n    case \"wait_205\":\n    if (msg.payload[0] == 205) {\n        buff.push(205)\n        state = \"buffering\"\n        count = 0\n    } else {\n        // only 205 is valid here, so start again\n        state = \"wait_171\"\n    }\n    msg = null\n    break;\n    \n    default: // buffering\n    buff.push(msg.payload[0])\n    count++\n    if (count >= maxCount) {\n        // have now received a full buffer\n        msg.payload = buff\n        state = \"wait_171\"\n        count = 0\n    } else {\n        msg = null\n    }\n}\ncontext.set(\"state\", state)\ncontext.set(\"buff\", buff)\ncontext.set(\"count\", count)\nnode.status({ text: `state: ${state}, count: ${count}` });\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":340,"y":260,"wires":[["5eef4a3f33425859"]]}]

indeed, it did quite good, there was still some issues and when i observe the tcp-stream, it seems node-red pick up more than one value in the array (sometimes) and that wont count...

i added some .hasOwnProperty and it seems to work but unsure if this looks ok, how would you done this?

[
    {
        "id": "31c19a45d4d1ba99",
        "type": "function",
        "z": "0f9de81aaa0f53ef",
        "name": "Build message",
        "func": "let state = context.get(\"state\") || \"wait_171\"\nlet buff = context.get(\"buff\") || []\nlet count = context.get(\"count\") || 0\nconst maxCount = 8  // number of additional chars to get\nswitch(state) {\n    case \"wait_171\":\n    if (msg.payload[0] == 171) {\n        buff = [171]\n        state = \"wait_205\"\n    }\n    // otherwise ignore this character\n    // send nothing back \n    msg = null\n    break;\n\n    case \"wait_205\":\n    if (msg.payload[0] == 205) {\n        buff.push(205)\n        state = \"buffering\"\n        count = 0\n    } else {\n        // only 205 is valid here, so start again\n        state = \"wait_171\"\n    }\n    msg = null\n    break;\n    \n    default: // buffering\n    buff.push(msg.payload[0])\n    if (msg.payload.hasOwnProperty([1])){\n        state = \"count [1]\"\n        buff.push(msg.payload[1])\n      // if theres a the msg.payload[] contains more than one value, then count this as well..\n        count++\n        if (msg.payload.hasOwnProperty([2])){\n        state = \"count [2]\"\n        buff.push(msg.payload[2])\n            // if theres a the msg.payload[] contains more than one message, then count this as well..\n        count++\n        if (msg.payload.hasOwnProperty([3])){\n        state = \"count [3]\"\n        buff.push(msg.payload[3])\n      // if theres a the msg.payload[] contains more than one value, then count this as well..\n        count++\n        if (msg.payload.hasOwnProperty([4])){\n        state = \"count [4]\"\n        buff.push(msg.payload[4])\n            // if theres a the msg.payload[] contains more than one message, then count this as well..\n        count++\n    }\n    }\n    }\n    }\n\n    \n    count++\n    if (count >= maxCount) {\n        // have now received a full buffer\n        msg.payload = buff\n        state = \"wait_171\"\n        count = 0\n    } else {\n        msg = null\n    }\n}\ncontext.set(\"state\", state)\ncontext.set(\"buff\", buff)\ncontext.set(\"count\", count)\nnode.status({ text: `state: ${state}, count: ${count}` });\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 500,
        "y": 2000,
        "wires": [
            [
                "5eef4a3f33425859"
            ]
        ]
    }
]

Instead of doing that, insert a split node in front of the function , configured as

image

which will split it up into single bytes for the function to handle.

As you currently have it, if a multibyte buffer arrived near the end then it would overflow the 10 bytes length.

This topic was automatically closed 60 days after the last reply. New replies are no longer allowed.