Simple sleep/wait example with ECMA script

I’ve spent hours on this and finally figured it out, so I thought I’d post it here in case anybody else runs into the same issue. After a lot of Googling I found out that OpenHAB doesn’t support the current version of Javascript, which means you can’t do the suggestion in the top StackOverflow post here. Also, setTimeout doesn’t work for some reason, so that’s also a no go.

Here’s the solution I ended up finding:

function sleep(milliseconds) {
  var start = new Date().getTime();
  for (var i = 0; i < 1e7; i++) {
    if ((new Date().getTime() - start) > milliseconds){
      break;
    }
  }
}

var dimPercent = 5;
var sleepTimeSeconds = 5
var sleepTime = 1000*sleepTimeSeconds; // DON'T EDIT THIS, edit sleepTimeSeconds

while(dimPercent >= 0)
{
  events.sendCommand('LivingRoomLights', dimPercent);
  sleep(sleepTime)
  dimPercent = dimPercent - 1;
}

In this example, the LivingRoomLights item will have its dimness set to 5%, then sleep for 5 seconds, then have its dimness set to 4%, then wait 5 seconds… until it’s turned off.

In case anybody wants to use Javascript and needs a way to sleep without any of the functions that it looks like should be included, here ya go.

3 Likes

By doing some research here in the community I came up with this alternative that uses timers. This would however need to be adapted a bit for your concrete use case of course:

var ScriptExecution = Java.type("org.openhab.core.model.script.actions.ScriptExecution");
var ZonedDateTime = Java.type("java.time.ZonedDateTime");

// Do some stuff in five seconds
var in5secs = ZonedDateTime.now().plusSeconds(5)
ScriptExecution.createTimer(in5secs, function(){events.postUpdate('test', "hello")});
1 Like

Here are two more examples on how to wait and block in a script. One example with java.lang.Thread.sleep() and one example with a timer and a timer and a java.util.concurrent.CompletableFuture.

Yeah, I found that out, too and noted it in this thread:

I hope, that OH3 will eventually update to a more recent ECMA Script version.

You don’t need to implement a busy wait like this. Just use

java.lang.Thread.sleep(5000);

Timers are also a great choice because they don’t block the rule.

One important thing to realize with Nashorn (the name of the JavaScript implementation embedded in Java 11) is that it’s running on top of and has access to all of Java in addition to JavaScript. And all the interaction you do between your rules and openHAB is done through Java Objects, so don’t think you’ll be able to head down the path of writing “pure” JavaScript either.

As a result, when searching for how to do a lot of stuff like this, it’s important to look here on the forums and in the docs first. And then maybe even to post a question asking rather than looking for the JavaScript/Python/Groovy native way to do something like this. Often that won’t be the best approach because ultimately most of the stuff we are interacting with in rules are Java Objects and the native approach won’t work.

But do realize we appreciate your posting this. And someone might find it useful for some edge case. But it’s not the best way to pause for a time in openHAB rules most of the time.

2 Likes

Oh, nice. I didn’t realize that everything was sitting on top of java, even if you select EMCA script.

I’ll go ahead and start messing around with that and hopefully it can replace my hacky solution.

This topic was automatically closed 41 days after the last reply. New replies are no longer allowed.