Rule does not work but can't find the error

Search thoroughly, also through examples but somehow I can’t figure out why this rule doesn’t work.

Rules:

var logger = Java.type("org.slf4j.LoggerFactory").getLogger("org.openhab.model.script.Rules.DoorsAndWindows");
var ScriptExecution = Java.type("org.openhab.core.model.script.actions.ScriptExecution");
var ZonedDateTime = Java.type("java.time.ZonedDateTime");

scriptExtension.importPreset("default");

this.OPENHAB_CONF = (this.OPENHAB_CONF === undefined) ? java.lang.System.getProperty("openhab.conf") : this.OPENHAB_CONF; 
load(OPENHAB_CONF + "/automation/lib/javascript/personal/utils.js")

var doorsOpen = getNames("gDeurenBg", function(i) { return i.state == OPEN; });
var msg = ""; var prio = "2";
var trgrItem = event.itemName;

if(trgrItem == "gDeurenBg") {
  var msgHeader = "Deur/raam geopend terwijl er niemand thuis is! Open deuren/ramen: "
} else {
  var msgHeader = "Er is niemand thuis en de volgende deuren/ramen staan nog open: "
}

msg = msgHeader + doorsOpen;

var sendMsg = function(msg, prio){
  if(ir.getItem("mainPresence").state == "OFF"){
    logger.info("60 seconden voorbij. Verstuur bericht");
    sendPushover(msg, prio);
  } else if(ir.getItem("mainPresence").state == "ON"){
    logger.info("60 seconden voorbij maar mainPresence is ON.")
  }
}

logger.info("Deur/raam geopend. Timer gestart");
logger.info("ZDT now + 1 min is " + ZonedDateTime.now().plusMinutes(1));
var msgTimer = ScriptExecution.createTimer(ZonedDateTime.now().plusMinutes(1), sendMsg(msg, prio));

Log:

2022-04-27 23:31:24.905 [INFO ] [b.model.script.Rules.DoorsAndWindows] - Deur/raam geopend. Timer gestart

2022-04-27 23:31:24.911 [INFO ] [b.model.script.Rules.DoorsAndWindows] - ZDT now + 1 min is 2022-04-27T23:32:24.906714+02:00[Europe/Amsterdam]

2022-04-27 23:31:24.933 [INFO ] [b.model.script.Rules.DoorsAndWindows] - 60 seconden voorbij. Verstuur bericht

2022-04-27 23:31:24.939 [INFO ] [b.model.script.Rules.DoorsAndWindows] - Pushover message with priority 2 sent: "Deur/raam geopend terwijl er niemand thuis is! Open deuren/ramen: middelste achterdeur"

2022-04-27 23:31:25.283 [ERROR] [e.automation.internal.RuleEngineImpl] - Failed to execute rule 'DoorOpenAway': Fail to execute action: 5

It did work prior to inserting my timer and the sendMsg-function. I reviewed multiple examples for the timers in Javascript (rule is not ECMA-2021 based) but could not find a solution. Maybe I am mixing things up… :grimacing:

Any help appreciated!.

I’m not familiar with javascript at all, but it seems to me that you’re calling sendMsg at the time of timer creation and giving createTimer the return value of sendMsg call, instead of passing a lambda there.

This is what it probably should look like (disclaimer: I don’t actually know javascript syntax):

var msgTimer = ScriptExecution.createTimer(ZonedDateTime.now().plusMinutes(1), () => { sendMsg(msg, prio); });

JimT is on the right track, but there’s more to it than just how you format the function call. There are two different methods for creating a timer depending on whether you want to send parameters to the the function the timer runs. You are using createTimer which only takes a function definition or name of a function as the input after the zonedDateTime. If you want to be able to include parameters for the function you have to use createTimerWithArguments.

For createTimerWithArguments the second input is an object that get passed to the function. So it looks something like this:

var logger = Java.type('org.slf4j.LoggerFactory').getLogger('org.openhab.rule.JSsDemo');
var ZonedDateTime = Java.type("java.time.ZonedDateTime");
var ScriptExecution = Java.type("org.openhab.core.model.script.actions.ScriptExecution");

runThisFunction = function (objParam) {
  logger.info(`Print ${objParam.name} and ${objParam.info}`)
}

ScriptExecution.createTimerWithArgument(ZonedDateTime.now().plusSeconds(30),{"name": "Titanic", "info": "Sunk"},runThisFunction);
1 Like

Thanks for the hint @JustinG!

For those who wonder, this is the solution. Note that the variables msg and prio are set elsewhere in the rule before the function is called/defined.

var sendMsg = function(objParam){
  if(ir.getItem("mainPresence").state == "OFF"){
    logger.info("60 seconden voorbij. Verstuur bericht");
    sendPushover(objParam.msg, objParam.prio);
  } else if(ir.getItem("mainPresence").state == "ON"){
    logger.info("60 seconden voorbij maar mainPresence is ON.")
  }
}

var msgTimer = ScriptExecution.createTimerWithArgument(ZonedDateTime.now().plusMinutes(1), {"msg": msg, "prio": prio}, sendMsg);