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":""}]