How to allow a message to pass through a Join node only when the contents have changed

I am rotating an object forward for n seconds and reverse for m seconds. n and m come from MQTT data. I have worked out everything (combining messages, javascript in function node, etc.), but I would like to adjust this so the merged message after the join node only moves when one or both of the values from the MQTT streams have changed. I thought there might be an easy way to do this using the standard nodes, but am stumped.

[{"id":"a67ac8a89bbb8154","type":"mqtt in","z":"46e0ed13d406fbe2","name":"","topic":"Furnace6CycleForwardTime","qos":"2","datatype":"auto-detect","broker":"4d962509f9845e41","nl":false,"rap":true,"rh":0,"inputs":0,"x":160,"y":1100,"wires":[["6361e86a19634190"]]},{"id":"dcf089de29b1950b","type":"mqtt in","z":"46e0ed13d406fbe2","name":"","topic":"Furnace6CycleReverseTime","qos":"2","datatype":"auto-detect","broker":"4d962509f9845e41","nl":false,"rap":true,"rh":0,"inputs":0,"x":160,"y":1180,"wires":[["4d68aeeeac56bd68"]]},{"id":"6361e86a19634190","type":"change","z":"46e0ed13d406fbe2","name":"","rules":[{"t":"move","p":"payload","pt":"msg","to":"payload.Furnace6CycleForwardTime","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":450,"y":1100,"wires":[["c4da7bb85acb7fa2"]]},{"id":"4d68aeeeac56bd68","type":"change","z":"46e0ed13d406fbe2","name":"","rules":[{"t":"move","p":"payload","pt":"msg","to":"payload.Furnace6CycleReverseTime","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":430,"y":1180,"wires":[["c4da7bb85acb7fa2"]]},{"id":"91a8af8b48eda358","type":"function","z":"46e0ed13d406fbe2","name":"Use Forward and Reverse Times as Timers to Send FWD & REV Commands","func":"// Define global variables to store timer IDs and current direction\nlet forwardTimer;\nlet reverseTimer;\nlet currentDirection = \"forward\"; // Initialize to forward\n\n// Function node code\n\n// Check if the input message contains valid values for forward and reverse times\nif (msg.payload.Furnace6CycleForwardTime && msg.payload.Furnace6CycleReverseTime) {\n  const forwardTime = parseInt(msg.payload.Furnace6CycleForwardTime, 10); // Use seconds directly\n  const reverseTime = parseInt(msg.payload.Furnace6CycleReverseTime, 10); // Use seconds directly\n\n  // Function to send commands in an infinite loop\n  function cycleCommands() {\n    // Clear any existing timers to prevent conflicts\n    clearTimeout(forwardTimer);\n    clearTimeout(reverseTimer);\n\n    // Set the payload based on the current direction\n    if (currentDirection === \"forward\") {\n      msg.payload = \"000000000010010\";\n      currentDirection = \"reverse\"; // Switch to reverse for the next cycle\n      forwardTimer = setTimeout(cycleCommands, forwardTime * 1000); // Set timer for forward duration\n    } else {\n      msg.payload = \"000000000100010\";\n      currentDirection = \"forward\"; // Switch back to forward for the next cycle\n      reverseTimer = setTimeout(cycleCommands, reverseTime * 1000); // Set timer for reverse duration\n    }\n\n    // Send the message\n    node.send(msg);\n  }\n\n  // Start the cycle\n  cycleCommands();\n\n} else {\n  node.warn(\"Missing or invalid Furnace6CycleForwardTime or Furnace6CycleReverseTime in the input message.\");\n}\n\nreturn msg; ","outputs":1,"timeout":0,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1010,"y":1140,"wires":[["4b46c167e91a8514"]]},{"id":"c4da7bb85acb7fa2","type":"join","z":"46e0ed13d406fbe2","name":"","mode":"custom","build":"merged","property":"payload","propertyType":"msg","key":"topic","joiner":"\\n","joinerType":"str","useparts":false,"accumulate":false,"timeout":"","count":"2","reduceRight":false,"reduceExp":"","reduceInit":"","reduceInitType":"","reduceFixup":"","x":630,"y":1140,"wires":[["91a8af8b48eda358"]]},{"id":"4d962509f9845e41","type":"mqtt-broker","name":"","broker":"192.168.10.85","port":"1883","clientid":"","autoConnect":true,"usetls":false,"protocolVersion":"5","keepalive":"60","cleansession":true,"autoUnsubscribe":true,"birthTopic":"","birthQos":"0","birthRetain":"false","birthPayload":"","birthMsg":{},"closeTopic":"","closeQos":"0","closeRetain":"false","closePayload":"","closeMsg":{},"willTopic":"","willQos":"0","willRetain":"false","willPayload":"","willMsg":{},"userProps":"","sessionExpiry":""}]

Have you tried a filter nodes after the change nodes and setting the join as key value and every subsequent message.
e.g.

[{"id":"e99162464f3c7c7a","type":"inject","z":"d1395164b4eec73e","name":"","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"10","payloadType":"str","x":170,"y":7460,"wires":[["6361e86a19634190"]]},{"id":"6361e86a19634190","type":"change","z":"d1395164b4eec73e","name":"","rules":[{"t":"set","p":"topic","pt":"msg","to":"Furnace6CycleReverseTime","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":360,"y":7480,"wires":[["02bcf6726fd73b4c"]]},{"id":"a320373501b05c84","type":"inject","z":"d1395164b4eec73e","name":"","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"20","payloadType":"str","x":170,"y":7500,"wires":[["6361e86a19634190"]]},{"id":"02bcf6726fd73b4c","type":"rbe","z":"d1395164b4eec73e","name":"","func":"rbe","gap":"","start":"","inout":"out","septopics":true,"property":"payload","topi":"topic","x":510,"y":7540,"wires":[["c4da7bb85acb7fa2"]]},{"id":"4d68aeeeac56bd68","type":"change","z":"d1395164b4eec73e","name":"","rules":[{"t":"set","p":"topic","pt":"msg","to":"Furnace6CycleForwardTime","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":360,"y":7600,"wires":[["02bcf6726fd73b4c"]]},{"id":"c4da7bb85acb7fa2","type":"join","z":"d1395164b4eec73e","name":"","mode":"custom","build":"object","property":"payload","propertyType":"msg","key":"topic","joiner":"\\n","joinerType":"str","useparts":false,"accumulate":true,"timeout":"","count":"2","reduceRight":false,"reduceExp":"","reduceInit":"","reduceInitType":"","reduceFixup":"","x":630,"y":7540,"wires":[["54099372c05f36e7"]]},{"id":"42a20071194ed606","type":"inject","z":"d1395164b4eec73e","name":"","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"10","payloadType":"str","x":170,"y":7580,"wires":[["4d68aeeeac56bd68"]]},{"id":"2c470d1bed57c864","type":"inject","z":"d1395164b4eec73e","name":"","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"20","payloadType":"str","x":170,"y":7620,"wires":[["4d68aeeeac56bd68"]]},{"id":"54099372c05f36e7","type":"debug","z":"d1395164b4eec73e","name":"debug 2575","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":770,"y":7480,"wires":[]}]
1 Like

Thank you! I knew there was probably a simple & elegant solutoin. This works perfectly.

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