openHAB – Sanftes Aufwachen mittels konfigurierbarem Lichtwecker

openHAB - konfigurierbarer Lichtwecker
openHAB – konfigurierbarer Lichtwecker

Lichtwecker sind grundsätzlich nichts neues, aber warum ein Gerät kaufen, wenn man das Smart Home dafür nutzen kann. Mit einem Dimmer (bei mir der von Homematic) im Schlafzimmer ist das mit openHAB schnell erledigt.

Zum Thema wecker liefert openhab im wiki ja bereits einige Beispiele aber irgendwie war mir das zu kompliziert. Timer, Locks, … – das muss doch einfacher gehen.

Als Anforderungen habe ich für mich festgelegt:

  • konfigurierbare Weckzeit und Wecktage
  • konfigurierbare Ziel-Helligkeit
  • konfigurierbare Geschwindigkeit für’s heller werden
  • Konfigurierbare maximale Helligkeit
  • Abbruchmöglichkeit, wenn Taste im Raum für betroffenen Lichtschalter gedrückt wurde

Hier nun mein Lösungsansatz:

Die Items

Grundsätzlich gibt es Items, über welche die Weckzeit und die ganze Konfiguration gesteuert wird.

Hier der relevante Auszug der Items-Datei:

Switch  weckerMontag     "Montag"     <switch>
Switch  weckerDienstag   "Dienstag"   <switch>
Switch  weckerMittwoch   "Mittwoch"   <switch>
Switch  weckerDonnerstag "Donnerstag" <switch>
Switch  weckerFreitag    "Freitag"    <switch>
Switch  weckerSamstag    "Samstag"    <switch>
Switch  weckerSonntag    "Sonntag"    <switch>

String weckerZeitMessage "%s"

Number weckerZeitStunde "Stunde [%d]" <clock>
Number weckerZeitMinute "Minute [%d]" <clock>

Number weckerMaxHelligkeit "Helligkeit Max. [%d]" <switch>
Number weckerDimmerSleep "Dimmer-Schritte (Sekunden) [%d]" <clock>

Die Sitemap

Hier der relevante Auszug der Sitemap:

Text label="Wecker [%s]" item=weckerZeitMessage icon="clock" {
    Frame label="Zeit" {
        Setpoint item=weckerZeitStunde minValue=0 maxValue=23 step=1
        Setpoint item=weckerZeitMinute minValue=0 maxValue=55 step=5
    }
    Frame label="Wochentage" {
        Switch item=weckerMontag
        Switch item=weckerDienstag
        Switch item=weckerMittwoch
        Switch item=weckerDonnerstag
        Switch item=weckerFreitag
        Switch item=weckerSamstag
        Switch item=weckerSonntag
    }
    Frame label="Konfiguration" {
        Setpoint item=weckerMaxHelligkeit minValue=10 maxValue=100 step=5
        Setpoint item=weckerDimmerSleep minValue=1 maxValue=20 step=1
    }
}

Die Rules

Hier gibt es drei relevante Rules – einmal Initialisieren, dann das Handling der eventuell geänderten Weckzeiten und zum andren den Wecker selbst

Initiales Setzen der Weckzeiten

Entweder kann dies beim Hochfahren des Systems erfolgen oder – wenn es die Variable / einen Wert für das Item einmal gibt – über eine Persistence gelöst werden, welche den Wert grundsätzlich speichert und mit der Strategie „RestoreOnStartup“ dann auch automatisch wieder lädt.

Bei mir übernimmt das Persistieren mapDB. Dies speichert zu jedem Item immer den letzten Wert – mehr brauche ich zu den Items auch nicht.

rule "Initialization"
 when 
   System started
 then
     // Muss nur temporär benutzt werden für erstes Initialisieren von Items
     // da diese ab erstmaliger Benutzung in der mapDB gespeichert werden. Werden die nicht persistiert hier Defaultwerte hinterlegen

    postUpdate(weckerZeitStunde,     06)
    postUpdate(weckerZeitMinute,     00)
    postUpdate(weckerMontag,         ON)
    postUpdate(weckerDienstag,       ON)
    postUpdate(weckerMittwoch,       ON)
    postUpdate(weckerDonnerstag,     ON)
    postUpdate(weckerFreitag,        ON)
    postUpdate(weckerSamstag,        OFF)
    postUpdate(weckerSonntag,        OFF)
    postUpdate(weckerMaxHelligkeit,    30)
    postUpdate(weckerDimmerSleep,    5)
end

Geänderte Weckzeiten

Wird die Weckzeit geändert, dann wird zwar das Item bereits selbst geändert, hier muss also nichts gemacht werden, da ich aber die Weckzeit in „schön“ auch in der GUI sehen will, muss das hierzu künstlich erschaffene Icon ein Update erfahren:

rule "Wecker - Aenderung der Konfiguration"
when
    Item weckerZeitStunde received update or
    Item weckerZeitMinute received update 
then
    var weckerStunde =  weckerZeitStunde.state as DecimalType
    var weckerMinute =  weckerZeitMinute.state as DecimalType
    
    var String weckerText = ''
    if (weckerStunde.intValue < 10) weckerText = '0'
    weckerText = weckerText + weckerStunde.intValue + ':'
    if (weckerMinute.intValue < 10) weckerText = weckerText + '0'
    weckerText = weckerText + weckerMinute.intValue
    
    postUpdate(weckerZeitMessage, weckerText)
end

Der Wecker selbst

Der Wecker selbst läuft via Cron. Jede Minute wird geprüft, ob der Wecker ausgelöst werden soll. Für Debugzwecke sind Log-Ausgaben dabei, die natürlich ausgeklammert werden können.

rule "Wecker - prüfen"
when 
    Time cron "0 0/1 * * * ?"   // minütlicher Aufruf
then
    var weckerStunde =  (weckerZeitStunde.state as DecimalType).intValue
    var weckerMinute =  (weckerZeitMinute.state as DecimalType).intValue
    var weckerHelligkeit = (weckerMaxHelligkeit.state as DecimalType).intValue
    var weckerWartezeit = 1000 * (weckerDimmerSleep.state as DecimalType).intValue
    //logInfo('rules','helligkeit: ' + weckerHelligkeit +' wartezeit ' + weckerWartezeit)

    if (
        (now.getHourOfDay.intValue == weckerStunde) && (now.getMinuteOfHour.intValue == weckerMinute)
        && (
            ((weckerMontag.state == ON) && now.getDayOfWeek.intValue == 1) ||
            ((weckerDienstag.state == ON) && now.getDayOfWeek.intValue == 2) ||
            ((weckerMittwoch.state == ON) && now.getDayOfWeek.intValue == 3) ||
            ((weckerDonnerstag.state == ON) && now.getDayOfWeek.intValue == 4) ||
            ((weckerFreitag.state == ON) && now.getDayOfWeek.intValue == 5) ||
            ((weckerSamstag.state == ON) && now.getDayOfWeek.intValue == 6) ||
            ((weckerSonntag.state == ON) && now.getDayOfWeek.intValue == 7)
            )
    ) {
        logInfo ('rules','Wecker wird aktiviert...')
        // Wecker nur notwendig, wenn Licht aus ist
        if (dg_licht_schlafen.state < weckerHelligkeit) {
            var Number dimmer = 0
            while (dimmer < weckerHelligkeit) {
                // Licht auf Dimmstufe schalten
                sendCommand(dg_licht_schlafen, dimmer.intValue)
                // Konfigurierte Anzahl an Sekunden warten
                Thread::sleep(weckerWartezeit)
                // prüfen ob zwischenzeitlich Dimmerhelligkeit manuell veraendert wurde und damit der Wecker ausgemacht wurde
                var dimmerStatus = (dg_licht_schlafen.state as DecimalType).intValue
                if (dimmer == dimmerStatus) {
                    dimmer = dimmer + 1
                    logInfo('rules', 'Wecker: Dimmer plus 1 gesetzt auf ' + dimmer)
                } else {
                    dimmer = 100 // Abbruchbedingung
                    logInfo('rules', 'Wecker: Abbruch durch Tastendruck')
                }
            }
            logInfo('rules', 'Wecker abgeschlossen, Zielhelligkeit erreicht')
        } else {
            logInfo('rules', 'Wecker nicht gestartet da Licht bereits heller als Ziel-Helligkeit des Weckers. Helligkeit Licht: ' + dg_licht_schlafen.state)
        }
    } else {
        logInfo('rules','Wecker nicht aktiviert, Bedingung für Wecker trifft nicht zu')
    }
end

Fazit

Nun lässt es sich über die GUI bequem einstellen, wann der Wecker wecken soll, wie schnell er heller werden soll und wie hell er überhaupt werden soll und wenn man aufgewacht ist oder weiterschlafen will, einfach den Lichtschalter kurz drücken.

3 Antworten auf „openHAB – Sanftes Aufwachen mittels konfigurierbarem Lichtwecker“

  1. Guten Tag

    Wäre es möglich ein Image von dieser Konfiguration zu erhalten bzw. fachmännische Hilfe? Ich müsste ein Projekt realisieren, welches bei Alarmzeit 2 Ausgänge des RPi Relayboard (230/12V) ansteuert. Die Hardwareumgebung ist soweit realisiert und funktioniert bei einfachen Testansteuerungen. Diese nun mit dem Wecker zu „verbinden“ gelingt mir nicht.

    Hierfür war ihre Konfiguration hilfreich, allerdings will es nicht so richtig. Alleine schon der Wecker „refresht“ seine Einstellungen jeweils in Sekundentakt.

    Ich weiss echt nicht mehr weiter und wäre heilfroh für einen Rat (Abschlussarbeit). Natürlich würde ich die aufgewendete Zeit entschädigen.

    Liebe Grüsse
    Marco

    1. Hallo Marco,

      wie erfolgt denn die Ansteuerung des RPi-Relay-Boards im Test-Fall? Ich kenne das Board selbst nicht, aber wahrscheinlich werden auf der Shell Commandos ausgeführt, welche dann die Relais schalten?
      Sogesehen müsste nach „logInfo (‚rules‘,’Wecker wird aktiviert…‘)“ doch einfach nur das gewünschte Kommando zum Schalten des Relais platziert werden, oder?

      Was ist mit der Wecker refreshed im Sekundentakt gemeint?
      Was heißt „allerdings will es nicht so richtig“?

      Ein komplettes Image meines Raspberry Pis will ich leider so nicht weitergeben, da die hier veröffentlichten Auszüge nur Teile der Aufgaben sind, welche der Raspberry für mich übernimmt und da ist viel Privates dabei, was nicht zur Weitergabe gedacht ist.

      Wenn es Probleme gibt, grundsätzlich mit openHAB zurecht zu kommen, empfehle ich die dortige Community http://community.openhab.org/ in welcher i.d.R. rasch weitergeholfen wird.

      Viele Grüße
      Florian

Schreibe einen Kommentar

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