hi,
i am reading data from a plc (s7 comm node) the object i get is built like this;
msg.payload.VarA_Var1, msg.payload.VarB_Var2, msg.payload.VarA_Var3 ... etc.
i would like to split this object to separate objects based on the criteria: the name of the variable between "payload." and the first "_" (VarX in my case).
is this possible somehow without using the function node?
thank you
It isn't fully clear what you want. Please show us a sample message, including values, and tell us exactly what you want as the result message or messages.
i'd like to split this object into two (or sometimes more) objects, based on the criteria of the naming before the character "_" preferably without the function node. (Z2Mill and H3Screw prefixed variables should get their own separate objects).
Tell us exactly what you want to get from that data (or part of it at least), so we can be sure we understand.
according to the snip i just sent, i want two objects, the two objects should contain the Z2Mill_ stuff and another object which should include the H3Screw_ stuff.
It is kind of irritating when someone falsifies their sample data in the hope of making it clearer for us.
I just wrote a flow to work with your "VarA_Var1": ...
stuff and now I see it's "Z2Mill_Spark1":..
, really can't be bothered to rewrite it all, sorry.
ok, however "criteria: the name of the variable between "payload." and the first "_" "
but i am not here to argue. sorry for bothering.
My approach made the assumption that "Var1", "Var2" (etc) were part of a limited and predefined set of values.
Looking at your actual data that seems an invalid assumption thus my flow is not applicable.
However, FYI it looked like this
You need to supply data in a text form, as images are not copyable.
e.g
{
"var1_test": true,
"var2_test": true
}
Here is how to retrieve the data using a debug node.
There’s a great page in the docs (Working with messages : Node-RED) that will explain how to use the debug panel to find the right path/value for any data item.
Pay particular attention to the part about the buttons that appear under your mouse pointer when you over hover a debug message property in the sidebar.
here is an example of how to split the object, check the recreate a sequence
in the switch node.
[{"id":"82b66663dc40aca4","type":"inject","z":"d1395164b4eec73e","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"{\"var1_test\":true,\"var2_test\":true}","payloadType":"json","x":210,"y":160,"wires":[["1ea2ebe4de9a1769"]]},{"id":"1ea2ebe4de9a1769","type":"split","z":"d1395164b4eec73e","name":"","splt":"\\n","spltType":"str","arraySplt":1,"arraySpltType":"len","stream":false,"addname":"","x":330,"y":160,"wires":[["a6e5ac5b703e8160"]]},{"id":"a6e5ac5b703e8160","type":"switch","z":"d1395164b4eec73e","name":"","property":"parts.key","propertyType":"msg","rules":[{"t":"cont","v":"var1","vt":"str"},{"t":"cont","v":"var2","vt":"str"}],"checkall":"true","repair":true,"outputs":2,"x":450,"y":160,"wires":[["34dc3046b33e7b85"],["5a7ae6f6da2254c7"]]},{"id":"34dc3046b33e7b85","type":"join","z":"d1395164b4eec73e","name":"","mode":"auto","build":"object","property":"payload","propertyType":"msg","key":"topic","joiner":"\\n","joinerType":"str","accumulate":"false","timeout":"","count":"","reduceRight":false,"x":570,"y":160,"wires":[["dd602262e66dff14"]]},{"id":"5a7ae6f6da2254c7","type":"join","z":"d1395164b4eec73e","name":"","mode":"auto","build":"object","property":"payload","propertyType":"msg","key":"topic","joiner":"\\n","joinerType":"str","accumulate":"false","timeout":"","count":"","reduceRight":false,"x":570,"y":200,"wires":[["6f04760920f758fa"]]},{"id":"dd602262e66dff14","type":"debug","z":"d1395164b4eec73e","name":"debug 2565","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":710,"y":160,"wires":[]},{"id":"6f04760920f758fa","type":"debug","z":"d1395164b4eec73e","name":"debug 2566","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":710,"y":200,"wires":[]}]
hi, thanks for the info;
{"payload":{"Z2Mill_Current":1.401298464324817e-43,"Z2Mill_Temp1":21.253530502319336,"Z2Mill_Temp2":21.152944564819336,"Z2Mill_StarterFuse":true,"Z2Mill_StarterFault":false,"Z2Mill_DoorSw":true,"Z2Mill_Spark1":false,"Z2Mill_LeftFbk":true,"Z2Mill_RightFbk":false,"Z2Mill_Spark2":false,"Z2Mill_LeftCmd":false,"Z2Mill_StarterBypass":false,"Z2Mill_Standstill":false,"Z2Mill_RightCmd":false,"Z2Mill_RunFbk":false,"Z2Mill_RunCmd":false,"H3Screw_OverloadSw":true,"H3Screw_RunFbk":false,"H3Screw_RunCmd":false},"topic":"","_msgid":"098c136beb9b15d8"}
this is the structure of an incoming message, it has no topic as you see or anything else besides the payload.
i observed that every variable name starts with "machine name underscore" (ie. Z2Mill_, S3Screw_).
from the presented message i would like to create two separate messages. The "separation criteria" should check for the "Z2Mill_" in the variable name and put every other variable with similar prefix into one message and same for "S3Screw_".
the structure of the newly created messages should be the same as the original (no topic, everything in the payload) but same prefix variables in their own bunch.
seems very simple when explaining but even chatgpt plus can't offer a working solution and i dont speak js.
It's not clear how you would use the messages down stream if they have no topic eg how would you know what machine they were from.
Is this more useful ?
[{"id":"daa66e9e6d9ccd5b","type":"inject","z":"7268a9c1d2c04065","name":"","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"{\"Z2Mill_Current\":1.401298464324817e-43,\"Z2Mill_Temp1\":21.253530502319336,\"Z2Mill_Temp2\":21.152944564819336,\"Z2Mill_StarterFuse\":true,\"Z2Mill_StarterFault\":false,\"Z2Mill_DoorSw\":true,\"Z2Mill_Spark1\":false,\"Z2Mill_LeftFbk\":true,\"Z2Mill_RightFbk\":false,\"Z2Mill_Spark2\":false,\"Z2Mill_LeftCmd\":false,\"Z2Mill_StarterBypass\":false,\"Z2Mill_Standstill\":false,\"Z2Mill_RightCmd\":false,\"Z2Mill_RunFbk\":false,\"Z2Mill_RunCmd\":false,\"H3Screw_OverloadSw\":true,\"H3Screw_RunFbk\":false,\"H3Screw_RunCmd\":false}","payloadType":"json","x":685,"y":570,"wires":[["db88f1b5f226e229"]]},{"id":"db88f1b5f226e229","type":"function","z":"7268a9c1d2c04065","name":"function 42","func":"// Input payload\nlet inputPayload = msg.payload;\n\n// Initialize the output payload\nlet outputPayload = {};\n\n// Iterate over each key-value pair in the input payload\nfor (let key in inputPayload) {\n if (inputPayload.hasOwnProperty(key)) {\n // Split the key by '_'\n let parts = key.split('_');\n let prefix = parts[0];\n let suffix = parts.slice(1).join('_');\n\n // Initialize the sub-object if it doesn't exist\n if (!outputPayload[prefix]) {\n outputPayload[prefix] = {};\n }\n\n // Assign the value to the sub-object\n outputPayload[prefix][suffix] = inputPayload[key];\n }\n}\n\n// Set the output payload\nmsg.payload = outputPayload;\n\n// Return the modified message\nreturn msg;\n\n\n","outputs":1,"timeout":0,"noerr":0,"initialize":"","finalize":"","libs":[],"x":850,"y":570,"wires":[["40b421c2f4070468"]]},{"id":"40b421c2f4070468","type":"debug","z":"7268a9c1d2c04065","name":"debug 2565","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":1025,"y":570,"wires":[]}]
Hi, it is a little unclear what you really want. It would be easier if you simply manually adjusted the JSON output and showed us exactly how you want the result to be structured.
I did the v1 then re-read your post and ended up adjusting it to the v2 demo. Then I thought perhaps you meant result in 2 properties of payload so did a v3 demo too.
See if any of those are close to what you want.
PS: This is all in function node. It will be possible in pure flow but at some point there will be a need for JSONata which is even less readable (and far less popular/searchable) than JavaScript.
[{"id":"91b8959f20bf7112","type":"function","z":"a852e4845e0e51a4","name":"v2: split group_var entries to own payload","func":"\nconst groups = {}\n\nObject.entries(msg.payload).forEach(([key,value]) => {\n const [prefix, suffix] = key.split('_')\n if (!prefix || !suffix) {\n return // not a key we are interested in\n }\n groups[prefix] = groups[prefix] || {}\n groups[prefix][suffix] = value\n})\n\nconst payloads = Object.values(groups)\n\nfor (let index = 0; index < payloads.length; index++) {\n const m = {payload: payloads[index]}\n node.send(m);\n}\n","outputs":1,"timeout":0,"noerr":0,"initialize":"","finalize":"","libs":[],"x":2240,"y":100,"wires":[["cdf29dbb0094d5c9"]]},{"id":"cdf29dbb0094d5c9","type":"debug","z":"a852e4845e0e51a4","name":"debug 189","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":2330,"y":140,"wires":[]},{"id":"5fa43c0895dc548b","type":"inject","z":"a852e4845e0e51a4","name":"your payload","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"{\"Z2Mill_Current\":1.401298464324817e-43,\"Z2Mill_Temp1\":21.253530502319336,\"Z2Mill_Temp2\":21.152944564819336,\"Z2Mill_StarterFuse\":true,\"Z2Mill_StarterFault\":false,\"Z2Mill_DoorSw\":true,\"Z2Mill_Spark1\":false,\"Z2Mill_LeftFbk\":true,\"Z2Mill_RightFbk\":false,\"Z2Mill_Spark2\":false,\"Z2Mill_LeftCmd\":false,\"Z2Mill_StarterBypass\":false,\"Z2Mill_Standstill\":false,\"Z2Mill_RightCmd\":false,\"Z2Mill_RunFbk\":false,\"Z2Mill_RunCmd\":false,\"H3Screw_OverloadSw\":true,\"H3Screw_RunFbk\":false,\"H3Screw_RunCmd\":false}","payloadType":"json","x":1980,"y":100,"wires":[["91b8959f20bf7112"]]},{"id":"37b4e60bc6fed733","type":"inject","z":"a852e4845e0e51a4","name":"your payload","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"{\"Z2Mill_Current\":1.401298464324817e-43,\"Z2Mill_Temp1\":21.253530502319336,\"Z2Mill_Temp2\":21.152944564819336,\"Z2Mill_StarterFuse\":true,\"Z2Mill_StarterFault\":false,\"Z2Mill_DoorSw\":true,\"Z2Mill_Spark1\":false,\"Z2Mill_LeftFbk\":true,\"Z2Mill_RightFbk\":false,\"Z2Mill_Spark2\":false,\"Z2Mill_LeftCmd\":false,\"Z2Mill_StarterBypass\":false,\"Z2Mill_Standstill\":false,\"Z2Mill_RightCmd\":false,\"Z2Mill_RunFbk\":false,\"Z2Mill_RunCmd\":false,\"H3Screw_OverloadSw\":true,\"H3Screw_RunFbk\":false,\"H3Screw_RunCmd\":false}","payloadType":"json","x":1900,"y":380,"wires":[["180657f208efc38f"]]},{"id":"180657f208efc38f","type":"function","z":"a852e4845e0e51a4","name":"v1: split group_var entries to own payload - keep prefix","func":"\nconst groups = {}\n\nObject.entries(msg.payload).forEach(([key,value]) => {\n const [prefix, suffix] = key.split('_')\n if (!prefix || !suffix) {\n return // not a key we are interested in\n }\n groups[prefix] = groups[prefix] || {}\n groups[prefix][key] = value\n})\n\nconst payloads = Object.values(groups)\n\nfor (let index = 0; index < payloads.length; index++) {\n const m = {payload: payloads[index]}\n node.send(m);\n}\n","outputs":1,"timeout":0,"noerr":0,"initialize":"","finalize":"","libs":[],"x":2200,"y":380,"wires":[["4caf3210348fe6fc"]]},{"id":"4caf3210348fe6fc","type":"debug","z":"a852e4845e0e51a4","name":"debug 2566","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":2330,"y":420,"wires":[]},{"id":"16b2731eec10cf7d","type":"function","z":"a852e4845e0e51a4","name":"v3: split group_var entries to own payload - as sub-object-single message","func":"\nconst groups = {}\n\nObject.entries(msg.payload).forEach(([key,value]) => {\n const [prefix, suffix] = key.split('_')\n if (!prefix || !suffix) {\n return // not a key we are interested in\n }\n groups[prefix] = groups[prefix] || {}\n groups[prefix][suffix] = value\n})\n\nmsg.payload = groups\nreturn msg","outputs":1,"timeout":0,"noerr":0,"initialize":"","finalize":"","libs":[],"x":2140,"y":640,"wires":[["12f2065875b0443a"]]},{"id":"e19d8ab850b862eb","type":"inject","z":"a852e4845e0e51a4","name":"your payload","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"{\"Z2Mill_Current\":1.401298464324817e-43,\"Z2Mill_Temp1\":21.253530502319336,\"Z2Mill_Temp2\":21.152944564819336,\"Z2Mill_StarterFuse\":true,\"Z2Mill_StarterFault\":false,\"Z2Mill_DoorSw\":true,\"Z2Mill_Spark1\":false,\"Z2Mill_LeftFbk\":true,\"Z2Mill_RightFbk\":false,\"Z2Mill_Spark2\":false,\"Z2Mill_LeftCmd\":false,\"Z2Mill_StarterBypass\":false,\"Z2Mill_Standstill\":false,\"Z2Mill_RightCmd\":false,\"Z2Mill_RunFbk\":false,\"Z2Mill_RunCmd\":false,\"H3Screw_OverloadSw\":true,\"H3Screw_RunFbk\":false,\"H3Screw_RunCmd\":false}","payloadType":"json","x":1790,"y":640,"wires":[["16b2731eec10cf7d"]]},{"id":"12f2065875b0443a","type":"debug","z":"a852e4845e0e51a4","name":"debug 2567","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":2330,"y":680,"wires":[]}]
idk man, i am asking the same question, the s7-com node spits out the data like that and this is the only node that can communicate with a siemens s7 plc.
thanks for your solution, it is a step closer to the desired outcome.
however i need 2 separate objects and no variable name change (yours cuts the prefixes).
funny how this exact same result was given by chatgpt plus too but the moment i gave instructions to not modify the variable names and i need two separate objects, it started the usual redundant mumbo jumbo and thats why i ended up here.
Thank you Setve,
v1 is the winner and so are you.
As you asked without using a function node
It would be something like this
[{"id":"82b66663dc40aca4","type":"inject","z":"d1395164b4eec73e","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"{\"Z2Mill_Current\":1.401298464324817e-43,\"Z2Mill_Temp1\":21.253530502319336,\"Z2Mill_Temp2\":21.152944564819336,\"Z2Mill_StarterFuse\":true,\"Z2Mill_StarterFault\":false,\"Z2Mill_DoorSw\":true,\"Z2Mill_Spark1\":false,\"Z2Mill_LeftFbk\":true,\"Z2Mill_RightFbk\":false,\"Z2Mill_Spark2\":false,\"Z2Mill_LeftCmd\":false,\"Z2Mill_StarterBypass\":false,\"Z2Mill_Standstill\":false,\"Z2Mill_RightCmd\":false,\"Z2Mill_RunFbk\":false,\"Z2Mill_RunCmd\":false,\"H3Screw_OverloadSw\":true,\"H3Screw_RunFbk\":false,\"H3Screw_RunCmd\":false}","payloadType":"json","x":190,"y":80,"wires":[["a5d7cea17b5b028c"]]},{"id":"a5d7cea17b5b028c","type":"change","z":"d1395164b4eec73e","name":"","rules":[{"t":"set","p":"keys","pt":"msg","to":"$distinct($keys($$.payload).($substringBefore($, \"_\") & \"_\"))","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":330,"y":80,"wires":[["1ea2ebe4de9a1769"]]},{"id":"1ea2ebe4de9a1769","type":"split","z":"d1395164b4eec73e","name":"","splt":"\\n","spltType":"str","arraySplt":1,"arraySpltType":"len","stream":false,"addname":"","x":490,"y":80,"wires":[["a6e5ac5b703e8160"]]},{"id":"a6e5ac5b703e8160","type":"switch","z":"d1395164b4eec73e","name":"","property":"parts.key","propertyType":"msg","rules":[{"t":"cont","v":"keys[0]","vt":"msg"},{"t":"cont","v":"keys[1]","vt":"msg"}],"checkall":"true","repair":true,"outputs":2,"x":110,"y":160,"wires":[["c5c795540f6dc0c2"],["aebd06b48274d172"]]},{"id":"c5c795540f6dc0c2","type":"change","z":"d1395164b4eec73e","name":"","rules":[{"t":"set","p":"group","pt":"msg","to":"keys[0]","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":280,"y":140,"wires":[["16c4f2ba00bbb50c"]]},{"id":"aebd06b48274d172","type":"change","z":"d1395164b4eec73e","name":"","rules":[{"t":"set","p":"group","pt":"msg","to":"keys[1]","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":280,"y":180,"wires":[["16c4f2ba00bbb50c"]]},{"id":"16c4f2ba00bbb50c","type":"change","z":"d1395164b4eec73e","name":"","rules":[{"t":"change","p":"parts.key","pt":"msg","from":"group","fromt":"msg","to":"","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":500,"y":160,"wires":[["34dc3046b33e7b85","dd602262e66dff14"]]},{"id":"34dc3046b33e7b85","type":"join","z":"d1395164b4eec73e","name":"","mode":"auto","build":"object","property":"payload","propertyType":"msg","key":"topic","joiner":"\\n","joinerType":"str","accumulate":"false","timeout":"","count":"","reduceRight":false,"x":690,"y":160,"wires":[["44678e86d1011446"]]},{"id":"dd602262e66dff14","type":"debug","z":"d1395164b4eec73e","name":"debug 2565","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":850,"y":100,"wires":[]},{"id":"44678e86d1011446","type":"change","z":"d1395164b4eec73e","name":"","rules":[{"t":"change","p":"group","pt":"msg","from":"_","fromt":"str","to":"","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":250,"y":240,"wires":[["5a7ae6f6da2254c7"]]},{"id":"5a7ae6f6da2254c7","type":"join","z":"d1395164b4eec73e","name":"","mode":"custom","build":"object","property":"payload","propertyType":"msg","key":"group","joiner":"\\n","joinerType":"str","accumulate":false,"timeout":"","count":"2","reduceRight":false,"reduceExp":"","reduceInit":"","reduceInitType":"","reduceFixup":"","x":410,"y":240,"wires":[["6f04760920f758fa"]]},{"id":"6f04760920f758fa","type":"debug","z":"d1395164b4eec73e","name":"debug 2566","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":550,"y":240,"wires":[]}]
which produces this (remove final join if you want 2 outputs.)
{
"Z2Mill": {
"Current": 1.401298464324817e-43,
"Temp1": 21.253530502319336,
"Temp2": 21.152944564819336,
"StarterFuse": true,
"StarterFault": false,
"DoorSw": true,
"Spark1": false,
"LeftFbk": true,
"RightFbk": false,
"Spark2": false,
"LeftCmd": false,
"StarterBypass": false,
"Standstill": false,
"RightCmd": false,
"RunFbk": false,
"RunCmd": false
},
"H3Screw": {
"OverloadSw": true,
"RunFbk": false,
"RunCmd": false
}
}
Which is what the preceding process should really produce.
I would suggest, if possible to fix the preceding output rather than fix it later.
You can achieve this with a change
node, using this JSONata expression:
payload.$spread() {
$keys()[0].$substringBefore("_"): $merge($)
}
I know it's pretty cryptic, but it spreads each property into its own object, and then combines them into groups based on the prefix of the property "key" name, as you can see in this output:
This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.