Problem mit Rule

Einrichtung der openHAB Umgebung und allgemeine Konfigurationsthemen.

Moderatoren: seppy, udo1toni

Backbe01
Beiträge: 123
Registriert: 19. Jul 2019 21:04
Answers: 0

Problem mit Rule

Beitrag von Backbe01 »

Hallo,

ich versuche jetzt schon länger eine rule zum laufen zu bekommen. Irgend etwas ist nun "schief" gelaufen und ich habe ein komisches Verhalten eines Items. Der Dimmer meines LED Stripes läßt sich nicht mehr direkt steuern, d.h. ich muss nun immer zweimal auf den Slider oder die "%-Buttons" in der Basic UI drücken bis der Stripe reagiert. Im Log schaltet das Item zwar richtig, in Real aber erst nach dem zweiten Klick.

Ich habe mit folgender Regel "experimentiert" (ohne genauere Kenntnis was ich da mache:-)) Problem war dann auch, dass der Stripe gar nicht mehr auszuschalten war.

Code: Alles auswählen

var Timer TimerH = null
rule "Alarma automática"
when
Item Detector_Gas changed to ON
then
if(TimerH != null) {
TimerH.cancel
TimerH = null
}
TimerH = createTimer(now.plusSeconds(1)) [|
    if(Alarma.state==ON){
            Alarma.sendCommand(OFF)
    }
    else{
            Alarma.sendCommand(ON)
    }
    TimerH.reschedule(now.plusSeconds(1))
]
end
rule "Apagado de alarma automática"
when
Item Detector_Gas changed to OFF
then
Alarma.sendCommand(OFF)
if(TimerH != null) {
TimerH.cancel
TimerH = null
}
end
Ich habe die angepasste Regel wieder gelöscht. Aber kann es sein, dass ich mir da etwas zerschossen habe?

VG
Gerhard
OH 4.1.0M2 auf nuc in Docker

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

Re: Problem mit Rule

Beitrag von udo1toni »

Die erste Frage dazu: Hast Du openHAB schon mal komplett neu gestartet?

Die Rules als solches scheinen erst mal in Ordnung. Ich sehe allerdings (wohl wegen Unkenntnis der betroffenen Items ;) ) keinen Zusammenhang zu Deinem LED Stripe.
Beide Rules lassen sich ein wenig optimieren:

Code: Alles auswählen

var Timer TimerH = null  // globale Variablen immer zu Beginn der Datei definieren!

rule "Alarma automática"
when
    Item Detector_Gas changed
then
    TimerH?.cancel
    if(Detector_Gas.state == ON)
        TimerH = createTimer(now, [|
            Alarma.sendCommand(if(Alarma.state == ON) OFF else ON)
            TimerH.reschedule(now.plusSeconds(1))
        ]
end
Die Rule triggert bei jedem Change (ON und OFF).
Da beide Rules einen identischen Block haben (das Canceln des Timers) und das auch direkt zu Beginn der Rule passiert, reicht es also, diesen Code einmal aufzuschreiben. Dieser Code besteht nur aus einem einzigen Befehl, TimerH?.cancel, was funktionsgleich zur Zeile

Code: Alles auswählen

if(TimerH !== null) TimerH.cancel
ist.
Es spielt keine Rolle, ob der Timer tatsächlich jemals null wird, wichtig ist nur, dass ein laufender Timer gecancelt wird.

Nur falls der Gasdetektor ON meldet, wird der Timer neu angelegt.
Dabei wird der Timer sofort ausgeführt (im Zweifel möchtest Du keine Sekunde warten, bis Du den Alarm zu Gesicht bekommst).
Im Timer selbst ist der ternäre Operator die elegante Variante, das Toggeln auszulösen.
openHAB4.3.3 stable in einem Debian-Container (bookworm) (Proxmox 8.3.5, LXC), mit openHABian eingerichtet

Backbe01
Beiträge: 123
Registriert: 19. Jul 2019 21:04
Answers: 0

Re: Problem mit Rule

Beitrag von Backbe01 »

Vielen Dank Udo für deine Einschätzung! Das "Doppelklick"-Problem werde ich im Auge behalten...

Die o.g. rule hatte ich so nicht direkt am laufen. Ich hatte sie natürlich auf meine Items angepasst aber nach dem o.g. Problem ersatzlos von OH gelöscht! Und wenn ich dein Kommentar so lese, bezweifle ich auch, dass diese rule die Richtige für mich ist.

Ich bastel derzeit an einem Shottimer für meine Espressomaschine. Das Signal des Bezugs kommt von einem Shelly 1, der Dank Deiner Hilfe, bereits erfolgreich in OH eingebunden ist. Nun möchte ich, dass der Shelly erkennt, wenn das Magnetventil schaltet, und ein "ON" an OH sendet. Das läuft derzeit auch schon. Aber ab dann wird es kompliziert für mich.

Ich habe bis jetzt die rule, das der genannte LED Stripe nach einer vorgegebenen Pause von 10 Sekunden zum Leuchten anfängt und in einer zweiten rule habe ich eingestellt, dass der Stripe bei Bezugende (Magnetventil stromlos) wieder den Stripe ausschaltet.

Folgenden Ablauf würde ich mir im Optimalfall für die Rule wünschen:

Shelly 1 erkennt Bezug
nach einer Pause von 10 Sekunden beginnt sich der LED Stripe langsam zu erhellen (also Gegenteil von dimmen)
nach weitern ca. 20 Sekunden Erhellung (bis 100%) soll der LED Stripe mit 100% zum blinken anfangen bis der Bezug beendet wird.
Danach soll der LED Stripe wieder in den Ausgangszustand gehen (also wenn vorher an, dann an, usw...)

(Toll, aber kein muss, wäre hierbei auch, dass der Stripe in den anfänglichen 10 Sekunden Pause den Zustand von davor behält (sprich Stripe ist vor Bezug aus = 10 sekunden ohne Licht dann von 0% erhellen. Bei Stripe vor Bezug an = 10 Sekunden diesen Zustand halten und beidesmal nach 10 Sekunden von 0% - 100% erhellen und nach 20 Sekunden "Erhellung" zum blinken anfangen bis der Bezug beendet wird und der Shelly "OFF" sendet.))

Meine Items dafür sehen derzeit folgendermaßen aus:

Item

Code: Alles auswählen

 Switch    Shottimer    "MQTT State [MAP(Bezug.map):%s]" "{channel="mqtt:topic:Mosquitto:Shottimer:Shottimer"}
Dimmer    LEDstripe_EG_KücheDH     "Helligkeit Küche"		(EG_Küche,gLampen)  	[ "Lighting" ]   {channel="hue:xxxxx"}
Als kurze Ergänzung: bei dem Stripe handelt es sich um einen DualWhite Stripe, sollte aber auf das Vorhaben keine Auswirkungen haben. Ich habe hier für den Helligkeitskanal und den Farbton jeweils ein Item erstellt (LEDstripe_EG_KücheDH = Dimmer Helligkeit; LEDstripe_EG_KücheDF = Dimmer Farbtemperatur).

Da ich derzeit in der Arbeit bin kann ich leider meine "mini rule´s" nicht posten, kann das aber gerne am Abend nachholen...

VG
Gerhard
OH 4.1.0M2 auf nuc in Docker

Backbe01
Beiträge: 123
Registriert: 19. Jul 2019 21:04
Answers: 0

Re: Problem mit Rule

Beitrag von Backbe01 »

So, hier meine bisherigen rules:

zum starten:

Code: Alles auswählen

// globale Variablen und Konstanten werden immer am Beginn der Datei definiert!
var Timer tDelay = null                               // Zeiger auf den Timer

rule "Shottimer"
when
    Item Shottimer received command ON                     // Befehl empfangen
then
    tDelay?.cancel                                    // lösche Timer, falls einer existiert
    if(receivedCommand == ON)                         // Kommando AN
        tDelay = createTimer(now.plusSeconds(3), [ |
            LEDstripe_EG_KuecheDH.sendCommand(ON)        // Licht an                
        ])
    else
        LEDstripe_EG_KuecheDH.sendCommand(OFF)           // Licht aus
end
und zum beenden:

Code: Alles auswählen

rule "Shottimer4"
when
    Item Shottimer received command OFF
then
    logInfo("Shottimer4", "Ende Bezug")
    LEDstripe_EG_KuecheDH.sendCommand(OFF) 
    
end
Wie gesagt, leider habe ich die anderen "Testrules" aus Panik gelöscht! :oops:
OH 4.1.0M2 auf nuc in Docker

Backbe01
Beiträge: 123
Registriert: 19. Jul 2019 21:04
Answers: 0

Re: Problem mit Rule

Beitrag von Backbe01 »

Nochmal zu dem Problem des LED Stripe´s:

Ist das Log für das Schalten normal? Wenn ich einmal in der Basic UI auf z.B. 25% klicke kommt kurz darauf der Befehl wieder auf % zu stellen. Klicke ich zweimal klappt´s! OH jetzt schon zweimal neu gestartet und auch die Things einmal gelöscht und nochmals neu eingebunden...
2019-07-30 20:00:45.662 [ome.event.ItemCommandEvent] - Item 'LEDstripe_EG_KuecheDH' received command 25

2019-07-30 20:00:45.666 [nt.ItemStatePredictedEvent] - LEDstripe_EG_KuecheDH predicted to become 25

2019-07-30 20:00:45.694 [vent.ItemStateChangedEvent] - LEDstripe_EG_KuecheDH changed from 0 to 25

2019-07-30 20:00:55.019 [vent.ItemStateChangedEvent] - LEDstripe_EG_KuecheDH changed from 25 to 0
OH 4.1.0M2 auf nuc in Docker

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

Re: Problem mit Rule

Beitrag von udo1toni »

Oh je, das sind aber ganz schön viele Wünsche :)

Und so richtig einfach wird das sicherlich auch nicht.
Ich habe keine Hue im Einsatz, deshalb eine Frage dazu: gibt es eine Möglichkeit, der Hue zu sagen, dass sie innerhalb 20 Sekunden auf eine bestimmte Helligkeit dimmt (ein Dimmer wird auf- oder abgedimmt)? openHAB sieht nicht vor, selbst eine Dimmkurve auszugeben.

Die Rule muss eine Ablaufsteuerung umsetzen.
  • Der erste Punkt ist, 10 Sekunden zu warten.
  • Der zweite Punkt ist, die Ausgangshelligkeit zu speichern (das brauchst Du schon, um wieder auf die alte Einstellung zu kommen, aber auch für das Dimmen ab dieser Helligkeit)
  • Der dritte Punkt ist, innerhalb 20 Sekunden auf 100% zu dimmen. Dabei kannst Du nur um ganze Prozentschritte dimmen, es wird also eher stufiges aufblenden.
  • Der vierte Punkt ist, zu blinken.
  • Der fünfte Punkt ist, auf die ursprüngliche Helligkeit zurück zu springen.
Dabei darf die Rule natürlich nicht von sich selbst überholt werden :) und die eigentliche Rule sollte niemals mehr als wenige Millisekunden benötigen. Sieht dann so aus:

Code: Alles auswählen

// globale Variablen immer am Anfang der Datei anlegen!
var Timer tShot = null                                                                             // Timer für den Shot Timer
var Number nShot = null                                                                            // Speicher für alte Helligkeit
var Number nShotDiff                                                                               // Differenzspeicher
var Number nShotAct                                                                                // aktuelle Helligkeit

rule "shot Timer"
when
    Item Shottimer changed                                                                         // Zustand des Ventils geändert
then
    if(Shottimer.state == OFF) {                                                                   // Zustand aus -> 
        tShot?.cancel                                                                              // Timer abbrechen
        tShot = null                                                                               // auf null setzen
        if(nShot !== null)                                                                         // der Timer wurde bereits ausgeführt ->
            if((LEDstripe_EG_KücheDH.state as Number) != nShot)                                    // falls die Helligkeit geändert wurde
                LEDstripe_EG_KücheDH.sendCommand(nShot)                                            // zurück auf alte Helligkeit
        nShot = null                                                                               // auf null setzen
    } else if(tShot === null) {                                                                    // timer wurde noch nicht initialisiert
        tShot = createTimer(now.plusSeconds(10), [|                                                // Timer starten mit 1. Schritt
            if(nShot === null) {                                                                   // falls erster Durchlauf
                nShot = LEDstripe_EG_KücheDH.state as Number                                       // Helligkeit merken
                nShotAct = nShot                                                                   // Anfangshelligkeit setzen
                nShotDiff = (100 - nShot)/60                                                       // Stufen berechnen
            } 
            if(nShotAct < 98) {                                                                    // maximale Helligkeit noch nicht erreicht
                nShotAct = nShotAct + nShotDiff                                                    // neue Helligkeit berechnen
                LEDstripe_EG_KücheDH.sendCommand(nShotAct.intValue)                                // und die Lampe auf die neue Stufe setzen
            } else {                                                                               // maximale Helligkeit wurde bereits erreicht
                LEDstripe_EG_KücheDH.sendCommand(if(LEDstripe_EG_KücheDH.state != 100) 100 else 0) // Licht toggeln
            }
            tShot.reschedule(now.plusMillis(if(nShotAct < 98) 333 else 1500))                     // timer erneut ausführen
        ])
    }
end
Wie so oft ist der Code nicht getestet, sollte aber funktionieren. Ich hoffe, dass die Inline Dokumentation die Funktionsweise genug erklärt, ansonsten frag nach :)

Einen Knackpunkt gibt es noch, es könnte sein, dass der Stripe bereits auf voller Helligkeit steht, dann wird der Dimmeffekt übersprungen und in der Folge wird das Blinken sofort beginnen. Man kann das natürlich abfangen...

Der Timer muss weniger als 333 Millisekunden für einen Durchlauf benötigen (am besten wesentlich weniger). Falls es zu Unregelmäßigkeiten kommt, müsste man die Rule so anpassen, dass für die Dimmkurve nur 40 Schritte (entsprechend 500mSec verwendet und entsprechend statt 333 mSec 500mSec im Reschedule verwendet werden.

EDIT: im reschedule den Schwellwert auf 98 gesenkt.
openHAB4.3.3 stable in einem Debian-Container (bookworm) (Proxmox 8.3.5, LXC), mit openHABian eingerichtet

Backbe01
Beiträge: 123
Registriert: 19. Jul 2019 21:04
Answers: 0

Re: Problem mit Rule

Beitrag von Backbe01 »

Wow!!! Ich weiß gar nicht was ich sagen soll?!! Vielen Dank!

Ich bin ja in mehreren "Fachforen" unterwegs, aber so eine schnelle, kompetente und freundliche Hilfe für Newbies kannte ich noch aus keinen Forum!

Ich werde die rule heute Abend sofort testen und berichten, auch wenn ich hierbei nicht wirklich durchblicke! Die Zeit für die Pause am Anfang ist mir noch klar, aber wo könnte ich die Zeit für das Erhellen einstellen und wo den Blinkintervall, also schneller, langsamer blinken?

Deinen letzten Absatz habe ich ehrlich gesagt auch noch nicht ganz verstanden. Aber vielleicht klärt sich das auch heute Abend beim testen...

Ob bei der Hue eine Dimmerfunktion fest hinterlegt werden kann weiß ich ehrlich gesagt auch nicht. Da mache ich mich mal schlau!
OH 4.1.0M2 auf nuc in Docker

Backbe01
Beiträge: 123
Registriert: 19. Jul 2019 21:04
Answers: 0

Re: Problem mit Rule

Beitrag von Backbe01 »

Hammer!!!

Im Prinzip funktioniert alles wie es soll. Leider ist das Blinken für den Stripe zu schnell! Im Basic UI sehe ich wie zwischen 0 und 100 geschalten wird, aber der Stripe bleibt dunkel. An welcher Schraube muss ich drehen um das Blinken langsamer zu machen? (Hinweis: Der Stripe blendet immer ein und aus beim ein- bzw. ausschalten. Das dauert ca. immer ne halbe Sekunde bis Sekunde)

VG
Gerhard
OH 4.1.0M2 auf nuc in Docker

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

Re: Problem mit Rule

Beitrag von udo1toni »

Diese Zeile ist die entscheidende:

Code: Alles auswählen

tShot.reschedule(now.plusMillis(if(nShotAct < 100) 333 else 1500))                     // timer erneut ausführen
Die 333 ist die Zeit zwischen zwei Dimmvorgängen.
Die 1500 ist die Zeit zwischen dem Togglen. Beide Werte sind Millisekunden. Du kannst also z.B. die 1500 gegen eine 3000 tauschen, das wären dann 3 Sekunden.

Funktioniert denn der Dimmvorgang (also das innerhalb 20 Sekunden aufblenden) wie gewünscht?

Falls nein, könnte man hier auch größere Sprünge verwenden und weniger Zwischenschritte einsetzen. Die Anzahl der benötigten Schritte ergibt sich aus der Zeile

Code: Alles auswählen

nShotDiff = (100 - nShot)/60                                                       // Stufen berechnen
Es werden also 60 Schritte benötigt, um vom aktuellen Wert auf 100% zu dimmen. sollen es z.B. nur 20 Schritte sein, teilst Du hier durch 20.
Entsprechend müsstest Du dann die 333 aus obiger Zeile gegen eine 1000 tauschen, damit der Dimmvorgang weiterhin 20 Sekunden benötigt.

EDIT: Ich stelle gerade fest, dass ich in der Abfrage auf kleiner 100 teste, was aber falsch ist es muss kleiner 98 heißen:

Code: Alles auswählen

tShot.reschedule(now.plusMillis(if(nShotAct < 98) 333 else 1500))                     // timer erneut ausführen
Die 98 habe ich weiter oben im Code ebenfalls verwendet, weil ich verhindern wollte, dass durch aufsummierte Rundungsfehler der eigentliche Schwellwert (100) nicht erreicht wird. Das muss ich natürlich im unteren Teil ebenfalls berücksichtigen, da die Variable anschließend nicht mehr hochgezählt wird.
openHAB4.3.3 stable in einem Debian-Container (bookworm) (Proxmox 8.3.5, LXC), mit openHABian eingerichtet

Backbe01
Beiträge: 123
Registriert: 19. Jul 2019 21:04
Answers: 0

Re: Problem mit Rule

Beitrag von Backbe01 »

Der Dimmvorgang läuft tadellos! Hab jetzt zwar nicht genauer darauf geachtet, schaut aber ganz gut aus! Notfalls weiß ja jetzt, wo ich etwas drehen kann!

Eine Frage hätte ich noch: Warum wird am Anfang bei Item Shottimer eigentlich "changed" genommen und nicht "received command ON"?
OH 4.1.0M2 auf nuc in Docker

Antworten