Sonnenschutz nach Himmelsrichtung: Rollläden nur bei Hitzestau heben
Ein Rollladen, der ganz unten steht, lässt bei praller Sonne keine Luft durch. Zwischen Panzer und Fensterscheibe staut sich die Wärme. Bei mir soll der Rollladen deshalb auf einen schmalen Spalt (Position 16) gehoben werden, sobald die Sonne auf seine Fassade trifft und Hitze zu erwarten ist. Dafür braucht es mehr als eine Uhrzeit: Die Sonne steht je Himmelsrichtung zu anderen Zeiten auf der Fassade, und nicht jeder sonnige Tag wird warm.
Was du brauchst
- Rollläden als
cover-Entitäten mit Positionsangabe - Die Integration
sunfür Azimut und Elevation - Einen Lux-Sensor im Freien und die PV-Leistung als Maß dafür, ob die Sonne wirklich scheint
- Eine Wetterentität mit Tagesprognose (bei mir met.no über
weather.forecast_home) - Hilfsentitäten:
input_numberfür die drei Schwellen und das Tagesmaximum der Prognose,input_datetimefür den Zeitstempel des letzten Abrufs - Fensterkontakte, falls der Abfang bei offenem Fenster ruhen soll
So funktioniert es
Der Sonnenstand wird in zwei Template-Sensoren ausgewertet, einer pro Fassade. Die Fassaden liegen bei 140° (Südost) und 230° (Südwest). Der Sensor ist an, wenn die Elevation über 10° liegt, der Azimut höchstens 75° von der Fassadenrichtung abweicht und zusätzlich ein dritter Sensor „Hitzestau möglich“ an ist.
Der Hitzestau-Sensor kombiniert Messwerte und Prognose. Es muss entweder die Helligkeit im Freien mindestens 40.000 lx erreichen oder die PV-Leistung mindestens 6.000 W. Dazu kommt die Prognose: Das erwartete Tagesmaximum muss mindestens 22 °C betragen. Ist der Abruf älter als sechs Stunden, wird die Prognose ignoriert, dann zählt nur die Sonne. So fällt der Schutz nicht aus, wenn das Internet weg ist.
Die Prognose holt eine eigene Automation stündlich und beim Start. Sie hat eine Haltelogik: Der Tageseintrag der Wetterentität enthält abends nur noch das Maximum der verbleibenden Stunden, der Wert schrumpft also im Tagesverlauf. Ein Beispiel aus meinem Betrieb: Am Abend stand dort 13,8 °C, obwohl der Tag 19,2 °C hatte. Deshalb wird der gespeicherte Wert innerhalb eines Tages nur nach oben korrigiert und erst am nächsten Tag neu gesetzt. Ohne das würde der Hitzeschutz an der Südwestfassade abends aussetzen, wo die Sonne im Juni bis 20:24 Uhr steht. Den Zeitstempel setzt die Automation bei jedem erfolgreichen Abruf, auch wenn der Wert nicht übernommen wird. Er dient als Frischeprüfung.
Die beiden Heben-Automationen reagieren auf den Fassadensensor. Steht ein Rollladen unter Position 16, wird er auf 16 gesetzt. Südost hat zusätzlich eine Untergrenze von 07:30 Uhr, weil dort ein Kinderzimmer liegt und der Sonnenstand im Juni schon deutlich früher passen würde. Ein zweiter Trigger um 07:30 Uhr holt den Fall nach, dass die Sonne vorher schon da war.
Ein Netz fängt Fahrten ab, die nicht über die Taster laufen: App, Wandschalter oder ein Switch-Manager. Fährt ein Rollladen echt nach unten und landet unter 16, setzt die Automation ihn zurück auf 16, solange die Sonne auf der Fassade des Rollladens steht und sein Fenster geschlossen ist. Taster und Gruppentasten senden in dieser Lage direkt 16 und lösen den Abfang gar nicht erst aus. Bei offenem Fenster greift er bewusst nicht: Kälte und Regen sollen dort ganz schließen.
Die Automation
Die Rollläden sind auf je zwei Beispiele gekürzt. Für jeden weiteren Rollladen ergänzt du einen Block.
# Template-Sensoren (bei mir als Helfer in der Oberfläche angelegt)
template:
- binary_sensor:
- name: Rollladen Hitzestau möglich
state: >-
{% set licht = states('sensor.aussen_helligkeit') | float(0) %}
{% set pv = states('sensor.pv_erzeugung_gesamt') | float(0) %}
{% set s_licht = states('input_number.rollladen_schwelle_licht') | float(40000) %}
{% set s_pv = states('input_number.rollladen_schwelle_pv') | float(6000) %}
{% set s_prog = states('input_number.rollladen_schwelle_prognose') | float(22) %}
{% set sonne = licht >= s_licht or pv >= s_pv %}
{% set stand = state_attr('input_datetime.rollladen_prognose_stand', 'timestamp') | float(0) %}
{% set frisch = stand > 0 and (now().timestamp() - stand) < 21600 %}
{% set tmax = states('input_number.rollladen_prognose_tagesmaximum') | float(-999) %}
{{ sonne and (not frisch or tmax >= s_prog) }}
- name: Rollladen Sonne Südost
state: >-
{% set az = state_attr('sun.sun', 'azimuth') | float(-1) %}
{% set el = state_attr('sun.sun', 'elevation') | float(-90) %}
{% set diff = ((az - 140 + 180) % 360) - 180 %}
{{ el > 10 and diff | abs <= 75 and is_state('binary_sensor.rollladen_hitzestau_moeglich', 'on') }}
- name: Rollladen Sonne Südwest
state: >-
{% set az = state_attr('sun.sun', 'azimuth') | float(-1) %}
{% set el = state_attr('sun.sun', 'elevation') | float(-90) %}
{% set diff = ((az - 230 + 180) % 360) - 180 %}
{{ el > 10 and diff | abs <= 75 and is_state('binary_sensor.rollladen_hitzestau_moeglich', 'on') }}alias: "Rollladen: Wetterprognose Tagesmaximum holen"
triggers:
- {trigger: time_pattern, hours: "/1", id: takt}
- {trigger: homeassistant, event: start, id: start}
conditions:
- condition: not
conditions:
- {condition: state, entity_id: weather.forecast_home, state: [unavailable, unknown]}
actions:
- action: weather.get_forecasts
target: {entity_id: weather.forecast_home}
data: {type: daily}
response_variable: fc
- variables:
tagesmax: "{{ fc['weather.forecast_home'].forecast[0].temperature | float(-999) }}"
alt_wert: "{{ states('input_number.rollladen_prognose_tagesmaximum') | float(-999) }}"
alt_datum: "{{ (state_attr('input_datetime.rollladen_prognose_stand', 'timestamp') | float(0)) | timestamp_custom('%Y-%m-%d', true) }}"
heute: "{{ now().strftime('%Y-%m-%d') }}"
- alias: Nur einen plausiblen Wert weiterverarbeiten
condition: template
value_template: "{{ tagesmax > -900 }}"
- alias: Wert nur bei neuem Tag oder höherem Maximum übernehmen
if:
- condition: template
value_template: "{{ alt_datum != heute or tagesmax > alt_wert }}"
then:
- action: input_number.set_value
target: {entity_id: input_number.rollladen_prognose_tagesmaximum}
data: {value: "{{ tagesmax }}"}
- alias: Zeitstempel bei jedem erfolgreichen Abruf setzen
action: input_datetime.set_datetime
target: {entity_id: input_datetime.rollladen_prognose_stand}
data: {datetime: "{{ now().strftime('%Y-%m-%d %H:%M:%S') }}"}
mode: single
max_exceeded: silentalias: "Rollladen: Sonne Südost – auf Spalt heben"
triggers:
- {trigger: state, entity_id: binary_sensor.rollladen_sonne_suedost, to: "on", id: sonne}
- {trigger: time, at: "07:30:00", id: fruehestens}
conditions:
- {condition: state, entity_id: binary_sensor.rollladen_sonne_suedost, state: "on"}
- {condition: time, after: "07:30:00", alias: Untergrenze wegen Kinderzimmer}
actions:
# je Rollladen ein eigener if-Block, kein choose
- alias: Wohnzimmer
if:
- {condition: numeric_state, entity_id: cover.rollladen_wohnzimmer, attribute: current_position, below: 16}
then:
- action: cover.set_cover_position
data: {position: 16}
target: {entity_id: cover.rollladen_wohnzimmer}
- alias: Kinderzimmer
if:
- {condition: numeric_state, entity_id: cover.rollladen_kinderzimmer_1, attribute: current_position, below: 16}
then:
- action: cover.set_cover_position
data: {position: 16}
target: {entity_id: cover.rollladen_kinderzimmer_1}
mode: single
max_exceeded: silentalias: "Rollladen: Sonne Südwest – auf Spalt heben"
triggers:
- {trigger: state, entity_id: binary_sensor.rollladen_sonne_suedwest, to: "on", id: sonne}
conditions:
- {condition: state, entity_id: binary_sensor.rollladen_sonne_suedwest, state: "on"}
actions:
- alias: Bad EG
if:
- {condition: numeric_state, entity_id: cover.rollladen_bad_eg, attribute: current_position, below: 16}
then:
- action: cover.set_cover_position
data: {position: 16}
target: {entity_id: cover.rollladen_bad_eg}
- alias: Bad 1. OG
if:
- {condition: numeric_state, entity_id: cover.rollladen_bad_1_og, attribute: current_position, below: 16}
then:
- action: cover.set_cover_position
data: {position: 16}
target: {entity_id: cover.rollladen_bad_1_og}
mode: single
max_exceeded: silentalias: "Rollladen: Sonnen-Abfang (App und Wandschalter)"
triggers:
- {trigger: state, entity_id: cover.rollladen_wohnzimmer, id: wohnzimmer}
- {trigger: state, entity_id: cover.rollladen_bad_eg, id: bad_eg}
# für jeden weiteren Rollladen ergänzen
conditions:
- alias: Echte Abwärtsbewegung unter 16 (filtert auch unavailable und unknown)
condition: template
value_template: >-
{{ trigger.from_state
and trigger.to_state
and trigger.from_state.attributes.current_position is number
and trigger.to_state.attributes.current_position is number
and trigger.to_state.attributes.current_position < trigger.from_state.attributes.current_position
and trigger.to_state.attributes.current_position < 16 }}
actions:
- choose:
- alias: Wohnzimmer – Südost
conditions:
- {condition: trigger, id: wohnzimmer}
- {condition: state, entity_id: binary_sensor.rollladen_sonne_suedost, state: "on"}
- {condition: state, entity_id: binary_sensor.gruppe_fenster_wohnzimmer, state: "off"}
sequence:
- action: cover.set_cover_position
data: {position: 16}
target: {entity_id: cover.rollladen_wohnzimmer}
- alias: Bad EG – Südwest
conditions:
- {condition: trigger, id: bad_eg}
- {condition: state, entity_id: binary_sensor.rollladen_sonne_suedwest, state: "on"}
- {condition: state, entity_id: binary_sensor.gruppe_fenster_bad_eg, state: "off"}
sequence:
- action: cover.set_cover_position
data: {position: 16}
target: {entity_id: cover.rollladen_bad_eg}
mode: queued
max: 10
max_exceeded: silentAnpassen
- Trage die Himmelsrichtung deiner Fassaden ein (die Zahlen 140 und 230 in den Sensoren) und den Abstand von 75°.
- Die Schwellen für Lux, PV und Prognose liegen in Helfern und lassen sich ohne Neustart ändern. Ohne PV-Anlage lässt du die PV-Bedingung weg.
- Die Untergrenze 07:30 Uhr gilt nur für Südost. Passe sie an deinen Tagesrhythmus an oder entferne den Trigger.
Stolpersteine
Zwei getrennte if-Blöcke pro Rollladen sind Pflicht. Meine erste Fassung benutzte choose, und choose bricht nach dem ersten passenden Zweig ab. Standen zwei Rollläden unten, wurde nur der erste gehoben. Beim Abfang gilt das Gegenteil: Dort ist choose richtig, weil immer genau ein Rollladen der Auslöser ist. Außerdem filtert die Bedingung des Abfangs unavailable und unknown heraus, indem sie fordert, dass beide Positionen Zahlen sind. Das Heben auf 16 ist selbst eine Aufwärtsbewegung und löst den Abfang nicht erneut aus.
Unterstützen
Diese Tools entstehen in meiner Freizeit und bleiben kostenlos, offen und cloud-frei. Wenn dir eins davon einen Nachmittag gespart hat, freue ich mich über einen Kaffee oder ein Stück Pizza.
Kaffee oder PizzaWeitere Beiträge
- Rollladen-Steuerung pro Raum: Taster, Fenster, Kälte und Regen Eine Automation pro Raum, die Taster, Fensterkontakt, Kälte, Regen und die Zeit vor Sonnenaufgang zusammenführt. Zwei Merker-Helfer verhindern, dass sich die Auslöser gegenseitig überfahren.
- Stromausfall erkennen und Geräte wiederherstellen in Home Assistant Nach einem Stromausfall booten Lampen und Steckdosen in zufälligen Zuständen. Drei Erkennungswege, ein gemeinsames Script und ein Wiederherstellungsfenster bringen alles wieder in den gewünschten Zustand.
- Rauchmelder löst aus: Alle Rollläden fahren hoch (Home Assistant) Bei Rauchalarm sollen die Rollläden im ganzen Haus hochfahren, damit Fenster als Fluchtweg frei sind. Die Automation ist kurz – aber ein fehlendes „from“ im Trigger entscheidet darüber, ob sie im Ernstfall überhaupt feuert.