Startseite » OpenHAB: Erinnerung, wenn man vergisst das Fenster zu schließen

OpenHAB: Erinnerung, wenn man vergisst das Fenster zu schließen

Wie oft passiert dir das? Du lüftest, vergisst aber nachher doch wieder das Fenster zu schließen. Der Raum ist Kalt. Vielleicht ist die Heizung dabei die ganze Zeit gelaufen. Das muss nicht sein.

Hardware: Fenstersensoren

Ich verwende die ZigBee-Tür- und Fenstersensoren von Sonoff, da sie sehr günstig sind. Mein Erster hat in 8 Monaten knappe 20% Batteriekapazität verbraucht. Entsprechend rechne ich also mit Laufzeiten von 3 Jahren bis zum Wechsel. Das scheint mir annehmbar.

Darüber hinaus lassen sich die Sensoren an anderer Stelle auch in ein OpenHAB-basiertes Alarm-System einbinden.

Vielleicht entscheidest du dich aber auch für drahtgebundene Sensoren. Einige der nachfolgenden Punkte wirst du vielleicht anpassen müssen. Dennoch dienen sie dir als Blaupause.

Die Fenstersensoren habe ich mit Zigbee2MQTT angebunden.

OpenHAB: Things

Entsprechend meinem Schema werden die Sensoren mit dem MQTT-Bindung angesprochen.

Thing mqtt:topic:myMosquitto:WindowSensor_OfficeAlex		"Fenster Alex"	(mqtt:broker:myMosquitto) @ "Büro Alex"	{
	Channels:
		Type contact	: contact		[ stateTopic="+/+/+/+/doorWindowSensor/+/+/0x00124b002513eb6a" , transformationPattern="REGEX:(.*contact.*)∩JSONPATH:$.contact", on="false", off="true" ]
		Type number		: battery		[ stateTopic="+/+/+/+/doorWindowSensor/+/+/0x00124b002513eb6a" , transformationPattern="REGEX:(.*battery[^_].*)∩JSONPATH:$.battery" ]
}

OpenHAB: Items

Entsprechend einem semantischen Schema definiere ich die Items. Mit dem semantischen Schema kann die Rule gleich sehr generisch ausfallen und so eine Erweiterung des Systems schnell erfolgen.

Ich gehe davon aus, dass alle Items zu einer Item-Group zusammengefasst werden. Eine Item-Group (ig*) entspricht immer einem realen Gegenstand.

Diese Item-Groups werden dann einem Raum (semantic Group: sg*) zugeordnet. Diesen semantischen Aufbau beschreibe ich im Kontext mit Heizregeln nochmal genauer.

Die Batterie wird aufgrund der semantischen Definition automatisch überwacht.

Group:Number:COUNT(OPEN)	igWindowSensor_OfficeAlex			"Fenster Büro Alex [%s]"	<Window>		(sgOfficeAlex)["Window"]
Contact						WindowSensor_OfficeAlex_contact		"Kontakt [%s]" 								(fgPersist,igWindowSensor_OfficeAlex,fgIntrusion,tgWindow)["OpenState","Opening"]	{ channel="mqtt:topic:myMosquitto:WindowSensor_OfficeAlex:contact" }
Number:Dimensionless		WindowSensor_OfficeAlex_battery		"Batterie [%.1f %%]" 		<Battery>		(igWindowSensor_OfficeAlex)["Battery","Measurement","Energy"]						{ channel="mqtt:topic:myMosquitto:WindowSensor_OfficeAlex:battery" }

OpenHAB: Rules

Im Folgenden wird eine Warnung generiert, wenn ein Fenster oder Tür mindestens 30min lang offen steht. Außerdem wird die Warnung wiederholt. Allerdings nur, wenn es draußen zu warm oder zu kalt ist, damit sich das lohnt. Die Wiederholung findet statt, indem der Fensterstatus kurz auf geschlossen, dann wieder auf offen gesetzt wird.

Falls du kein Item hast, welches die Außentemperatur enthält, kannst du diese Zeilen auch streichen. Ich verwende die Daten eines Wetter-Bindings.

Vergiss nicht, deinen Telegram-Bot dafür zu konfigurieren.

import java.util.Map
import org.openhab.core.model.script.ScriptServiceUtil

var Map<String, Timer> timers = newHashMap

rule "Fenster/Tür zu lange offen"
when
	Member of tgWindow changed to OPEN
then {
	if(!timers.containsKey(triggeringItem.name)){
		timers.put(triggeringItem.name, createTimer(now.plusMinutes(30), [ |
			
			if(triggeringItem.state == OPEN){
				//detect itemGroup (ig) of the item
				val String igName = triggeringItem.getGroupNames.findFirst[ String groupName | groupName.startsWith("ig") ]
				val GroupItem igItem = ScriptServiceUtil.getItemRegistry.getItem(igName) as GroupItem
		
				//detect semanticGroup of the itemGroup
				val String sgName = igItem.getGroupNames.findFirst[ String groupName | groupName.startsWith("sg") ]
				val roomItem = ScriptServiceUtil.getItemRegistry.getItem(sgName) as GroupItem
			
				//val NumberItem temperatureItem = roomItem.allMembers.findFirst[ item | item.hasTag("Measurement") && item.hasTag("Temperature") ]
				//val float temperature = (temperatureItem.state as Number).floatValue
				
				//Environment
				val float temperatureEnvironment = (OpenWeatherMapWetterinformationen_Current_Aussentemperatur.state as Number).floatValue()
			
				if(
					(temperatureEnvironment < 18) //draussen ist es zu kalt
					|| (temperatureEnvironment > 25) //draussen ist es zu warm
				){
					getActions("telegram","telegram:telegramBot:home_Bot").sendTelegram(-000000000L,"noch offen: %s in %s", igItem.label, roomItem.label)
				}
				
				timers.get(triggeringItem.name).reschedule(now.plusMinutes(30))
			}
		]))
	}
	else {
		timers.get(triggeringItem.name).reschedule(now.plusMinutes(30))
	}
}
end

Kommentar verfassen

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

Diese Seite verwendet Akismet, um Spam zu reduzieren. Erfahre, wie deine Kommentardaten verarbeitet werden..

Translate »