Elektrischen Rolladen abhängig von Sonnenstand und Wetter steuern lassen mit openHAB2

Im Sommer nervt es besonders, wenn wir vergessen, die Rolläden der Kinderzimmer herunterzulassen. Dann heizen diese Zimmer sich sehr schnell auf und abends vor dem Schlafengehen ist es dann nur bedingt möglich, die wieder kühl zu lüften. Grund genug, darüber nachzudenken, was das Smarthome hier für uns leisten kann…

Und da ich mir kürzlich von Rademacher Rohrmotoren gegönnt und eingebaut habe und zur Steuerung den Homematic Unterputzaktor zur Jalosiensteuerung gekauft habe möchte ich das natürlich gleich ausprobierne und da wäre es doch schön, wenn das Haus die Zimmer automatisch beschattet, solange die Sonne auf bzw. in die Zimmer scheinen würde. Dies ist bei uns grundsätzlich grob ab Mittag der Fall, wenn die Sonne seitlich „um die Ecke kommt“ bis zum Abend, wenn die Sonne hinter den Nachbarhäusern verschwindet, der Fall. Also soll eine Schaltung abhängig von Sonnenwinkel und Sonnenhöhe erfolgen. Natürlich soll das aber erst ab einer bestimmten Außentemperatur greifen, denn im Winter sind wir dann doch eher froh über das Licht und wenn Regen oder auch nur Wolken am Himmel stehen, ist eine Beschattung auch nicht notwendig. Ist der Rolladen bereits weiter geschlossen, als er geschlossen werden soll, soll nichts passieren. Ebenso soll nichts passieren, der Rolladen beim Versuch ihn hochzufahren einen inzwischen veränderten Zustand hat.

Das Ganze soll natürlich auch für andere verwendbar und entsprechend konfigurierbar sein. Voraussetzung ist, dass das Szenario das gleiche ist, ansonsten muss man eben ein paar Bedingungen anpassen.

Für openHAB gibt es ja einerseits ein Wetter- und andrerseits ein Astro-Binding. Diese Daten können hier gut genutzt werden.

Wie es sich mit Sonnenrichtung und Sonnenhöhe so verhält, das kann man ganz gut auf folgender Website simulieren: https://www.sonnenverlauf.de

Was in openHAB2 zu tun ist

Ist das getan können die notwendigen Dateien angelegt werden.

.items-Datei

Group gruppeWetter "Wetter-Daten" <sun> (debug) 
Group gruppeAstro "Astronomische Daten" <sun_clouds>(debug)
Group gruppeRollo

// Wetter
Number wetter_temperatur "Temperatur [%.2f °C]" <temperature> (gruppeWetter) {weather="locationId=home, type=temperature, property=current"}
Number wetter_temperatur_gefuehlt "Temperatur gefühlt [%.2f °C]" <temperature> (gruppeWetter) {weather="locationId=home, type=temperature, property=feel"}
String wetter_temperatur_minmax "Temp. Min/Max [%s °C]" <temperature> (gruppeWetter) {weather="locationId=home, forecast=0, type=temperature, property=minMax"}
Number wetter_temperatur_min "Temperatur min [%.2f °C]" <temperature> (gruppeWetter) {weather="locationId=home, type=temperature, property=min"}
Number wetter_temperatur_max "Temperature max [%.2f °C]" <temperature> (gruppeWetter) {weather="locationId=home, type=temperature, property=max"}
Number wetter_windgeschwindigkeit "Windgeschwindigkeit [%.2f km/h]" <wind> (gruppeWetter) {weather="locationId=home, type=wind, property=speed"}
Number wetter_feuchtigkeit "Luftfeuchtigkeit [%d %%]" <humidity> (gruppeWetter) {weather="locationId=home, type=atmosphere, property=humidity"}
Number wetter_luftdruck "Luftdruck [%.2f mb]" <pressure> (gruppeWetter) {weather="locationId=home, type=atmosphere, property=pressure"}
Number wetter_bewoelkung "Bewölkung [%.0f %%]" <sun_clouds> (gruppeWetter) {weather="locationId=home, type=clouds, property=percent"}
Number wetter_regen "Regen [%.2f mm/h]" <rain> (gruppeWetter) {weather="locationId=home, type=precipitation, property=rain"}
Number wetter_schnee "Schnee [%.2f mm/h]" <snow> (gruppeWetter) {weather="locationId=home, type=precipitation, property=snow"}

// Astro-Werte
DateTime astro_Sonnenaufgang "Sonnenaufgang" <sun> (gruppeAstro) {channel="astro:sun:local:rise#start"}
DateTime astro_Sonnenuntergang "Sonnenuntergang" <moon> (gruppeAstro) {channel="astro:sun:local:set#start"}
Number astro_elevation "Sonnenwinkel" <niveau> (gruppeAstro) {channel="astro:sun:local:position#elevation"}
Number astro_azimuth "Azimuth" <niveau> (gruppeAstro) {channel="astro:sun:local:position#azimuth"}

// Konfiguration Rollo-Automatik
Switch rolloautomatik "Rollo-Automatik an/aus"
Number rolloautomatik_zielwert "Schließen auf [%d Prozent]"
Number rolloautomatik_temp_min "Temperatur größer [%d °C]"
Number rolloautomatik_wolken_max "Bewölkung weniger als [%d Prozent]"
Number rolloautomatik_azimuth_start "Sonnenrichtung größer gleich [%d °]"
Number rolloautomatik_elevation_ende "Sonnenhöhe kleiner gleich [%d] °"
DateTime rolloautomatik_start_last "Letzte Ausführung (Rollo ab)"
DateTime rolloautomatik_ende_last "Letzte Ausführung (Rollo hoch)"

.sitemap-Datei

Das Folgende ist nur der relevante Auszug der Sitemap

Text label="Konfiguration Rollo-Automatik" icon="rollershutter" {
 Frame label="Aktivieren der Automatik" {
 Switch item=rolloautomatik
 Setpoint item=rolloautomatik_zielwert minValue=0 maxValue=100 step=1
 }
 Frame label="Rollo ab, wenn..." {
 Setpoint item=rolloautomatik_temp_min minValue=0 maxValue=35 step=1
 Setpoint item=rolloautomatik_wolken_max minValue=0 maxValue=100 step=1
 Setpoint item=rolloautomatik_azimuth_start minValue=0 maxValue=360 step=1
 }
 Frame label="Rollo hoch, wenn..." {
 Setpoint item=rolloautomatik_elevation_ende minValue=-20 maxValue=50 step=1
 } 
}

.rules-Datei

Die Regel fragt ab, ob die Automatik generell an, eventuell bereits gelaufen ist, ob Temperatur, Bewölkung und aktueller Status der Rolläden passen und wenn dies so ist werden sie hinuntergefahren.

Wichtig ist: Alle Rolläden müssen der Gruppe gruppeRollo zugeordnet werden.

Ist zum errechneten Zeitpunkt des wieder-hinauf-fahrens ein Rolladen in einem anderen Status, als er hätte sein müssen, als er heruntergefahren wurde, wird er nicht automatisch wieder hochgefahren.

var boolean log = true
rule "Rollos abfahren"
when Item astro_azimuth changed
then
    val String logPrefix = 'Rolloautomatik (Rollo ab) - '
    if (log) logInfo('rules', logPrefix + 'Regel wurde gestartet')
    
    var String timeLast = 'xxxx-xx-xx'
    if (rolloautomatik_start_last.state == NULL) {
        if (log) logInfo('rules', logPrefix + 'Erstmalige Ausführung am System, Belegung mit Initialwert')
    } else {
        timeLast = rolloautomatik_start_last.state.toString().substring(0,10)
    }
	var String timeNow = now.toString().substring(0,10)

    if (rolloautomatik.state == ON) {
        if (timeNow != timeLast) {
            if (astro_azimuth.state > Integer::parseInt(rolloautomatik_azimuth_start.state.toString())) {
                if (wetter_temperatur.state > Integer::parseInt(rolloautomatik_temp_min.state.toString())) {
                    if (wetter_bewoelkung.state  <= Integer::parseInt(rolloautomatik_wolken_max.state.toString())) { if (astro_elevation.state > Integer::parseInt(rolloautomatik_elevation_ende.state.toString())) {
                            // Rollos runterfahren
                            if (log) logInfo('rules', logPrefix + 'Rollos werden abgefahren')
                            gruppeRollo.members.forEach[i|
                                if (i.state <= Integer::parseInt(rolloautomatik_zielwert.state.toString())) {
                                    if (log) logInfo('rules', logPrefix + 'Fahre Rolladen auf ' + rolloautomatik_zielwert.state.toString() + '%: ' + i.name)
                                    i.sendCommand(Integer::parseInt(rolloautomatik_zielwert.state.toString()))
                                } else {
                                    if (log) logInfo('rules', logPrefix + 'Rolladen ist bereits weiter geschlossen (' + i.state.toString() + '%) als er geschlossen werden sollte und wird daher ignoriert')
                                }
                            ]
                            // Letzte Ausführung mit entsprechendem Zeitstempel belegen
                            rolloautomatik_start_last.postUpdate(now.toString())
                        } else {
                            if (log) logInfo('rules', logPrefix + 'Elevation für wieder abfahren (' + rolloautomatik_elevation_ende.state.toString() + ') ist groesser als aktuelle (' + astro_elevation.state.toString() + ')')
                        }
                    } else {
                        if (log) logInfo('rules', logPrefix + 'Mindestbewoelkung (' + rolloautomatik_wolken_max.state.toString() + ') wurde unterschritten (' + wetter_bewoelkung.state.toString() + ')')
                    }
                } else {
                    if (log) logInfo('rules', logPrefix + 'Mindest-Temperatur (' + rolloautomatik_temp_min.state.toString() + ') wurde nicht erreicht durch aktuelle Temperatur (' + wetter_temperatur.state.toString() + ')')
                }
            } else {
                if (log) logInfo('rules', logPrefix + 'Azimuth (' + astro_azimuth.state.toString() + ') hat noch nicht Schwellwert (rolloautomatik_azimuth_start.state.toString()) erreicht')
            }
        } else {
            if (log) logInfo('rules', logPrefix + 'Automatik heute bereits einmal gelaufen, wird daher ignoriert')
        }
    } else {
         if (log) logInfo('rules', logPrefix + 'Beende, da Automatik generell nicht aktiv')
    }
end

rule "Rollo wieder öffnen"
when Item astro_elevation changed
then
    val String logPrefix = 'Rolloautomatik (Rollo hoch) - '
    if (log) logInfo('rules', logPrefix + 'Regel wurde gestartet')

    var String timeLastEnde = 'xxxx-xx-xx'
    if (rolloautomatik_ende_last.state == NULL) {
        if (log) logInfo('rules', logPrefix + 'Erstmalige Ausführung am System, Belegung mit Initialwert')
    } else {
        timeLastEnde = rolloautomatik_ende_last.state.toString().substring(0,10)
    }

    var String timeLastStart = 'yyyy-yy-yy'
    if (rolloautomatik_start_last.state == NULL) {
        if (log) logInfo('rules', logPrefix + 'Erstmalige Ausführung am System, Belegung mit Initialwert')
    } else {
        timeLastStart = rolloautomatik_start_last.state.toString().substring(0,10)
    }

	var String timeNow = now.toString().substring(0,10)


    if (rolloautomatik.state == ON) {
        if (astro_elevation.state <= Integer::parseInt(rolloautomatik_elevation_ende.state.toString())) {
            if (timeLastStart == timeNow) {
                if (timeLastEnde != timeNow) {
                    // Rollos wieder hoch
                    if (log) logInfo('rules', logPrefix + 'Rollos werden hinaufgefahren')
                    gruppeRollo.members.forEach[i|
                        if (rolloautomatik_zielwert.state == Integer::parseInt(i.state.toString())) {
                            if (log) logInfo('rules', logPrefix + 'Fahre Rolladen auf 0%: ' + i.name)
                            i.sendCommand(0)
                        } else {
                            if (log) logInfo('rules', logPrefix + 'Fahre Rolladen nicht auf 0%, da dieser zwischenzeitlich manuell verändert wurde: ' + i.name)
                        }
                    ]
                    // Letzte Ausführung mit entsprechendem Zeitstempel belegen
                    rolloautomatik_ende_last.postUpdate(now.toString())
                } else {
                    if (log) logInfo('rules', logPrefix + 'Beende, da heute bereits ein automatisches Wiederhochfahren stattfand')
                }
            } else {
                if (log) logInfo('rules', logPrefix + 'Beende, da heute noch keine Ausführung stattfand. Demzufolge kann auch kein automatisches Öffnen gewollt sein')
            }
        } else {
            if (log) logInfo('rules', logPrefix + 'Beende, da Elevation (' + astro_elevation.state.toString() + ') nicht  kleiner der eingestellten Elevation (' + rolloautomatik_elevation_ende.state.toString()+ ') war')
        }
    } else {
        if (log) logInfo('rules', logPrefix + 'Beende, da Automatik generell nicht aktiv')
    }
end

Ergebnis an der Oberfläche:

8 Antworten auf „Elektrischen Rolladen abhängig von Sonnenstand und Wetter steuern lassen mit openHAB2“

  1. Hallo Florian
    danke für diese klasse Umsetzung. Wäre es möglich die Rolladen abhängig vom Sonnenwinkel auch wieder hoochzufahren? Hintergrund ist dass beim Haus der Rollladen an der Ostseite ja nur morgens unten sein soll, der im Westen müsste aber erst Nachmittag zufahren. Der im Süden erst etwas nach dem Rollladen im Osten.
    Gruss Manuel

    1. Hallo Manuel,

      Im Prinzip ist das einfach möglich, es müssen nur die Regeln im Rule entsprechend angepasst bzw. erweitert werden. So kann man alle Rollläden auch separat je einzeln per Winkel und Richtung zur Sonne konfigurieren. Mir selbst fehlt leider der Anwendungsfall, daher bitte ich um Verständnis, dass ich nicht individuelle Programmierung einfach so anbieten kann, das geht nur, wenn ich es selbst für mich auch nutzen will. Wenn du Hilfe als Dienstleistung haben willst kannst du dich gerne bei mir melden, dann können wir das Weitere besprechen.
      Es freut mich aber, dass du zumindest mit dem veröffentlichen Code etwas anfangen und ihn nutzen konntest!

      Viele Grüße
      Florian

  2. Hallo Florian.
    Danke für die schnelle Antwort. Ich werde mal schauen ob ich die Regel entsprechend erweitern kann. Eine Frage noch zu der gruppeRollo. Was muss ich denn in die Gruppe Rollo packen und wo ist die Gruppe gruppeRollo definiert?

    Grus Manuel

    1. Hallo Manuel,
      die Gruppe muss einfach nur als Gruppe existieren (habe das im Artikel eben noch ergänzt im .items-file) und die Rollädenaktoren, die durch die Rule geschalten werden sollen, müssen natürlich der Gruppe zugewiesen sein.
      Gruß
      Florian

  3. Danke Florian.
    welche Items vom Rolladen Aktor ordnest du denn alles der Gruppe gruppeRollo zu? irgendwie will es bei mir nicht funktionieren

    1. Hallo Manuel alle Rollladenaktoren, die durch das Script geschaltet werden sollen müssen in der Gruppe sein.
      Bitte ggf das logfile im Auge behalten, falls irgendwo ein Fehler reingekommen ist hilft das meist schnell..

  4. Danke dir hat geklappt. Ich musste noch die Items LEVEL in die Gruppe gruppeRollo packen und das Astro Binding hat bei mir keine Werte gesendet.
    Hast du eine Quick n Dirty Idee wie ich in deinen Code die Bedingung hochfahren einbauen kann wenn die Bewölkung zunimmt? wenn also nachmittags der Himmel zuzieht würde ich die Rollos gerne wieder hochfahren

    1. Hallo Manuel, man müsste in die Regel für’s Hochfahren weitere Kriterien wie die Bewölkung einbringen, dann geht das schon. Aber mal schnell gemacht ist es nicht. Und es bleibt die Frage, was machst Du, wenn dann die Sonne wieder kommt? Dann hätte man am Ende eventuell ständig hoch- und runterfahrende Rollos…

Schreibe einen Kommentar

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