Calculate Differences

Node-RED Flow: Calculate Differences

This flow is designed to calculate the difference between consecutive numerical values along with the time elapsed between them.

Flow Overview

  1. Inject Nodes

    • Several inject nodes send predefined numerical values (0, 10, 20, 50, 100) into the flow to simulate data input.
    • Each inject node triggers the flow manually when clicked.
  2. Set Value Node (Function Node: "set val")

    • Converts the incoming numerical value into an object:
      {
        "value": <input_value>
      }
      
    • Adds a timestamp (msg.timestamp) representing the current time.
  3. RBE (Report-by-Exception) Node

    • Ensures that only changes in the payload value are forwarded to the next stage, filtering out duplicate values.
  4. Calculate Differences (Function Node)

    • Computes the difference (diffValue) between the current and previous values.
    • Computes the time difference (diffTimestamp) between the current and previous timestamps.
    • Outputs an object with:
      {
        "diffValue": <difference>,
        "diffTimestamp": <time_difference>,
        "newValue": <current_value>,
        "newTimestamp": <current_timestamp>,
        "prevValue": <previous_value>,
        "prevTimestamp": <previous_timestamp>
      }
      
    • Stores the current value and timestamp in the node’s context for the next calculation.
  5. Debug Node ("Show Output")

    • Displays the computed differences in the Node-RED debug pane.

Expected Output

  • On each new value input, the flow calculates and outputs the difference from the previous value along with the time difference between updates.
  • If it’s the first received value, diffValue and diffTimestamp will be null.

This flow can be useful for tracking sensor data changes, logging rate-of-change metrics, or monitoring process values over time.

[{"id":"1a0b1c8a.2d4b7b","type":"tab","label":"Calculate Differences","disabled":false,"info":""},{"id":"f9f14f0f.12cd28","type":"rbe","z":"1a0b1c8a.2d4b7b","name":"","func":"rbe","gap":"0","start":"false","inout":"out","septopics":true,"property":"payload","topi":"topic","x":430,"y":280,"wires":[["24c0b35d.46ea3a"]]},{"id":"24c0b35d.46ea3a","type":"function","z":"1a0b1c8a.2d4b7b","name":"Calculate Differences","func":"//[input]\n// msg.payload.value\n// msg.timestamp\n\nlet prevValue = context.get('prevValue');\nlet prevTimestamp = context.get('prevTimestamp');\n\nlet newValue = msg.payload.value;\nlet newTimestamp = new Date(msg.timestamp).getTime();\n\n\n\n// If we have a previous value/timestamp, calculate differences\nif (prevValue !== undefined && prevTimestamp !== undefined) {\n    \n    prevTimestamp = new Date(prevTimestamp).getTime();\n    \n    let diffValue = newValue - prevValue;\n    let diffTimestamp = newTimestamp - prevTimestamp;\n    \n    msg.payload = {\n        diffValue: diffValue,\n        diffTimestamp: diffTimestamp,\n        newValue: newValue,\n        newTimestamp: newTimestamp,\n        prevValue: prevValue,\n        prevTimestamp: prevTimestamp\n    };\n} else {\n    // First run - no differences yet\n    msg.payload = {\n        diffValue: null,\n        diffTimestamp: null,\n        newValue: newValue,\n        newTimestamp: newTimestamp,\n        prevValue: null,\n        prevTimestamp: null\n    };\n}\n\ncontext.set(\"prevValue\",newValue);\ncontext.set(\"prevTimestamp\",newTimestamp);\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":460,"y":400,"wires":[["b0b3a6e9.d63c8"]]},{"id":"b0b3a6e9.d63c8","type":"debug","z":"1a0b1c8a.2d4b7b","name":"Show Output","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":690,"y":400,"wires":[]},{"id":"7ee6438287ad9016","type":"inject","z":"1a0b1c8a.2d4b7b","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"10","payloadType":"num","x":150,"y":160,"wires":[["127d7b092805890b"]]},{"id":"127d7b092805890b","type":"function","z":"1a0b1c8a.2d4b7b","name":"set val","func":"msg.payload = {\n    value: msg.payload,  \n};\nmsg.timestamp = new Date();\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":350,"y":200,"wires":[["f9f14f0f.12cd28","a5ab0fe5a8237ce8","90c06b57413a7042"]]},{"id":"43dc4671f3c9713a","type":"inject","z":"1a0b1c8a.2d4b7b","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"20","payloadType":"num","x":150,"y":220,"wires":[["127d7b092805890b"]]},{"id":"4afdd1702bf1fba4","type":"inject","z":"1a0b1c8a.2d4b7b","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"50","payloadType":"num","x":150,"y":280,"wires":[["127d7b092805890b"]]},{"id":"fa9fc23e09721b85","type":"inject","z":"1a0b1c8a.2d4b7b","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"100","payloadType":"num","x":150,"y":340,"wires":[["127d7b092805890b"]]},{"id":"eb0ec244618a894a","type":"inject","z":"1a0b1c8a.2d4b7b","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"0","payloadType":"num","x":150,"y":100,"wires":[["127d7b092805890b"]]},{"id":"a5ab0fe5a8237ce8","type":"debug","z":"1a0b1c8a.2d4b7b","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":690,"y":80,"wires":[]},{"id":"90c06b57413a7042","type":"debug","z":"1a0b1c8a.2d4b7b","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"timestamp","targetType":"msg","statusVal":"","statusType":"auto","x":690,"y":140,"wires":[]}]

Flow Info

Created 1 year, 2 months ago
Rating: not yet rated

Owner

Actions

Rate:

Node Types

Core
  • debug (x3)
  • function (x2)
  • inject (x5)
  • rbe (x1)
Other
  • tab (x1)

Tags

Copy this flow JSON to your clipboard and then import into Node-RED using the Import From > Clipboard (Ctrl-I) menu option