Regel ausführen bei Werteänderung, die von einem bestimmten Sender ausgelöst wurde

Einrichtung der openHAB Umgebung und allgemeine Konfigurationsthemen.

Moderatoren: seppy, udo1toni

Antworten
Benutzeravatar
RES
Beiträge: 33
Registriert: 20. Aug 2020 14:38
Answers: 0
Wohnort: Innsbruck
Kontaktdaten:

Regel ausführen bei Werteänderung, die von einem bestimmten Sender ausgelöst wurde

Beitrag von RES »

Guten Tag.

Ich verwende eine Regel wie diese:

Code: Alles auswählen

var Timer timer_Sensor_Haupteingang_Tuere_Dimmer_Eingang = null

rule "Sensor_Haupteingang_Tuere_Dimmer_Eingang"
when
 Item Sensor_Haupteingang_Tuere changed to OPEN
then
 if(timer_Sensor_Haupteingang_Tuere_Dimmer_Eingang !== null) {
  timer_Sensor_Haupteingang_Tuere_Dimmer_Eingang.cancel
  timer_Sensor_Haupteingang_Tuere_Dimmer_Eingang = null
 }
 Dimmer_Eingang.sendCommand(20)
 timer_Sensor_Haupteingang_Tuere_Dimmer_Eingang = createTimer(now.plusSeconds(300)) [|
  Dimmer_Eingang.sendCommand(0)
 ]
end
Ich würde nun gerne erreichen, dass der Timer deaktiviert wird, wenn der Dimmer während der Laufzeit des Timers manuell betätigt wird. Ich kann nicht die Änderung des Werts in "Dimmer_Eingang" als Auslöser verwenden, da ich den Wert mit den Regeln selbst verändere.

Gibt es eine Möglichkeit, ein "when/then" nur dann auszuführen, wenn eine Datenänderung von einem bestimmten Gerät (nicht von der Regel selbst) erfolgt ist?

Vielen Dank für Eure Bemühungen.
von udo1toni » 27. Dez 2020 14:27
Ich muss vorneweg schicken, dass ich selbst kein zwave verwende. Ich gehe aber davon aus, dass es wie bei anderne Bindings auch einen Unterschied zwischen UI und Binding indizierten Änderungen gibt. Über die UI wird immer ein sendCommand Befehl gesendet, erfolgt eine Änderung innerhalb zwave, gibt es nur ein update. Auch wenn Du in der Rule den Dimmerwert änderst, arbeitest Du immer mit sendCommand. Eine mögliche Variante sähe also ungefähr so aus:

Code: Alles auswählen

var Timer tDimmEin = null

rule "Dimmer Eingang received command"
when
    Item Dimmer_Eingang received command
then
    tDimmEin?.cancel
    tDimmEin = createTimer(now.plusMillis(500),[|
        tDimmEin = null
    ])
end

rule "Dimmer Eingang change"
when
    Item Dimmer_Eingang changed
then
    if(tDimmEin !== null)
        return;
    timer_Sensor_Haupteingang_Tuere_Dimmer_Eingang?.cancel
end
Ich bevorzuge kurze Variablennamen :)

Das ganze Konstrukt arbeitet etwas indirekt. Die erste Rule (received command) triggert nur, wenn der Dimmer einen Befehl aus openHAB heraus bekommt. Nur in diesem Fall wird der Timer tDimmEin gestartet. Der Befehl tDimmEin?.cancel bedeutet: breche den Timer ab, falls er existiert, das sind also 3 Zeilen Code...
Wenn der Timer nach eine halben Sekunde abläuft, tut der Code nichts anderes, als die Timer Variable zu leeren.
Die zweite Rule (changed) triggert immer, wenn sich der Wert des Items ändert, also gewöhnlich, wenn der Dimmer einen neuen Wert meldet.
Die Rule prüft, ob der Timer tDimmEin existiert (!== null) und bricht ab, falls das zutrifft. Ansonsten cancelt sie den eigentlichen Timer, falls dieser existiert.
Ich habe hier 500 Millisekunden für tDimmEin angesetzt, Du musst aber vermutlich hier einen wesentlich höheren Wert ansetzen, da der Dimmwert von zwave vermutlich erst gegen Ende des Dimmvorgangs gemeldet wird, und vermutlich wird der Dimmer "weich" dimmen. Die Totzeit (von tDimmEin vorgegeben) muss also mindestens die Zeitspanne abdecken, die Dimmer_Eingang benötigt, um von 0 auf 20% zu dimmen, plus einige hundert Millisekunden zur Sicherheit.
Gehe zur vollständigen Antwort
--
Rudolf E. Steiner
res-1@communicate.at

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

Re: Regel ausführen bei Werteänderung, die von einem bestimmten Sender ausgelöst wurde

Beitrag von udo1toni »

Es kommt darauf an, welches Binding Du verwendest.
openHAB4.3.5 stable in einem Debian-Container (bookworm) (Proxmox 8.4.1, LXC), mit openHABian eingerichtet

Benutzeravatar
RES
Beiträge: 33
Registriert: 20. Aug 2020 14:38
Answers: 0
Wohnort: Innsbruck
Kontaktdaten:

Re: Regel ausführen bei Werteänderung, die von einem bestimmten Sender ausgelöst wurde

Beitrag von RES »

udo1toni hat geschrieben: 27. Dez 2020 01:43 Es kommt darauf an, welches Binding Du verwendest.
Als Binding wird in diesem Fall Z-Wave verwendet. Ich möchte den Timer also stoppen, wenn eine Änderung des Werts "Dimmer_Eingang" durch "zwave:device:77f222ed:node9" erfolgt.
--
Rudolf E. Steiner
res-1@communicate.at

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

Re: Regel ausführen bei Werteänderung, die von einem bestimmten Sender ausgelöst wurde

Beitrag von udo1toni »

Ich muss vorneweg schicken, dass ich selbst kein zwave verwende. Ich gehe aber davon aus, dass es wie bei anderne Bindings auch einen Unterschied zwischen UI und Binding indizierten Änderungen gibt. Über die UI wird immer ein sendCommand Befehl gesendet, erfolgt eine Änderung innerhalb zwave, gibt es nur ein update. Auch wenn Du in der Rule den Dimmerwert änderst, arbeitest Du immer mit sendCommand. Eine mögliche Variante sähe also ungefähr so aus:

Code: Alles auswählen

var Timer tDimmEin = null

rule "Dimmer Eingang received command"
when
    Item Dimmer_Eingang received command
then
    tDimmEin?.cancel
    tDimmEin = createTimer(now.plusMillis(500),[|
        tDimmEin = null
    ])
end

rule "Dimmer Eingang change"
when
    Item Dimmer_Eingang changed
then
    if(tDimmEin !== null)
        return;
    timer_Sensor_Haupteingang_Tuere_Dimmer_Eingang?.cancel
end
Ich bevorzuge kurze Variablennamen :)

Das ganze Konstrukt arbeitet etwas indirekt. Die erste Rule (received command) triggert nur, wenn der Dimmer einen Befehl aus openHAB heraus bekommt. Nur in diesem Fall wird der Timer tDimmEin gestartet. Der Befehl tDimmEin?.cancel bedeutet: breche den Timer ab, falls er existiert, das sind also 3 Zeilen Code...
Wenn der Timer nach eine halben Sekunde abläuft, tut der Code nichts anderes, als die Timer Variable zu leeren.
Die zweite Rule (changed) triggert immer, wenn sich der Wert des Items ändert, also gewöhnlich, wenn der Dimmer einen neuen Wert meldet.
Die Rule prüft, ob der Timer tDimmEin existiert (!== null) und bricht ab, falls das zutrifft. Ansonsten cancelt sie den eigentlichen Timer, falls dieser existiert.
Ich habe hier 500 Millisekunden für tDimmEin angesetzt, Du musst aber vermutlich hier einen wesentlich höheren Wert ansetzen, da der Dimmwert von zwave vermutlich erst gegen Ende des Dimmvorgangs gemeldet wird, und vermutlich wird der Dimmer "weich" dimmen. Die Totzeit (von tDimmEin vorgegeben) muss also mindestens die Zeitspanne abdecken, die Dimmer_Eingang benötigt, um von 0 auf 20% zu dimmen, plus einige hundert Millisekunden zur Sicherheit.
openHAB4.3.5 stable in einem Debian-Container (bookworm) (Proxmox 8.4.1, LXC), mit openHABian eingerichtet

Benutzeravatar
RES
Beiträge: 33
Registriert: 20. Aug 2020 14:38
Answers: 0
Wohnort: Innsbruck
Kontaktdaten:

Re: Regel ausführen bei Werteänderung, die von einem bestimmten Sender ausgelöst wurde

Beitrag von RES »

Vielen Dank für Deine Bemühungen.

Wenn ich das richtig verstehe, wird der Timer dabei aber immer abgebrochen, wenn sich der Wert für den Dimmer ändert. Auch, wenn die Änderung z. B. aus einer Regel heraus erfolgt.

Ich würde eine Möglichkeit suchen, den Timer nur zu beenden, wenn der Wert des Dimmers per Z-Wave verändert wird, da ich, während der Laufzeit des Timers, weitere Änderungen am Wert des Dimmers über Regeln durchführen möchte.

Kennst Du evtl. eine Lösung dazu?
--
Rudolf E. Steiner
res-1@communicate.at

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

Re: Regel ausführen bei Werteänderung, die von einem bestimmten Sender ausgelöst wurde

Beitrag von udo1toni »

Nein, das hast Du nicht richtig verstanden.

So, wie ich es angelegt habe (und unter der Voraussetzung, dass Du tDimmEin großzügig genug bemessen hast (wie oben erläutert) wird der Timer nur bei Steuerung über zwave abgebrochen, aber nicht, wenn über openHAB gesteuert wurde.

Die Idee der Rule ist, dass der Timer nur dann abgebrochen wird, wenn im Zeitraum tDimmEin zuvor kein sendCommand erfolgte. Dafür braucht es den 2. Timer. Vielleicht erscheint mein Code zu simpel...
openHAB4.3.5 stable in einem Debian-Container (bookworm) (Proxmox 8.4.1, LXC), mit openHABian eingerichtet

Benutzeravatar
RES
Beiträge: 33
Registriert: 20. Aug 2020 14:38
Answers: 0
Wohnort: Innsbruck
Kontaktdaten:

Re: Regel ausführen bei Werteänderung, die von einem bestimmten Sender ausgelöst wurde

Beitrag von RES »

Jetzt verstehe ich. Vielen Dank für die Erläuterungen.

Dann kann mit openHAB in einer Regel also tatsächlich nativ keine Unterscheidung dahingehend getroffen werden, von "wem" eine Werteänderung durchgeführt wurde.

Ich werde Deinen "Workaround" testen, auch wenn ich befürchte, dass das nicht immer zuverlässig laufen wird (bei Z-Wave variieren die Zeiten (z. B. bei hoher Netzwerkbelastung) oft stark, bis Daten beim Empfänger ankommen).

Vielen Dank für Deine Bemühungen.
--
Rudolf E. Steiner
res-1@communicate.at

Antworten