How do I calculate diff between two consecutive payloads

I'm trying to calculate the difference between to two consecutive payloads. I'm using SNMP node to query a router interface and return data bytes received. I want to subtract value payload n from payload n+1 to obtain throughput figure per second.

I've looked at context and function nodes but not not sure where to start.

Any suggestions would be appreciated.

Thanks

Chris

Look at the storing data part of https://nodered.org/docs/writing-functions

1 Like

I use a delay node, then store the output in a flow variable

Then the undelayed message go into a function which subtracts the flow variable from the current and divide with the delay time to get the rate.

Perhaps this pre-built node could help you ?

Thanks for your responses. To be clear, I want to subtract content of payload n from payload n+1, not find the time gap between the two.

As suggested, I'm going to run two snmp nodes and fire the second one with a short delay. Store both to context and run function node to subtract one from the other.

[{"id":"a014e37e.af038","type":"debug","z":"e8e5ccfb.8b54e","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","x":630,"y":80,"wires":[]},{"id":"e62bf4.e47cc41","type":"inject","z":"e8e5ccfb.8b54e","name":"","topic":"","payload":"2","payloadType":"num","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":170,"y":60,"wires":[["6b749ee9.5af15"]]},{"id":"4424359f.3033ec","type":"inject","z":"e8e5ccfb.8b54e","name":"","topic":"","payload":"1","payloadType":"num","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":170,"y":120,"wires":[["6b749ee9.5af15"]]},{"id":"6b749ee9.5af15","type":"join","z":"e8e5ccfb.8b54e","name":"","mode":"custom","build":"array","property":"payload","propertyType":"msg","key":"topic","joiner":"\\n","joinerType":"str","accumulate":false,"timeout":"","count":"2","reduceRight":false,"reduceExp":"","reduceInit":"","reduceInitType":"","reduceFixup":"","x":330,"y":80,"wires":[["53168641.5a4cb8"]]},{"id":"53168641.5a4cb8","type":"change","z":"e8e5ccfb.8b54e","name":"","rules":[{"t":"set","p":"result","pt":"msg","to":"payload[0]-payload[1]","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":480,"y":80,"wires":[["a014e37e.af038"]]}]
1 Like

Here are a couple other contrib nodes that may do some of this for you...


Thanks Leifnel.

Used this technique and have it working fine now.

Chris

What about the following:
First SNMP node, then a change node that stores the payload in an other property of the message, then the second SNMP node with the second request, then a function node that does the subtraction. This way you have no delays, no storage, no race conditions, no parallel execution.
That would be a more flow based programming style

1 Like

Here is another way with joining:

[{"id":"9e03a15e.eb805","type":"function","z":"c421dfeb.3e752","name":"AJV10","func":"var countmsg = 2;          //how many items to join?\n\nvar nodublicates = false;   //only join if payload unequal existing payload\nvar limit;                 //only join if payloads are on both sides of the limit\nvar hysteresis;      //hysteresis \nvar clearaftersend = false;//clear queue after sending\nvar sendinstantly = false;\nvar reverse = false;         //reverse output array\nvar priomode = false;\nvar storagemode = false;     \nvar topicmatch = false;\n//------------ different topic mode ------------------\nvar diftopics = false;      //true: join only different topics; false: join only same topics\nvar alphasort = false;\n\nvar inmsg = msg;\nvar msgs = context.get(\"aggmsgs\")||{};\nvar topicmsgs = msgs[inmsg.topic]||[];\n\n\nif (inmsg.topic === \"\")\n    return null;\nif (typeof inmsg.reset != \"undefined\") {\n    msgs = {};\n    topicmsgs = [];\n    lastval = undefined;\n    context.set(\"aggmsgs\",msgs);\n    context.set(\"lastval\",lastval);\n    return null;\n}\nif (typeof inmsg.resettopic != \"undefined\") {\n    topicmsgs = [];\n    lastval = undefined;\n}\nif (typeof hysteresis !== 'undefined' && typeof lastval !== 'undefined') {\n    if (Math.abs(inmsg.payload - lastval) <= hysteresis) {\n        return null;\n    }\n}\nif (typeof lastval !== 'undefined') {\n    if (nodublicates && lastval == inmsg.payload)\n        return null;\n    if (typeof limit !== 'undefined' && countmsg == 2) {\n        if (!((lastval <= limit && inmsg.payload >= limit) || (lastval >= limit && inmsg.payload <= limit)))   \n            return null;\n    }\n} \n\nif (topicmatch) {\n    if (typeof inmsg.payload.jointopic != \"undefined\") {\n        if (topicmsgs.length === 0) {\n            topicmsgs.push(inmsg);\n            msgs[inmsg.topic] = topicmsgs;\n            context.set(\"aggmsgs\",msgs);\n            return null;   \n        }\n        else {\n            topicmsgs[0] = inmsg;\n        }\n    }\n    else {  //only accept topics specified by jointopics\n        for (var tmsgs in msgs) {\n            if (msgs.hasOwnProperty(tmsgs)) {   \n                var bfound = false;\n                var btopicfound = false;\n                var ar = msgs[tmsgs];\n                for (var i = 0; i < ar.length; i++) {    //search and replace\n                    if (i === 0) {\n                        if (ar[i].payload.jointopic == inmsg.topic)\n                            btopicfound = true;\n                    } else {\n                        if (ar[i].topic == inmsg.topic) {\n                            ar[i] = inmsg;\n                            bfound = true;\n                        }\n                    }\n                }\n                if (!bfound && btopicfound)        //add new\n                    msgs[tmsgs].push(inmsg);\n            }\n        }\n    }\n}\n\nvar outmsg = { \"topic\": inmsg.topic , \"payload\": \"\"};\nvar lastval = context.get(\"lastval\");\nvar inprio = typeof inmsg.priority != \"undefined\" ? inmsg.priority: countmsg-1 ;     //default prio is 1\n\nif (diftopics) {\n    if (topicmsgs.length > 0) {     //msg with same topic -> replace old msg\n        topicmsgs.shift();\n    }\n    topicmsgs.push(inmsg);\n    msgs[inmsg.topic] = topicmsgs;    \n    if (Object.keys(msgs).length > countmsg) {\n        for (var tmsgs in msgs) {\n            if (msgs.hasOwnProperty(tmsgs)) {   \n                delete msgs[tmsgs];\n                break;\n            }\n        }\n    }\n    context.set(\"aggmsgs\",msgs);\n    context.set(\"lastval\",inmsg.payload);\n    if (Object.keys(msgs).length == countmsg || sendinstantly) {\n        var aout = [];\n        outmsg.topic = \"\";\n        \n        for (var tmsgs in msgs) {\n            if (msgs.hasOwnProperty(tmsgs)) \n                aout.push(msgs[tmsgs][0]);\n        }\n        if (clearaftersend) {\n            context.set(\"aggmsgs\",undefined);\n            context.set(\"lastval\",undefined);\n        }\n        if (alphasort) \n            aout.sort(function(a,b) {return (a.topic > b.topic) ? 1 : ((a.topic > b.topic) ? -1 : 0);});\n\n        if (reverse) \n            aout.reverse();\n\n        for (var i =0; i<aout.length;i++) {outmsg.topic += aout[i].topic + \"_\"; }\n        outmsg.topic = outmsg.topic.substr(0,String(outmsg.topic).length-1);\n        outmsg.payload = aout;\n\n        return outmsg;\n    } else\n        return null;\n} else {\n    if (topicmsgs.length == countmsg && !storagemode && !topicmatch){\n        topicmsgs.shift();\n    }\n    if (storagemode) {\n        topicmsgs[inprio] = inmsg;\n    } \n    if (!topicmatch) {\n        topicmsgs.push(inmsg);\n        msgs[inmsg.topic] = topicmsgs;\n    }\n\n    context.set(\"aggmsgs\",msgs);\n    context.set(\"lastval\",inmsg.payload);\n    \n    if (storagemode) {                          //check send msg\n        if (inprio < topicmsgs.length - 1)      //only send on trigger msg => no priority\n            return null;\n        for (var i = 0; i < topicmsgs.length; i++) { //only send if storage is full\n            if (topicmsgs[i] === undefined)\n                return null;\n        }    \n    }\n\n    if (topicmatch) {\n        for (var tmsgs in msgs) {\n            if (msgs.hasOwnProperty(tmsgs)) {   \n                var ar = msgs[tmsgs];\n                if (ar.length == countmsg) {\n                    for (var i = 0; i < ar.length; i++) {\n                        if (ar[i].topic == inmsg.topic) {\n                            outmsg.payload = ar;\n                            outmsg.topic = ar[0].topic;\n                            node.send(RED.util.cloneMessage(outmsg));\n                        }\n                    }\n                }\n            }\n        }\n    } else {\n        if (topicmsgs.length == countmsg || sendinstantly) {\n            outmsg.payload = topicmsgs;\n            if (topicmatch) {\n                outmsg.topic = topicmsgs[0].topicori;\n                outmsg.payload[0].topic = outmsg.topic;\n            }\n            \n            if (clearaftersend) {\n                msgs[inmsg.topic] = undefined;\n                context.set(\"aggmsgs\",msgs);\n                context.set(\"lastval\",undefined);\n            }\n            if (reverse) {\n                var revArr = outmsg.payload.map(a => Object.assign({}, a));\n                revArr.reverse();\n                outmsg.payload = revArr;\n            }\n            return outmsg;\n        }\n        else\n            return null;\n    }\n}\n","outputs":1,"noerr":0,"x":580,"y":2223,"wires":[["7dbd79.3f6b3288"]]},{"id":"7e87f6e1.e8b438","type":"inject","z":"c421dfeb.3e752","name":"","topic":"lala","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":419,"y":2170,"wires":[["9e03a15e.eb805"]]},{"id":"afd70e5b.5f155","type":"debug","z":"c421dfeb.3e752","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","x":965,"y":2271,"wires":[]},{"id":"7dbd79.3f6b3288","type":"change","z":"c421dfeb.3e752","name":"","rules":[{"t":"set","p":"dif","pt":"msg","to":"payload[1].payload - payload[0].payload","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":744,"y":2247,"wires":[["afd70e5b.5f155"]]}]

Hi,
I want "2" be all time the first payload and 1 the second to get a positif value (If 1 is befor 2 the result is -1 and If 1 wans sent two times we obtain 0). So I want to fix the range of payload. have you an idea?
Thank you for your help.

Are the two values coming from different places?

Hi all

Can you please guide me with the flow , Im having a same kind of issue .

I have raised issue in [How to calculate the difference in KWH values received every 5 min from modbus data and save it as a new values in csv]

Please guide me

Appreciate , your effort in notifying the issue
thank you !

Energycharges :smiley: :smiley:

Please keep your discussion in one thread.
You could of tagged the above, from your other thread.