Multiple inputs to one msg function (noob)

Hello

I have 4 sting and you will want to make a message to make a Command (sox -t mp3 SomeSong.mp3 -t wav -r 22050 -c 1 - | sudo ./pifm - 102.3)

I tried the function but it does not work


var newMsg = { toutp: msg.payload,toutt:msg.topic };
var le1pay;
var le2pay;
var le3pay;
var le4pay;

switch (msg.topic){
    case "le1":
        le1pay = msg.paydoad;
        break;
    case "Musique":
        le2pay = msg.paydoad;
        break;
    case "Frequence":
        le4pay = msg.paydoad;
        break;
    case "le3":
        le3pay = msg.paydoad;
        break;      
}

newMsg.topic = "go";
newMsg.payload = le1pay + le2pay + le3pay + le4pay;
return newMsg;

am I good or another function does the same

[{"id":"fcdd2e5a.b96d","type":"exec","z":"c894e6fb.9c1a38","command":"","addpay":true,"append":"","useSpawn":"false","timer":"","oldrc":false,"name":"command","x":840,"y":100,"wires":[[],[],[]]}]

Thank you for a lot

In a function node only the latest message is available. A solution to this is to use the Join node to combine the messages, as in this example from the cookbook.
https://cookbook.nodered.org/basic/join-streams

or store them in context...


var le1pay = context.get("le1pay") || 0; //get from context or default to 0
var le2pay = context.get("le2pay") || 0; //get from context or default to 0
var le3pay = context.get("le3pay") || 0; //get from context or default to 0
var le4pay = context.get("le4pay") || 0; //get from context or default to 0

switch (msg.topic){
    case "le1":
        le1pay = msg.payload; //payload NOT paydoad  :)
        context.set("le1pay", le1pay); //store in context for next time 
        break;
    case "Musique":
        le2pay = msg.payload; //payload NOT paydoad  :)
        context.set("le2pay", le2pay); //store in context for next time 
        break;
    case "Frequence":
        le4pay = msg.payload; //payload NOT paydoad  :)
        context.set("le4pay", le4pay); //store in context for next time 
        break;
    case "le3":
        le3pay = msg.payload; //payload NOT paydoad  :)
        context.set("le3pay", le3pay); //store in context for next time 
        break;      
}

msg.topic = "go";
msg.payload = le1pay + le2pay + le3pay + le4pay;
return msg;

The function node has the possible disadvantage that it will send a message on each input message even if not all the topics have been received. If that mattered then the function would need additional logic.

it's better

I tried but argument are not in order

sox -t mp3   -t wav -r 22050 -c 1 - | sudo ./pifm -  80 /home/pi/pifm/interferences_01.mp3

thanks to you

@Steve-Mcl What exactly would be the advantage of your solution? After all, it is inflexible and a lot to write...so whats the big benefit?

setup the join node to create a key/value object where the topic is the key

Did you consider using the template node (not the dashboard template, the core template) for building the string ?

The variable part could be stored in context variables. Once you press a button in the dashboard or an inject node the flow will build the final string.

the line inside the template node would be something like this

I don´t know what are the other variable parts of the command.

sox -t mp3   -t wav -r {{frequency}} -c 1 - | sudo ./pifm -  80 {{song}}

thank you to you, but the node le4 is not present

thanks to you

or he could feed the result of the join node into the template node...

Show us what is coming out of the Join node.
[Edit] And show us how you have configured the Join node.

Hello

Output

image

Join node
image

Thanks to you

Look at the example I posted again. You have not got the join node configured correctly. The 'to create' field is wrong.

Aside from the other comments, I noted that you have spelt payload incorrectly as msg.paydoad.

I already pointed that out to OP here...



Readable, portable ~(i.e. no external nodes), full control of how & when things occur, self contained (no external switches / changes etc. Each to thier own. I often find a single function node doing several relatively small task is far cleaner than the multiple nodes to achieve the same thing (though not saying that would be the case here)

Inflexible - yes, but to be fair, all I did was add to the original code to achieve the OPs requirement.
He didnt ask for flexible & didnt provide a specification :man_shrugging:

On the flexible point...
However, if lets say the OP had a requirement for any number of unknown topics to sum up & wanted it to be truly flexible he could do this dynamically...

//Premise: Store any value received against its topic & return the sum of them all;
//if topic is empty or == "go", dont store anything, just return the sum
//NOTE: Probably need error handling and type checking but should work if only known types are sent to the node.
//NOTE2: Untested - but probably works :) 
let lookup = context.get("lookup") || {}; //get/create the lookup

if(msg.topic && msg.topic != "go") {
 lookup[msg.topic] = msg.payload;//store this value in lookup against topic
 context.set("lookup", lookup) || {}; //store updated lookup for next time
}

//scan the lookup for every topic value sent & add them up
let sumval = 0;
for (var prop in lookup) {
 let v = lookup[prop];  
 if(v) //if v is "something...
   sumval +=  v; //add it
}

msg.topic = "go";
msg.payload = sumval;

100% flexible - though I suspect this is not really what is wanted either. might prove useful to someone?

I find this comment somehow offensive, not the sort of response we are used to here!

i see...point taken.
But it's clear that op wrote "paydoad" and the code didnt work - thats one of the major arguments against the function node...(btw the join node is not an external node - also not the template node)

Point taken :slight_smile:

Options are good & if someone learns something, bonus.