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

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

Beitrag von Heavy-Dee »

Danke für den Tipp,
Ich werde mir das heute Abend mal genauer ansehen, aber ein Fehler wird mir nicht ausgegeben.
Der von dir genannte Pkt. 2 ist für mich nachvollziehbar, aber das ist ungefähr so als ob du einem "Blinden" (...mir) einen Farbfernseher erklären möchtest. ( Hashmaps ??? )
Aber ich versuche mal meinen Freund GOOGLE zu kontaktieren.
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 »

@ udo1toni
Als erstes habe meine Fensterkontakte entsprechend der Räumen zu Gruppen zusammen gefasst und somit die rule für die Fensterkontakte aufgelöst.

Code: Alles auswählen

    Group:Contact:OR(OPEN, CLOSED) grpKontakte_WEZ_Hz
    Group:Contact:OR(OPEN, CLOSED) grpKontakte_KZ1_Hz
    Group:Contact:OR(OPEN, CLOSED) grpKontakte_KZ2_Hz
als nächstes habe ich aus dem Trigger den Namen des Ziel-Items gebastelt,
macht z.B. aus "grpKontakte_WEZ_Hz" -> "HM_WEZ_Fenster"

Code: Alles auswählen

    // Umwandlung des auslösenden Gruppenamens in den auszuführenden Itemnamen
    // macht  aus "grpKontakte_xxx_Hz" -> "HM_xxx_Fenster"
    val trigItemStr1 = triggeringItem.name
    val trigItemStr2 = trigItemStr1.replace("grpKontakte_","HM_")
    val zielitem = trigItemStr2.replace("Hz","Fenster")
    logInfo (valFileName + ":" + valRuleName, zielItem)
Jetzt würde ich gerne dem Ziel-Item den Status/Wert der Gruppe übergeben.

Habe versucht ein paar Infos über Hashmaps zu bekommen (https://community.openhab.org/t/design- ... ules/36210)
Aber irgendwie werde ich nicht Schlau daraus.

Bei der rule "Systemstart"

Code: Alles auswählen

 rule "Systemstart"
    when
        System started
    then
        // Fensterstatus
        FensterOffen.put("HM_WEZ_Fenster", "OPEN")
        FensterOffen.put("HM_KZ1_Fenster", "OPEN")
        FensterOffen.put("HM_KZ2_Fenster", "OPEN")

        FensterGeschlossen.put("HM_WEZ_Fenster", "CLOSED")
        FensterGeschlossen.put("HM_KZ1_Fenster", "CLOSED")
        FensterGeschlossen.put("HM_KZ2_Fenster", "CLOSED")
end
bekomme ich schon folgende Fehlermeldung:

Code: Alles auswählen

020-06-26 13:20:18.412 [ERROR] [ntime.internal.engine.RuleEngineImpl] - Error during the execution of startup rule 'Systemstart': 'put' is not a member of 'Object'; line 27, column 9, length 42
.

Bin jetzt eigentlich ganz, ganz weit weg von meinem ursprünglichen Problem, aber vielleicht löst es sich dann leichter.!
openHab4 (v. 4.1.0) Docker auf Synology DS920+ :!:

thomas_w

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

Beitrag von thomas_w »

Heavy-Dee hat geschrieben: 26. Jun 2020 13:49
Bei der rule "Systemstart"

Code: Alles auswählen

 rule "Systemstart"
    when
        System started
    then
        // Fensterstatus
        FensterOffen.put("HM_WEZ_Fenster", "OPEN")
        FensterOffen.put("HM_KZ1_Fenster", "OPEN")
        FensterOffen.put("HM_KZ2_Fenster", "OPEN")

        FensterGeschlossen.put("HM_WEZ_Fenster", "CLOSED")
        FensterGeschlossen.put("HM_KZ1_Fenster", "CLOSED")
        FensterGeschlossen.put("HM_KZ2_Fenster", "CLOSED")
end
bekomme ich schon folgende Fehlermeldung:

Code: Alles auswählen

020-06-26 13:20:18.412 [ERROR] [ntime.internal.engine.RuleEngineImpl] - Error during the execution of startup rule 'Systemstart': 'put' is not a member of 'Object'; line 27, column 9, length 42
.

Bin jetzt eigentlich ganz, ganz weit weg von meinem ursprünglichen Problem, aber vielleicht löst es sich dann leichter.!
Zwei Sachen fallen mir auf:
Die Fehlermeldung verweist auf die Zeile 27 in der rule "Systemstart". Soweit ich sehe, hat die Rule nur 13 Zeilen. Sie ist also hier nicht vollständig zu sehen.
Die Fehlermeldung verweist auf eine fehlende Objekt-Methode oder Object-Member .put() woher kommt die Methode put()? Sollte es die geben?

Grüße
Thomas

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 sind noch 3 Zeilen davor, die bisher funktioniert haben.
Das "put" kommt kann nur aus den angegebenen Zeilen kommen.
Ich schaue aber heute Abend nochmal nach.
Die Codezeilen stammen aus dem o.a. Link

Gruß Dirk


Gesendet von meinem SM-A405FN mit Tapatalk


openHab4 (v. 4.1.0) Docker auf Synology DS920+ :!:

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 »

Es gibt in openHAB Rules weder ein .put noch ein .get (jedenfalls nicht, solange man keine speziellen Imports macht)

Um mit Items zu arbeiten, gibt es Item.state um den aktuellen Status zu erhalten, Item.postUpdate(Wert) um den Status des Items auf Wert zu ändern (so das Item diesen Wert als Status unterstützt) und Item.sendCommand, um einen Befehl an das Item (und alles, was damit verknüpft ist - Stichwort Channel) zu senden. Es gibt noch massig weitere Methoden, aber diese beiden (plus .state als Eigenschaft) sind die mit Abstand wichtigsten.

Die angegebene Zeile ist die Zeile in der Datei, nicht in der Rule. Column ist die Position innerhalb der Zeile.

Hasmaps... Das Stichwort ist so nicht ausreichend, um zu verstehen, was man damit macht. Der Punkt ist, dass Du ja für jedes Ziel einen eigenen Timer brauchst, wenn Du timergesteuert Statusupdates wiederholt senden möchtest. Eine Hashmap kann beliebig viele Timer zur Verfügung stellen, wo Du normalerweise für jeden Timer eine eigene Variable definieren musst. Das ist aber jedenfalls nichts, was man mal eben so aus dem Hut zaubert.
openHAB4.3.3 stable in einem Debian-Container (bookworm) (Proxmox 8.3.5, LXC), mit openHABian eingerichtet

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 »

Gibt es eine Möglichkeit in einer rule nach einem vorhandenem item mit einem bestimmten/variabelen Namen (in meinem Fall : val zielItem) zu suchen und diesem einen Wert/Status zuzuweisen?

Gesendet von meinem SM-A405FN mit Tapatalk

openHab4 (v. 4.1.0) Docker auf Synology DS920+ :!:

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 »

Ja, gewöhnlich macht man das mit einer Gruppe. Du legst ein Group Item an, in dem Du alle möglichen Items zusammenfasst (z.B. alle Fensterkontakte) Anschließend nutzt Du in der Rule dieses Group Item in der Form

Code: Alles auswählen

GroupItem.members.filter[i|i.name == theName].head
Dieser Ausdruck liefert das erste Item aus der Liste der Items, für die der Name des Items identisch mit dem Inhalt der Variablen theName ist. Es wird nur innerhalb der Gruppe GroupItem gesucht.

Statt einer Variablen, kann man z.B. Auch triggeringItem.name verwenden (aber Obacht, dass die implizite Variable im Kontext auch zur Verfügung steht)
Wenn Du eine Liste mit Inputs hast und eine Liste mit Outputs hast, geht auch sowas:

Code: Alles auswählen

gInput.members.forEach[i|
    val myOutput = gOutput.members.filter[j|j.name.contains(i.name)].head
    if(i.state != myOutput.state)
        myOutput.sendCommand(i.state)
]
Die Gruppe gInput wird durchlaufen. Für jedes Item wird das passende Item herausgesucht (in diesem Beispiel gehe ich der Einfachheit halber davon aus, dass der Name der Output-Items den Namen des Input-Items komplett enthält)
Anschließend prüft der Code, ob die Status beider Items gleich sind. Ist das nicht der Fall, wird der Status ans Output-Item gesendet.
Dieser Code käme mit einem Timer für alle Zuordnungen aus. Du musst nur noch ein Zähleritem definieren, welches Du vor dem Start auf 0 setzt und im Falle eines sendCommands auf 1 setzt. Ist die Variable nach dem Durchlauf noch 0, muss der Timer nicht mehr ausgeführt werden. Ist er 1, folgt ein Reschedule. Läuft der Timer noch, muss er nicht erneut angelegt werden (also wenn mehrere Fenster hintereinander verstellt werden)
openHAB4.3.3 stable in einem Debian-Container (bookworm) (Proxmox 8.3.5, LXC), mit openHABian eingerichtet

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 »

Ok. Danke für die Info.
Ich werde das morgen mal versuchen.

Gesendet von meinem SM-A405FN mit Tapatalk

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 »

Lösung des Problems:

Ich habe den den Status der Fensterkontakte an die jeweilige Raumgruppe von Homematic (Thing HmIP-HEATING INT0000001) und nicht an den jeweiligen Wandthermostat (Thing HmIP-WTH-2 000A9A49A6A7E0) gesendet.
Nach dieser Änderung werden die Commands der Fenstersensoren übertragen und richtig von Homematic verarbeitet.

Die Verzögerung der Fensterkontakte habe ich wie folgt realisiert:

Code: Alles auswählen

// Variablen
var Timer varKontakt_WEZ = null
var Timer varKontakt_KZ1 = null
var Timer varKontakt_KZ2 = null

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

rule "Verzögerung Fenster"  // Schleife gegen PRELLEN bei Fenster-/Türkontakten für Heizungssteuerung
when
    Item grpKontakte_WEZ changed or
    Item grpKontakte_KZ1 changed or
    Item grpKontakte_KZ2 changed
then
    val String valRuleName = "Verzögerung Fenster"

    if (triggeringItem.name == "grpKontakte_WEZ") {       
        varKontakt_WEZ?.cancel                                           // Überprüfung ob Timer läuft, sonst Abbruch !                         // wenn Bedingung erfüllt, Timer starten
        varKontakt_WEZ = createTimer(now.plusSeconds(30), [|             // Starte Timer
            MX_WEZ_Kontakte_Status.postUpdate(if(grpKontakte_WEZ.state == OPEN) "OPEN" else "CLOSED")   
        ])
    }

    if (triggeringItem.name == "grpKontakte_KZ1") {       
        varKontakt_KZ1?.cancel                                           // Überprüfung ob Timer läuft, sonst Abbruch !                         // wenn Bedingung erfüllt, Timer starten
        varKontakt_KZ1 = createTimer(now.plusSeconds(30), [|             // Starte Timer
            MX_KZ1_Kontakte_Status.postUpdate(if(grpKontakte_KZ1.state == OPEN) "OPEN" else "CLOSED")
        ])
    }
    
    if (triggeringItem.name == "grpKontakte_KZ2") {       
        varKontakt_KZ2?.cancel                                           // Überprüfung ob Timer läuft, sonst Abbruch !                         // wenn Bedingung erfüllt, Timer starten
        varKontakt_KZ2 = createTimer(now.plusSeconds(30), [|             // Starte Timer
            MX_KZ2_Kontakte_Status.postUpdate(if(grpKontakte_KZ2.state == OPEN) "OPEN" else "CLOSED")
        ])
    }

end
Mit der Hilfestellung von Udo1Toni habe ich auch meine Übergabe an Homematic angepasst.

Code: Alles auswählen

val String valFileName = "HomeNet.individual.Heizungssteuerung.rules"
val String trigItemName1
val String trigItemName2
val String zielItemName
val String zielItemState
val zielItem
var Timer varFensterStatus = null
var Number varZaehler = null

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

rule "Fenster-Status" // Warteschleife für die Änderungen an den Türkontakten
when
    Item MX_WEZ_Kontakte_Status changed or
    Item MX_KZ1_Kontakte_Status changed or
    Item MX_KZ2_Kontakte_Status changed
then 
    val valRuleName = "Fenster-Status"
    // Umwandlung des auslösenden Gruppenamens in den auszuführenden Itemnamen
    val trigItemName1 = triggeringItem.name
    val trigItemName2 = trigItemName1.replace("MX_","HM_")
    val zielItemName = trigItemName2.replace("Kontakte_Status","Wandthermostat_Fenster")
    val zielItem = grpHM_Fenster.members.filter[i|i.name == zielItemName].head
    Thread::sleep(1000)
    zielItem.sendCommand(if(triggeringItem.state == "OPEN") "OPEN" else "CLOSED")   // Überprüfung *.state bei Gruppe = OPEN/CLOSED, bei Item = "OPEN"/"CLOSED" als String
    varZaehler = 1                                                      // Startwert des Zählers setzen
    varFensterStatus?.cancel                                            // Überprüfung ob Timer läuft, sonst Abbruch !                         // wenn Bedingung erfüllt, Timer starten
    varFensterStatus = createTimer(now.plusSeconds(15), [|              // Starte Timer
        // Überprüfung ob Statuswert gesendet wurde
        if (triggeringItem.state != zielItem.state) {
            logInfo (valFileName + ":" + valRuleName, "Neustart: (" + varZaehler + ") " + triggeringItem.state + " / " + zielItem.state)
            zielItem.sendCommand(if(triggeringItem.state == "OPEN") "OPEN" else "CLOSED")
            // Zählerüberprüfung und ggf. Neustart des Timers
            if (varZaehler <= 5) {
                varZaehler = varZaehler + 1
                varFensterStatus.reschedule(now.plusSeconds(15))                
            }
            else {
                logWarn (valFileName + ":" + valRuleName, "Diskrepanz: " + triggeringItem.name + " (" + triggeringItem.state + ") / " + zielItem.name + " (" + zielItem.state + ")")
            }
        } 
    ])

end
Danke für die Unterstützung !!!
openHab4 (v. 4.1.0) Docker auf Synology DS920+ :!:

Antworten