Good thinking. So this seems to be the best so far
[{"id":"a8ab2ec3.838e38","type":"delay","z":"bdd7be38.d3b55","name":"","pauseType":"rate","timeout":"5","timeoutUnits":"seconds","rate":"1","nbRateUnits":"5","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":true,"x":470,"y":4620,"wires":[["baaa13ea.e41a6"]]},{"id":"fc72e97d.d02f78","type":"rbe","z":"bdd7be38.d3b55","name":"","func":"rbe","gap":"","start":"","inout":"out","property":"payload","x":450,"y":4660,"wires":[["baaa13ea.e41a6"]]},{"id":"fa1143fa.826cb","type":"inject","z":"bdd7be38.d3b55","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"0","payloadType":"num","x":90,"y":4620,"wires":[["7ba6c786.a8ab3"]]},{"id":"8f6dc68d.e4811","type":"inject","z":"bdd7be38.d3b55","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"1","payloadType":"num","x":90,"y":4660,"wires":[["7ba6c786.a8ab3"]]},{"id":"baaa13ea.e41a6","type":"rbe","z":"bdd7be38.d3b55","name":"","func":"rbe","gap":"","start":"","inout":"out","property":"timestamp","x":630,"y":4620,"wires":[["bc41c698.c69a7"]]},{"id":"bc41c698.c69a7","type":"debug","z":"bdd7be38.d3b55","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":670,"y":4680,"wires":[]},{"id":"7ba6c786.a8ab3","type":"change","z":"bdd7be38.d3b55","name":"Set msg.timestamp","rules":[{"t":"set","p":"timestamp","pt":"msg","to":"$millis()\t","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":270,"y":4640,"wires":[["a8ab2ec3.838e38","fc72e97d.d02f78"]]}]
Though, having also tried writing it in a Function node, it turns out to be very simple, so perhaps it is better just to use that.
const minInterval = 5000 // min interval between outputs, msec
const previous = context.get("previous") || {timestamp: 0}
const now = new Date().getTime()
if ( msg.payload == previous.value && (now - previous.timestamp) < minInterval )
{
// same value as last one and too soon to send again, so send nothing
msg = null
} else {
previous.timestamp = now
previous.value = msg.payload
context.set("previous", previous)
}
return msg;