Es gibt verschiedene Möglichkeiten, dieses Problem anzugehen.
Was Du möchtest, ist letztlich ein Makro, welches parametriert werden kann. Das ist in openHAB eher umständlich zu realisieren. Du könntest aber natürlich eine (externe) Funktion dafür schreiben, die Du dann aus diversen Rules aufrufst.
Die bessere Alternative wird sein, das über Gruppen zu realisieren. Mittels Gruppen kann man gleichartige Items zusammenfassen und dann eine Rule für alle Items verwenden. Leider ist das nicht trivial, aber so als Idee:
Code: Alles auswählen
rule "fenster auf oder zu"
when
Item Fenster changed
then
if(fenster1.state == OPEN)
tempStore1.postUpdate(tempIst1.state)
else
tempStore1.postUpdate(-999)
end
rule "temperatur update"
when
Item tempIst1 changed
then
if(tempStore1.state == -999)
return;
if(Math.abs(tempIst1.state - tempStore1.state) > 2) {
fensterAlarm1.postUpdate(ON)
// Meldung für Fenster 1 ausgeben
logInfo("tempAlarm","Fenster 1 ist geöffnet, Temperaturdifferenz seit Öffnen auf über 2 °C gestiegen!")
}
end
So sähe der Code mehr oder weniger aus, um ein Fenster abzudecken. Die eine Rule kümmert sich um den Fensterkontakt und schreibt die aktuelle Temperatur des Raums in den zugehörigen Speicher. Ist das Fenster geschlossen, wird stattdessen ein unsinniger Wert gespeichert (-999).
Die zweite Rule wird ausgelöst, wenn sich die aktuelle Temperatur ändert. Befindet sich die unsinnige Temperatur im Store, so bricht die Rule ab. (alternativ könnte man auch prüfen, ob das Fenster geschlossen ist...) Ansonsten wird der Absolutwert nach Subtraktion der beiden Temperaturen ermittelt. Ist dieser über 2, so weicht die aktuelle Temperatur um mehr zwei Grad ab und es erfolgt eine Alarmierung, in welcher Form auch immer.
Möchte man das Ganze nun generalisieren, so müssen die Items in Gruppen gepackt werden, mit verschiedenen Optionen. Einfach: alle Fensterkontakte in eine Gruppe, alle Temperaturen in eine zweite Gruppe, alle Stors für die Temperaturen in eine dritte Gruppe, alle Alarmspeicher (falls gewünscht) in eine vierte Gruppe. Nennen wir die Gruppen gFenster, gTempIs, gTempStore und gTempAlarm.
Wichtig ist, dass alle Items Namen tragen, die zueinander passen, also z.B.
Fenster_Wohnzimmer Temperatur_Wohnzimmer TempStore_Wohnzimmer, Alarm_Wohnzimmer
Nun können wir die Rules generalisieren:
Code: Alles auswählen
rule "Fenster auf oder zu"
when
Member of gFenster changed
then
val strRoom = triggeringItem.name.split("_").get(1) // Name des Raums
val tempIs = gTempIs.members.filter[i| i.name.endsWith(strRoom)].head
val tempStore = gTempStore.members.filter[i|i.name.endsWith(strRoom)].head
if(newState == OPEN)
tempStore.postUpdate(tempIs.state)
else
tempStore.postUpdate(-999)
end
rule "Temperatur update"
when
Member of gTempIs changed
then
val strRoom = triggeringItem.name.split("_").get(1) // Name des Raums
val tempStore = gTempStore.members.filter[i|i.name.endsWith(strRoom)].head
val tempalarm = gTempalarm.members.filter[i|i.name.endsWith(strRoom)].head
if(tempStore.state == -999)
return;
if(Math.abs(newState - tempStore.state) > 2) {
tempAlarm.postUpdate(ON)
// Meldung mit Bezug auf strRoom ausgeben
logInfo("tempAlarm","Fenster im {} ist geöffnet, Temperaturdifferenz seit Öffnen auf über 2 °C gestiegen!",strRoom)
}
end
Zu Beginn der Rules wird also ermittelt, welche Items zu dem Item gehören, welches die Rule ausgelöst hat- anschließend werden diese Items verwendet. Im Grunde ist das also recht einfach. Wichtig ist nur, dass die Namen der Räume alle eindeutig sind. Gibt es z.B. zwei Wohnzimmer, so muss eine weitere Unterscheidung in den Namen aufgenommen werden, z.B. OGWohnzimmer und EGWohnzimmer. Da der Teil hinter dem Unterstrich komplett als Raumname verwendet wird, darf auch kein Name Teil eines anderen Namens sein, OGWohnzimmer und Wohnzimmer ginge also nicht.
Dafür reichen tatsächlich diese beiden Rules, um beliebig viele Räume mit der Funktion auszustatten.