Run Script with timer from multiple rules

Hi,
I have multiply rules for each floor heating in each room:

  • Rule 1: Floor heating living room
  • Rule 2: Floor heating bathroom
  • Rule 3: Floor heating guestroom
  • Rule 4: Floor heating bathroom

Each rule is triggered by the “same” items.
This triggers a blockly script (every time the same).
Here an example for the living room:

The script “33e8ea3d88” is my “Universal heating script”. It’s written in blockly and here is the code:

var text, GROUP, SOLL, FENSTER_TIME, IST, FENSTER, VENTIL, AKTIV, OFF_TEMP, HYST_STATE, HYST, TIMER_STATE;

if (typeof this.timers === 'undefined') {
  this.timers = [];
}

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

// Describe this function...
function log(text) {
  logger.info(([GROUP,': ',text].join('')));
}

// Describe this function...
function Init() {
  GROUP = ctx['group'];
  SOLL = itemRegistry.getItem(([GROUP,'_','Solltemperatur'].join(''))).getState();
  IST = itemRegistry.getItem(([GROUP,'_','Isttemperatur'].join(''))).getState();
  FENSTER = itemRegistry.getItem(([GROUP,'_','Fensterstatus'].join(''))).getState();
  VENTIL = [GROUP,'_','Ventil'].join('');
  AKTIV = itemRegistry.getItem(([GROUP,'_','Aktiv'].join(''))).getState();
  HYST_STATE = GROUP.lastIndexOf('_') + 1;
  HYST_STATE = GROUP.slice(0, HYST_STATE - 1);
  HYST_STATE = [HYST_STATE,'_','Hysterese'].join('');
  HYST = itemRegistry.getItem(HYST_STATE).getState();
  if (HYST == 'NULL') {
    events.sendCommand(HYST_STATE, 0.5);
    HYST = 0.5;
  }
  TIMER_STATE = GROUP.lastIndexOf('_') + 1;
  TIMER_STATE = GROUP.slice(0, TIMER_STATE - 1);
  TIMER_STATE = [TIMER_STATE,'_','FensterTimer'].join('');
  FENSTER_TIME = itemRegistry.getItem(TIMER_STATE).getState();
  if (FENSTER_TIME == 'NULL') {
    events.sendCommand(TIMER_STATE, 15);
    FENSTER_TIME = 15;
  }
  OFF_TEMP = SOLL + HYST;
}

var scriptExecution = Java.type('org.openhab.core.model.script.actions.ScriptExecution');

var zdt = Java.type('java.time.ZonedDateTime');

// Describe this function...
function Fensterstatus() {
  if (typeof this.timers['FensterTimer'] === 'undefined' || this.timers['FensterTimer'].hasTerminated()) {
    this.timers['FensterTimer'] = scriptExecution.createTimer(zdt.now().plusMinutes(FENSTER_TIME), function () {
      log('Fenster sind nicht geschloßen. Schalte Heizung ab.');
      events.sendCommand(VENTIL, 'OFF');
      })
  } else {
    // do nothing
  }
}


Init();
log('Änderung ausgelöst durch: ' + String(ctx['trigger']));
log('Timer: ' + String(FENSTER_TIME));
// Wenn die Heizung nicht aktiv ist, dann Schalte das Ventil immer aus.
if (AKTIV != 'ON') {
  if (itemRegistry.getItem(VENTIL).getState() != 'OFF') {
    log('Schalte Heizung aus.');
    events.sendCommand(VENTIL, 'OFF');
    if (typeof this.timers['FensterTimer'] !== 'undefined') {
      this.timers['FensterTimer'].cancel();
      this.timers['FensterTimer'] = undefined;
    }
  }
} else {
  if (FENSTER != 'CLOSED') {
    log('Fenster sind nicht geschloßen -> Starte Timer.');
    Fensterstatus();
  } else {
    if (IST >= OFF_TEMP) {
      log(['Solltemperatur erreicht. Schalte Heizung ab. ',IST,'/',SOLL].join(''));
      events.sendCommand(VENTIL, 'OFF');
      if (typeof this.timers['FensterTimer'] !== 'undefined') {
        this.timers['FensterTimer'].cancel();
        this.timers['FensterTimer'] = undefined;
      }
    }
    if (IST < OFF_TEMP) {
      log(['Solltemperatur unterschritten. Schalte Heizung ein. ',IST,'/',SOLL].join(''));
      events.sendCommand(VENTIL, 'ON');
      if (typeof this.timers['FensterTimer'] !== 'undefined') {
        this.timers['FensterTimer'].cancel();
        this.timers['FensterTimer'] = undefined;
      }
    }
  }
}

Now my problem is, when on room is triggered by “Fensterstatus” the timer is started. Now in another room a trigger is fired the timer from the first room is aborted.

Also when I set the “Aktiv”-item for more then on room at the same time I get these error:

[ERROR] [e.automation.internal.RuleEngineImpl] - Failed to execute rule ‘33e8ea3d88' with status 'RUNNING'

So my question is:
Is it not possible to use a “universal script” which is triggered from multiply rules?

Include the room name into your timer name (instead of giving it a fixed name “FensterTimer” call it eg “FensterTimer_”+ctx[‘group’])

Hi,
now I have named the timer FensterTimer-[RoomName] where [RoomName] is the name of the room.

timer

No the following is happening:

  • I open a window in the living room. The timer “FensterTimer_Wohnzimmer” is started.
  • I open a window in the bathroom. The timer “FensterTimer_Badezimmer” is started.
  • After the configured time the timer “FensterTimer_Badezimmer” as finished and make his actions.
  • A little bite later (the time I need to go from one windows to the other) the “FensterTimer_Badezimmer” finished the second time.

It look’s like the second run from my script is killing the “FensterTimer_Wohnzimmer” and rerun it as “FensterTimer_Badezimmer”.

2022-12-29 15:10:31.912 [INFO ] [org.openhab.rule.33e8ea3d88         ] - gHeizung_Wohnzimmer: Änderung ausgelöst durch: gHeizung_Wohnzimmer_Fensterstatus

2022-12-29 15:10:31.918 [INFO ] [org.openhab.rule.33e8ea3d88         ] - gHeizung_Wohnzimmer: Fenster sind nicht geschloßen -> Starte Timer (FensterTimer_Wohnzimmer).

2022-12-29 15:10:41.009 [INFO ] [org.openhab.rule.33e8ea3d88         ] - gHeizung_Badezimmer: Änderung ausgelöst durch: gHeizung_Badezimmer_Fensterstatus

2022-12-29 15:10:41.009 [INFO ] [org.openhab.rule.33e8ea3d88         ] - gHeizung_Badezimmer: Fenster sind nicht geschloßen -> Starte Timer (FensterTimer_Badezimmer).

2022-12-29 15:11:31.928 [INFO ] [org.openhab.rule.33e8ea3d88         ] - gHeizung_Badezimmer: Fenster-Timer (FensterTimer_Badezimmer) ausgelöst -> Schalte Heizung ab.

2022-12-29 15:11:41.011 [INFO ] [org.openhab.rule.33e8ea3d88         ] - gHeizung_Badezimmer: Fenster-Timer (FensterTimer_Badezimmer) ausgelöst -> Schalte Heizung ab.

That’s because the variables used within the timer are changing in between.

You would need to pass them as additional arguments so that they will not change between scheduling and execution of the time

Thank you,
I changed my FensterStatus-Function to get the VENTIL- and the TIMER-NAME-Var as argument. Now everything is working.