Rule erst Starten wenn OpenHab sauber hochgefahren ist

Einrichtung der openHAB Umgebung und allgemeine Konfigurationsthemen.

Moderatoren: seppy, udo1toni

Antworten
Benutzeravatar
PeterA
Beiträge: 1106
Registriert: 8. Feb 2019 12:12
Answers: 13

Rule erst Starten wenn OpenHab sauber hochgefahren ist

Beitrag von PeterA »

Hallo Udo,

vielleicht kannst Du Dich noch an dieses wunderbare Rule Konstrukt erinnern:

Code: Alles auswählen

//https://openhabforum.de/viewtopic.php?p=23905#p23905 by UdoToni/
import java.util.HashMap

val HashMap <String,String> hmRoller = newHashMap(  "InnenDG"            -> "Shellyswitch25_745118_roller",               // von Sensor nach Shutter
                                                    "InnenDGKind1"       -> "Shellyswitch25_00B713_roller",
                                                    "InnenDGKind2"       -> "Shellyswitch25_E58F7A_roller",
                                                    "InnenWHZ"           -> "Shellyswitch25_740A26_roller",
                                                    "InnenEGAbstellraum" -> "Shellyswitch25_E66E4E_roller",
                                                    "InnenEGKueche"      -> "Shellyswitch25_00B12B_roller"
)

val HashMap <String,String> hmSensor = newHashMap(  "Shellyswitch25_745118_roller" -> "InnenDG",                          // von Shutter nach Sensor
                                                    "Shellyswitch25_00B713_roller" -> "InnenDGKind1",
                                                    "Shellyswitch25_E58F7A_roller" -> "InnenDGKind2",
                                                    "Shellyswitch25_740A26_roller" -> "InnenWHZ",
                                                    "Shellyswitch25_E66E4E_roller" -> "InnenEGAbstellraum",
                                                    "Shellyswitch25_00B12B_roller" -> "InnenEGKueche"
)

var Boolean bUpdate = false                                                                                               // Sperrvariable
var String strSensor = ""

rule "Update Kombi Item"
when
    Member of gTemp changed or
    Member of gHum changed or
    Member of gruppeRolladen_Sued changed or
    Member of gruppeRolladen_West changed
then
    if(bUpdate) {                                                                                                         // Falls Sperre aktiv
        logInfo("kombiupdate","Doppeltrigger. Abbruch!")
        return;                                                                                                           // Rule abbrechen
    }
    bUpdate = true                                                                                                        // Sperre aktivieren
    strSensor = triggeringItem.name.split("_").get(0)                                                                     // Sensor bestimmen
    if(triggeringItem.name.contains("Shellyswitch25")) {                                                                  // Falls ein Rollershutter die Rule getriggert hat
        if(hmSensor.get(triggeringItem.name) !== null)                                                                    // Falls in der Hashmap enthalten
            strSensor = hmSensor.get(triggeringItem.name)                                                                 // Ermittle Sensornamen
        else {                                                                                                            // falls nicht in der Hashmap enthalten
            logInfo("kombiupdate","Rollladen ohne Sensoren. Abbruch!")
            bUpdate = false                                                                                               // Sperrvariable zurücksetzen
            return;                                                                                                       // Rule abbrechen
        }
    }
    logInfo("kombiupdate","var String strSensor: {}",strSensor)
                                                                                                                          // zugehörige Items bestimmen
    val ItemTempTendenz =  gTempTendenz.members.findFirst[i|i.name.split("_").get(0) == strSensor] as StringItem          // Item für Temperatur Tendenz bestimmen
    logInfo("kombiupdate","ItemTempTendenz: {}",ItemTempTendenz.name)
    val ItemTempProxy   =    gTempProxy.members.findFirst[i|i.name.split("_").get(0) == strSensor] as NumberItem          // Proxy Item für Temperatur bestimmen
    logInfo("kombiupdate","ItemTempProxy: {}",ItemTempProxy.name)
    val ItemHumTendenz  =   gHumTendenz.members.findFirst[i|i.name.split("_").get(0) == strSensor] as StringItem          // Item für Feuchte Tendenz bestimmen
    logInfo("kombiupdate","ItemHumTendenz: {}",ItemHumTendenz.name)
    val ItemHumProxy    =     gHumProxy.members.findFirst[i|i.name.split("_").get(0) == strSensor] as NumberItem          // Proxy Item für Feuchte bestimmen
    logInfo("kombiupdate","ItemHumProxy: {}",ItemHumProxy.name)
    val ItemTemp        =         gTemp.members.findFirst[i|i.name.split("_").get(0) == strSensor] as NumberItem          // Temperatur Item bestimmen
    logInfo("kombiupdate","ItemTemp: {}",ItemTemp.name)
    val ItemHum         =          gHum.members.findFirst[i|i.name.split("_").get(0) == strSensor] as NumberItem          // Feuchte Item bestimmen
    logInfo("kombiupdate","ItemHum: {}",ItemHum.name)
    val ItemKombi       =        gKombi.members.findFirst[i|i.name.split("_").get(0) == strSensor] as StringItem          // Kombi Item bestimmen
    logInfo("kombiupdate","ItemKombi: {}",ItemKombi.name)
    val ItemShutter = if(hmRoller.get(strSensor) !== null)                                                                // falls Rollladen vorhanden
        grAllshutters.allMembers.findFirst[i|i.name == hmRoller.get(strSensor)]  as RollershutterItem                     // Rolladen Pos Item bestimmen.
    else
        null
                                                                                                                          // Werte bestimmen
    val Number nTempProxy = if(ItemTempProxy.state instanceof Number) (ItemTempProxy.state as Number) else 0              // Temperatur Proxy auslesen
    val Number nTemp = if(ItemTemp.state instanceof Number) (ItemTemp.state as Number).floatValue else nTempProxy         // Temperatur auslesen
    logInfo("kombiupdate","Temperatur neu {}°C alt {}°C",nTemp,nTempProxy)
    val Number nHumProxy  = if(ItemHumProxy.state instanceof Number) (ItemHumProxy.state as Number) else 0                // Feuchte  Proxy auslesen
    val Number nHum  = if(ItemHum.state instanceof Number) (ItemHum.state as Number).floatValue else nHumProxy            // Feuchte auslesen
    logInfo("kombiupdate","Luftfeuchte neu {}% alt {}%",nHum,nHumProxy)
                                                                                                                          // Tendenz Temperatur
    var String strTempTendence = "⬅️➡️"                                                                                    // Default String für Tendenz Anzeige
    var String strTempMessage = "stagnierend"                                                                             // Default String für Tendenz Logmeldung
    if(nTemp > nTempProxy) {                                                                                              // falls aktuelle Temperatur höher als alte Temperatur
        strTempTendence = "⬆️"                                                                                            // String für Tendenz Anzeige steigend
        strTempMessage = "steigend"                                                                                       // String für Logmeldung steigend
    }
    if(nTemp < nTempProxy) {                                                                                              // falls aktuelle Temperatur geringer als alte Temperatur
        strTempTendence = "⬇️"                                                                                            // String für Tendenz Anzeige sinkend
        strTempMessage = "fallend"                                                                                        // String für Logmeldung sinkend
    }
    logInfo("kombiupdate","Sensor {} Temperatur {}",strSensor,strTempMessage)                                             // Logmeldung ausgeben
    ItemTempProxy.postUpdate(nTemp)                                                                                       // Neue Temperatur in Proxy Item übernehmen
    ItemTempTendenz.postUpdate(strTempTendence)                                                                           // Tendenz Item setzen
                                                                                                                          // Tendenz Feuchte
    var String strHumTendence = "⬅️➡️"                                                                                     // Default String für Tendenz Anzeige
    var String strHumMessage = "stagnierend"                                                                              // Default String für Tendenz Logmeldung
    if(nHum > nHumProxy) {                                                                                                // falls aktuelle Feuchte höher als alte Feuchte
        strHumTendence = "⬆️"                                                                                             // String für Tendenz Anzeige steigend
        strHumMessage = "steigend"                                                                                        // String für Logmeldung steigend
    }
    if(nHum < nHumProxy) {                                                                                                // falls aktuelle Feuchte geringer als alte Feuchte
        strHumTendence = "⬇️"                                                                                             // String für Tendenz Anzeige sinkend
        strHumMessage = "fallend"                                                                                         // String für Logmeldung sinkend
    }
    logInfo("kombiupdate","Sensor {} Feuchte {}",strSensor,strHumMessage)                                                 // Logmeldung ausgeben
    ItemHumProxy.postUpdate(nHum)                                                                                         // Neue Feuchte in Proxy Item übernehmen
    ItemHumTendenz.postUpdate(strHumTendence)                                                                             // Tendenz Item setzen
                                                                                                                          // Kombiitem setzen
    var String strKombi = strTempTendence + " " + String::format("%.1f °C / ",nTemp) + strHumTendence + " " + String::format("%.0f %%",nHum) // Kombinierter String ohne Shutter
    if(ItemShutter !== null)                                                                                              // Falls es ein passendes Shutteritem gibt
        strKombi = "Rollladen: " + ItemShutter.state.toString + "% / " + strKombi                                         // füge den Shutterstatus vorne an
    ItemKombi.postUpdate(strKombi)                                                                                        // Setze das Kombiitem
    bUpdate = false                                                                                                       // Sperrvariable zurücksetzen
end
Dieses Rule läuft wunderbar.
Nur bei bzw. im laufe eines Neustart von OpenHab (2.4) gibt es "Doppeltrigger" und die Rule wird gesperrt.
Das bekomme ich nur weg in dem ich die Rule quasi neu Speichere und damit wird die "bUpdate" Sperrvariable zurück gesetzt.
Wie könnte ich das lösen ? Die Rule erst aktivieren wenn das System komplett sauber hochgefahren ist ?

Gruß Peter
- OpenHab 2.4
#PWRUP

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

Re: Rule erst Starten wenn OpenHab sauber hochgefahren ist

Beitrag von udo1toni »

Die Frage ist, warum die Rule nicht durch läuft. Die Doppeltrigger sind klar, weil beim Systemstart zu schnell zu viele Werte rein kommen. Die variable bUpdate muss aber immer wieder auf false zurück springen, es sei denn, die Rule bleibt mit einem Ausnahmefehler hängen.

Gibt es denn Fehlermeldungen beim Systemstart?
openHAB4.3.3 stable in einem Debian-Container (bookworm) (Proxmox 8.3.5, LXC), mit openHABian eingerichtet

Benutzeravatar
PeterA
Beiträge: 1106
Registriert: 8. Feb 2019 12:12
Answers: 13

Re: Rule erst Starten wenn OpenHab sauber hochgefahren ist

Beitrag von PeterA »

Joar schon.
Aber das sind viele erstmal weil viele Items noch nicht befüllt sind usw.

Aber einen Fehler wirft diese Rule nicht
- OpenHab 2.4
#PWRUP

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

Re: Rule erst Starten wenn OpenHab sauber hochgefahren ist

Beitrag von udo1toni »

Dann kann die Variable aber nicht auf true stehen bleiben. Die Rule muss irgendwo abbrechen, bevor sie bei der letzten Zeile angekommen ist.

Du kannst einen schmutzigen Workaround einbauen und die Variable z.B. 60 Sekunden nach System started auf false setzen. aber das löst ja nicht das eigentliche Problem, sondern übertüncht es nur.

Grundsätzlich sollte Die Rule auch ohne das Sperren funktionieren. Man könnte noch darüber nachdenken, die Sperre abhängig vom triggernden Item zu machen, falls tatsächlich innerhalb Millisekunden zum gleichen Item mehrere changes kommen sollten.
openHAB4.3.3 stable in einem Debian-Container (bookworm) (Proxmox 8.3.5, LXC), mit openHABian eingerichtet

Benutzeravatar
PeterA
Beiträge: 1106
Registriert: 8. Feb 2019 12:12
Answers: 13

Re: Rule erst Starten wenn OpenHab sauber hochgefahren ist

Beitrag von PeterA »

Leider hab ich nicht sehen können wann der Doppeltrigger genau kommt.
Da ist soviel Los im Log während einem Neustart.
Wenn alles wieder normal läuft bleibt die Rule quasi im Status "Doppeltrigger"

Im normalen Alltagsbetrieb kommen Doppeltrigger aber sehr selten vor.
- OpenHab 2.4
#PWRUP

Benutzeravatar
PeterA
Beiträge: 1106
Registriert: 8. Feb 2019 12:12
Answers: 13

Re: Rule erst Starten wenn OpenHab sauber hochgefahren ist

Beitrag von PeterA »

Könnte ich denn die Variable von Hand also bei Bedarf selbst auf "false" setzen ?
Also mit einem Switch und Rule ?

Gruß Peter
- OpenHab 2.4
#PWRUP

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

Re: Rule erst Starten wenn OpenHab sauber hochgefahren ist

Beitrag von udo1toni »

Wie gesagt, das ist kein Problem, solange die Rule, die sich darum kümmert, in der selben Datei definiert ist. Aber noch mal: es ist schlicht nicht möglich, dass die Variable auf true bleibt, ohne dass die Rule mit einem Fehler aussteigt. Wenn Du in Deinem Log beim Systemstart viele Fehlermeldungen hast, solltest Du diese Stück für Stück untersuchen und beseitigen. Ein normaler Systemstart sollte eigentlich gar keine Fehler ausgeben.
openHAB4.3.3 stable in einem Debian-Container (bookworm) (Proxmox 8.3.5, LXC), mit openHABian eingerichtet

Benutzeravatar
PeterA
Beiträge: 1106
Registriert: 8. Feb 2019 12:12
Answers: 13

Re: Rule erst Starten wenn OpenHab sauber hochgefahren ist

Beitrag von PeterA »

Also. Ich hab mir nun mal zwei Rules geschrieben mit welchen ich Variable "bUpdate" auf "true" oder "false" setzen kann.
Setze ich auf "true". Meldet die Rule "Doppeltrigger"
Setze ich auf "false". Läuft die Rule ganz normal weiter.
Keine Fehlermeldung.
So solls erstmal für mich ausreichen. Neustarts von OpenHab kommen zum Glück nicht so oft vor.

Gruß Peter
- OpenHab 2.4
#PWRUP

Antworten