Alternative to multiple setTimeout statements in JS rules

This is a great example for how to use Promise. Thanks for posting!

Not quite. You can create as many as you want, but only one can run at a time. If you are careful to stagger the times so they don’t run at the same time they will work fine.

Another way you can sequence events is to use the Gatekeeper design pattern which I’ve provided as a part of openhab_rules_tools which you can install using npm.

So the above could be:

var {gatekeeper} = require('openhab_rules_tools');

var gk = cache.put(ruleUID+'_gatekeeper', () => new gatekeeper.Gatekeeper());

if(trigger = 'LivingroomSensor_MotionAlarm') {
  gk.addCommand(600, () => { items.getItem('HuespotHallway2_Color').sendCommand('5,100,30'); });
  gk.addCommand(600, () => { items.getItem('HuespotHallway1_Color').sendCommand('5,100,30'); });
  gk.addCommand('PT2m', () => { items.getItem('HuespotDR4_Color').sendCommand('5,100,30'); });
  gk.addCommand(0, () => {  if(items.getItem("HueRoomLR_Power").state == "OFF") {
      gk.addCommand(600, () => { items.getItem("HuespotHallway2_Color").sendCommand("30,65,0"); } );
      gk.addCommand(600, () => { items.getItem("HuespotHallway1_Color").sendCommand("5,100,30"); } );
      gk.addCommand(0, () => { items.getItem("HuespotDR4_Color").sendCommand("5,100,30"); } );
    }
  }; );
}
else { 
  ...

The first number is how long to wait after the passed in command is executed before running the next command. So the first line will command 'HuespotHallway2_Color, wait 600 msec and then run the command to HuespotHallway1_Color, wait 600 msec then run the command to HuespotDR4_Color. Then it'll wait two minutes (see the docs for time.toZDT()` in the JS Scripting addon for details on how that works) and run the if statement. If the if statement evaluates to true it adds those commands to the list with the indicated 600 msec spacing.

I’m not saying this is necessarily better, just pointing out alternatives. The reason why this works is that there is only the one timer in Gatekeeper. So you can never have two running at the same time.

1 Like