Regel von Openhab 3.5 auf 4.0 ändern

Einrichtung der openHAB Umgebung und allgemeine Konfigurationsthemen.

Moderatoren: seppy, udo1toni

N1d45
Beiträge: 123
Registriert: 5. Jan 2020 14:26
Answers: 2

Regel von Openhab 3.5 auf 4.0 ändern

Beitrag von N1d45 »

Moin.

Ich habe ein Problem, das eine Regel, die in 3.4 funktionierte, jetzt in 4.0 nicht mehr funktioniert. (Eigentlich zwei Regeln, aber erst einmal die eine Baustelle)

Es ist eine Regel, die eine Sprachausgabe auf Amazon Echos steuert, falls ich die Fenster beim Lüften vergesse zu schließen.

Über einen Timer soll nach 10 Minuten, wiederholend auf weitere 10 Minuten, auf den Echos ausgegeben werden, welche Fenster geschlossen werden sollen.

Die Ausgabe auf die Echos, habe ich schon erfolgreich angepasst. Sie funktioniert auch, wenn ich alles was mit Zeit und Timer zu tun hat, auskommentiere. Leider finde ich nicht die Information, wahrscheinlich weil ich gar nicht so richtig weiß wo und nach was ich suchen soll, im Netz nicht, wie ich es anpassen soll.

Im Moment sieht der Code noch so aus, der nicht funktioniert.

Code: Alles auswählen

var scriptExecution = Java.type('org.openhab.core.model.script.actions.ScriptExecution');
var zdt = Java.type('java.time.ZonedDateTime');
var text = '';                                // Text den Alexa ausgibt
var temperatur = 25;                          // Außentemperatur, die unterschritten sein muss, um das Skript auszuführen
var timerZeitMinuten = 10;                    // Zeit in Minuten, die der Timer laufen soll

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

function fTimerCode() {         // Code nach ablauf des Timers
  if (OpenWindows.state > 0                                                   // Wenn Fenster noch offen
      && SensEgg58_Temperatur.state < temperatur) {                           // UND wenn Temperatur noch unterschritten
    text = '';
    if (zdt.now().getHour() >= 20 || zdt.now().getHour() <= 5){
      text = text + '<amazon:effect name="whispered"> ';
      EchoKuche_SprichLautstarke.sendCommand(30);
      EchoWohnen_SprichLautstarke.sendCommand(30);
    }
    if (FensterkontaktBadezimmer_Wert1.state == 'OPEN') text = text + 'Bad <break time =\"200ms\"/>';
    if (FensterkontaktBalkon_Wert1.state == 'OPEN') text = text + 'Balkon <break time =\"200ms\"/>';
    if (FensterkontaktSchlafzimmer_Wert1.state == 'OPEN') text = text + 'Schlafzimmer <break time =\"200ms\"/>';
    if (FensterkontaktBuro_Wert1.state == 'OPEN') text = text + 'Niki <break time =\"200ms\"/>';
    if (FensterkontaktKinderzimmer_Wert1.state == 'OPEN') text = text + 'Kinder <break time =\"200ms\"/>';
    if (FensterkontaktWohnzimmer_Wert1.state == 'OPEN') text = text + 'Wohnen <break time =\"200ms\"/>';
    if (FensterkontaktKuche_Wert1.state == 'OPEN') text = text + 'Küche <break time =\"200ms\"/>';
    text = text + 'Fenster schließen';
    if (zdt.now().getHour() >= 20 || zdt.now().getHour() <= 5) text = text + '</amazon:effect>';
    if (zdt.now().getHour() <= 21 && zdt.now().getHour() >= 8) {                                           // Wenn im Zeitfenster
      EchoNici_Sprich.sendCommand(text);                                                         // Ausgabe Echo Nici
    }
    EchoWohnen_Sprich.sendCommand(text);                                                         // Ausgabe Echo Wohnen
    EchoKuche_Sprich.sendCommand(text);                                                          // Ausgabe Echo Küche
    EchoBad_Sprich.sendCommand(text);                                                            // Ausgabe Echo Bad
    EchoKuche_SprichLautstarke.sendCommand(20);
    EchoWohnen_SprichLautstarke.sendCommand(20);
    if (typeof this.timers['FensterTimer'] !== 'undefined') {                                              // Wenn Timer nicht das gleiche wie undefinierd
      this.timers['FensterTimer'].reschedule(zdt.now().plusMinutes(timerZeitMinuten));                     // Starte Timer neu 
    }
  }
//}

if (SensEgg58_Temperatur.state() < temperatur) {                                        // Nur ausführen, wenn Außentemperatur unter (Damit nicht Timer unnötig erstellt werden und die Lautstärke unnötig geändert wird)
  if (typeof this.timers['FensterTimer'] === 'undefined' || this.timers['FensterTimer'].hasTerminated()) {         // Wenn der Timer nicht definiert oder abgelaufen
    this.timers['FensterTimer'] = scriptExecution.createTimer(zdt.now().plusMinutes(timerZeitMinuten), fTimerCode) // Erstelle einen Timer und führe Funktion aus
  } 
  else {
    this.timers['FensterTimer'].reschedule(zdt.now().plusMinutes(timerZeitMinuten));                               // Setzt den Timer neu, wenn der Rule Trigger erneut auslöst und Bedingung (Temperatur) oben erfüllt ist
  }
}
Mit folgenden auskomentiert funktioniert es.

Code: Alles auswählen

// var scriptExecution = Java.type('org.openhab.core.model.script.actions.ScriptExecution');
// var zdt = Java.type('java.time.ZonedDateTime');
var text = '';                                // Text den Alexa ausgibt
var temperatur = 25;                          // Außentemperatur, die unterschritten sein muss, um das Skript auszuführen
var timerZeitMinuten = 10;                    // Zeit in Minuten, die der Timer laufen soll

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

// function fTimerCode() {         // Code nach ablauf des Timers
  if (OpenWindows.state > 0                                                   // Wenn Fenster noch offen
      && SensEgg58_Temperatur.state < temperatur) {                           // UND wenn Temperatur noch unterschritten
    text = '';
    /* if (zdt.now().getHour() >= 20 || zdt.now().getHour() <= 5){
      text = text + '<amazon:effect name="whispered"> ';
      EchoKuche_SprichLautstarke.sendCommand(30);
      EchoWohnen_SprichLautstarke.sendCommand(30);
    } */
    if (FensterkontaktBadezimmer_Wert1.state == 'OPEN') text = text + 'Bad <break time =\"200ms\"/>';
    if (FensterkontaktBalkon_Wert1.state == 'OPEN') text = text + 'Balkon <break time =\"200ms\"/>';
    if (FensterkontaktSchlafzimmer_Wert1.state == 'OPEN') text = text + 'Schlafzimmer <break time =\"200ms\"/>';
    if (FensterkontaktBuro_Wert1.state == 'OPEN') text = text + 'Niki <break time =\"200ms\"/>';
    if (FensterkontaktKinderzimmer_Wert1.state == 'OPEN') text = text + 'Kinder <break time =\"200ms\"/>';
    if (FensterkontaktWohnzimmer_Wert1.state == 'OPEN') text = text + 'Wohnen <break time =\"200ms\"/>';
    if (FensterkontaktKuche_Wert1.state == 'OPEN') text = text + 'Küche <break time =\"200ms\"/>';
    text = text + 'Fenster schließen';
    /* if (zdt.now().getHour() >= 20 || zdt.now().getHour() <= 5) text = text + '</amazon:effect>';
    if (zdt.now().getHour() <= 21 && zdt.now().getHour() >= 8) {                                           // Wenn im Zeitfenster
      EchoNici_Sprich.sendCommand(text);                                                         // Ausgabe Echo Nici
    } */
    EchoWohnen_Sprich.sendCommand(text);                                                         // Ausgabe Echo Wohnen
    EchoKuche_Sprich.sendCommand(text);                                                          // Ausgabe Echo Küche
    EchoBad_Sprich.sendCommand(text);                                                            // Ausgabe Echo Bad
    EchoKuche_SprichLautstarke.sendCommand(20);
    EchoWohnen_SprichLautstarke.sendCommand(20);
    /* if (typeof this.timers['FensterTimer'] !== 'undefined') {                                              // Wenn Timer nicht das gleiche wie undefinierd
      this.timers['FensterTimer'].reschedule(zdt.now().plusMinutes(timerZeitMinuten));                     // Starte Timer neu 
    } */
  }
//}

/* if (SensEgg58_Temperatur.state() < temperatur) {                                        // Nur ausführen, wenn Außentemperatur unter (Damit nicht Timer unnötig erstellt werden und die Lautstärke unnötig geändert wird)
  if (typeof this.timers['FensterTimer'] === 'undefined' || this.timers['FensterTimer'].hasTerminated()) {         // Wenn der Timer nicht definiert oder abgelaufen
    this.timers['FensterTimer'] = scriptExecution.createTimer(zdt.now().plusMinutes(timerZeitMinuten), fTimerCode) // Erstelle einen Timer und führe Funktion aus
  } 
  else {
    this.timers['FensterTimer'].reschedule(zdt.now().plusMinutes(timerZeitMinuten));                               // Setzt den Timer neu, wenn der Rule Trigger erneut auslöst und Bedingung (Temperatur) oben erfüllt ist
  }
} */
Wie müssten die Code Zeilen angepasst werden, damit sie mit 4.0 konform gehen?


Edit: Und hier noch der Code, der mit 3.5 noch funktioniert hat.

Code: Alles auswählen

var scriptExecution = Java.type('org.openhab.core.model.script.actions.ScriptExecution');
var zdt = Java.type('java.time.ZonedDateTime');
var text = '';                                // Text den Alexa ausgibt
var temperatur = 15;                          // Außentemperatur, die unterschritten sein muss, um das Skript auszuführen
var timerZeitMinuten = 10;                    // Zeit in Minuten, die der Timer laufen soll

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

function fTimerCode() {         // Code nach ablauf des Timers
  if (itemRegistry.getItem('OpenWindows').getState() > 0                                                   // Wenn Fenster noch offen
      && itemRegistry.getItem('SensEgg58_Temperatur').getState() < temperatur) {                           // UND wenn Temperatur noch unterschritten
    text = '';
    if (zdt.now().getHour() >= 19 || zdt.now().getHour() <= 6) text = text + '<amazon:effect name="whispered"> ';
    if (itemRegistry.getItem('FensterkontaktBadezimmer_Wert1').getState() == 'OPEN') text = text + 'Bad <break time =\"200ms\"/>';
    if (itemRegistry.getItem('FensterkontaktBalkon_Wert1').getState() == 'OPEN') text = text + 'Balkon <break time =\"200ms\"/>';
    if (itemRegistry.getItem('FensterkontaktSchlafzimmer_Wert1').getState() == 'OPEN') text = text + 'Schlafzimmer <break time =\"200ms\"/>';
    if (itemRegistry.getItem('FensterkontaktBuro_Wert1').getState() == 'OPEN') text = text + 'Niki <break time =\"200ms\"/>';
    if (itemRegistry.getItem('FensterkontaktKinderzimmer_Wert1').getState() == 'OPEN') text = text + 'Kinder <break time =\"200ms\"/>';
    if (itemRegistry.getItem('FensterkontaktWohnzimmer_Wert1').getState() == 'OPEN') text = text + 'Wohnen <break time =\"200ms\"/>';
    if (itemRegistry.getItem('FensterkontaktKuche_Wert1').getState() == 'OPEN') text = text + 'Küche <break time =\"200ms\"/>';
    text = text + 'Fenster schließen';
    if (zdt.now().getHour() >= 19 || zdt.now().getHour() <= 6) text = text + '</amazon:effect>';
    if (zdt.now().getHour() <= 21 && zdt.now().getHour() >= 8) {                                           // Wenn im Zeitfenster
      events.sendCommand('EchoNici_Sprich', text);                                                         // Ausgabe Echo Nici
    }
    events.sendCommand('EchoWohnen_Sprich', text);                                                         // Ausgabe Echo Wohnen
    events.sendCommand('EchoKuche_Sprich', text);                                                          // Ausgabe Echo Küche
    events.sendCommand('EchoBad_Sprich', text);                                                            // Ausgabe Echo Bad
    if (typeof this.timers['FensterTimer'] !== 'undefined') {                                              // Wenn Timer nicht das gleiche wie undefinierd
      this.timers['FensterTimer'].reschedule(zdt.now().plusMinutes(timerZeitMinuten));                     // Starte Timer neu 
    }
  }
}

if (itemRegistry.getItem('SensEgg58_Temperatur').getState() < temperatur) {                                        // Nur ausführen, wenn Außentemperatur unter (Damit nicht Timer unnötig erstellt werden)
  if (typeof this.timers['FensterTimer'] === 'undefined' || this.timers['FensterTimer'].hasTerminated()) {         // Wenn der Timer nicht definiert oder abgelaufen
    this.timers['FensterTimer'] = scriptExecution.createTimer(zdt.now().plusMinutes(timerZeitMinuten), fTimerCode) // Erstelle einen Timer und führe Funktion aus
  } 
  else {
    this.timers['FensterTimer'].reschedule(zdt.now().plusMinutes(timerZeitMinuten));                               // Setzt den Timer neu, wenn der Rule Trigger erneut auslöst und Bedingung (Temperatur) oben erfüllt ist
  }
}
von udo1toni » 21. Okt 2023 17:04
Ich selbst nutze JavaScript nicht, aber es gab eine wichtige Änderung, openHAB 3 nutzte Nashorn als JavaScript Engine, während openHAB 4 GraalVM anbietet (Nashorn steht allerdings immer noch zur Verfügung).
Gehe zur vollständigen Antwort

Benutzeravatar
udo1toni
Beiträge: 15247
Registriert: 11. Apr 2018 18:05
Answers: 242
Wohnort: Darmstadt

Re: Regel von Openhab 3.5 auf 4.0 ändern

Beitrag von udo1toni »

Ich selbst nutze JavaScript nicht, aber es gab eine wichtige Änderung, openHAB 3 nutzte Nashorn als JavaScript Engine, während openHAB 4 GraalVM anbietet (Nashorn steht allerdings immer noch zur Verfügung).
openHAB4.3.3 stable in einem Debian-Container (bookworm) (Proxmox 8.3.5, LXC), mit openHABian eingerichtet

N1d45
Beiträge: 123
Registriert: 5. Jan 2020 14:26
Answers: 2

Re: Regel von Openhab 3.5 auf 4.0 ändern

Beitrag von N1d45 »

udo1toni hat geschrieben: 21. Okt 2023 17:04 ...
Nashorn steht allerdings immer noch zur Verfügung.
...
Kann/Muß man das irgendwie aktivieren?

Edit: Tausend Dank. Ich habe es gefunden. Unter Automation und instalieren. Und dann natürlich wieder als ECMAScript (ECMA - 262 Edition 5.1) laufen lassen.

Benutzeravatar
udo1toni
Beiträge: 15247
Registriert: 11. Apr 2018 18:05
Answers: 242
Wohnort: Darmstadt

Re: Regel von Openhab 3.5 auf 4.0 ändern

Beitrag von udo1toni »

:)

Allerdings möchte ich empfehlen, Dich dennoch mit der Umstellung zu beschäftigen (aber ohne den Druck, das "sofort" lauffähig zu haben).
openHAB4.3.3 stable in einem Debian-Container (bookworm) (Proxmox 8.3.5, LXC), mit openHABian eingerichtet

N1d45
Beiträge: 123
Registriert: 5. Jan 2020 14:26
Answers: 2

Re: Regel von Openhab 3.5 auf 4.0 ändern

Beitrag von N1d45 »

Gibt es da ein Beispiel für Timer, erstellen, erneuern (Verlängerung bzw. neu Setzen), und löschen?

Gibt es ein Beispiel für Funktionen? Weil das

Code: Alles auswählen

function fTest(){ 
  … 
}
gefiel dem System auch irgendwie nicht mehr.

gethour habe ich schon erfolgreich in einem Test lösen können.

Danke für die Ermutigung. Bin ja froh das es wieder wie gewohnt läuft. Da ist man schnell dabei es zu lassen.

Harka
Beiträge: 489
Registriert: 30. Apr 2021 13:13
Answers: 19

Re: Regel von Openhab 3.5 auf 4.0 ändern

Beitrag von Harka »

Moin,
die Funktion als solche ist nicht das Problem. Änderungen solltest Du bei scriptExecution, zdt und dem Timer suchen. z.B reicht jetzt ein var zdt = time.ZonedDateTime;
Eine Übersicht findest Du unter https://www.openhab.org/addons/automation/jsscripting/ und aktuell auch hier.
Für die wiederkehrenden Timer ist setInterval imho die bessere Lösung.

N1d45
Beiträge: 123
Registriert: 5. Jan 2020 14:26
Answers: 2

Re: Regel von Openhab 3.5 auf 4.0 ändern

Beitrag von N1d45 »

Danke.
Und ein Weg ohne JavaSkript?
In Rules DSL.
Gibt es ein Link dazu? Irgendwie such ich immer falsch.

Edit: Ich denke ich habe etwas gefunden https://www.openhab.org/docs/configurat ... elays.html

Blockly erstellt doch auch nur Rules DSL im Hintergrund?

Ich probiere mich mal.

Harka
Beiträge: 489
Registriert: 30. Apr 2021 13:13
Answers: 19

Re: Regel von Openhab 3.5 auf 4.0 ändern

Beitrag von Harka »

Sehe gerade, Du nutzt ja auch noch itemRegistry.getItem. Ist auch veraltet.
Wenn es Dir nur um mehr Unterstützung geht - Blockly erzeugt nun auch den neuen Code (wenn auch manchmal nicht den schönsten, aber die Anforderungen sind ja auch andere). Diesen kannst Du dann in Deine Rules übernehmen.
E: Achtung, beim wiederholenden Timer ist in Blockly gerade ein Fehler enthalten

N1d45
Beiträge: 123
Registriert: 5. Jan 2020 14:26
Answers: 2

Re: Regel von Openhab 3.5 auf 4.0 ändern

Beitrag von N1d45 »

Hmm. Ich habe jetzt gut zwei Stunden rumprobiert. Aber die Rules geben im Log immer einen Fehler aus. Selbst mit Blockly erstellt. Irgendwie fehlt mir eine Anzeige, was ich falsch geschrieben habe. Oder warum der Error eigentlich erfolgt. Ich bin es von C++ gewöhnt das mir der Compiler sagt, in welcher Zeile er ein Problem sieht und was für ein Problem er hat. Gibt es hier in openHAB so etwas wie ein Prüfprogramm, was aufzeigen kann, was in der Syntax falsch ist?

Wahrscheinlich brauche ich ein Buch der jeweiligen Sprache. Naja, ich sehe das Experiment gescheitert.

Harka
Beiträge: 489
Registriert: 30. Apr 2021 13:13
Answers: 19

Re: Regel von Openhab 3.5 auf 4.0 ändern

Beitrag von Harka »

nix da! ;-)
Jetzt habe ich das Teil mal zur Fehlerbereinigen eines Blocks "Marke Eigenbau" benutzt und dabei ist folgendes Beispiel bei raus gekommen. Da, wo bei mir Bewegung 1 u.s.w. steht, kommen bei Dir die Kontakte hin und bei console.warn die Alexaausgabe.

Code: Alles auswählen

var nameTimer, WarteZeit, temperatur, text, iCounter;

nameTimer = 'FensterTimer';
WarteZeit = 10*60; 
temperatur = 15;
iCounter = 0;  

if (typeof(this[nameTimer]) != 'undefined') clearInterval(this[nameTimer]); 

this[nameTimer] = setInterval(function() {

  if (items.getItem('FensterGruppeTest').numericState > 0 && items.getItem('TemperaturTest').numericState < temperatur) {
    text = '';
	
    if (items.getItem('Bewegung_1').state == 'ON')  text += 'erster Text'; // hier die Kontakte und Alexas
    if (items.getItem('Bewegung_2').state == 'ON')  text += 'zweiter Text';
    console.warn(text);
	
  } else {
    if (typeof(this[nameTimer]) != 'undefined') clearInterval(this[nameTimer]);
  }
  iCounter++;
  
  if iCounter >= 10) clearInterval(this[nameTimer]); // max 10 Wiederholungen a 10 Minuten
}, WarteZeit*1000);

Antworten