Edit: Updates for OH 4.
Please see Design Pattern: What is a Design Pattern and How Do I Use Them first.
Problem Statement
Often one will be in a situation where an event will occur many times but an action should only be taken on the event once over a certain time period and the rest ignored. This is related to Gatekeeper but differs in that Gatekeeper queues up the actions and works them off in time whereas Event Limit throws away events that occur too soon after the last processed events.
This is best explained with an example.
For example, in my own rules I generate an alert when the temperature outside is a few degrees cooler than the inside (in the summer) to open the windows and another alert when it is warmer outside than inside to close the blinds.
Every time the temperature changes both inside and outside there is the potential to generate this alert. Given that some of the thermometers report every two minutes receiving an alert every time is unacceptable.
Concept
Create a flag of some sort which gets set when the first event occurs. Each subsequent event will check this flag and suppress the activity if the flag indicates it’s too soon. The simplest way to implement this is to use a timestamp as the “flag” and test to see if enough time has passed since that timestamp before allowing a new event to be processed.
Blockly
The openHAB Rules Tools [4.1.0.0;4.9.9.9] Block Library provides a rate limit block that implements this design pattern.
To implement this yourself it would be something like the following.
JS Scripting
The OHRT library used above in the Blockly example is also available in JS Scripting.
var { RateLimit } = require('openhab_rules_toolks');
var rateLimit = cache.private.get('RateLimitName', () => RateLimit());
rateLimit.run(() => console.info('Rate limited action'), 'PT24H');
Rules DSL
val lastAction = privateCache.get('LastAction', [ | now ]);
if(lastAction.isBefore(now.minusHours(24)) {
logInfo('RateLimit', 'Rate limited action');
privateCache.put('LastAction', now);
}