Item.state Übergabe u. Überwachung mit Timer

Einrichtung der openHAB Umgebung und allgemeine Konfigurationsthemen.

Moderatoren: seppy, udo1toni

Heavy-Dee
Beiträge: 143
Registriert: 18. Jan 2018 16:38
Answers: 0

Item.state Übergabe u. Überwachung mit Timer

Beitrag von Heavy-Dee »

Nachdem ich meine Wandthermostate u. Themostatventile auf HomematicIP umgestellt habe,
möchte den Status meiner alten MAX! Fensterkontakte an HomematicIP übergeben.
Da das Homematic System ein wenig träge bei der Verarbeitung ist, möchte ich nach 10 Sek. kontrollieren ob der Status der Fensterkontakte übergeben wurde und ggf. das "sendCommand" wiederholen.

Die items der Fensterkontakte sind wie folgt angelegt:

Code: Alles auswählen

/* Allgemein: Dummy-Items */
    // Fensterstatus nach  Rule "Fenster-Toggle" für Homematic-Steuerung
    String MX_WEZ_Fenster_Status	// Wohn-/Esszimmer
    String MX_KZ1_Fenster_Status	// Kinderzimmer 1
    String MX_KZ2_Fenster_Status	// Kinderzimmer 2
// -------------------
/* Türkontakt Wohnzimmer */
    // Fensterkontakt (OPEN/CLOSED)
    Contact MX_WEZ_Kontakt_TuerWz	 "Terrasse  [MAP(heizung.map):%s]"	(grpKontakte)	{channel="max:shuttercontact:NEQ1633554:NEQ0846023:contact_state"}
Über eine Rule werden die einzelnen Kontakte Raumweise zusammen geführt und an die DummyItems übergeben!.

Code: Alles auswählen

 /* Wohn-/Esszimmer */
        if ((MX_WEZ_Kontakt_TuerWz.state == CLOSED) && (MX_WEZ_Kontakt_FensterWz.state == CLOSED) && (MX_WEZ_Kontakt_FensterEz.state == CLOSED)) { 
            MX_WEZ_Fenster_Status.postUpdate("CLOSED")
        }    
        else if ((MX_WEZ_Kontakt_TuerWz.state == OPEN) || (MX_WEZ_Kontakt_FensterWz.state == OPEN) || (MX_WEZ_Kontakt_FensterEz.state == OPEN)) {		
            MX_WEZ_Fenster_Status.postUpdate("OPEN")
        }
        /* Kinderzimmer 1 */
       // ...... 
Die Items für den Fensterkontakt am Homematic-System sind wie folgt angelegt.
Diese sind die speziellen Ein-/Ausgänge für die Gruppensteuerung (Gruppenchannel) bei Homematic

Code: Alles auswählen

    // Fensterstatus (OPEN/CLOSED)
    String HM_WEZ_Fenster	{channel="homematic:HmIP-HEATING:ccu:INT0000001:1#WINDOW_STATE"}
Jetzt zur eigentlichen Rule bzw. Problem !
(die ganzen logInfos nur temporär zur Kontrolle)

Code: Alles auswählen

val String valFileName = "HomeNet.individual.Heizungssteuerung.rules"
val String valRuleName
val String valStatus
var Timer vTimer = null
var Number vZaehler = null


rule "Fenster-Status" // Warteschleife für die Änderungen an den Türkontakten
when
    Item MX_WEZ_Fenster_Status received update or
    Item MX_KZ1_Fenster_Status received update or
    Item MX_KZ2_Fenster_Status received update
then 
val valRuleName = "Fenster-Status"
// Wohn-/Esszimmer
    if (triggeringItem.name == "MX_WEZ_Fenster_Status") {
            vTimer?.cancel
            vTimer = null       // Timer auf "null"
            vZaehler = 1        // Zähler auf "null"
            valStatus = ""
logInfo (valFileName + ":" + valRuleName, "getriggert: " + triggeringItem.name)
        // Statusübergabe an HomematiIP (open/closed)
valStatus = MX_WEZ_Fenster_Status.state.toString
        HM_WEZ_Fenster.sendCommand(valStatus)
logInfo (valFileName + ":" + valRuleName, "variable: " + valStatus)
        vTimer = createTimer(now.plusSeconds(10), [|
logInfo (valFileName + ":" + valRuleName, "Status HM: " + HM_WEZ_Fenster.state + " / Status MX: " + valStatus)
        // Überprüfung des Fensterstatus (HomematikIP / MAX-Fensterkontakte) nach 10 Sekunden
            if (HM_WEZ_Fenster.state != valStatus) {
                // erneute Statusübergabe
                HM_WEZ_Fenster.sendCommand(valStatus)
logInfo (valFileName + ":" + valRuleName, "Schleifenstatus HM: " + HM_WEZ_Fenster.state + " / Schleifenstatus MX: " + valStatus + " / Zähler: " + vZaehler)
                vZaehler = vZaehler + 1
                // Solange Timer neustarten bis Zählerwert erreicht
                if (vZaehler <= 5) {
                vTimer.reschedule(now.plusSeconds(10))                
                }
                else {
                    logWarn (valFileName + ":" + valRuleName, "Fehler bei Statusübergabe !")
                }
            }
            else {
logInfo (valFileName + ":" + valRuleName, "Status übertragen ! ")
                vTimer = null
            }
        ])

    }
 // Kinderzimmer 1
 // analog wie Wohn-/Esszimmer mit entsprechendem "triggeringItem.name"
    end
Die Rule funktioniert nur beim MX_WEZ_Fenster_Status -> "OPEN", bei MX_WEZ_Fenster_Status -> "CLOSED" erfolgt kein Übertrag nach Homematic.
LOG:

Code: Alles auswählen

2020-06-22 22:24:37.737 [INFO ] [izungssteuerung.rules:Fenster-Status] - getriggert: MX_WEZ_Fenster_Status
2020-06-22 22:24:37.739 [INFO ] [izungssteuerung.rules:Fenster-Status] - variable: OPEN
2020-06-22 22:24:47.741 [INFO ] [izungssteuerung.rules:Fenster-Status] - Status HM: OPEN / Status MX: OPEN
2020-06-22 22:24:47.743 [INFO ] [izungssteuerung.rules:Fenster-Status] - Status übertragen ! 
2020-06-22 22:27:01.423 [INFO ] [izungssteuerung.rules:Fenster-Status] - getriggert: MX_WEZ_Fenster_Status
2020-06-22 22:27:01.426 [INFO ] [izungssteuerung.rules:Fenster-Status] - variable: CLOSED
2020-06-22 22:27:11.428 [INFO ] [izungssteuerung.rules:Fenster-Status] - Status HM: OPEN / Status MX: CLOSED
2020-06-22 22:27:11.434 [INFO ] [izungssteuerung.rules:Fenster-Status] - Schleifenstatus HM: OPEN / Schleifenstatus MX: CLOSED / Zähler: 1
2020-06-22 22:27:21.445 [INFO ] [izungssteuerung.rules:Fenster-Status] - Status HM: OPEN / Status MX: CLOSED
2020-06-22 22:27:21.448 [INFO ] [izungssteuerung.rules:Fenster-Status] - Schleifenstatus HM: OPEN / Schleifenstatus MX: CLOSED / Zähler: 2
2020-06-22 22:27:31.451 [INFO ] [izungssteuerung.rules:Fenster-Status] - Status HM: OPEN / Status MX: CLOSED
2020-06-22 22:27:31.453 [INFO ] [izungssteuerung.rules:Fenster-Status] - Schleifenstatus HM: OPEN / Schleifenstatus MX: CLOSED / Zähler: 3
2020-06-22 22:27:41.455 [INFO ] [izungssteuerung.rules:Fenster-Status] - Status HM: OPEN / Status MX: CLOSED
2020-06-22 22:27:41.459 [INFO ] [izungssteuerung.rules:Fenster-Status] - Schleifenstatus HM: OPEN / Schleifenstatus MX: CLOSED / Zähler: 4
2020-06-22 22:27:51.462 [INFO ] [izungssteuerung.rules:Fenster-Status] - Status HM: OPEN / Status MX: CLOSED
2020-06-22 22:27:51.470 [INFO ] [izungssteuerung.rules:Fenster-Status] - Schleifenstatus HM: OPEN / Schleifenstatus MX: CLOSED / Zähler: 5
2020-06-22 22:27:51.471 [WARN ] [izungssteuerung.rules:Fenster-Status] - Fehler bei Statusübergabe !
Ich habe verschiedenste Varianten probiert:
z.B. mit Variablen
valStatus = MX_WEZ_Fenster_Status.state.toString
valStatus = MX_WEZ_Fenster_Status.state
ohne Variablen
HM_WEZ_Fenster.sendCommand(MX_WEZ_Fenster_Status.state)
HM_WEZ_Fenster.sendCommand(MX_WEZ_Fenster_Status.state.toString)
... das Ergebnis ist eigentlich immer gleich ;-(

Wäre schön wenn mir jmd. nen Tipp geben kann.

[openHab2 (v. 2.5) via Docker auf Synology DS216II ]
openHab4 (v. 4.1.0) Docker auf Synology DS920+ :!:

Heavy-Dee
Beiträge: 143
Registriert: 18. Jan 2018 16:38
Answers: 0

Re: Item.state Übergabe u. Überwachung mit Timer

Beitrag von Heavy-Dee »

Wenn ich mir die Daten der Items logge, bekomme ich folgende Ausgaben:
-> OPEN:

Code: Alles auswählen

2020-06-23 09:09:10.519 [INFO ] [izungssteuerung.rules:Fenster-Status] - HM: HM_WEZ_Fenster (Type=StringItem, State=OPEN, Label=null, Category=null)
2020-06-23 09:09:10.520 [INFO ] [izungssteuerung.rules:Fenster-Status] - MX: MX_WEZ_Fenster_Status (Type=StringItem, State=OPEN, Label=null, Category=null)
-> CLOSED:

Code: Alles auswählen

2020-06-23 09:11:16.623 [INFO ] [izungssteuerung.rules:Fenster-Status] - HM: HM_WEZ_Fenster (Type=StringItem, State=OPEN, Label=null, Category=null)
2020-06-23 09:11:16.626 [INFO ] [izungssteuerung.rules:Fenster-Status] - MX: MX_WEZ_Fenster_Status (Type=StringItem, State=CLOSED, Label=null, Category=null)
openHab4 (v. 4.1.0) Docker auf Synology DS920+ :!:

Benutzeravatar
peter-pan
Beiträge: 2758
Registriert: 28. Nov 2018 12:03
Answers: 30
Wohnort: Schwäbisch Gmünd

Re: Item.state Übergabe u. Überwachung mit Timer

Beitrag von peter-pan »

Ich hab mir deine Regel nicht genau angeschaut, aber mir ist aufgefallen, dass du die "Status" deiner Items pro Zimmer immer einzeln abfragst. Das habe ich am Anfang auch probiert, das ist aber nix !!!. Dann bin draufgekommen, dass das viel einfacher geht mit einem Gruppen-Item pro Raum.

Hier ein Beispiel für's Arbetiszimmer:

Die (teilweise verlinkt) Items:

Code: Alles auswählen

Group:Contact:OR(OPEN,CLOSED)      gWindowOffice                      "Fensterkontakte Büro [MAP(de.map):%s]"                                            
Contact                HmIP_SWDO_DB1C_1STATECONTACT                   "Fenster Arbeitszimmer Ost Kontakt[MAP(de.map):%s]"                 <window>            (gWindow,EG_Buro,gWindowOffice)      {channel="homematic:HMIP-SWDO:ABCDE:EFGHI:1#STATE_CONTACT"}
Contact                HmIP_SWDO_D6D5_1STATECONTACT                   "Fenster Arbeitszimmer Nord Kontakt[MAP(de.map):%s]"                <window>            (gWindow,EG_Buro,gWindowOffice)      {channel="homematic:HMIP-SWDO:ABCDE:EFGHI:1#STATE_CONTACT"}
und die Regel für die Steuerung:

Code: Alles auswählen

//===============================================================================
rule "Fenster Arbeitszimmer Offen"
    when
      Item gWindowOffice changed from "CLOSED" to "OPEN" 
    then
	  if(radiator_valve_01_Mode.state == "OFF") return;  // Es sind bereits Fenster offen bzw. der Thermostat ist ausgeschaltet
      radiator_valve_01_Set_prev.postUpdate(radiator_valve_01_Set.state)
      radiator_valve_01_Mode_prev.postUpdate(radiator_valve_01_Mode.state)
      radiator_valve_01_Mode.sendCommand("OFF")
      logInfo("Fenster Arbeitszimmer Offen"," radiator_valve_01_Set {}", radiator_valve_01_Set)
end
//===============================================================================
rule "Fenster Arbeitszimmer Geschlossen"
    when
      Item gWindowOffice changed from "OPEN" to "CLOSED"
    then
      if ((radiator_valve_01_Mode_prev.state == "ECO") || (radiator_valve_01_Mode_prev.state == "COMFORT") || (radiator_valve_01_Mode_prev.state == "OFF")) {
        radiator_valve_01_Mode.sendCommand(radiator_valve_01_Mode_prev.state.toString)
        logInfo("Fenster Arbeitszimmer Geschlossen"," radiator_valve_01_Set {}", radiator_valve_01_Set)
      }
      if (radiator_valve_01_Mode_prev.state == "ON") {
        radiator_valve_01_Set.sendCommand(radiator_valve_01_Set_prev.state as Number)
        logInfo("Fenster Arbeitszimmer Geschlossen"," radiator_valve_01_Set {}", radiator_valve_01_Set)
      }
end
Hier ist zunächst der Trigger-Teil interessant. Sobald ein Item(Kontakt/Fenster/Tür) der Gruppe (hier:gWindowOffice ) " geöffnet wird, wird das Gruppen-Item auf "OPEN" gesetzt und erst wenn alle Items(Kontakte/Fenster/Türen) der Gruppe wieder geschlossen sind, wird das Gruppen-Item wieder auf "CLOSED" gesetzt.

Der Ablauf-Teil ist dann wieder individuell. Ich habe für meine Heizkörper Thermostat-Ventile von AVM/Comet im Einsatz. Die hatte ich schon bevor ich mir eine "ccu3" angeschafft habe.
In meiner Regel "Fenster Arbeitszimmer Offen" passiert Folgendes: Wenn ein Fenster geöffnet wird, werden der Thermostat-Status und die aktuelle Soll-Temperatur in "Dummy-Items" gespeichert und das Thermostat ausgeschaltet.

Wenn alle Fenster wieder geschlossen sind, wird der Thermostat wieder angeschaltet. Allerdings muss ich hier noch überprüfen, ob ein "Standard-Modus (ECO/COMFORT/OFF)" eingestellt war, oder ob eine individuelle Temperatur (ON) gewählt wurde.

Die Anzeige in OH2, ob ein Fenster geöffnet oder geschlossen wurde, geht bei mir ziemlich zügig, d.h. ich habe an den Fensterkontakten eine Verzögerung von 3. Sek. eingebaut (in Homematic). Im Normalfall, wird das auch sofort (per Rule) an den Thermostaten umgesetzt, kann aber lt. AVM-Fritz bis zu 15 Minuten dauern (hab ich aber noch nie bemerkt). Das soll wohl mit dem "Deep-Sleep-Modus" der Batterie-Geräte zusammen hängen.

Ich benutze den Kanal "STATE_CONTACT" des Kontaktes(Item-Type:Contact) und nicht "STATE" (Item-Type:String). Allerdings habe ich nicht ganz verstanden, was du da mit deinen Dummy-Items machst und warum du den Fenster-Status von deinem verlinkten Item (Fenster-Kontakt) überschreiben willst.
Pi5/8GB(PiOS Lite 64-bit(bookworm)/SSD 120GB - OH4.3.5 openhabian

Heavy-Dee
Beiträge: 143
Registriert: 18. Jan 2018 16:38
Answers: 0

Re: Item.state Übergabe u. Überwachung mit Timer

Beitrag von Heavy-Dee »

Es kommt ja öfters mal vor das man die Terassentüre öffnet und sofort wieder schließt oder von geöffnet über schließen in kippen!
Um einen kurzzeitigen Toggle der Signale zu verhindern, habe ich eine Timerschleife benutzt, die erst nach 30 Sek. das "endgültige" Signal weiter gibt.

Code: Alles auswählen

var Timer varKontakt_Verzoegerung


// ------------------------------------------------------------------

rule "Kontaktprellung"  // Schleife gegen PRELLEN bei Fenster-/Türkontakten für Heizungssteuerung
when
    Item grpKontakte changed
then
    val String valRuleName = "Kontaktprellung"
    var Timer varKontakt_Verzoegerung = null

    // Überprüfung ob Verzoegerung = Null, sonst Neustart !
    if (varKontakt_Verzoegerung === null) {
        // Wartezeit für Statusänderung der Fensterkontakte
        varKontakt_Verzoegerung = createTimer(now.plusSeconds(30), [|
        // nach Verzoegerungszeit !

        /* Wohn-/Esszimmer */
        if ((MX_WEZ_Kontakt_TuerWz.state == CLOSED) && (MX_WEZ_Kontakt_FensterWz.state == CLOSED) && (MX_WEZ_Kontakt_FensterEz.state == CLOSED)
        ) { 
            MX_WEZ_Fenster_Status.postUpdate("CLOSED")
        }    
        else if ((MX_WEZ_Kontakt_TuerWz.state == OPEN) || (MX_WEZ_Kontakt_FensterWz.state == OPEN) || (MX_WEZ_Kontakt_FensterEz.state == OPEN)
        ) {		
            MX_WEZ_Fenster_Status.postUpdate("OPEN")
        }
        else {
            // Wenn kein gültiger Wert von Kontakt 
            logWarn (valFileName +":"+ valRuleName, "Kontaktstatus: kein gültiger Wert für 'MX_WEZ_Kontakte' [" + MX_WEZ_Kontakt_TuerWz.state + "/" + MX_WEZ_Kontakt_FensterWz.state + "/" + MX_WEZ_Kontakt_FensterEz.state + "]")
            Thread::sleep(1000)
            MX_WEZ_Kontakt_TuerWz.postUpdate(CLOSED)
            Thread::sleep(500)
            MX_WEZ_Kontakt_FensterWz.postUpdate(CLOSED)
            Thread::sleep(500)
            MX_WEZ_Kontakt_FensterEz.postUpdate(CLOSED)
            Thread::sleep(3000)
            logInfo (valFileName +":"+ valRuleName, "Kontaktstatus: 'HM_WEZ_Kontakte' -> " +  MX_WEZ_Kontakt_TuerWz.state + "/" + MX_WEZ_Kontakt_FensterWz.state + "/" + MX_WEZ_Kontakt_FensterEz.state) 
        }
            // Timer rücksetzen !
            varKontakt_Verzoegerung = null          
        ])  
    } 
    else if (varKontakt_Verzoegerung !== null) {
        // Timer neustarten, Änderung in der DelayZeit !    
        varKontakt_Verzoegerung.reschedule(now.plusSeconds(15))
    }
    else {
        var String valWarnMsg = "Laufzeit überschritten: " + varKontakt_Verzoegerung
        logWarn (valFileName + ":" + valRuleName, valWarnMsg)  
    }
end
KontaktItems:

Code: Alles auswählen

/* Türkontakt Wohnzimmer */
    // Fensterkontakt (OPEN/CLOSED)
    Contact MX_WEZ_Kontakt_TuerWz
        "Terrasse  [MAP(heizung.map):%s]"
        <windoor>
        (grpKontakte,grpKontakte_WEZ)
        {channel="max:shuttercontact:NEQ1633554:NEQ0846023:contact_state"}
    // niedriger Batteriestatus (ON/OFF)
    Switch MX_WEZ_Kontakt_TuerWz_Batterie
        (grpBatteriestoerung)
        {channel="max:shuttercontact:NEQ1633554:NEQ0846023:battery_low"}
openHab4 (v. 4.1.0) Docker auf Synology DS920+ :!:

Benutzeravatar
peter-pan
Beiträge: 2758
Registriert: 28. Nov 2018 12:03
Answers: 30
Wohnort: Schwäbisch Gmünd

Re: Item.state Übergabe u. Überwachung mit Timer

Beitrag von peter-pan »

Also die Verzögerung bei einem Homematic-Kontaktsensor ist relativ einfach einzustellen und man braucht eigentlich keine Regel dazu:
verz.jpg
Ich habe das bei allen meinen Kontakten auf 3 Sekunden eingestellt (hab ich so für mich ermittelt), es geht aber auch jeder andere Wert.

Frage:
Gibt es den Sensor "String HM_WEZ_Fenster" wirklich als physischen Homematic-Sensor und ist der auch in Homematic bekannt? Ich frage deshalb so blöd, weil ich bisher nicht sehr viel mit Homematic gemacht habe, ausser, dass ich mir eine "ccu3" angeschafft habe und ein paar Sensoren (12) und eine Aussentemperaturmessung darüber laufen lasse. Das geht aber mehr oder weniger alles automatisch in Homematic und die Anbindung an Openhab ist auch über PaperUi (Autodiscovery+ Binding-Installation) gelaufen. Lediglich die Items habe ich als Textdatei mit VSC angelegt(auch mehr oder weniger automatisch).
Ich könnte mir nämlich vorstellen, dass ein Ändern des Kontakt-Status eines verlinkten Items gar nicht möglich sein sollte, da der Status vom jeweiligen Zustand des verlinkten Items bestimmt wird und nicht vom Benutzer.
Pi5/8GB(PiOS Lite 64-bit(bookworm)/SSD 120GB - OH4.3.5 openhabian

Heavy-Dee
Beiträge: 143
Registriert: 18. Jan 2018 16:38
Answers: 0

Re: Item.state Übergabe u. Überwachung mit Timer

Beitrag von Heavy-Dee »

"String HM_WEZ_Fenster" ist kein physischer Schalter. Das ist ein Ein-/Ausgabekanal für eine, in Homematic definierte Gruppe. ( {channel="homematic:HmIP-HEATING:ccu:INT0000001:1#WINDOW_STATE"}).
Meine physischen Schalter sind von MAX! und können nicht an der CCU angelernt werde. Dafür ist der Max!Cube zuständig.
openHab4 (v. 4.1.0) Docker auf Synology DS920+ :!:

Benutzeravatar
peter-pan
Beiträge: 2758
Registriert: 28. Nov 2018 12:03
Answers: 30
Wohnort: Schwäbisch Gmünd

Re: Item.state Übergabe u. Überwachung mit Timer

Beitrag von peter-pan »

Ok ?!
Noch 'ne Frage:
Braucht man dann keine hinzufügbaren Geräte für die Gruppe ?

Ich hab mal so eine Gruppe angelegt und da wurde ich dann gefragt, welche Sensoren in die Gruppe mit aufgenommen werden sollen. Müsstest du das nicht auch, oder reicht da ein "virtuelles" Gerät in Homematic (das wird als Thermostat(e) angezeigt ? Mir ist der Zusammenhang noch nicht ganz klar.
Pi5/8GB(PiOS Lite 64-bit(bookworm)/SSD 120GB - OH4.3.5 openhabian

Heavy-Dee
Beiträge: 143
Registriert: 18. Jan 2018 16:38
Answers: 0

Re: Item.state Übergabe u. Überwachung mit Timer

Beitrag von Heavy-Dee »

Ich habe eine Gruppe pro Raum angelegt. Mit dieser Gruppe habe ich den entsprechenden Wandthermostat und die Thermostatventile verknüft.
Die Solltemperaturen, Statuswerte ect. werden über die GruppenID's (INT0000001, INT0000002, ...) nicht über die Einzelgeräte übermittelt.
In diesen Gruppen gibt es über #WINDOW_STATE die Möglichkeit den Status zu setzen oder auszulesen. Wird der Status dort gesetzt, übermittelt HM diesen an alle relevanten Geräte in der Gruppe. d.h. Am Wandthermostat wird das geöffnete Fenster angezeigt und alle mit dem Raum verknüpften Thermostatventile werden entsprechend geschlossen. HM regelt dann den vorgegebenen Temperaturwert.
In https://smarthouse-control.de/2018/11/1 ... c-openhab/ Artikel ist das Gruppenprinzip gut dargestellt.
openHab4 (v. 4.1.0) Docker auf Synology DS920+ :!:

Benutzeravatar
peter-pan
Beiträge: 2758
Registriert: 28. Nov 2018 12:03
Answers: 30
Wohnort: Schwäbisch Gmünd

Re: Item.state Übergabe u. Überwachung mit Timer

Beitrag von peter-pan »

Danke für deine Info. Das hört sich gar nicht mal so schlecht an.
Das muss ich mir nochmal genauer anschauen. Aber beim quer lesen habe ich gesehen, dass alle Geräte von Homematic sind und dazu auch für die virtuellen Devices ein "Thing" angelegt werden muss. Da meine Thermostate aber von AVM sind, müsste ich erst mal prüfen, ab sich das überhaupt so realisieren lässt (Profile, etc)
Pi5/8GB(PiOS Lite 64-bit(bookworm)/SSD 120GB - OH4.3.5 openhabian

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

Re: Item.state Übergabe u. Überwachung mit Timer

Beitrag von udo1toni »

Ich hänge mich hier mal rein... Und ich betrachte die ursprüngliche Rule.
Die Rule kann eigentlich gar nicht funktionieren, denn schon der erste Befehl sollte ein WARN schmeißen. Du hast valRuleName nämlich global als Konstante definiert und definierst sie erneut innerhalb der Rule, das ist nicht erlaubt. Abgesehen davon ist das ganze gelogge nicht so, wie das Logging verwendet werden soll. Der Logger heißt (unabänderlich) "org.openhab.model.script." + 1. String aus dem log-Befehl. Du kannst natürlich den Loggernamen beliebig ergänzen, die Vorgehensweise ist aber denkbar ungünstig.

Auch die Variable valStatus hast Du ungünstigerweise als Konstante globlal definiert. Sie kann also nie einen anderen als den Ursprungswert annehmen.
Ich hab noch nicht weiter gucken können, weil ich jetzt erst mal einen Termin habe. aber so als Anregung:

Code: Alles auswählen

var String varStatus = ""
var Timer vTimer = null
var Number vZaehler = 0


rule "Fenster-Status" // Warteschleife für die Änderungen an den Türkontakten
when
    Item MX_WEZ_Fenster_Status received update or
    Item MX_KZ1_Fenster_Status received update or
    Item MX_KZ2_Fenster_Status received update
then 
    if(triggeringItem.name == "MX_WEZ_Fenster_Status") {                                                    // Wohn-/Esszimmer
        vTimer?.cancel
        vTimer = null       // Timer auf "null"
        vZaehler = 1        // Zähler auf "null"
        varStatus = ""
        logInfo ("Fenster-Status", "getriggert: " + triggeringItem.name)
        varStatus = MX_WEZ_Fenster_Status.state.toString
        HM_WEZ_Fenster.sendCommand(varStatus)                                                                // Statusübergabe an HomematiIP (open/closed)
        logInfo ("Fenster-Status", "variable: {}", varStatus)
        vTimer = createTimer(now.plusSeconds(10), [|                                                        // Überprüfung des Fensterstatus (HomematikIP / MAX-Fensterkontakte) nach 10 Sekunden
            logInfo ("Fenster-Status", "Status HM: {} / Status MX: {}",HM_WEZ_Fenster.state,  varStatus)
            if (HM_WEZ_Fenster.state != varStatus) {                                                        // erneute Statusübergabe
                HM_WEZ_Fenster.sendCommand(varStatus)
                logInfo ("Fenster-Status", "Schleifenstatus HM: {} / Schleifenstatus MX: {} / Zähler: {}",HM_WEZ_Fenster.state, varStatus, vZaehler)
                vZaehler = vZaehler + 1
                if (vZaehler <= 5) {                                                                        // Solange Timer neustarten bis Zählerwert erreicht
                    vTimer.reschedule(now.plusSeconds(10))
                } else {
                    logWarn ("Fenster-Status", "Fehler bei Statusübergabe!")
                }
            } else {
                logInfo ("Fenster-Status", "Status übertragen!")
                vTimer = null
            }
        ])
    }
    // Kinderzimmer 1
    // analog wie Wohn-/Esszimmer mit entsprechendem "triggeringItem.name"
end
Grundsätzlich wäre es aber sinnvoller,
1. herauszufinden, warum eine Statusübergabe nicht geklappt hat (bis zu 5 Versuche...)
2. Die Rule so zu gestalten, dass der Code nicht doppelt aufgeführt werden muss, nur, weil es sich um unterschiedliche Zielitems handelt. Das geht, indem man die Namen der Items geschickt wählt und sie Gruppen zuweist. Wird ein Item in einer Gruppe geändert, sucht die Rule das passende Item aus der 2. Gruppe anhand des Namens heraus und ändert dieses. Die Timer und itemspezifische globale Variablen muss man dann natürlich über Hashmaps realisieren. Als Belohnung muss man dann aber keine weitere Codezeile programmieren, wen zusätzliche gleichartige Items dazu kommen (hier weitere Fenster in weiteren Räumen)
openHAB4.3.3 stable in einem Debian-Container (bookworm) (Proxmox 8.3.5, LXC), mit openHABian eingerichtet

Antworten