Not dense, it isn't obvious if you've not done it before.
The trick is to remember that a set timer returns a timer object reference. So you have to assign to a variable. Then you can track/clear multiple timers.
Still looking at your flow yet but that is the basics.
From your flow, you are not saving the timers to context so they will be created/lost on each incoming msg.
Since I had a few minutes and the excercise was good for me, here is a working example - note that you need to change your triggers to use boolean
inputs rather than text.
function timer1 () {
// This runs when the timer expires
// msg is set to the incoming msg at the time the timer was created
node.send(msg)
node.warn('TIMER IS SELF CANCELLING FOR TOPIC ' + msg.topic )
// Delete the entry from the context var and write back
delete timers[msg.topic]
context.set('timers', timers)
}
// Get the timers from the context store
let timers = context.get('timers') || {}
// Is there an existing timer for this topic?
if ( timers[msg.topic] ) {
// If so, is the NEW payload TRUE?
if ( msg.payload === true ) {
// Cancel the timer & delete from context
node.warn('CANCELLING TIMER FOR EXISTING TOPIC ' + msg.topic )
clearTimeout(timers[msg.topic])
delete timers[msg.topic]
} else {
// NEW payload is FALSE so create a timer
// NB: timouts cancel themselves when they run
node.warn('CREATING NEW TIMER FOR EXISTING TOPIC ' + msg.topic )
timers[msg.topic] = setTimeout(timer1, 5000)
}
} else {
// Only interested in a payload of FALSE since
// there will be no timer to cancel in this case
if ( msg.payload === false ) {
// NEW payload is FALSE so create a timer
// NB: timouts cancel themselves when they run
node.warn('CREATING NEW TIMER FOR NEW TOPIC ' + msg.topic )
timers[msg.topic] = setTimeout(timer1, 5000)
}
}
// Update the timers to the context store
context.set('timers', timers)
You could refactor that code slightly to simplify the nested if's.
I also suspect that it would be possible to get race conditions with this code if you were sending through topics and cancelling them faster than the timeout value.