Creating Json message from multiple messages

I am new to node red, on trying to input an mqtt message and split the message to individual variables and adjusted the range to required but now I need to merge them back to json and send over mqtt.

Merge all outputs from different nodes to a single JSon to send over mqtt. Could someone help out on how to get this done.

Thanks in advance.

Welcome to the forum @muhammedsuhail1997

You need to look at the Join node.

Here is an example where a complicated message is split into multiple messages which are processed individually and then rejoined into a single javascript object.
This uses the "Automatic" mode of the Join node, there is also "Manual" for more control.


The input and output look like this
image

You can import it and take a look:

`[{"id":"9dd5bcdfb8b59d06","type":"inject","z":"69db689bc6253632","name":"Go","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":110,"y":80,"wires":[["6e4727f550db7b84"]]},{"id":"740ae4dc592edbda","type":"split","z":"69db689bc6253632","name":"","splt":"\\n","spltType":"str","arraySplt":1,"arraySpltType":"len","stream":false,"addname":"topic","property":"payload","x":110,"y":180,"wires":[["7a167b77db192767"]]},{"id":"86f61adf90e5f808","type":"join","z":"69db689bc6253632","name":"","mode":"auto","build":"object","property":"payload","propertyType":"msg","key":"topic","joiner":"\\n","joinerType":"str","accumulate":"false","timeout":"","count":"","reduceRight":false,"x":690,"y":200,"wires":[["84772704d0e77550"]]},{"id":"84772704d0e77550","type":"debug","z":"69db689bc6253632","name":"Output","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":810,"y":200,"wires":[]},{"id":"6e4727f550db7b84","type":"template","z":"69db689bc6253632","name":"Sample data","field":"payload","fieldType":"msg","format":"handlebars","syntax":"mustache","template":"{\n\"standingcharge\":60.75,\n\"dayrate\":26.65,\n\"nightrate\":11.83\n}","output":"json","x":250,"y":80,"wires":[["740ae4dc592edbda","bf37946f6072dcf7"]]},{"id":"bf37946f6072dcf7","type":"debug","z":"69db689bc6253632","name":"Input","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":810,"y":80,"wires":[]},{"id":"7a167b77db192767","type":"switch","z":"69db689bc6253632","name":"","property":"parts.key","propertyType":"msg","rules":[{"t":"eq","v":"dayrate","vt":"str"},{"t":"eq","v":"nightrate","vt":"str"},{"t":"eq","v":"standingcharge","vt":"str"},{"t":"else"}],"checkall":"true","repair":false,"outputs":4,"x":250,"y":180,"wires":[["ca6366acdb26ad51"],["28e0439e8a916acf"],["6eaa9842a343dc44"],["86f61adf90e5f808"]]},{"id":"ca6366acdb26ad51","type":"function","z":"69db689bc6253632","name":"Add 10% to dayrate","func":"msg.payload *= 1.1\nreturn msg;","outputs":1,"timeout":0,"noerr":0,"initialize":"","finalize":"","libs":[],"x":490,"y":100,"wires":[["86f61adf90e5f808"]]},{"id":"28e0439e8a916acf","type":"function","z":"69db689bc6253632","name":"Add 20% to nightrate","func":"msg.payload *= 1.2\nreturn msg;","outputs":1,"timeout":0,"noerr":0,"initialize":"","finalize":"","libs":[],"x":480,"y":140,"wires":[["86f61adf90e5f808"]]},{"id":"6eaa9842a343dc44","type":"function","z":"69db689bc6253632","name":"Decrease standingcharge","func":"msg.payload = 24\nreturn msg;","outputs":1,"timeout":0,"noerr":0,"initialize":"","finalize":"","libs":[],"x":490,"y":180,"wires":[["86f61adf90e5f808"]]}]`

Hi and welcome.
As jbudd has mentioned you can use a join node.

But, did you really need to split the json in the first place? could you have altered it as it was?

To answer this we would need the example incoming payload and an example of the outgoing payload.

Thanks @jbudd, that worked out.
But why does the Join node take an otherwise input from the switch?

@E1cid, is there a better way of doing it without splitting; I dont know. could you give an example.

input data:
{"timestamp":1727883908,"main_coolant_level":7.00,"hopper_coolant_level":0.00,"dirty_tank_level":2.40,"dirty_tank_pump_inverter":4.82,"filter_inlet_pressure":2.28,"filter_outlet_pressure":0.44,"proportional_cooling_valve":4.39,"temperature_sensor":5.03,"barrel_full":1,"heat_exchanger_temperature_sensor":3.84,"vac_pressure":9.92,"dirty_tank_gate_valve":0,"flow_sensor":1215.00}

Thanks guys.

Good question.

My example shows different processing for different parts of the message eg increase nightrate by 20%.

But there could be parts of the message that don't need modifying.

These will not be caught by any of the first three tests but will instead be fielded by "Otherwise" and so passed on to the join node.

Without the "otherwise" test, these message parts would just be silently discarded, possibly breaking the Join.

I could but i have no idea what the out put for the input you have supplied would be. You would need to show us how it should look after processing.

input data:
{"timestamp":1727883908,
"main_coolant_level":7.00,
"hopper_coolant_level":0.00,
"dirty_tank_level":2.40,
"dirty_tank_pump_inverter":4.82,
"filter_inlet_pressure":2.28,
"filter_outlet_pressure":0.44,
"proportional_cooling_valve":4.39,
"temperature_sensor":5.03,
"barrel_full":1,
"heat_exchanger_temperature_sensor":3.84,
"vac_pressure":9.92,
"dirty_tank_gate_valve":0,
"flow_sensor":1215.00}

Output:
{"timestamp":remains same,
"main_coolant_level": multiplied by 10 to get depth of fluid filled in cm,
"hopper_coolant_level": multiplied by 4 to get depth in cm,
"dirty_tank_level": multiply by 10 to get depth filled in cm,
"dirty_tank_pump_inverter": tank multiply by 10 to get a percentage of maximum speed (100% full speed),
"filter_inlet_pressure": multiply by 0.2 to get pressure in range is 0 – 2 bar,
"filter_outlet_pressure": multiply by 0.2 to get pressure in range is 0 – 2 bar,
"proportional_cooling_valve": multiply by 100 to get percentage (100% is fully open),
"temperature_sensor": this sensor has a full range of 0 to 50 degrees C so multiply by 5 ,
"barrel_full": digital sensor (normally closed) output "full" if 0 and "filling" if 1 ,
"heat_exchanger_temperature_sensor": this sensor has a full range of 0 to 50 degrees C so multiply by 5,
"vac_pressure": range is 0 to -1bar so multiply by 0.1,
"dirty_tank_gate_valve": digital sensor so output "open" if 1 and "closed" if 0,
"flow_sensor": remains same (output the same reading)}

Also, is it possible to include the units like cm/°C/bar alongside the value; and values restricted to 2 or 3 decimal places.

{"timestamp": 1727883908,
"main_coolant_level": 70.00 cm,
"hopper_coolant_level":0 cm,
"dirty_tank_level": 24 cm,
"dirty_tank_pump_inverter": 48.20 %,
"filter_inlet_pressure": 0.456 bar,
"filter_outlet_pressure": 0.088 bar,
"proportional_cooling_valve":43.90 %,
"temperature_sensor": 25.15 °C,
"barrel_full": filling,
"heat_exchanger_temperature_sensor": 19.20%,
"vac_pressure":0.992 bar,
"dirty_tank_gate_valve": closed,
"flow_sensor": 1215 rpm}

@jbudd Thankyou for explaining, I get it now.

You should be able to do it in a function node with Javascript, or in a change node using JSONata

JSONata example

[{"id":"55420db8d81c6886","type":"inject","z":"d1395164b4eec73e","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"{\"timestamp\":1727883908, \"main_coolant_level\":7.00, \"hopper_coolant_level\":0.00, \"dirty_tank_level\":2.40, \"dirty_tank_pump_inverter\":4.82, \"filter_inlet_pressure\":2.28, \"filter_outlet_pressure\":0.44, \"proportional_cooling_valve\":4.39, \"temperature_sensor\":5.03, \"barrel_full\":1, \"heat_exchanger_temperature_sensor\":3.84, \"vac_pressure\":9.92, \"dirty_tank_gate_valve\":0, \"flow_sensor\":1215.00}","payloadType":"jsonata","x":290,"y":7820,"wires":[["7511d52353dbdce4"]]},{"id":"7511d52353dbdce4","type":"change","z":"d1395164b4eec73e","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"{\t    \"timestamp\": $$.payload.timestamp, \t    \"main_coolant_level\": $$.payload.main_coolant_level * 10 & \" cm\",\t    \"hopper_coolant_level\":$round($$.payload.hopper_coolant_level * 4, 3) & \" cm\",\t    \"dirty_tank_level\": $$.payload.dirty_tank_level * 10 & \" cm\", \t    \"dirty_tank_pump_inverter\": $$.payload.dirty_tank_pump_inverter * 10 & \" %\",\t    \"filter_inlet_pressure\": $$.payload.filter_inlet_pressure * 0.2 & \" bar\", \t    \"filter_outlet_pressure\": $$.payload.filter_outlet_pressure * 0.2 & \" bar\", \t    \"proportional_cooling_valve\": $$.payload.proportional_cooling_valve & \" %\", \t    \"temperature_sensor\": $$.payload.temperature_sensor & \" °C\" , \t    \"barrel_full\": ($$.payload.barrel_full = 0 ? \"full\" : \"filling\"), \t    \"heat_exchanger_temperature_sensor\": $$.payload.heat_exchanger_temperature_sensor * 5 & \" °C\", \t    \"vac_pressure\": $$.payload.vac_pressure * 0.1 & \" bar\",\t    \"dirty_tank_gate_valve\": $$.payload.dirty_tank_gate_valve = 1 ? \"open\" : \"closed\", \t    \"flow_sensor\": $$.payload.flow_sensor & \" rpm\"\t}","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":460,"y":7800,"wires":[["5c3c76598ef4d036"]]},{"id":"5c3c76598ef4d036","type":"debug","z":"d1395164b4eec73e","name":"debug 2576","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":670,"y":7800,"wires":[]}]

Expression

{
    "timestamp": $$.payload.timestamp, 
    "main_coolant_level": $$.payload.main_coolant_level * 10 & " cm",
    "hopper_coolant_level":$round($$.payload.hopper_coolant_level * 4, 3) & " cm",
    "dirty_tank_level": $$.payload.dirty_tank_level * 10 & " cm", 
    "dirty_tank_pump_inverter": $$.payload.dirty_tank_pump_inverter * 10 & "%",
    "filter_inlet_pressure": $$.payload.filter_inlet_pressure * 0.2 & " bar", 
    "filter_outlet_pressure": $$.payload.filter_outlet_pressure * 0.2 & " bar", 
    "proportional_cooling_valve": $$.payload.proportional_cooling_valve & " %", 
    "temperature_sensor": $$.payload.temperature_sensor & " °C" , 
    "barrel_full": ($$.payload.barrel_full = 0 ? "full" : "filling"), 
    "heat_exchanger_temperature_sensor": $$.payload.heat_exchanger_temperature_sensor * 5 & " °C", 
    "vac_pressure": $$.payload.vac_pressure * 0.1 & " bar",
    "dirty_tank_gate_valve": $$.payload.dirty_tank_gate_valve = 1 ? "open" : "closed", 
    "flow_sensor": $$.payload.flow_sensor & " rpm"
}

Output

{
    "timestamp": 1727883908,
    "main_coolant_level": "70 cm",
    "hopper_coolant_level": "0 cm",
    "dirty_tank_level": "24 cm",
    "dirty_tank_pump_inverter": "48.2%",
    "filter_inlet_pressure": "0.456 bar",
    "filter_outlet_pressure": "0.088 bar",
    "proportional_cooling_valve": "4.39 %",
    "temperature_sensor": "5.03 °C",
    "barrel_full": "filling",
    "heat_exchanger_temperature_sensor": "19.2 °C",
    "vac_pressure": "0.992 bar",
    "dirty_tank_gate_valve": "closed",
    "flow_sensor": "1215 rpm"
}

I included one example of how to round to 3 decimal places.