Wow! that's a good trick!
I ended up coding it, after all. Javascript can do exactly what I want.
This outputs the 1st message to the 1st output and the second and all following messages to a second output.
Wait for 10 seconds and it resets - and will block the first message again.
It also resets on a 'reset' message.
It's a kind of debounce but instead of dropping the 2nd message, it drops the 1st.
It called 'I insist' because you need to trigger it twice to get through.
[{"id":"5077248c.5ead5c","type":"tab","label":"Flow 1","disabled":false,"info":""},{"id":"11cda614.9dc72a","type":"inject","z":"5077248c.5ead5c","name":"","props":[{"p":"payload.occupancy","v":"false","vt":"bool"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":120,"y":200,"wires":[["aea06469.6ec938"]]},{"id":"251c14fa.54998c","type":"debug","z":"5077248c.5ead5c","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":640,"y":220,"wires":[]},{"id":"8a0485e2.5fa118","type":"inject","z":"5077248c.5ead5c","name":"true","props":[{"p":"payload.occupancy","v":"true","vt":"bool"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":110,"y":280,"wires":[["aea06469.6ec938"]]},{"id":"e11b04c4.e8dd08","type":"inject","z":"5077248c.5ead5c","name":"reset","props":[{"p":"reset","v":"true","vt":"bool"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":130,"y":140,"wires":[["aea06469.6ec938"]]},{"id":"aea06469.6ec938","type":"function","z":"5077248c.5ead5c","name":"I Insist","func":"// input:\n// messages. \n// Send only 2nd and following message within a given timeframe.\n// reset after 'msg reset'\n// reset if time window expires\n\n// implementation: node keeps track of a state. It can be in either one of \n// two modes: holding or Passthrough.\n// Holding mode: when it receives a message it does not send, but goes to Passthrough mode.\n// Passthrough mode:\n// Every message received will be sent on.\n// After N minutes after the last message, the node will leave Passthrough mode and fall back to Holding mode.\n// every message resets the timer, so it takes N mins without messages to fall back to Holding mode\n\nconst BLOCK=1;\nconst PASSTHROUGH=2;\n\nvar now = Date.now();\nvar startTimer=context.get('starttimer')||now;\nvar mode=context.get('mode')||BLOCK; \n\nnewMsg=[null,null];\n// case: Message has arrived.\n// handle reset message: Go to mode BLOCK\nif (msg.hasOwnProperty('reset') && msg.reset!=false)\n{\n mode=BLOCK;\n node.status({fill:\"blue\",shape:\"ring\",text:\"reset. now blocking.\"});\n newMsg=[null,null];\n}\nelse // regular message, either block or forward it. \n{\n // check timer for expiration, since we do not have a callback when it expires. First time we check is on this message-event.\n if (mode==PASSTHROUGH && (now-startTimer) > 10*1000)\n {\n // timer expired. kill message and go to mode BLOCK\n mode=BLOCK;\n }\n \n if (mode==BLOCK)\n {\n // discard message. change mode. set timer.\n mode=PASSTHROUGH;\n startTimer=now;\n node.status({fill:\"yellow\",shape:\"ring\",text:\"blocked 1 msg\"});\n newMsg=[msg,null];\n }\n else\n {\n // mode is passthrough. \n // reset timer\n startTimer=now;\n node.status({fill:\"green\",shape:\"ring\",text:\"forwarded 1 or more msg\"});\n newMsg=[null,msg];\n }\n} \n\ncontext.set('mode', mode);\ncontext.set('starttimer', startTimer);\nreturn(newMsg);","outputs":2,"noerr":0,"initialize":"","finalize":"","x":370,"y":220,"wires":[["251c14fa.54998c"],["251c14fa.54998c"]],"outputLabels":["First message ","Next messages"]}]```