Script with delay function not work

The script will check the temperature of my heating unter conditions.
When temperarture ist lower than 55°C the script will send an alert via myopenhab.org.
The problem is, that the temperature of my heating trigger every minute. The alert popup every minute.
That is why i want is to have a delay of 10 minutes. But it is no working! The allert still popup every minute
Hint: The item '“TempWarn” is a dummy-switch.

this.ScriptExecution = (this.ScriptExecution === undefined) ? Java.type("org.openhab.core.model.script.actions.ScriptExecution") : this.ScriptExecution;
this.ZonedDateTime = (this.ZonedDateTime === undefined) ? Java.type("java.time.ZonedDateTime") : this.ZonedDateTime;

var delay = function() { events.sendCommand("TempWarn", "ON"); }
var now = this.ZonedDateTime.now();

var Schlaf_Temp, Aussen_Temp, Vorlauf_FW_Temp;

var NotificationAction = org.openhab.io.openhabcloud.NotificationAction;

TempWarn = itemRegistry.getItem('TempWarn').getState();
Schlaf_Temp = itemRegistry.getItem('WandthermostatSchlafzimmer_Temperature').getState();
Aussen_Temp = itemRegistry.getItem('OutdoorModulWolferstadt_Temperatur').getState();
Vorlauf_FW_Temp = itemRegistry.getItem('TemperaturenHeizung_FernwarmeVorlauftemperatur').getState();
if (TempWarn == 'ON' && Vorlauf_FW_Temp < 55 && Aussen_Temp < 15 && Schlaf_Temp < 18) {
  NotificationAction.sendBroadcastNotification("Vorlauftemperatur Fernwärme unter 55°C");
  events.sendCommand("TempWarn", "OFF");
  var timer = ScriptExecution.createTimer(now.plusMinutes(10), delay);
}

What is the problem?

hi,
your timer only delays the sending of the alert message, but the timer will be triggered every minute. so if the first alarm triggers it waits 10 minutes before sending the alert, and the second alert receives after eleven minutes …
you have to check if the timer already exists and then interrupt.

i don´t know how it is coded correct in java but sth like this i think:

this.ScriptExecution = (this.ScriptExecution === undefined) ? Java.type("org.openhab.core.model.script.actions.ScriptExecution") : this.ScriptExecution;
this.ZonedDateTime = (this.ZonedDateTime === undefined) ? Java.type("java.time.ZonedDateTime") : this.ZonedDateTime;

var delay = function() { events.sendCommand("TempWarn", "ON"); timer = NULL}
var now = this.ZonedDateTime.now();
var timer = NULL

var Schlaf_Temp, Aussen_Temp, Vorlauf_FW_Temp;

var NotificationAction = org.openhab.io.openhabcloud.NotificationAction;

TempWarn = itemRegistry.getItem('TempWarn').getState();
Schlaf_Temp = itemRegistry.getItem('WandthermostatSchlafzimmer_Temperature').getState();
Aussen_Temp = itemRegistry.getItem('OutdoorModulWolferstadt_Temperatur').getState();
Vorlauf_FW_Temp = itemRegistry.getItem('TemperaturenHeizung_FernwarmeVorlauftemperatur').getState();
if (TempWarn == 'ON' && Vorlauf_FW_Temp < 55 && Aussen_Temp < 15 && Schlaf_Temp < 18) {
  NotificationAction.sendBroadcastNotification("Vorlauftemperatur Fernwärme unter 55°C");
  events.sendCommand("TempWarn", "OFF");
  if timer === NULL{
     timer = ScriptExecution.createTimer(now.plusMinutes(10), delay);
  }
}

now only if no timer is active a new timer will be created. when the message was sent then reset the timer and only then a new timer can be created

In the openhab.log appears the error:
2021-01-18 14:26:34.391 [ERROR] [internal.handler.ScriptActionHandler] - Script execution of rule with UID ‘f1e0e06c61’ failed: :19:5 Expected ( but found timer
if timer === NULL{
^ in at line number 19 at column number 5

Any ideas?

The correct syntax is:
if (timer === NULL) {

It works! Thank you @bastler

1 Like

sorry for that, as i said i don´t know how it is correct in java.
but good you found the solution :slight_smile:

I tried to replace the dummy switch with a boolean variable.
The result is, that the script never send an alert.
Where is the problem?

this.ScriptExecution = (this.ScriptExecution === undefined) ? Java.type("org.openhab.core.model.script.actions.ScriptExecution") : this.ScriptExecution;
this.ZonedDateTime = (this.ZonedDateTime === undefined) ? Java.type("java.time.ZonedDateTime") : this.ZonedDateTime;

var TempWarn = true
var now = this.ZonedDateTime.now();
var timer = NULL
var delay = function() { TempWarn = true; timer = NULL }

var Schlaf_Temp, Aussen_Temp, Vorlauf_FW_Temp;

var NotificationAction = org.openhab.io.openhabcloud.NotificationAction;

TempWarn = itemRegistry.getItem('TempWarn').getState();
Schlaf_Temp = itemRegistry.getItem('WandthermostatSchlafzimmer_Temperature').getState();
Aussen_Temp = itemRegistry.getItem('OutdoorModulWolferstadt_Temperatur').getState();
Vorlauf_FW_Temp = itemRegistry.getItem('TemperaturenHeizung_FernwarmeVorlauftemperatur').getState();
if (TempWarn === true && Vorlauf_FW_Temp < 55 && Aussen_Temp < 15 && Schlaf_Temp < 18) {
  NotificationAction.sendBroadcastNotification("Vorlauftemperatur Fernwärme unter 55°C");
  TempWarn = false;
  if (timer === NULL) {
     timer = ScriptExecution.createTimer(now.plusMinutes(10), delay);
  }
}

perhaps you have to declare as boolen, not var

Doesn’t matter; whatever it is it is going to get overwritten with an Item state, which not be boolean true. In previous rule versions shown, expected state was ‘ON’

when i declare this variable as boolean:
2021-01-19 12:35:58.146 [ERROR] [internal.handler.ScriptActionHandler] - Script execution of rule with UID ‘f1e0e06c61’ failed: :4:12 Expected ; but found alertDelay
var boolean alertDelay = false;
^ in at line number 4 at column number 12

it looks like the “TempWarn === true” dos not work?
i got every minute from the alert “Vorlauftemperatur …” in the log!

Yes, I also noticed this error and eliminated it.

Here the corrected script again.
It does not work with variables! why???
It seems the condition alertDelay == false is ignored and the alert is scribed every minute in the log.

var alertDelay = false;
var now = this.ZonedDateTime.now();
var timer = NULL;
var delay = function() { alertDelay = false; timer = NULL; }

var Schlaf_Temp, Aussen_Temp, Vorlauf_FW_Temp;

var NotificationAction = org.openhab.io.openhabcloud.NotificationAction;
var logger = Java.type('org.slf4j.LoggerFactory').getLogger('org.openhab.rule.' + ctx.ruleUID)

Schlaf_Temp = itemRegistry.getItem('WandthermostatSchlafzimmer_Temperature').getState();
Aussen_Temp = itemRegistry.getItem('OutdoorModulWolferstadt_Temperatur').getState();
Vorlauf_FW_Temp = itemRegistry.getItem('TemperaturenHeizung_FernwarmeVorlauftemperatur').getState();
if (alertDelay == false && Vorlauf_FW_Temp < 75 && Aussen_Temp < 15 && Schlaf_Temp < 19) {
  // NotificationAction.sendBroadcastNotification("Vorlauftemperatur Fernwärme unter 55°C");
  logger.info("Vorlauftemperatur Fernwärme unter 55°C");
  alertDelay = true;
  if (timer === NULL) {
     timer = ScriptExecution.createTimer(now.plusMinutes(5), delay);
  }
}

Which version of OH and is this a Script Action for a UI Rule or did you not show the rest of the Rule definition and it’s in a .js file?

I’ll assume OH 3 and UI Script Action.

As written, every time the Script Action runs alertDelay is set to false, timer is set to NULL (which is a mistake, should be null. So every time the script runs, any value held by those variables get overwritten and it’s as if the rule were run for the first time every time.

You have to preserve the values from the previous runs of the rule.

this.alertDelay = (this.alertDelay === undefined) ? false : this.alertDelay;
this.timer = (this.timer === undefined) ? null : this.timer;

This way if the variables are undefined, which they will be only the first time the Script Action runs, it will be initialized. If it is defined, it’s current value is used instead of the default. That way the flag and the timer will remain the same as they were the last time the Script Action ran.

A different approach to use would be to create a DateTime Item, let’s call it LastAlert. You can simply update that Item to now when you send the alert and then in the condition skip the rule if not enough time has passed.

The Script Action would be something like

var Schlaf_Temp = items["WandthermostatSchlafzimmer_Temperature"];
var Aussen_Temp = items["OutdoorModulWolferstadt_Temperatur"];
var Vorlauf_FW_Temp = items["TemperaturenHeizung_FernwarmeVorlauftemperatur"];
if(Vorlauf_FW_Temp < 75 && Aussen_Temp < 15 && Schlaf_Temp < 19) {
  logger.info("Vorlauftemperatur Fernwärme unter 55°C");
  events.postUpdate("LastUpdate", new DateTimeType().toString());
}

Then add a Script Condition which would be something like:

var ZonedDateTime = Java.type("java.time.ZonedDateTime");

now.minusMinutes(5).isBefore(items["LastUpdate"].getZonedDateTime());

Hi,
youre right, it is OH 3 and a UI Script Action.
I have added the 2 lines.
The Script always send the alert to log without the delay of 5 minutes.
Here the complete script:

this.ScriptExecution = (this.ScriptExecution === undefined) ? Java.type("org.openhab.core.model.script.actions.ScriptExecution") : this.ScriptExecution;
this.ZonedDateTime = (this.ZonedDateTime === undefined) ? Java.type("java.time.ZonedDateTime") : this.ZonedDateTime;
this.alertDelay = (this.alertDelay === undefined) ? false : this.alertDelay;
this.timer = (this.timer === undefined) ? null : this.timer;

var alertDelay = false;
var now = this.ZonedDateTime.now();
var timer = null;
var delay = function() { alertDelay = false; timer = null; }

var Schlaf_Temp, Aussen_Temp, Vorlauf_FW_Temp;

var NotificationAction = org.openhab.io.openhabcloud.NotificationAction;
var logger = Java.type('org.slf4j.LoggerFactory').getLogger('org.openhab.rule.' + ctx.ruleUID)

Schlaf_Temp = itemRegistry.getItem('WandthermostatSchlafzimmer_Temperature').getState();
Aussen_Temp = itemRegistry.getItem('OutdoorModulWolferstadt_Temperatur').getState();
Vorlauf_FW_Temp = itemRegistry.getItem('TemperaturenHeizung_FernwarmeVorlauftemperatur').getState();
if (alertDelay == false && Vorlauf_FW_Temp < 75 && Aussen_Temp < 15 && Schlaf_Temp < 19) {
  // NotificationAction.sendBroadcastNotification("Vorlauftemperatur Fernwärme unter 55°C");
  logger.info("Vorlauftemperatur Fernwärme unter 55°C");
  alertDelay = true;
  if (timer === null) {
     timer = ScriptExecution.createTimer(now.plusMinutes(5), delay);
  }
}

This is why cargo cult programming is so frustrating.

Those two lines are not magical incantations that make everything work.

As written you define ScriptExectuion, ZonedDateTime, alertDelay, and timer on this. Then you undo all that and define all those variables again in the next four lines of code and set them to default values and you are now right back where you started. Get rid of lines 6-10.