-
-
Save dominicusmento/4ec7a9ed5ec482be2f2d908b0bde121e to your computer and use it in GitHub Desktop.
Homeassistant blueprint to close/open covers depending on sun position and weather
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# see https://community.home-assistant.io/t/close-open-curtain-cover-blinds-based-on-sun-and-weather/584240 | |
blueprint: | |
name: cover sun | |
description: Close cover when sun is shining and open when stops. This considers weather (sunny, partly cloudy), sun position (elevation, azimuth) and temperature. | |
domain: automation | |
input: | |
cover_entity: | |
name: cover | |
selector: | |
entity: | |
domain: cover | |
sun_position_start: | |
name: Sun azimuth position start | |
description: Sun azimuth. When sun is over this value, shutter could closed. | |
default: 89 | |
selector: | |
number: | |
min: 0 | |
max: 360 | |
unit_of_measurement: ° | |
sun_position_end: | |
name: Sun azimuth position end | |
description: Sun azimuth. when sun is over this value, shutter should open. | |
default: 200 | |
selector: | |
number: | |
min: 0 | |
max: 360 | |
unit_of_measurement: ° | |
sun_elevation_start: | |
name: Sun elevation to start | |
description: Sun elevation. When sun is over this value, shutter could be closed. | |
default: 32 | |
selector: | |
number: | |
min: -100 | |
max: 360 | |
unit_of_measurement: ° | |
outdoor_temp: | |
name: Temperature threshold | |
description: Temperature above which the shutters will close. Based on Temperature source (see below). | |
default: 16 | |
selector: | |
number: | |
min: 0 | |
max: 30 | |
unit_of_measurement: °C | |
close_position: | |
name: Closing position of curtain | |
description: "Target position for closed curtain. Note: 100 is open!" | |
default: 30 | |
selector: | |
number: | |
min: 1 | |
max: 99 | |
no_open_after: | |
name: Skip opening after this time | |
description: When the opening would happen after this time, it is skipped. This can be used to keep curtain closed at evenings. | |
default: "22:00:00" | |
selector: | |
time: | |
weather: | |
name: Weather service | |
default: "weather.home" | |
selector: | |
entity: | |
domain: weather | |
temperature_entity: | |
name: Temperature source | |
default: "weather.home" | |
selector: | |
entity: | |
filter: | |
- domain: | |
- weather | |
- device_class: | |
- temperature | |
close_weather_conditions: | |
name: Weather conditions | |
description: Close curtain on all of the selected weather conditions (if all other conditions are met) | |
default: | |
- sunny | |
- partlycloudy | |
selector: | |
select: | |
multiple: true | |
options: | |
- "clear-night" | |
- "cloudy" | |
- "fog" | |
- "hail" | |
- "lightning" | |
- "lightning-rainy" | |
- "partlycloudy" | |
- "pouring" | |
- "rainy" | |
- "snowy" | |
- "snowy-rainy" | |
- "sunny" | |
- "windy" | |
- "windy-variant" | |
- "exceptional" | |
variables: | |
sun_elevation_close: !input sun_elevation_start | |
sun_azimuth_close: !input sun_position_start | |
sun_azimuth_open: !input sun_position_end | |
temp_close: !input outdoor_temp | |
curtain_entity_id: !input cover_entity | |
curtain_target_position: !input close_position | |
no_open_after_time: !input no_open_after | |
weather_entity_id: !input weather | |
temperature_entity_id: !input temperature_entity | |
weather_close: !input close_weather_conditions | |
curtain_current_position: "{{ state_attr(curtain_entity_id, 'current_position') if state_attr(curtain_entity_id, 'current_position') is not none else state_attr(curtain_entity_id, 'position') }}" | |
current_temp: "{{ state_attr(temperature_entity_id, 'temperature') if state_attr(temperature_entity_id, 'temperature') is not none else states(temperature_entity_id) }}" | |
mode: queued # We rely on trigger changes, so 'single' and 'restart' are not possible. 'parallel' might work. | |
trigger: | |
- platform: numeric_state | |
entity_id: sun.sun | |
attribute: elevation | |
above: !input sun_elevation_start | |
id: t_sun_elevation_above | |
- platform: numeric_state | |
entity_id: sun.sun | |
attribute: elevation | |
below: !input sun_elevation_start | |
id: t_sun_elevation_below | |
- platform: numeric_state | |
entity_id: sun.sun | |
attribute: azimuth | |
above: !input sun_position_start | |
id: t_sun_azimuth_start_above | |
- platform: numeric_state | |
entity_id: sun.sun | |
attribute: azimuth | |
above: !input sun_position_end | |
id: t_sun_azimuth_end_above | |
- platform: state | |
entity_id: !input weather | |
to: !input close_weather_conditions | |
not_from: !input close_weather_conditions | |
id: t_weather_sunny | |
- platform: state | |
entity_id: !input weather | |
not_to: !input close_weather_conditions | |
from: !input close_weather_conditions | |
id: t_weather_not_sunny | |
# note: temperature_entity can either be a weather or temperature entity! | |
- platform: numeric_state | |
entity_id: !input temperature_entity | |
attribute: temperature | |
above: !input outdoor_temp | |
id: t_temp_above_weather | |
- platform: numeric_state | |
entity_id: !input temperature_entity | |
above: !input outdoor_temp | |
id: t_temp_above_temp | |
- platform: numeric_state | |
entity_id: !input temperature_entity | |
attribute: temperature | |
below: !input outdoor_temp | |
id: t_temp_below_weather | |
- platform: numeric_state | |
entity_id: !input temperature_entity | |
below: !input outdoor_temp | |
id: t_temp_below_temp | |
condition: | |
- condition: or | |
conditions: | |
# do close (when it is above curtain_target_position): | |
- condition: and | |
conditions: | |
- condition: template | |
value_template: "{{ curtain_current_position > curtain_target_position }}" | |
- condition: template | |
value_template: "{{ states(weather_entity_id) in weather_close }}" | |
- condition: template | |
value_template: "{{ state_attr('sun.sun', 'elevation') >= sun_elevation_close }}" | |
- condition: template | |
value_template: "{{ (sun_azimuth_close <= sun_azimuth_open and sun_azimuth_close <= state_attr('sun.sun', 'azimuth') <= sun_azimuth_open) or (sun_azimuth_close > sun_azimuth_open and (state_attr('sun.sun', 'azimuth') >= sun_azimuth_close or state_attr('sun.sun', 'azimuth') <= sun_azimuth_open)) }}" | |
- condition: template | |
value_template: "{{ current_temp >= temp_close }}" | |
# do open (when it (first) leaves the closed conditions (prevent e.g. opening at night when any trigger fires)): | |
- condition: and | |
conditions: | |
- condition: template | |
value_template: "{{ curtain_current_position < 100 }}" # add delta? | |
- condition: template | |
value_template: "{{ now() < today_at(no_open_after_time) }}" | |
- condition: or | |
conditions: | |
- condition: and | |
conditions: | |
- condition: trigger | |
id: t_weather_not_sunny | |
- condition: template | |
value_template: "{{ state_attr('sun.sun', 'elevation') >= sun_elevation_close }}" | |
- condition: template | |
value_template: "{{ (sun_azimuth_close <= sun_azimuth_open and sun_azimuth_close <= state_attr('sun.sun', 'azimuth') <= sun_azimuth_open) or (sun_azimuth_close > sun_azimuth_open and (state_attr('sun.sun', 'azimuth') >= sun_azimuth_close or state_attr('sun.sun', 'azimuth') <= sun_azimuth_open)) }}" | |
- condition: template | |
value_template: "{{ current_temp >= temp_close }}" | |
- condition: and | |
conditions: | |
- condition: template | |
value_template: "{{ states(weather_entity_id) in weather_close }}" | |
- condition: trigger | |
id: t_sun_elevation_below | |
- condition: template | |
value_template: "{{ (sun_azimuth_close <= sun_azimuth_open and sun_azimuth_close <= state_attr('sun.sun', 'azimuth') <= sun_azimuth_open) or (sun_azimuth_close > sun_azimuth_open and (state_attr('sun.sun', 'azimuth') >= sun_azimuth_close or state_attr('sun.sun', 'azimuth') <= sun_azimuth_open)) }}" | |
- condition: template | |
value_template: "{{ current_temp >= temp_close }}" | |
- condition: and | |
conditions: | |
- condition: template | |
value_template: "{{ states(weather_entity_id) in weather_close }}" | |
- condition: template | |
value_template: "{{ state_attr('sun.sun', 'elevation') >= sun_elevation_close }}" | |
- condition: trigger | |
id: t_sun_azimuth_end_above | |
- condition: template | |
value_template: "{{ current_temp >= temp_close }}" | |
- condition: and | |
conditions: | |
- condition: template | |
value_template: "{{ states(weather_entity_id) in weather_close }}" | |
- condition: template | |
value_template: "{{ state_attr('sun.sun', 'elevation') >= sun_elevation_close }}" | |
- condition: template | |
value_template: "{{ (sun_azimuth_close <= sun_azimuth_open and sun_azimuth_close <= state_attr('sun.sun', 'azimuth') <= sun_azimuth_open) or (sun_azimuth_close > sun_azimuth_open and (state_attr('sun.sun', 'azimuth') >= sun_azimuth_close or state_attr('sun.sun', 'azimuth') <= sun_azimuth_open)) }}" | |
- condition: or | |
conditions: | |
- condition: trigger | |
id: t_temp_below_weather | |
- condition: trigger | |
id: t_temp_below_temp | |
action: | |
- choose: | |
# close cover | |
- conditions: | |
- condition: template | |
value_template: "{{ curtain_current_position > curtain_target_position }}" | |
- condition: template | |
value_template: "{{ states(weather_entity_id) in weather_close }}" | |
- condition: template | |
value_template: "{{ state_attr('sun.sun', 'elevation') >= sun_elevation_close }}" | |
- condition: template | |
value_template: "{{ (sun_azimuth_close <= sun_azimuth_open and sun_azimuth_close <= state_attr('sun.sun', 'azimuth') <= sun_azimuth_open) or (sun_azimuth_close > sun_azimuth_open and (state_attr('sun.sun', 'azimuth') >= sun_azimuth_close or state_attr('sun.sun', 'azimuth') <= sun_azimuth_open)) }}" | |
- condition: template | |
value_template: "{{ current_temp >= temp_close }}" | |
sequence: | |
- service: cover.set_cover_position | |
data: | |
position: "{{ curtain_target_position }}" | |
target: | |
entity_id: "{{ curtain_entity_id }}" | |
# open cover (conditions are somewhat redundant here, as 'condition' is more specific..) | |
- conditions: | |
- condition: template | |
value_template: "{{ curtain_current_position <= curtain_target_position }}" | |
- condition: or | |
conditions: | |
- condition: template | |
value_template: "{{ states(weather_entity_id) not in weather_close }}" | |
- condition: template | |
value_template: "{{ state_attr('sun.sun', 'elevation') < sun_elevation_close }}" | |
- condition: template | |
value_template: "{{ (sun_azimuth_close <= sun_azimuth_open and (sun_azimuth_close > state_attr('sun.sun', 'azimuth') or state_attr('sun.sun', 'azimuth') > sun_azimuth_open)) or (sun_azimuth_close > sun_azimuth_open and (state_attr('sun.sun', 'azimuth') < sun_azimuth_close and state_attr('sun.sun', 'azimuth') > sun_azimuth_open)) }}" | |
- condition: template | |
value_template: "{{ current_temp < temp_close }}" | |
sequence: | |
- service: cover.set_cover_position | |
data: | |
position: 100 | |
target: | |
entity_id: "{{ curtain_entity_id }}" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment