Mit Bewegungssensoren und Schaltaktoren kann man ganz gut Lichter nur dann schalten, wenn auch jemand sich bewegt und das Licht gebraucht wird. Hierzu gibt es grundsätztlich zwar die Möglichkeit, in homematic den Bewegungsmelder direkt mit einem Licht zu verknüpfen, aber das bietet sich tatsächlich dann doch nicht immer an.
Als problematisch erwiesen sich hier bei mir folgende Aspekte:
- Der Helligkeitswert des Sensors verfälscht sich, denn wenn das Licht an ist, dann ist es ja hell und irgendwann ist die Helligkeit ja dann auch der Auslöser, das Licht wieder abzuschalten. Es ist zwar möglich die Helligkeitswerte als Mittelwert der letzten 1-8 Messungen übertragen zu lassen, aber irgendwann passt der Wert einfach nicht mehr
- Gerade bei kurzen Schaltzeiten ist es wichtig, nicht nach z.B. 15 Sekunden zu prüfen, ob die Bewegung aus ist und dann gleich das Licht aus zu machen, vielmehr wünsche ich mir hier einen Timer, der nochmal z.B. 10 Sekunden wartet und erst wenn dann in dem Wartezeitraum wirklich keine Bewegung mehr statt fand, das Licht ausschaltet
- In einem Flur vor den Kinderzimmern soll das Licht nicht nur an und aus gehen, je nach Tageszeit (und damit Schlafzeit der Kinder) soll der Aktor (in diesem Fall ein Dimmer) verschiedene Helligkeitswerte schalten. Tags heller (z.B. 70%) und nachts dunkler (z.B. 17%). So dient das Flurlicht nachts als Nachlicht-on-demand und leuchtet gerade so den Weg zum Bad für die Kleinen aus und macht sie nicht zu wach.
- Wurde das Licht manuell angeschalten (100%) oder Heller als der Tageswert gedreht, soll es so lange anbleiben, bis es auch manuell wieder ausgeschalten wird.
Dies ergibt somit folgende Anforderungen:
- Der unverwässerte Helligkeitswert (Licht ist aus) muss mitgespeichert werden, um zu wissen, ob überhaupt das Licht an oder aus geschalten werden soll
- Wir brauchen einen Timer, der den Nachlauf erledigt
- Wir brauchen einen Abgleich der Tageszeiten, damit es nachts, wenn es draußen dunkel ist, auch drinnen nicht zu hell wird.
Zur Berücksichtigung der Zeiten für Sonnenauf- und -untergang wird auf das Astro-Binding von openHAB zurückgegriffen, damit bekommen wir Sonnenuntergangs- und Sonnenaufgangswerte einfach bereitgestellt.
Items-Datei:
Switch og_pir_flur_motion "Bewegungsmelder OG Flur" (debug) {homematic="address=xxx, channel=3, parameter=MOTION"} Number og_pir_flur_helligkeit "Helligkeit OG Flur [%d]" (debug) {homematic="address=xxx, channel=3, parameter=BRIGHTNESS"} Number og_pir_flur_helligkeit_vorLicht "Helligkeit Flur vor Licht an [%d]" (debug)
Rules-Datei für das Speichern des Helligkeitswertes ohne Licht (d.h. es wird geprüft, ob das Licht aus ist, wenn der PIR-Melder die Helligkeit meldet und wenn ja merken wir uns diesen Wert…):
var boolean log = false rule "PIR-Sensoren: Tatsaechliche Helligkeit OG Flur" when Item OG_PIR_FLUR_HELLIGKEIT received update then val String prefix = 'PIR OG Flur: ' if (log) logInfo('rules', prefix + 'Prüfe ob Helligkeitswert ohne Licht ermittelt werden kann...') if (OG_LICHT_FLUR.state == 0) { if (log) logInfo('rules', prefix + 'Licht aus, Ermittelte aktuelle Helligkeit: ' + OG_PIR_FLUR_HELLIGKEIT.state.toString()) OG_PIR_FLUR_HELLIGKEIT_VORLICHT.postUpdate(OG_PIR_FLUR_HELLIGKEIT.state) } else { if (log) logInfo('rules', prefix + 'Licht nicht aus, keine neue Helligkeit gespeichert. Aktuelle Helligkeit: ' + OG_PIR_FLUR_HELLIGKEIT.state.toString() + ' Letzte Helligkeit vor Licht: ' + OG_PIR_FLUR_HELLIGKEIT_VORLICHT.state.toString()) } end
Rules-Datei für das Schalten des Lichtes:
import org.openhab.core.library.types.* import org.openhab.core.persistence.* import org.openhab.* import java.util.* import org.joda.time.* import java.util.TimeZone import java.util.Date import java.util.Calendar var Integer einschaltschwelle = 150 //Nur wenn Helligkeit vor Licht an < Wert/255 ist soll überhaupt Licht angschalten werden - für PIR-Sensoren rule "Licht durch Bewegungsmelder: OG Flur" when Item og_pir_flur_motion changed then // Berechnung der gewünschten Helligkeit var DateTime datumSonnenaufgang = new DateTime((astro_Sonnenaufgang.state as DateTimeType).calendar.timeInMillis) var DateTime datumSonnenuntergang = new DateTime((astro_Sonnenuntergang.state as DateTimeType).calendar.timeInMillis) val boolean istDunkel = datumSonnenaufgang.afterNow || datumSonnenuntergang.beforeNow var Integer dummyInt = 17 //Helligkeit für Nacht-Modus if (!istDunkel) dummyInt = 80 //Helligkeit für Tag-Modus val helligkeit = dummyInt if ((og_pir_flur_motion.state == OFF) && (og_licht_flur.state <= helligkeit) && (og_licht_flur.state > 0)) { // Keine Bewegung (mehr), nicht absichtlich heller geschalten und grundsätzlich an, dann mit Timer abschalten createTimer(now.plusSeconds(10)) [| // Obige Bedingungen treffen noch zu? Dann Licht aus! if ((og_pir_flur_motion.state == OFF) && (og_licht_flur.state <= helligkeit) && (og_licht_flur.state > 0)) { sendCommand(og_licht_flur, 0) } ] } else if ((og_pir_flur_motion.state == ON) && (og_licht_flur.state <= helligkeit) && (og_pir_flur_helligkeit_vorLicht.state < einschaltschwelle)) { // Bewegung registriert, Licht ist aus oder dunkler als gewünschte Helligkeit und Einschaltschwelle grundsätzlich unterschritten? Licht an! sendCommand(og_licht_flur, helligkeit) } end
Streng genommen gibt es wohl noch ein Lücke. Wenn die Sonne untergeht und in dem Moment gerade das Licht durch Bewegung an war, dann wird es nicht mehr ausgeschalten, weil das System davon ausgeht, dass das Licht absichtlich heller gedreht wurde.
Aber dann muss man eben einmal auf den Schalter drücken 😉
Hi Florian,
danke für den Denkanstoß. Ich wundere mich nur das nirgends der Wert für „og_pir_flur_helligkeit_vorLicht“ gesetzt wird. Passiert das nicht in der Regel?
LG, Ben
Hallo Ben,
Danke für den Hinweis, da hat ein Codeschnipsel im Blogbeitrag gefehlt. Ich habe ihn aktualisiert!
Viele Grüße
Florian
Hi Florian,
hast du zufällig deine Rule nochmal angepasst. Leider sind mittlerweile eine dinge deprecated wie zb.: The use of wildcard imports is deprecated.
Läuft dein System noch oder hat du es nochmal angepasst?
LG, Ben