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?