Seite 11 von 12
Re: Fensterkontakt Status
Verfasst: 11. Mär 2022 10:33
von tommesd
Ich habe jetzt etwas getestet. Ich lese den Namen des Raumes aus und versuche daraus den Namen des CONTACT Items zusammenzusetzen. Es scheitert daran, dass ich einen String habe und diesen als Itemnamen brauche. Wie kann man einen String entsprechend umwandeln?
Außerdem benötige ich pro Raum die Anzahl der offenen Fenster.
Code: Alles auswählen
rule "Test"
when
Member of gFenster_Schlafzimmer changed or
Member of gFenster_Paul changed or
Member of gFenster_Julia changed or
Member of gFenster_Badezimmer changed or
Member of gFenster_WC changed or
Member of gFenster_Garage changed or
Member of gFenster_Kueche changed or
Member of gFenster_Esszimmer changed or
Member of gFenster_Wohnzimmer changed or
Member of gFenster_Buero changed or
Member of gFenster_Waschkeller changed or
Member of gFenster_Vorratskeller changed or
Member of gFenster_Gaestezimmer changed or
Member of gFenster_Hobbyraum changed
then
val strRaum = triggeringItem.name.split("_").get(1)
val strGruppe = ("gFenster_" + strRaum)
val strStatusGruppe = ("Status_" + strGruppe)
val strGruppeAnzahlOffen = ("offeneFenster_" + triggeringItem.name.split("_").get(1))
AmazonEchoBuero_Sprich.sendCommand("Raum " + strRaum)
AmazonEchoBuero_Sprich.sendCommand(strGruppe)
AmazonEchoBuero_Sprich.sendCommand(strStatusGruppe)
AmazonEchoBuero_Sprich.sendCommand(strGruppeAnzahlOffen)
offeneFenster_Buero.postUpdate(gFenster_Buero.members.filter[i|i.state != "CLOSED"].size)
if(gFenster_Buero.members.filter[i|i.state != "CLOSED"].size > 0)
Status_gFenster_Buero.postUpdate(OPEN)
else
Status_gFenster_Buero.postUpdate(CLOSED)
end
Re: Fensterkontakt Status
Verfasst: 11. Mär 2022 15:55
von udo1toni
Was tust Du denn da? Du nimmst ja Bezug auf eine feste Gruppe (Buero). Und was das Echo damit zu tun? Willst Du wirklich jedes Mal, wenn Du ein Fenster bewegt, eine entsprechende Ansage haben?
Grundsätzlich: .members liefert eine Liste (in openHAB DSL Rules gewöhnlich im Zusammenhang mit einem Gruppen Item, das heißt, die Liste enthält die Member der Gruppe) .filter liefert eine Liste. Die Ausgangsliste enthält alle Elemente der Eingangsliste, für die der Filter zutrifft. Wenn der Filter z.B. .state != "CLOSED" lautet, beinhaltet die Ausgangsliste alle Items, deren Status nicht "CLOSED" lautet. .size zählt die Elemente einer Liste. Hier wäre das also die Anzahl offener (genauer: Nicht geschlossener) Fenster.
Wenn man die Itemnamen geschickt wählt, ist es kein Problem, entsprechende Rückschlüsse zu ziehen. Es wäre aber sinnvoll, das an einem konkreten Beispiel festzumachen.
Re: Fensterkontakt Status
Verfasst: 11. Mär 2022 16:51
von tommesd
Die Echo Ausgabe war nur dafür da zu testen ob der Name richtig gebildet wird. Also in den jeweiligen VAL sind die richtigen Item Namen drin, nur eben als String. Das heißt es ist nicht möglich ein VAL String in einen Item Namen umzuwandeln?
Re: Fensterkontakt Status
Verfasst: 12. Mär 2022 01:38
von udo1toni
Es gibt drei verschiedene Wege, auf das Item zuzugreifen. Weg 1: Du verwendest die Action. Damit kannst Du den Itemnamen als String übergeben. Allerdings musst Du dann den Status oder den Befehl ebenfalls als String übergeben.
Weg 2: Du greifst auf die Itemregistry zu. Unter JavaScript die einzige Möglichkeit, auf Items zuzugreifen und extrem unsexy, gefühlte 15 Zeilen Code, statt einer Zeile.
Weg 3: Die Items sind gruppiert und Du nutzt theGroup.members.filter[i|i.name == "der Itemname"].head um auf das Item zu verweisen.
Re: Fensterkontakt Status
Verfasst: 12. Mär 2022 09:52
von tommesd
Also zu dem konkreten Beispiel:
Die Fenstergruppen heißen gFenster_Raumname. Die String Fenster Items heißen Fenster_Raumname_ZusatzSTATE (Zusatz aber nur wenn in dem Raum mehr als ein Fenster ist, wobei ich die auch noch umbenennen könnte.
Ich hatte jetzt Dummy Items als CONTACT angelegt, nach dem Muster Status_Raumname.
Außerdem noch ein Dummy als Number, wo die Anzahl der geöffneten Fenster des Raums gespeichert werden, Muster offeneFenster_Raumname.
Wenn ich eine Rule für jeden Raum erstelle funktioniert das auch. Ich hatte gehofft, dass man mit members.filter den Raumname extrahiert und dann dazu einen Prefix anbaut und das dann als Itemname deklariert.
Oder kann man über das triggeringItem auf die dazugehörige Gruppe zugreifen? Ich denke damit wäre mir auch schon geholfen.
Kannst du mir ein Beispiel mit der Action geben? Kann das irgendwie funktionieren?
Re: Fensterkontakt Status
Verfasst: 12. Mär 2022 13:23
von udo1toni
Wie gesagt, die Anzahl der offenen Fenster pro Gruppe steht ja schon zur Verfügung, die wird im if(...size > 0) mit der 0 verglichen.
Den Namen der Gruppe bekommst Du über g.name (bezogen auf die Rule oben), natürlich kannst Du dort mit split("_").get(1) auch den Teil nach dem 1. Unterstrich ermitteln.
Wenn Du teilweise mehrere Fenster in einem Raum hast, ist das kein Problem, allerdings solltest Du darauf achten, dass der Raum dennoch an der gleichen Stelle steht. Die Nummer des Fensters wäre dann also weiter hinten. Alternativ könntest Du bei allen Räumen, die nur ein Fenster haben, noch die 1 ergänzen.
Wichtig ist ja nur, dass man die Namen der beteiligten Items voneinander ableiten kann. Und dann bietet es sich an, die Items nach Art in Gruppen zusammenzufassen, also alle Anzahl-Items in eine Gruppe, alle Zustands-Items in eine zweite Gruppe. Das ist ja pro Raum jeweils nur ein Item. Dann kannst Du einfach per gruppe.members.filter[item|item.name.contains(raumname)].head auf das betreffende Item zugreifen.
Re: Fensterkontakt Status
Verfasst: 12. Mär 2022 14:05
von tommesd
Sorry, aber so ganz verstehe ich das noch nicht. Ich habe eine Gruppe (gFenster_alle) in der alle Fenstergruppen enthalten sind. Ich habe für jeden Raum eine Gruppe (gFenster_Raum), darin enthalten sind 1 bis n Fenster. Die Rule triggerd über member of gFenster_Raum changed. Wie bekomme ich jetzt den Raumnamen des triggernden Fensters in ein VAL? Den Rest habe ich soweit verstanden, glaube ich

Re: Fensterkontakt Status
Verfasst: 12. Mär 2022 16:49
von udo1toni
Ah. Jetzt weiß ich, wo Du hin willst...
triggeringItem ist ein Zeiger auf das Item, welches als
Member of die Gruppe getriggert hat. Also kannst Du mit
triggeringItem.name das konkrete Item erfragen.
triggeringItem.name.split("_").get(1) liefert den Teilstring nach dem ersten Unterstrich und vor dem zweiten Unterstrich (falls ein solcher vorhanden ist). Du musst die Itemnamen (die String Items, welche den tatsächlichen Status OPEN, CLOSED, AJAR oder TILTED enthalten) so einrichten, dass Du an einer fixen Stelle den Raumnamen stehen hast, also z.B. immer nach dem ersten Unterstrich.
So könnte man auch dafür sorgen, dass nur jeweils die Gruppe abgefragt wird, in welcher sich tatsächlich ein Zustand geändert hat.
So vielleicht (auf die Schnelle, ungeprüft):
Code: Alles auswählen
rule "update group status"
when
Member of gFenster_Schlafzimmer changed or
Member of gFenster_Paul changed or
Member of gFenster_Julia changed or
Member of gFenster_Badezimmer changed or
Member of gFenster_WC changed or
Member of gFenster_Garage changed or
Member of gFenster_Kueche changed or
Member of gFenster_Esszimmer changed or
Member of gFenster_Wohnzimmer changed or
Member of gFenster_Buero changed or
Member of gFenster_Waschkeller changed or
Member of gFenster_Vorratskeller changed or
Member of gFenster_Gaestezimmer changed or
Member of gFenster_Hobbyraum changed
then
logInfo("gwindow","Rule ausgelöst: {}",triggeringItem.name)
val String strRaum = triggeringItem.name.split("_").get(1) // Format des Itemnamens: Fenster_Raum_weiteres
val GroupItem g = gFenster_alle.members.filter[k|k.name.contains(strRaum)].head
logInfo("gwindow","aktuelles Item: {}",g.name)
val Integer intAnzahl = g.members.filter[i|i.state != "CLOSED"].size
val zielStat = gstate.members.filter[j|j.name.contains(strRaum)].head
val zielNum = gnumber.members.filter[j|j.name.contains(strRaum)].head
logInfo("gwindow","Itemname: {} Anzahl",zielStat.name,intAnzahl)
if(intAnzahl > 0)
zielStat.postUpdate(OPEN)
else
zielStat.postUpdate(CLOSED)
end
Die Räume müssen alle eindeutige Namen haben.
Re: Fensterkontakt Status
Verfasst: 12. Mär 2022 19:25
von tommesd
Dann darf aber in Raumname kein Unterstrich sein, da ich sonst nicht den Teilstring aus dem Fensteritem extrahieren kann. Ich bau das morgen mal um.
Re: Fensterkontakt Status
Verfasst: 13. Mär 2022 10:01
von udo1toni
Ja, der Raumname darf keine Unterstriche enthalten.