Multiple cases with multiple actions

Hello everybody, I don't have programming experience and I need your help.

I am using node-red to analyze a tcp-output string that includes this sequence: "00000000" (8 characters).
This is sent by an electronic card that has 8 inputs (each "0" corresponds to an input).
If an input is activated, the corresponding "0" changes to "1" and for each input activation I need to send an e-mail with a specific text.
E.g. 10000000 (first input active), 10100000 (1st and 3rd are active) etc.

I can create a switch node with each case, but that would be quite difficult, because more than 1 input can be activated at the same time. Or perhaps another input is activated while others are already active.

I think a function node should be created, but I don't know exactly how. Can you help please?
Thank you.

Do you mean that each time the string arrives that you have to send one message dependent on the pattern, or one message for each 1 in the string?
Can the text for the message be worked out automatically? Perhaps tell us what the text would consist of.

Demo flow...

[{"id":"f23bfd68.03fe1","type":"inject","z":"5e6c8b.7f38b374","name":"Simulate TCP data 00000000","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"00000000","payloadType":"str","x":920,"y":80,"wires":[["7448498f.5c0428"]]},{"id":"c25fb754.4bf128","type":"debug","z":"5e6c8b.7f38b374","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":1190,"y":140,"wires":[]},{"id":"7448498f.5c0428","type":"function","z":"5e6c8b.7f38b374","name":"","func":"var bitString = msg.payload; // or wherever your data is.\nif ( bitString === \"00000000\" ) {\n    msg.payload = \"All off.\";\n    return msg;\n}\nif ( bitString === \"11111111\" ) {\n    msg.payload = \"All on.\";\n    return msg;\n}\n\nvar strTemp = [];\nfor (let bitIdx = 0; bitIdx < 8; bitIdx++) {\n    if(bitString[bitIdx] == \"1\") {\n        strTemp.push([\"1st\",\"2nd\",\"3rd\",\"4th\",\"5th\",\"6th\",\"7th\",\"8th\"][bitIdx])\n    }\n}\n\nif(strTemp.length > 0) {\n    var s1 = strTemp.join(\", \");\n    var s2 = strTemp.length > 1 ? \" are on.\" : \" is on.\"\n    msg.payload = s1.trim() + s2;\n    return msg;\n} \n","outputs":1,"noerr":0,"initialize":"","finalize":"","x":1180,"y":80,"wires":[["c25fb754.4bf128"]]},{"id":"b3038865.23be78","type":"inject","z":"5e6c8b.7f38b374","name":"Simulate TCP data 10000000","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"10000000","payloadType":"str","x":920,"y":120,"wires":[["7448498f.5c0428"]]},{"id":"72e0dea7.e06df","type":"inject","z":"5e6c8b.7f38b374","name":"Simulate TCP data 10000001","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"10000001","payloadType":"str","x":920,"y":160,"wires":[["7448498f.5c0428"]]},{"id":"b1dd8d2a.62b9a","type":"inject","z":"5e6c8b.7f38b374","name":"Simulate TCP data 10100101","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"10100101","payloadType":"str","x":920,"y":200,"wires":[["7448498f.5c0428"]]},{"id":"8ea22f58.1d8a9","type":"inject","z":"5e6c8b.7f38b374","name":"Simulate TCP data 11111111","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"11111111","payloadType":"str","x":920,"y":240,"wires":[["7448498f.5c0428"]]}]

Thank you for your replies.
Each input will have a different text, for example input1 text might be "faulty zone1", while input2 be "rain sensor was activated.
I don't need a specific message for any multiple inputs, but to send one message each time one input is activated.

Thats not what you asked for.


Again, not what you asked for.

to save us wasting time, please be PRECISE

With my examples I was just trying to explain the structure of my string.
But you are right, I should have been more precise. I'm sorry.

Change the function to this...

const bitString = msg.payload; // or wherever your data is.
const onPayload = "ON" ;//change to whatever you desire
const offPayload = "OFF" ;//change to whatever you desire

//Define bit descriptions - EDIT THESE
const bitDefinitions = [
    "faulty zone1","rain sensor",
    "input 3","input 4",
    "input 5","input 6",
    "input 7","input 8"]; 

//get last values from memory
var memory = context.get("memory") || ["0","0","0","0","0","0","0","0"];

//split the string into an array
var values = bitString.split("");

//compare bitString to memory & send a message if different
for (let bitIdx = 0; bitIdx < 8; bitIdx++) {
    if(bitString[bitIdx] !== memory[bitIdx]) {
        node.send({
            topic: bitDefinitions[bitIdx],
            payload: bitString[bitIdx] == "1" ? onPayload: offPayload
        })
    }
}

//store actual values for next time
context.set("memory", values); 

You should get...

if you are not interested in the "OFF" signals, use a SWITCH node after and check the payload is == "ON"

if you want true and false edit the constants in the function,

This should be enough to get you moving.

1 Like

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