MQTT values sorting

Hello everyone,

I would like to make a script that sorts my values automaticly. I tried it allready but it seems to look like i did somth wrong.

this is the script i made:

[{"id":"aeb5b23752a36cba","type":"function","z":"76de9c78a268111d","name":"","func":"var Vermogens = msg.payload\n\nfor (i = 0; Vermogens.channelPowers.length > i; i++){\n    if (Vermogens.channelPowers[i].formula == \"$5600004355/2$\" ){\n        if (Vermogens.channelPowers[i].phaseId == 0 ){\n            L1net= Vermogens.channelPowers[i].power\n        }\n        if (Vermogens.channelPowers[i].phaseId == 1 ){\n            L2net= Vermogens.channelPowers[i].power\n        }\n        if (Vermogens.channelPowers[i].phaseId == 2 ){\n            L3net= Vermogens.channelPowers[i].power\n        }\n    }\n    \n    if (Vermogens.channelPowers[i].formula == \"$5600004035/2$\" ){\n        if (Vermogens.channelPowers[i].phaseId == 0 ){\n            L1auto= Vermogens.channelPowers[i].power\n        }\n        if (Vermogens.channelPowers[i].phaseId == 1 ){\n            L2auto= Vermogens.channelPowers[i].power\n        }\n        if (Vermogens.channelPowers[i].phaseId == 2 ){\n            L3auto= Vermogens.channelPowers[i].power\n        }\n    }\n}\n\nNet= L1net + L2net + L3net\nAuto = L1auto + L2auto + L3auto\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1220,"y":780,"wires":[["6e60695de9ef8e71"]]}]

I would like to have change this data :

[{"publishIndex":0,"formula":"$5600004355/2$","power":3702,"exportEnergy":0,"importEnergy":25693200,"phaseId":0,"current":162,"apparentPower":3705,"cosPhi":99},{"publishIndex":1,"formula":"$5600004355/1$","power":0,"exportEnergy":0,"importEnergy":2340000,"phaseId":1,"current":0,"apparentPower":0,"cosPhi":95},{"publishIndex":2,"formula":"$5600004355/0$","power":0,"exportEnergy":0,"importEnergy":1389600,"phaseId":2,"current":0,"apparentPower":0,"cosPhi":-46},{"publishIndex":3,"formula":"$5500027192/0$","power":0,"exportEnergy":194400,"importEnergy":0,"phaseId":0,"current":0,"apparentPower":0,"cosPhi":94},{"publishIndex":4,"formula":"$5500027192/1$","power":0,"exportEnergy":0,"importEnergy":0,"phaseId":1,"current":0,"apparentPower":0,"cosPhi":-57},{"publishIndex":5,"formula":"$5600004035/0$","power":3699,"exportEnergy":0,"importEnergy":20988000,"phaseId":0,"current":162,"apparentPower":3702,"cosPhi":99},{"publishIndex":6,"formula":"$5600004035/1$","power":0,"exportEnergy":0,"importEnergy":1414800,"phaseId":1,"current":0,"apparentPower":0,"cosPhi":96},{"publishIndex":7,"formula":"$5600004035/2$","power":0,"exportEnergy":0,"importEnergy":1386000,"phaseId":2,"current":0,"apparentPower":0,"cosPhi":-45}]

The first item my script has to look at is the formula if it end with 355 before the / then they should belong together, ...
Then it has to seperate by the phaseId... after that it can sort the values as i show in my script...

the full data can be found here:

{"totalPower":3702,"totalReactivePower":166,"totalExportEnergy":194400,"totalImportEnergy":53211600,"monitorStatus":0,"utcTimeStamp":1650631894000,"measuredFrequency":49999996,"channelPowers":[{"publishIndex":0,"formula":"$5600004355/2$","power":3702,"exportEnergy":0,"importEnergy":25693200,"phaseId":0,"current":162,"apparentPower":3705,"cosPhi":99},{"publishIndex":1,"formula":"$5600004355/1$","power":0,"exportEnergy":0,"importEnergy":2340000,"phaseId":1,"current":0,"apparentPower":0,"cosPhi":95},{"publishIndex":2,"formula":"$5600004355/0$","power":0,"exportEnergy":0,"importEnergy":1389600,"phaseId":2,"current":0,"apparentPower":0,"cosPhi":-46},{"publishIndex":3,"formula":"$5500027192/0$","power":0,"exportEnergy":194400,"importEnergy":0,"phaseId":0,"current":0,"apparentPower":0,"cosPhi":94},{"publishIndex":4,"formula":"$5500027192/1$","power":0,"exportEnergy":0,"importEnergy":0,"phaseId":1,"current":0,"apparentPower":0,"cosPhi":-57},{"publishIndex":5,"formula":"$5600004035/0$","power":3699,"exportEnergy":0,"importEnergy":20988000,"phaseId":0,"current":162,"apparentPower":3702,"cosPhi":99},{"publishIndex":6,"formula":"$5600004035/1$","power":0,"exportEnergy":0,"importEnergy":1414800,"phaseId":1,"current":0,"apparentPower":0,"cosPhi":96},{"publishIndex":7,"formula":"$5600004035/2$","power":0,"exportEnergy":0,"importEnergy":1386000,"phaseId":2,"current":0,"apparentPower":0,"cosPhi":-45}],"voltages":[{"voltage":229,"phaseId":0},{"voltage":242,"phaseId":1},{"voltage":244,"phaseId":2}]}

Thanks in advance,

Olivia

If I understand correctly try something like this

msg.payload = msg.payload.channelPowers.reduce((acc, obj) => {
    if(obj.formula.includes("$5600004355/")){
        acc.net += obj.power;
    }else if (obj.formula.includes("$5600004035/")){
        acc.auto += obj.power;
    }
    return acc;
},{"net":0,"auto":0});
return msg;

I think i understand what you are doing but i dont see how it seperates the phaseId's from eatch other...
the meaning of the script would be that the script automaticly search for the yellow values... even if the order of the payload changes...

after it found the yellow values it shoud store those in global valueble but that would be possible to find on my own

I looked at your function and it totaled them , so i did the same, you could save them also

msg.payload = msg.payload.channelPowers.reduce((acc, obj) => {
    if(obj.formula.includes("$5600004355/")){
        acc.net[obj.phaseId] = obj.power;
    }else if (obj.formula.includes("$5600004035/")){
        acc.auto[obj.phaseId] = obj.power;
    }
    return acc
},{"net":[],"auto":[]})
return msg;

or

msg.payload = msg.payload.channelPowers.reduce((acc, obj) => {
    if(obj.formula.includes("$5600004355/")){
        acc["L" + (obj.phaseId+1) + "net"] = obj.power;
    }else if (obj.formula.includes("$5600004035/")){
        acc["L" + (obj.phaseId+1) + "auto"] = obj.power;
    }
    return acc
},{});
return msg;

Or save and total

msg.payload = msg.payload.channelPowers.reduce((acc, obj) => {
    if(obj.formula.includes("$5600004355/")){
        acc["L" + (obj.phaseId+1) + "net"] = obj.power;
        acc.net += obj.power;
    }else if (obj.formula.includes("$5600004035/")){
        acc["L" + (obj.phaseId+1) + "auto"] = obj.power;
        acc.auto += obj.power;
    }
    return acc
},{net:0,auto:0});
return msg;
1 Like

Dear @E1cid ,

This looks allready pretty good, i am wondering how can plot this in a line graph ?

Thanks in advance!!
olivia

That would be a new question so might be better in a new thread, and also you would need to define "this". As i gave many solutions and you never pointed to a solution.
But to help, you would output the auto/net values, then split the object using key as msg.topic and feed the live data into the chart.

1 Like

all 3 answers look good to me, ill probably use the last one.
and ill try it by my selves first and otherwise ill ask in a new question.

Thanks !

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