Hallo,
ich habe ein „Lüftungsregel“ erstellt, die nach Öffnen des Fensters einen Timer startet, die Heizung runterregelt und von Zeit zu Zeit eine Whatsapp mit der Aufforderung zum Schließen des Fensters sendet usw. Im Prinzip wechselt also der Zustand eines Items (der Fensterkontakt) und es werden der State mehrerer anderer Items modifiziert. So weit so gut.
Ich könnte jetzt für andere Räume mit Fensterkontakt und Thermostat die Regel natürlich kopieren und durch Ersetzung der Items anpassen. Ist aber redundant und nicht gut wartbar. Damit zur eigentlichen Frage: Wie kann ich die Regel so generalisieren, dass sie für mehrere Räume anwendbar ist? Für das auslösende Element geht’s über eine Gruppe und Filter, so wie ich das verstehe, aber wie geht das für die anderen beteiligten Items, zum Beispiel die Zielgröße des Thermostats? Kann man zum Beispiel dieses Item einer Variablen zuweisen und dann im Verlauf der Regel das Item durch Veränderung der Variablen ändern? Oder gibts da eine bessere Herangehensweise. Ich verwende grade übrigens RulesDSL als Scriptsprache. Danke für Eure Hinweise!
Frage zur Verallgemeinerung von Rules
-
- Beiträge: 5
- Registriert: 2. Mai 2020 01:36
- udo1toni
- Beiträge: 15247
- Registriert: 11. Apr 2018 18:05
- Wohnort: Darmstadt
Re: Frage zur Verallgemeinerung von Rules
Es gibt mehrere Möglichkeiten.
Der openHAB-Weg
ist es, eine oder mehrere Gruppen zu verwenden. Wobei mehrere Gruppen die Rule vereinfachen.
Der grundsätzliche Aufbau;
Du hast (für den vorliegenden Fall) eine Gruppe, in der alle Fensterkontakte zuhause sind. z.B. gFensterkontakte
Eine weitere Gruppe beinhaltet alle Solltemperaturen. z.B. gSolltemperatur
Der Trick besteht nun darin, die Itemnamen so zu wählen, dass openHAB vom einen Item auf das andere Item schließen kann. z.B. Fenster_Wohnzimmer und Soll_Wohnzimmer, Fenster_Kueche und Soll_Kueche usw., wichtig sind der Unterstrich, dass die Schlüsselbegriffe identisch und eindeutig sind und dass der Schlüsselbegriff mindestens beim Quellitem (hier Fenster_*) immer an der gleichen Stelle zu finden ist, zwischen zwei Unterstrichen, vor dem ersten Unterstrich oder nach dem letzten Unterstrich (im Beispiel immer nach dem ersten Unterstrich).
Nun kannst Du innerhalb der Rule anhand des triggernden Items das Gegenstück identifizieren. Das läuft so:
Da ich hier auch beim Zielitem (Soll_*) nach dem Namensteil nach dem 1. Unterstrich suche, muss dieser bei allen Zielitems an dieser Stelle zu finden sein. Man könnte auch mittels .name.contains(strRaum) nach dem Teilstring im Namen suchen, dann wäre es egal, wo dieser zu finden ist, man muss halt genau aufpassen, z.B. der String Wohnzimmer05 enthält auch den Teilstring Wohnzimmer, wenn man nun nach Wohnzimmer sucht, könnte openHAB beide Elemente finden (mal vorausgesetzt, sie sind in der Gruppe enthalten). Die Variante mit dem gleichen Teilstring schafft eventuell mehr Klarheit.
Wenn noch andere Aktionen ausgeführt werden sollen, die ebenfalls raumabhängig sind, musst Du halt weitere Gruppen für die entsprechenden Items anlegen.
Was die Alarmierung betrifft, so kannst Du über gFensterkontakte.filter[i|istate == OPEN].size bestimmen, wieviele Fenster gerade offen sind. Genauso kannst Du die gefilterte Liste durchlaufen gFensterkontakte.filter[i|istate == OPEN].forEach[j|j...] um z.B. eine Meldung auszugeben, welche Fenster noch offen sind.
Dazu gibt es hier im Forum ein paar Beispiele
Man könnte auch alle ITems in einer Gruppe zusammenfassen, dann muss man halt zusätzlich noch nach dem Namensteil filtern, der bestimmt, welche Funktion das Item hat (also im Beispiel Fenster oder Soll). Da Gruppen nicht weiter auftragen, sind einzelne Gruppen pro Funktion meist sinnvoller.
Anspruchsvoller wird es, wenn Du z.B. für jedes Fenster individuell nach einer festgelegten Zeitspanne Alarm geben willst, denn dann benötigst Du für jedes Fenster einen eigenen Timer. Auch das geht, indem man für die Timervariable ein Array verwendet, das ist aber schon etwas aufwändiger.
Der openHAB-Weg

Der grundsätzliche Aufbau;
Du hast (für den vorliegenden Fall) eine Gruppe, in der alle Fensterkontakte zuhause sind. z.B. gFensterkontakte
Eine weitere Gruppe beinhaltet alle Solltemperaturen. z.B. gSolltemperatur
Der Trick besteht nun darin, die Itemnamen so zu wählen, dass openHAB vom einen Item auf das andere Item schließen kann. z.B. Fenster_Wohnzimmer und Soll_Wohnzimmer, Fenster_Kueche und Soll_Kueche usw., wichtig sind der Unterstrich, dass die Schlüsselbegriffe identisch und eindeutig sind und dass der Schlüsselbegriff mindestens beim Quellitem (hier Fenster_*) immer an der gleichen Stelle zu finden ist, zwischen zwei Unterstrichen, vor dem ersten Unterstrich oder nach dem letzten Unterstrich (im Beispiel immer nach dem ersten Unterstrich).
Nun kannst Du innerhalb der Rule anhand des triggernden Items das Gegenstück identifizieren. Das läuft so:
Code: Alles auswählen
rule "Fenster Automatik"
when
Member of gFensterkontakte changed // einer der Fensterkontakte hat seinen Zustand geändert
then
val strRaum = triggeringItem.name.split("_").get(1) // Nimm den Teilstring zwischen 1. und 2. Unterstrich
val soll = gSolltemperatur.members.filter[i|i.name.split("_").get(1) == strRaum].head // nimm das erste Item der Gruppe, welches den gleichenTeilstring hat
if(newState == CLOSED) // Fenster wurde geschlossen
soll.sendCommand(soll.previousState(true).state) // sende den letzten Zustand vor dem aktuellen Zustand als Befehl
else
soll.sendCommand(7) // Frostschutz
end
Wenn noch andere Aktionen ausgeführt werden sollen, die ebenfalls raumabhängig sind, musst Du halt weitere Gruppen für die entsprechenden Items anlegen.
Was die Alarmierung betrifft, so kannst Du über gFensterkontakte.filter[i|istate == OPEN].size bestimmen, wieviele Fenster gerade offen sind. Genauso kannst Du die gefilterte Liste durchlaufen gFensterkontakte.filter[i|istate == OPEN].forEach[j|j...] um z.B. eine Meldung auszugeben, welche Fenster noch offen sind.
Dazu gibt es hier im Forum ein paar Beispiele

Man könnte auch alle ITems in einer Gruppe zusammenfassen, dann muss man halt zusätzlich noch nach dem Namensteil filtern, der bestimmt, welche Funktion das Item hat (also im Beispiel Fenster oder Soll). Da Gruppen nicht weiter auftragen, sind einzelne Gruppen pro Funktion meist sinnvoller.
Anspruchsvoller wird es, wenn Du z.B. für jedes Fenster individuell nach einer festgelegten Zeitspanne Alarm geben willst, denn dann benötigst Du für jedes Fenster einen eigenen Timer. Auch das geht, indem man für die Timervariable ein Array verwendet, das ist aber schon etwas aufwändiger.
openHAB4.3.3 stable in einem Debian-Container (bookworm) (Proxmox 8.3.5, LXC), mit openHABian eingerichtet
-
- Beiträge: 5
- Registriert: 2. Mai 2020 01:36
Re: Frage zur Verallgemeinerung von Rules
Super, herzlichen Dank. Das hilft mir wirklich weiter