Possible error in the Rules - Advanced Page

Good {zoned time of day} Developers,
I was reading through the Rules-Advanced page in the Documentation site and came across an example showing how to use the “cache” feature and the createTimer function of “ScriptExecution” Here is the example I am referencing:

console.info('Motion was detected');
items.getItem('FrontPorchLight').sendCommand('ON');

timerId = ruleUID+'_timer';
var lightsOut = function() {
  console.info('No more motion, turning off the light');
  items.getItem('FrontPorchLight').sendCommand('OFF');
  cache.put(timerId, null);
};

var timer = cache.get(timerId);
if(!timer) {
    cache.put(timerId, ScriptExecution.createTimer(time.ZonedDateTime.now().plusMinutes(30), lightsOut));
}
else {
    timer.reschedule(time.ZonedDateTime.now());
}

When I used this code for my Stairway Lights, I got 2 errors. The first error complained about the cache.put(timerId, null); line. I solved it with editing the line to "cache.private.put(timerId, null)

Then the second error appeared. It complained about the ScriptExecution section of this line:

cache.private.put(timerId, ScriptExecution.createTimer(time.ZonedDateTime.now().plusMinutes(30), lightsOut));

(I already corrected the cache statement to include .private). I solved this by adding the prefix “actions.” to it, i.e. “actions.ScriptExecution.createTimer…” After that the rule ran fine.

I saw the notice at the bottom of the page asking if I caught a mistake and a link to the GitHub page. However I am so far away from being an expert on javascript that I didn’t want to risk saying something wrong, messing up the documentation, etc. So I thought I would quietly bring it up here. Of course, if I am wrong with any of the above then please ignore everything I said. I will still continue to read, learn, and trust the Advanced Rules documentation, its a great resource.

Anything you submit would be reviewed and accepted before it gets added/changes the actual docs. You can’t mess anything up.

Indeed, the APIs have changed for both of these since the advanced rules page was written and your updates are correct. Actually, the createTimer part might have always been wrong. :fearful:

Updating that example to take advantage of all the latest in openhab-js should look something like this:

console.info('Motion was detected');
items.FrontPorchLight.sendCommand('ON');

timerId = ruleUID+'_timer';

var lightsOut = function() {
  console.info('No more motion, turning off the light');
  items.FrontPorchLight.sendCommand('OFF');
  cache.private.put(timerId, null);
};

var timer = cache.private.get(timerId);
if(!timer) {
    cache.private.put(timerId, actions.ScriptExecution.createTimer(time.toZDT('PT30M'), lightsOut));
}
else {
    timer.reschedule(time.toZDT('PT30M'));
}

Since the private cache is being used there really is no need to use the ruleUID in the timerId but it doesn’t hurt.

Also, I don’t have the page in front of my right now but shouldn’t the timer be rescheduled to 30 minutes from now, not now, if it already exists? I can’t remember the flow of the example and whether there is a reason to reschedule it for right now. I’ve adjusted the code above to reschedule it to 30 minutes from now.

The code could be made even a little cleaner but I worry it becomes less clear how it works to new users:

console.info('Motion was detected');
items.FrontPorchLight.sendCommand('ON');

timerId = ruleUID+'_timer';

var lightsOut = function() {
  console.info('No more motion, turning off the light');
  items.FrontPorchLight.sendCommand('OFF');
};

var timer = cache.private.get(timerId, () => actions.ScriptExecution.createTimer(time.toZDT('PT30M'), lightsOut));
timer.reschedule(time.toZDT('PT30M'));

This version uses the ability to pass a function to the cache’s get function which is executed when the entry doesn’t exist. So in this case if timerId doesn’t exist it’s created and the cache updated all on that one line. Then we reschedule it whether it was newly created or not, which is redundant if the timer didn’t already exist, but it makes the code a lot simpler. But it means the explanation may need to be more complex.

Please do go ahead and click that link. You can’t really mess anything up. See [Wiki] How to contribute to the openHAB Documentation for detailed instructions if you need them.