Passing multiple args to exec node

I have a python script, which expects 2 arguments. MQTT Topic and Payload.

Using exec node, I am able to send the 'Payload', but I also need to send msg.topic to the script.
I have tried a lot, using msg.topic under the msg.payload option in exec node config, tried {{msg.topic}}, tried adding msg.topic directly in the command itself. Nothing has worked.
So, is there a way to send 2 arguments?
What I think can work is, use a node to merge msg.topic and msg.payload under msg.topic in a list/array. But change/join nodes have not been useful for these.
I have nearly zero knowledge of javascript.

If you don't have quotes in your msg.payload or msg.topic, then it sounds pretty easy. Just add a template node before the exec node and set msg.payload to:

"{{{payload}}}" "{{{topic}}}"

like this:

[{"id":"67e4cc00.8a08d4","type":"template","z":"ca1010aa.273f4","name":"","field":"payload","fieldType":"msg","format":"handlebars","syntax":"mustache","template":"\"{{payload}}\" \"{{topic}}\"","output":"str","x":700,"y":260,"wires":[["48ac40d.b5d42c"]]}]

join is for different purpose, but change fits well. Set msg.payload to JSONata:

'"' & msg.payload & '" "' & msg.topic & '"'

like this:

[{"id":"59c6553.283a4ac","type":"change","z":"ca1010aa.273f4","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"'\"' & msg.payload & '\" \"' & msg.topic & '\"'","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":400,"y":180,"wires":[["8edfc0fb.b851a"]]}]
1 Like

Thanks, I quickly built upon it and used 'parsed json' option at the bottom, and it has been successful. Still a small problem, as one of the inputs is 'mqtt topic', it has '/', which is leading to my outputs of template node like this:
{'pld':ON, 'tpc': stat/strip/POWER2 }

Can you suggest how to deal with that?

I am sorry it got printed like that.

{'pld':ON, 'tpc': stat/strip/POWER2 }

So what exactly do you want to pass to the script? You asked:

But now it seems, you want a single argument with a JSON string...

You can prevent escaping forward slashes using triple moustaches {{{topic}}} in the template.

Earlier, the msg.payload had just one string. eg: "ON"

I wanted to send the topic as well as payload (coming from mqtt subscription).

So, now I have added both topic and payload to msg.payload. ie a JSON inside the msg.topic (at least this is the intention). Now this should get passed to the python script, where I will read it using "json.loads(xxx)", and parse both topic and payload and do some processing, and return my results by 'print(xxx)'.

Ok, so you're good now, right?

The template I've written isnt getting passed like a JSON object, but rather weird string which python isnt able to read as JSON.

I will manage that part. Thanks a lot for your help, I literally spent 2 days and then finally took help of 'python-contrib-node', but it started throwing random errors.

If you need it passed like a json object, that’s a different thing than passing multiple arguments. Which exactly do you need?

It's really not a rocket science. Google for online json parser, choose one, and verify if what you are passing is correct, because if you are trying:

{'pld':ON, 'tpc': stat/strip/POWER2 }

then no wonder it doesn't work.

And the template, I suspect you want, is as simple as:

'{ "pld": "{{{payload}}}", "tpc": "{{{topic}}}" }'

Apologies for late reply.

I actually needed multiple arguments itself. But figured that it is not possible to send multiple argument. Only a single json or arg can be passed.

So I decided to send a JSON which hold all my arguments.

Essentially, I am subscribing to a topic using mqtt, and then i want to send both the payload and topic to the python script

Yes it is, if you want to run a command myscript with args set to the topic and payload in a message then in a function node put

msg.payload = msg.topic + " " + msg.payload
return msg

then in the exec node tell it to execute the script and select the checkbox to add the payload to the message. It gets a little more complex if the parameters include spaces as then you would have surround each one with quotes.
You can use a Change node rather than a Function node if you prefer.

Thanks, will try that too.

But again, this method is a workaround. It isnt exactly sending multiple args.
Just being able to send both 'msg.topic' and 'msg.payload' would've been convenient.

When, in a terminal you type something like
myScript arg1 arg2
you are sending the command two arguments by putting the two args on the command line. To do the same with an exec node you put the command in the exec node and the two args in msg.payload. What is the difference?
I think what you are asking for is to be able to source the two args from different properties of the message, which is a different question.

Yeah, that's right. Would be a bit more convenient.
Current solution works fine too.

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