Temperatur Vergleich mit Nummer

Einrichtung der openHAB Umgebung und allgemeine Konfigurationsthemen.

Moderatoren: seppy, udo1toni

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

Temperatur Vergleich mit Nummer

Beitrag von N1d45 »

Ich bekomme schon wieder etwas nicht hin, wo ich mir eigentlich vorgestellt habe das es einfach sein sollte.

Wie in diesem Thread zu sehen, möchte ich die Öffnung der Fenster überwachen, und mich warnen lassen, wenn sie zu lange auf sind.

Jetzt wollte ich das noch Temperatur abhängig machen. Also z.B. nur ausführen, wenn die Außentemperatur unter 15°C liegt.
Jetzt habe ich schon einiges mit Blockly probiert, aber der Vergleich der Temperatur mit einem Wert liefert nicht true, obwohl er in meinen Augen true sein sollte.

Das Problem liegt, so denke ich, dass der Wert vom Item als String geliefert wird. Nach einigem googeln, habe ich rausgelesen, das man eine Variable erstellen sollte, damit man diese mit einer Zahl vergleichen kann. Aber leider funktioniert dies auch nicht.

Das Item selber ist als reine Nummer angelegt. Ist kein UoM.

Code: Alles auswählen

var Temperatur;

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

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

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


Temperatur = itemRegistry.getItem('SensEgg58_Temperatur').getState();
if (typeof this.timers['WohnzimmerFensterTimer'] === 'undefined' || this.timers['WohnzimmerFensterTimer'].hasTerminated()) {
  this.timers['WohnzimmerFensterTimer'] = scriptExecution.createTimer(zdt.now().plusSeconds(10), function () {
    if (itemRegistry.getItem('FensterkontaktWohnzimmer_Wert1').getState() == 'OPEN' && Temperatur < 15) {
      events.sendCommand('EchoWohnen_Sprich', 'Wohnzimmer Fenster schließen');
      if (typeof this.timers['WohnzimmerFensterTimer'] !== 'undefined') { this.timers['WohnzimmerFensterTimer'].reschedule(zdt.now().plusSeconds(10)); }
    }
    })
} else {
  this.timers['WohnzimmerFensterTimer'].reschedule(zdt.now().plusSeconds(10));
}
FensterAlarm.png
Wie macht so einen Vergleich richtig?

Ist dies eigentlich der richtige Forum Bereich um Fragen zu Regeln zu stellen?

Die Forums Suche ist leider etwas störrisch, den die Suchbegriffe werden ignoriert, da sie zu oft vorkommen. Nur fielen mir keine anderen passenden Stichworte ein. Ich bin mir auch sicher, dass ich nicht der erste bin, der einen Vergleich mit einem Temperaturwert anstellen will.

Ein Link zu einem Thema, wo es behandelt wird, wäre auch super.

Vielen Dank.
von N1d45 » 1. Okt 2022 20:25
Wäre ich doch mal selber auf die Idee mit dem Log gekommen. Aber nach eurem Feeback war mir schon klar das der Fehler auf meiner Seite liegt. Es war der Falsche Trigger für die Regel gewählt. Muss ich beim rumprobieren falsch gewählt haben. Denn ohne Temperatur funktionierte es bereits. Im Log kam keinerlei Ausgabe. Die Regel wurde also gar nicht gestartet.

Das Problem ist, das ich ein Equipment erstellt habe, das Fensterkontakt_Wohnzimmer heißt. Darin ist das Item für den Fensterkontakt hinterlegt, namens FensterkontaktWohnzimmer_Wert1. Natürlich muss man dann als Trigger dieses Item nehmen für den Change. Das ärgert mich gerade Total :x

Selbst der Vergleich des getStateItems mit einem Text vom Wert "15" funktioniert.
FensterAlarm.png

Code: Alles auswählen

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

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

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


if (typeof this.timers['WohnzimmerFensterTimer'] === 'undefined' || this.timers['WohnzimmerFensterTimer'].hasTerminated()) {
  this.timers['WohnzimmerFensterTimer'] = scriptExecution.createTimer(zdt.now().plusSeconds(10), function () {
    if (itemRegistry.getItem('FensterkontaktWohnzimmer_Wert1').getState() == 'OPEN' && itemRegistry.getItem('SensEgg58_Temperatur').getState() < '15') {
      events.sendCommand('EchoWohnen_Sprich', 'Wohnzimmer Fenster schließen');
      if (typeof this.timers['WohnzimmerFensterTimer'] !== 'undefined') { this.timers['WohnzimmerFensterTimer'].reschedule(zdt.now().plusSeconds(10)); }
    }
    })
} else {
  this.timers['WohnzimmerFensterTimer'].reschedule(zdt.now().plusSeconds(10));
}
Ich habe jetzt auch noch einmal Versucht das gestrige Problem zu rekonstruieren, das es nur mit dem Fensterkontaktwert funktioniert und mit dem hinzufügen des Temperaturvergleiches dann nicht mehr, und mit dem Entfernen des Temperaturvergleiches funktionierte es wieder. Aber ich bekomme es nicht rekonstruiert. Keine Ahnung was ich da gestern angestellt hatte.

Ich entschuldige mich für die Verwirrung.

Danke für eure Hilfe!
Gehe zur vollständigen Antwort
Du hast keine ausreichende Berechtigung, um die Dateianhänge dieses Beitrags anzusehen.

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

Re: Temperatur Vergleich mit Nummer

Beitrag von Harka »

Moin,
versuch mal mit Temperatur zu rechnen bevor Du es mit 15 vergleichst ( z.B. Temperatur * 1 < 15 ).

Ich selbst nutze die Parse-Funktion von guinnes um Strings zuverlässig in Zahlenwerte umzuwandeln. Da stören die angehängten Einheiten auch nicht mehr.

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

Re: Temperatur Vergleich mit Nummer

Beitrag von N1d45 »

Danke.
Ich habe mit der Temperatur gerechnet. Funktioniert leider auch nicht.
FensterAlarm.png

Code: Alles auswählen

var Temperatur;

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

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

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


Temperatur = itemRegistry.getItem('SensEgg58_Temperatur').getState();
Temperatur = Temperatur * 1;
if (typeof this.timers['WohnzimmerFensterTimer'] === 'undefined' || this.timers['WohnzimmerFensterTimer'].hasTerminated()) {
  this.timers['WohnzimmerFensterTimer'] = scriptExecution.createTimer(zdt.now().plusSeconds(10), function () {
    if (itemRegistry.getItem('FensterkontaktWohnzimmer_Wert1').getState() == 'OPEN' && Temperatur < 15) {
      events.sendCommand('EchoWohnen_Sprich', 'Wohnzimmer Fenster schließen');
      if (typeof this.timers['WohnzimmerFensterTimer'] !== 'undefined') { this.timers['WohnzimmerFensterTimer'].reschedule(zdt.now().plusSeconds(10)); }
    }
    })
} else {
  this.timers['WohnzimmerFensterTimer'].reschedule(zdt.now().plusSeconds(10));
}
FensterAlarm.png
Du hast keine ausreichende Berechtigung, um die Dateianhänge dieses Beitrags anzusehen.

int5749
Beiträge: 1173
Registriert: 4. Nov 2019 22:08
Answers: 9

Re: Temperatur Vergleich mit Nummer

Beitrag von int5749 »

Also eine Variable sollte eigentlich nicht extra notwendig sein.
Es sollte eigentlich direkt mit

Code: Alles auswählen

if((Temperatur.state as DecimalType) < 15)
funktionieren, sofern Dein Item-String keine führenden/endenden Leerzeichen enthält.
Ansonsten könnte es noch ge-parsed werden.

Code: Alles auswählen

if(Integer::parseInt(Temperatur.state) < 15)
If it does have a decimal point use

Code: Alles auswählen

Double::parseDouble() instead
gefunden => hier und bereits an Dein Item angepasst.
openHAB 4.1.0 Release mit openHABian in einem Debian Bookworm (LXC) unter Proxmox 8.1.3

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

Re: Temperatur Vergleich mit Nummer

Beitrag von N1d45 »

Danke. Bin gerade nicht zuhause zum probieren.

Dazu muss ich die Regel textbasierend anlegen, richtig?

Gibt es einen Weg in Blockly?

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

Re: Temperatur Vergleich mit Nummer

Beitrag von Harka »

mmm, ich sehe die Ursache nicht. Bei der Fehlersuche hilft meist ein Blick ins Log weiter ( IPvonOpenHAB:9001/ ) und das gezielte "spielen" damit erst recht. Wenn Du die Log-Ausgaben vom Beispiel vor dem Timer einbaust sollte für eine Echo-Ansage 11, true, false, true raus kommen.
Log2.jpg
Du hast keine ausreichende Berechtigung, um die Dateianhänge dieses Beitrags anzusehen.

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

Re: Temperatur Vergleich mit Nummer

Beitrag von N1d45 »

Danke. Ich werde heute Abend, spätestens Morgen früh mich ransetzen und die Log-Ausgaben einfügen.

Wenn noch jemanden vorab noch etwas offensichtliches auffällt, immer raus damit.

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

Re: Temperatur Vergleich mit Nummer

Beitrag von udo1toni »

Ich möchte einen Schritt zurückgehen.
Wie ist das Item SensEgg58_Temperatur definiert?
Handelt es sich um ein String Item? Das ist von vornherein verkehrt. Alle Channel, welche Messwerte in Zahlenform liefern, können als Number weiterverarbeitet werden. Blockly wird dann den Wert automatisch als Zahl betrachten.
Da es sich um eine Temperatur handelt, könnte es auch sein, dass das Item vom Typ Number:Temperature ist. Dann handelt es sich um ein UoM Item, welches also nicht nur den Zahlenwert, sondern auch die zugehörige Einheit mitbringt.
Diese muss dann beim Vergleich mit angegeben werden. Alternativ kann man die Einheit auch vorher entfernen.
UoM ist allerdings durchaus hilfreich, weil es keine Rolle spielt, wie ein Messwert angeliefert wird, z.B. Temperatur in °C, in °F oder gar in K? Spielt keine Rolle. Wenn ich mit °C vergleiche, kümmert sich openHAB darum, dass der gelieferte Messwert passend interpretiert wird.
openHAB4.3.5 stable in einem Debian-Container (bookworm) (Proxmox 8.4.1, LXC), mit openHABian eingerichtet

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

Re: Temperatur Vergleich mit Nummer

Beitrag von udo1toni »

Ich wusste, ich wollte noch was dazu schreiben...

Wenn Du die Temperatur vergleichen willst, so musst Du das immer mit dem aktuellen Wert tun. Eine Variable wird nicht von einem Preprocessor durch das ersetzt, was hinten dran steht. Die Variable verweist auf eine Speicherzelle, bei der Zuweisung einer Funktion wird der aktuelle Wert der Funktion in die Speicherzelle geschrieben, kein Verweis auf die Funktion. Wenn Du also eine Schleife programmierst (ein Timer, der sich selbst aufruft ist ebenfalls eine Schleife), dann musst Du unbedingt den Wert innerhalb der Schleife zuweisen, wenn Du eine Variable verwendest.
Außerdem muss der Timer so lange immer wieder durchlaufen werden, bis das Fenster geschlossen wurde. Lediglich die Wernmeldung muss nur ausgegeben werden, wenn ide Temperatur zu niedrig ist.
Als DSL Rule:

Code: Alles auswählen

var Timer tFenster = null

rule "fenster geöffnet"
when
    Item FensterkontaktWohnzimmer_Wert1 changed
then
    tFenster?.cancel
    if(newState == OPEN)
        tFenster = createTimer(now.plusMinutes(10), [|
            val nTemp = (SensEgg58_Temperatur.state as Number).floatValue
            if(nTemp < 15)
                EchoWohnen_Sprich.sendCommand('Wohnzimmer Fenster schließen')
            tFenster.reschedule(now.plusMinutes(10))
        ])
end
Schönes Beispiel, warum DSL Code oft einfacher ist , als durch Blockly generierter ECDA Code.
Die Rule triggert, wenn sich der Zustand des Fensterkontakts ändert.
Die Rule bricht einen eventuell vorhandenen Timer ab.
Falls der Kontakt OPEN meldet, legt sie einen Timer an, der nach zehn Minuten seinen Code ausführt.
Damit ist die Rule beendet.

Startet der Timer, muss das Fenster noch offen sein (denn die Rule hätte den Timer sonst abgebrochen).
Es reicht also, die Temperatur zu vergleichen und gegebennfalls die Warnung auszugeben.
Zum Schluss wird der Timer erneut geplant (wir erinnern uns - das Fenster ist definitiv offen)-
Wir benötigen hier keinerlei geschweifte Klammern, denn die if-Anweisungen gelten immer nur für einen Befehl. Beim ersten if ist der Befehl createTimer, beim zweiten if (innerhalb des Timer Codes) ist es das sendCommand.
openHAB4.3.5 stable in einem Debian-Container (bookworm) (Proxmox 8.4.1, LXC), mit openHABian eingerichtet

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

Re: Temperatur Vergleich mit Nummer

Beitrag von N1d45 »

udo1toni hat geschrieben: 1. Okt 2022 12:22 ...
Handelt es sich um ein String Item? Das ist von vornherein verkehrt. Alle Channel, welche Messwerte in Zahlenform liefern, können als Number weiterverarbeitet werden. Blockly wird dann den Wert automatisch als Zahl betrachten.
Da es sich um eine Temperatur handelt, könnte es auch sein, dass das Item vom Typ Number:Temperature ist. Dann handelt es sich um ein UoM Item, welches also nicht nur den Zahlenwert, sondern auch die zugehörige Einheit mitbringt.
...
Nein
N1d45 hat geschrieben: 1. Okt 2022 08:09 ...
Das Item selber ist als reine Nummer angelegt. Ist kein UoM.
...
Ich hatte sogar oben ein Bildschirmfoto vom Item angehängt, was zeigt das es eine Nummer ist.
Ich habe nur einen MetaData erzeugt. State Description. Wo ich ein Pattern %.1f °C anwende. Wenn ich mich recht Entsinne wirkt das nur auf die Anzeige.
Auf dem Bildschirmfoto vom Item, sieht man auch das der Wert des Items rein aus 11.2 besteht.

Was auf jedenfall nicht in Blockly geht, get state of item item SensEgg58_Temperatur direkt mit einem Zahlenwert zu vergleichen. Dies lässt sich nur mit einem Text vergleichen. Die Zahl lässt sich nicht verknüpfen. Dafür hatte ich aber in einem englischen Forum gefunden, das man den Wert einer Variable zuweisen soll, so das man dann mit einer Nummer vergleichen kann. Dies lässt sich dann auch in Blockly zusammenfügen.
https://community.openhab.org/t/blockly ... ber/130909
https://community.openhab.org/t/oh3-blo ... r/116517/2

OK, da es so eigentlich funktionieren sollte, und dennoch bei mir nicht funktioniert, werde ich mal mit dem log auf die Pirsch gehen, warum der Inhalt von If nicht ausgeführt wird. Also muss ja einer der beiden Werte nicht true sein. Die Items selber hatten aber den Wert OPEN und 11.2
Eine Sprachausgabe auf dem Echo Dot erfolgte nicht. Ein reine Abfrage des Zustandes OPEN, ohne die AND Abfrage der Temperatur, lässt den Echo Dot aber richtig ansagen. Daher die Vermutung das der Vergleich zwischen Wert des Items der Temperatur und 15, nicht true sondern false ausgibt.

Bin gespannt was die log-Ausgaben ausgeben. Dazu komme ich aber erst, wenn ich wieder Daheim bin.

Danke
udo1toni hat geschrieben: 1. Okt 2022 12:59 ...
Schönes Beispiel, warum DSL Code oft einfacher ist , als durch Blockly generierter ECDA Code.
Die Rule triggert, wenn sich der Zustand des Fensterkontakts ändert.
Die Rule bricht einen eventuell vorhandenen Timer ab.
Falls der Kontakt OPEN meldet, legt sie einen Timer an, der nach zehn Minuten seinen Code ausführt.
Damit ist die Rule beendet.

Startet der Timer, muss das Fenster noch offen sein (denn die Rule hätte den Timer sonst abgebrochen).
Es reicht also, die Temperatur zu vergleichen und gegebennfalls die Warnung auszugeben.
Zum Schluss wird der Timer erneut geplant (wir erinnern uns - das Fenster ist definitiv offen)-
Wir benötigen hier keinerlei geschweifte Klammern, denn die if-Anweisungen gelten immer nur für einen Befehl. Beim ersten if ist der Befehl createTimer, beim zweiten if (innerhalb des Timer Codes) ist es das sendCommand.
Irgendwo hatte ich gelesen (oder gehört in einem Video). das die DSL Regeln langsam währen und man deshalb ECDA Code nehmen sollte. Als Unerfahrener kann man das natürlich nicht gewichten und einschätzen. Danke für das Beispiel als DSL Rule.

Die geschweiften If-Klammern schaden aber auch nicht. Ist ja in c++ auch so. Oder ist das hier anders?

Antworten