Viele unbeantwortete Fragen zu Rules

Einrichtung der openHAB Umgebung und allgemeine Konfigurationsthemen.

Moderatoren: seppy, udo1toni

Blui
Beiträge: 52
Registriert: 6. Jul 2020 14:50
Answers: 0

Viele unbeantwortete Fragen zu Rules

Beitrag von Blui »

Da bin ich mal wieder mit Fragen deren Arntwort hier im Forum schwer zu finden sind. Dieses mal geht es um Rules.

Erste Frage:
Gibt es die Möglichkeit über eine Rule das schalten eines Items zu verhindern?
Als Beispiel, ich schalte einen 3D-Drucker über eine Schaltfläche im HabPanel an. Jetzt kann ich den dort natürlich auch jederzeit wieder ausschalten. Gibt es eine Möglichkeit das zu verhindern, beispielsweise weil der Drucker grade mitten im Druck ist? Über MQTT mit Octoprint kommen da ja diverse Daten rein.

Wobei ich auch noch nach eine Lösung suche das sich der Drucker nach dem Druck und einer Abkühlpause automatisch wieder ausschaltet. Das bekomme ich aber vielleicht noch selber hin demnächst.

Meine zweite Frage:
Ich nutze eine Rule um eine Wasserpumpe zeitgesteuert 30 Minuten vor Sonnenaufgang einzuschalten

Code: Alles auswählen

rule "Wasserpumpe 1 an 30 Minuten vor Sonnenaufgang"
    when 
        Channel "astro:sun:home:rise#event" triggered START
    then 
        Wasserpumpe1Power27.sendCommand(ON)
    end
Das Item dazu ist

Code: Alles auswählen

DateTime   RiseStart   "Startzeit -30 Minuten"   {channel="astro:sun:home:rise#start"}
Das funktioniert auch problemlos

Ausgeschaltet werden soll diese dann wieder zu Sonnenaufgang, das funktioniert allerdings nicht

Code: Alles auswählen

 rule "Wasserpumpe 1 aus bei Sonnenaufgang"
    when 
       Channel "astro:sun:local:rise#start" triggered START
    then 
       Wasserpumpe1Power27.sendCommand(OFF)
    end   
Der Schaltbefehl scheint einfach nicht an zu kommen, die Pumpe läuft einfach weiter.

Ich habe mir jetzt erst einmal mit dieser Lösung geholfen, sicherlich nicht die elegantetse aber sie funktioniert zumindest.

Code: Alles auswählen

rule "Wasserpumpe 1 an 30 Minuten vor Sonnenaufgang"
    when 
        Channel "astro:sun:home:rise#event" triggered START
    then 
        Wasserpumpe1Power27.sendCommand(ON)
        Thread::sleep(1200000)                                 // 20 Minuten Pause //
        Wasserpumpe1Power27.sendCommand(OFF)
    end
Und weil es so schön ist noch eine dritte Frage. irgendwie passt sie vielleicht auch zur zweiten
Wenn ich mit der Rule

Code: Alles auswählen

rule "Strahler an"
    when 
        Channel "astro:sun:local:set#start" triggered START 
    then 
        Power56.sendCommand(ON)
    end 
ein Licht einschalte, kann ich die Zeit auch über die Rule ändern indem ich da irgendwie sage "Rechne von dem Zeitpunkt x minuten ab/zu" oder geht das dann wirklich nur mit einem RangeEvent?

Dass waren erstmal die Fragen die mir spontan eingefallen sind, vielleicht ergeben sich ja noch mehr. ;)

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

Viele unbeantwortete Fragen zu Rules

Beitrag von udo1toni »

Zu Frage 1: Es gibt keine direkte Möglichkeit, das Ausschalten zu verhindern. Was Du machen kannst, ist, in der UI die Schaltfläche zu beseitigen (indem Du mit visibility arbeitest). Dann müsste der 3D-Drucker openHAB aber irgendwie mitteilen, dass er angefangen hat zu drucken und natürlich, dass er mit dem Drucken fertig ist. das kannst Du dann verwenden, um die Ausschaltoption zu aktivieren.

Oder Du nutzt ein Mapping, um ausschließlich einen Einschaltbefehl zu bekommen und der Drucker kümmert sich grundsätzlich selbst um das Ausschalten, indem er vor dem Shutdown z.B. Per REST API die Off-Sequenz auslöst. Natürlich muss openHAB das Ausschalten noch verzögern, damit der Shutdown vollständig durchlaufen kann.

Du hast beim Thing Trigger den falschen Channel gewählt (nicht #event, sondern #start. Kleine Ursache, große Wirkung... ;)

Zur dritten Frage: Der Trigger ist über das Addon definiert, und das kann man nicht mit Rules beeinflussen. Du kannst natürlich in einer Rule, die so getriggert wird, ohne Probleme auch noch einen Timer starten, um die Aktion zu verzögern. Dieser Timer kann auch direkt in der Rule beeinflusst werden.

Tipp am Rande: Astro stellt nicht nur rise und set als Trigger bereit, sondern auch public, nautical und astronomic rise/set. Dies sind die Zeitpunkte, zu denen die Sonne 0°, -6°, -12° und -18° Höhenlinie berührt (START) bzw. verlässt (END). Jeder dieser Punkte lässt sich individuell verschieben, so dass man also nicht weniger als 8 (bzw. 16) Triggerpunkte pro Thing zur Verfügung hat, die vielleicht hilfreich sind. (Allerdings stehen die Punkt in keinem fixen Abstand zueinander, der hängt von der Jahreszeit ab.)


Gesendet von iPad mit Tapatalk
openHAB4.3.3 stable in einem Debian-Container (bookworm) (Proxmox 8.3.5, LXC), mit openHABian eingerichtet

Blui
Beiträge: 52
Registriert: 6. Jul 2020 14:50
Answers: 0

Re: Viele unbeantwortete Fragen zu Rules

Beitrag von Blui »

Gut, das mit dem mapping habe ich ja schon bei anderen Schaltern, allerdings noch nicht im HabPanel.

Mit REST API werde ich mich dann vermutlich auch mal auseinander setzen müssen. Mal sehen wann ich da Zeit für finde. ;)

Das mit dem falschen Channel teste ich gleich mal, so lange ist es ja nicht mehr bis zum Sonnenuntergang.

Dafür habe ich nun diverse Fehlermeldungen bei folgender Rule

Code: Alles auswählen

rule "3D-Drucker nach Druckjob ausschalten"
when
    Item Progress changed 
then    
    if (Progress.state as Number == 100) 
    && (Printerstate.state as String = "Operational") 
    && (OctoprintTooltempist.state as Number <= 40) 
    && (OctoprintBettempist.state as Number <= 40)
    {
      Power49.sendCommand(OFF)
    }
else 
    Thread::sleep(12000)    
end
Vermutlich habe ich da alle Werte falsch definiert, aber zumindest werden sie mir soweit richtig angezeigt.

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

Re: Viele unbeantwortete Fragen zu Rules

Beitrag von udo1toni »

Ja, da sind ja nun auch ein paar Fehler drin. :)
Das Typecasting muss geklammert werden, damit der Vergleich korrekt funktioniert. Die gesamte Bedingung für if muss in eine Klammer. Da alle Verknüpfungen (&&) die gleichen sind, müssen hier aber keine Klammern gesetzt werden. Den Status kann und muss man nicht nach String casten, stattdessen verwendet man einfach die Methode .toString.

Also eher so:

Code: Alles auswählen

rule "3D-Drucker nach Druckjob ausschalten"
when
    Item Progress changed 
then    
    if ((Progress.state as Number) == 100 
    && Printerstate.state.toString == "Operational"
    && (OctoprintTooltempist.state as Number) <= 40
    && (OctoprintBettempist.state as Number) <= 40)
    {
      Power49.sendCommand(OFF)
    } else 
        Thread::sleep(12000)    
end
Allerdings ist das mit dem Thread::sleep(12000) ein ganz dumme Idee. Und im derzeitigen Zustand der Rule passiert ja auch gar nichts nach dem Thread::sleep(). Der Befehl tut exakt das: es hält den Thread für die angegebene Anzahl Millisekunden an. Sonst nichts. Die Rule wird also nicht erneut durchlaufen (und das ist auch gut so).
Da es vermutlich um das Ausschalten des Drucker geht, denke ich, Du suchst eher so was:

Code: Alles auswählen

// globale Variablen zu Beginn der Datei vor der ersten Rule definieren!
var Timer tPrinter = null                                  // Timer für Abschaltung Drucker

rule "3D-Drucker nach Druckjob ausschalten"
when
    Item Progress changed to 100                           // Fortschritt hat 100% erreicht
then
    tPrinter?.cancel                                       // Timer löschen, falls vorhanden
    tPrinter = createTimer(now.plusMillis(100),[|
        if(Printerstate.state.toString == "Operational" && 
           (OctoprintTooltempist.state as Number) <= 40 && 
           (OctoprintBettempist.state as Number) <= 40)
            Power49.sendCommand(OFF)
        else
            if(Power49.state == ON)
                tPrinter.reschedule(now.plusMillis(12000))
    ])
end
Sobald die Rule triggert wird, startet ein Timer, in dessen Schleife dann der Zustand der verschiedenen Temperaturen und dem Printerstate überprüft wird. Sind die Bedingungen nicht erfüllt, wird der Timer erneut eingeplant, bis ide Bedingungen erfüllt sind. Falls der Drucker auf anderem Weg ausgeschaltet wurde, sollte der Timer aber nicht erneut ausgeführt werden (deshalb die zusätzliche Prüfung des Schaltzustands).
openHAB4.3.3 stable in einem Debian-Container (bookworm) (Proxmox 8.3.5, LXC), mit openHABian eingerichtet

Blui
Beiträge: 52
Registriert: 6. Jul 2020 14:50
Answers: 0

Re: Viele unbeantwortete Fragen zu Rules

Beitrag von Blui »

Ich bin jetzt schon irgendwie verwirrt.
Ich habe es zuerst mit Deiner Rule probiert

Code: Alles auswählen

rule "3D-Drucker nach Druckjob ausschalten"
when
    Item Progress changed to 100                           // Fortschritt hat 100% erreicht
then
    tPrinter?.cancel                                       // Timer löschen, falls vorhanden
    tPrinter = createTimer(now.plusMillis(100),[|
        if(Printerstate.state.toString == "Finishing" && 
           (OctoprintTooltempist.state as Number) <= 40 && 
           (OctoprintBettempist.state as Number) <= 40)
            Power49.sendCommand(OFF)
        else
            if(Power49.state == ON)
                tPrinter.reschedule(now.plusMillis(12000))
    ])
end
in der mir Printerstat jetzt komischerweise was anderes ausgibt wie oben zu sehen. Aber der Drucker bzw. die Steckdose schaltet nicht ab.

Dann habe ich im Netz rumgesucht und eine Möglichkeit gefunden das ganze nach Wunsch abschalten zu lassen über einen extra Switch

Code: Alles auswählen

rule "Shutdown after finish"
    when
        Item State changed from Printing to Operational
    then
        if (OctoprintShutdownAfterPrint.state == ON && Progress.state == 100){
            createTimer(now.plusSeconds(60),  [
            Power49.sendCommand(OFF)
            ])
         createTimer(now.plusSeconds(70),  [
             OctoprintShutdownAfterPrint.sendCommand(OFF)
            ])
      }
 end
Dazu noch einen Switch

Code: Alles auswählen

Switch  OctoprintShutdownAfterPrint   "Turn Off after Print" (gOctoprint)
angelegt aber auch damit schaltet der Drucker nicht ab.

Ich habe es nun schon auf die Steckdose geschoben, erstaunlicherweise funktioniert das abschalten mit

Code: Alles auswählen

rule "Drucker aus"
    when 
        Time cron "0 10 17 * * ?"
    then 
        Power49.sendCommand(OFF)
end
aber problemlos.

Muss da doch noch mehr in Klammen?

Benutzeravatar
poetos
Beiträge: 11
Registriert: 3. Aug 2020 20:58
Answers: 0

Re: Viele unbeantwortete Fragen zu Rules

Beitrag von poetos »

Hallo Blui,
zum Problem mit # Wasserpumpe aus #. Kann es sein, das die Zwangsunterbrechung des Routers genau zum gleichen Zeitpunkt stattfindet? An der Rule liegt es jedenfalls nicht, die sieht gut aus. Die Zeit für die die Zwangsunterbrechung ändert sich normal nicht, aber die für den Sonnenaufgang ; deshalb einfach noch mal testen.
openHab 2.5.9, Raspberry Pi 3 Model B, Shelly, Broadlink, Telegram, Samsung TV, Bosch Indego

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

Re: Viele unbeantwortete Fragen zu Rules

Beitrag von udo1toni »

Also, nur so auf Verdacht... OctoprintTooltempist und OctoprintBettempist sind beide Number Items (nicht Number:Temperature)?

Welche Items hast Du denn nun tatsächlich in Nutzung? Ursprünglich hieß das eine Item Printerstate, in der Rule "Shutdown after finish" versuchst Du aber auf ein Item "State" zu triggern.

Wir könnten noch ein bisschen Logging dazu machen, damit klar wird, welcher Teil der Rule nicht funktioniert:

Code: Alles auswählen

rule "3D-Drucker nach Druckjob ausschalten"
when
    Item Progress changed to 100                           // Fortschritt hat 100% erreicht
then
    logInfo("autooff","Rule getriggert, Progress {}",Progress.state)
    tPrinter?.cancel                                       // Timer löschen, falls vorhanden
    tPrinter = createTimer(now.plusMillis(100),[|
        logInfo("autooff","Timer ausgeführt, Printerstate {}",Printerstate.state)
        logInfo("autooff","Tooltemp {}, Betttemp {}",OctoprintTooltempist.state, OctoprintBettempist.state)
        if(Printerstate.state.toString == "Finishing" && 
           (OctoprintTooltempist.state as Number) <= 40 && 
           (OctoprintBettempist.state as Number) <= 40)
            Power49.sendCommand(OFF)
        else
            if(Power49.state == ON)
                logInfo("autooff","Timer wird erneut geplant!")
                tPrinter.reschedule(now.plusMillis(12000))
    ])
end
Entsprechende Meldungen sollten nun in frontail bzw. openhab.log sichtbar werden (in Frontail kann man prima filtern, openhab.log lässt sich auf der Kommandozeile ebenfalls einfach überwachen:

Code: Alles auswählen

tail -f /var/log/openhab2/openhab.log | grep autooff
openHAB4.3.3 stable in einem Debian-Container (bookworm) (Proxmox 8.3.5, LXC), mit openHABian eingerichtet

Blui
Beiträge: 52
Registriert: 6. Jul 2020 14:50
Answers: 0

Re: Viele unbeantwortete Fragen zu Rules

Beitrag von Blui »

Oh, jetzt funktioniert es.

Danke mal wieder. :-)

Zeitlich passte es wohl auch ganz gut, es vergehen rund 9 Minuten bis die Temperaturen erreicht sind. Allerdings wir dem Logging nach die Rule nach dem Power off weiterhin ausgeführt. Ist das normal oder kann man das auch abschalten?
Ich vermute mal wenn dann über das entfernen des "else"-Bereichs, oder?

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

Re: Viele unbeantwortete Fragen zu Rules

Beitrag von udo1toni »

Nein, da habe ich ein Klammerpaar vergessen (notwendig geworden durch das logging). Korrekt ist es so:

Code: Alles auswählen

rule "3D-Drucker nach Druckjob ausschalten"
when
    Item Progress changed to 100                                                     // Fortschritt hat 100% erreicht
then
    logInfo("autooff","Rule getriggert, Progress {}",Progress.state)
    tPrinter?.cancel                                                                 // Timer löschen, falls vorhanden
    tPrinter = createTimer(now.plusMillis(100),[|
        logInfo("autooff","Timer ausgeführt, Printerstate {}",Printerstate.state)
        logInfo("autooff","Tooltemp {}, Betttemp {}",OctoprintTooltempist.state, OctoprintBettempist.state)
        if(Printerstate.state.toString == "Finishing" && 
           (OctoprintTooltempist.state as Number) <= 40 && 
           (OctoprintBettempist.state as Number) <= 40)
            Power49.sendCommand(OFF)
        else
            if(Power49.state == ON) {                                                // öffnende Klammer
                logInfo("autooff","Timer wird erneut geplant!")
                tPrinter.reschedule(now.plusMillis(12000))
            }                                                                        // schließende Klammer
    ])
end
'Die bedingte Ausführung gilt immer nur für exakt einen Befehl, mit den geschweiften Klammern werden alle Befehle innerhalb der Klammern als ein Block betrachtet.
openHAB4.3.3 stable in einem Debian-Container (bookworm) (Proxmox 8.3.5, LXC), mit openHABian eingerichtet

Blui
Beiträge: 52
Registriert: 6. Jul 2020 14:50
Answers: 0

Re: Viele unbeantwortete Fragen zu Rules

Beitrag von Blui »

Tatsächlich, es funktioniert. Super!

Noch etwas das wohl eher nichts mit Rules zu tun hat, aber beim sichten des Logs sind mir noch 3 Warnungen aufgefallen die anscheinend alle das gleiche Problem haben. Aber woher die kommen ist mir nicht so ganz klar.

Code: Alles auswählen

2020-08-31 20:33:14.426 [WARN ] [ab.binding.mqtt.generic.ChannelState] - Command '{"Time":"2020-08-31T20:33:14","BME280":{"Temperature":22.5,"Humidity":41.4,"DewPoint":8.7,"Pressure":1014.6},"PressureUnit":"hPa","TempUnit":"C"}' not supported by type 'OnOffValue': No enum constant org.eclipse.smarthome.core.library.types.OnOffType.{"Time":"2020-08-31T20:33:14","BME280":{"Temperature":22.5,"Humidity":41.4,"DewPoint":8.7,"Pressure":1014.6},"PressureUnit":"hPa","TempUnit":"C"}
2020-08-31 20:33:30.006 [WARN ] [ab.binding.mqtt.generic.ChannelState] - Command '{"Time":"2020-08-31T20:33:30","BMP180":{"Temperature":21.7,"Pressure":1015.4},"PressureUnit":"hPa","TempUnit":"C"}' not supported by type 'OnOffValue': No enum constant org.eclipse.smarthome.core.library.types.OnOffType.{"Time":"2020-08-31T20:33:30","BMP180":{"Temperature":21.7,"Pressure":1015.4},"PressureUnit":"hPa","TempUnit":"C"}
2020-08-31 20:33:58.698 [WARN ] [ab.binding.mqtt.generic.ChannelState] - Command '{"Time":"2020-08-31T20:33:58","AM2301":{"Temperature":19.4,"Humidity":64.4,"DewPoint":12.5},"TempUnit":"C"}' not supported by type 'OnOffValue': No enum constant org.eclipse.smarthome.core.library.types.OnOffType.{"Time":"2020-08-31T20:33:58","AM2301":{"Temperature":19.4,"Humidity":64.4,"DewPoint":12.5},"TempUnit":"C"}
Bei allen dreien handelt es sich um Sensoren, wieso wird dann da OnOffValue bemängelt?

Antworten