How to automate my awning (sunscreen)

A bayesien sensor would seem to fit the bill :slight_smile:

A bayesian sensor could work nice, but be careful about how you incorporate wind speed, because the awning should close if the wind is high. That seems like the “most important” sensor.

I don’t know if a template is the right thing for this, perhaps just a whole bunch of triggers, and two automations?

For example:

open awning:

triggers: temperature above 25 C, wind speed drops below 5 km/h for thirty minutes, rain likelihood above 90%, UV above… 7.
conditions: wind speed below 5 km/h

close awning:

triggers: temperature below 22, wind speed above 5 km/h for two minutes, UV below… 6
conditions: not raining or wind above 5.

That’s three directions to try out: template, bayesian binary sensor and a bunch of triggers.

I feel like I still have a lot to learn :slight_smile:

When I get a working solution I’ll report back!

1 Like

I think I’ve put together an automation that I hope might work. I’m curious what you guys think about this approach, should this work as expected? In automations.yaml:

- alias: 'Roll down awning'
  trigger:
    platform: numeric_state
    entity_id: sun.sun
    value_template: '{{ state.attributes.azimuth }}'
    above: 150  #sun light starts to hit the window
    below: 275  #275 is about West, where the sun sets
  condition:
    condition: and
    conditions:
      - condition: state
        entity_id: switch.fibaro_system_roller_shutter_controller_switch
        state: 'on'  #ON means awning is all the way up
        for:
          hours: 1
      - condition: numeric_state
        entity_id: sun.sun
        value_template: '{{ state.attributes.elevation }}'
        above: 0  #above the horizon
      - condition: numeric_state
        entity_id: sensor.br_temperature_1d
        above: 15 #predicted max temp today
      - condition: numeric_state
        entity_id: sensor.pws_uv
        above: 2  #predicted UV-index around noon (1-10)
      - condition: numeric_state
        entity_id: sensor.pws_wind_kph
        below: 6 #1-5 is a mild breeze
      - condition: numeric_state
        entity_id: sensor.pws_wind_gust_kph
        below: 15 #15 is still a light breeze
      - condition: numeric_state
        entity_id: sensor.br_precipitation_forecast_total
        below: 0.5 #rain less than 0.5 mm/h in the next 20 minutes
      - condition: template
        value_template: '{{ now().month > 1 }}' #starting February
      - condition: template
        value_template: '{{ now().month < 10 }}' #ending September
      - condition: numeric_state
        entity_id: sensor.br_irradiance
        above: 300 #up to 300 no sun shielding is necessary (cloudy)
  action:
    service: light.turn_on  # for testing purposes; will eventually be 'roll out awning'
    entity_id: light.yeelight_rgb
    data:
      color_name: blue
      brightness: 255

Of course what is missing is something comparable for ‘roll up awning’, working on that :slight_smile:

I would like to borrow your code. Doed it work like expected? i am using the exact same setup. Fibaro Shutter and Buienradar sensor.

Hi Martin, I’ve tuned the configuration further since the posting above. I’ll add the relevant bits here. I have to say I have not thorougly tested it. It’s basically working, but I’m waiting for springtime to put it to the test :slight_smile:

automations.yaml

- alias: Roll down awning
  trigger:
    platform: state
    entity_id: sun.sun
  condition:
    condition: and
    conditions:
    - condition: numeric_state
      entity_id: sun.sun
      value_template: '{{ state.attributes.azimuth }}'
      above: 150  ## This is the position where the sunlight starts hitting the window
      below: 235  ## This is about west, sun down
    - condition: numeric_state
      entity_id: sun.sun
      value_template: '{{ state.attributes.elevation }}'
      above: 0  ## Sun should be above the horizon, not below
    - condition: state
      entity_id: cover.fibaro_system_fgr221_roller_shutter_controller_switch
      state: open
      for:
        minutes: 30  ## Trying to prevent a crazy repetitive up-and-down action
    - condition: sun
      before: sunset
      before_offset: -00:45:00  ## Some time before sunset, there's no point in rolling out anymore
    - condition: numeric_state
      entity_id: sensor.br_temperature_1d
      above: 16   ## Expected highest temperature for the day should be over 16
    - condition: numeric_state
      entity_id: sensor.pws_uv
      above: 1   ## Expected UV index at noon should at least be above 1, but perhaps it needs to be higher
    - condition: numeric_state
      entity_id: statistics.wind_kph_avg
      below: 7   ## I still have to tune this value 
    # - condition: numeric_state
    #   entity_id: sensor.pws_wind_gust_kph
    #   below: 25    ## I removed this one because I think wind speed should be enough
    - condition: numeric_state
      entity_id: sensor.br_precipitation_forecast_total
      below: 0.1  ## Almost no rain in the next 20 minutes
    - condition: template
      value_template: '{{ now().month > 2 }}'  ## Starting March 
    - condition: template
      value_template: '{{ now().month < 10 }}' ## Ending October
    - condition: numeric_state
      entity_id: statistics.irradiance_avg
      above: 300  ## This indicates direct sunlight on my location (as in: not cloudy)
    - condition: state
      entity_id: input_boolean.vacation_mode
      state: 'off'  ## When we are on vacation, the awning does not need to move
  action:
    service: cover.close_cover
    entity_id: cover.fibaro_system_fgr221_roller_shutter_controller_switch
    
- alias: Roll up awning
  trigger:
  - platform: sun
    event: sunset
    offset: -00:45:00
  - platform: numeric_state
    entity_id: statistics.wind_kph_avg
    above: 7
  # - platform: numeric_state
  #   entity_id: sensor.pws_wind_gust_kph
  #   above: 19
  - platform: numeric_state
    entity_id: sensor.br_precipitation_forecast_total
    above: 0.2
  - platform: numeric_state
    entity_id: statistics.irradiance_avg
    below: 100
  condition:
    condition: state
    entity_id: cover.fibaro_system_fgr221_roller_shutter_controller_switch
    state: closed
    for:
      seconds: 30  ## The screen takes some time to fully roll up or down, I don't want it changing direction half way
  action:
    service: cover.open_cover
    entity_id: cover.fibaro_system_fgr221_roller_shutter_controller_switch

configuration.yaml

sensor:

  - platform: wunderground
    api_key: xxxx
    monitored_conditions:
    # - precip_today_metric
      - temp_c
      - wind_kph
    # - wind_gust_kph
      - UV
    scan_interval: 10
  - platform: buienradar
    timeframe: 20
    monitored_conditions:
      - symbol
      - conditiondetailed
      - temperature
      - windspeed
      - precipitation_forecast_average
      - precipitation_forecast_total
      - temperature_1d
      - irradiance
  - platform: template
    sensors:
      solar_elevation:
        friendly_name: "Sun elevation"
        unit_of_measurement: 'degrees'
        value_template: "{{ states.sun.sun.attributes.elevation }}"
      solar_azimuth:
        friendly_name: "Sun azimuth"
        unit_of_measurement: 'degrees'
        value_template: "{{ states.sun.sun.attributes.azimuth }}"
  - platform: statistics  ## For smoothing out spikes
    name: wind_kph_avg
    entity_id: sensor.pws_wind_kph
    sampling_size: 3 #Measures every 15 minutes
    max_age:
      minutes: 65
  - platform: statistics
    name: irradiance_avg   ## For smoothing out spikes
    entity_id: sensor.br_irradiance
    sampling_size: 3  #Measures every 10 minutes
    max_age:
      minutes: 40
3 Likes

Ok Thanks for you code. a few markups:

  • why not using only Buienradar?
  • aren’t those precipitation for the next day?
  • it look likes you cover close and cover open are reversed?
  • those are a lot of conditions. Isn’t a little to much?

Thanks again

  1. Because Buienradar does not have the UV index. More importantly, I believe the wind speed from Buienradar is measured at their own location(s?) (for me: De Bilt). Weather Underground provides a wind speed that is measured by a neighbour of mine a couple 100 meters away, so way more local.

  2. No I don’t think so. At least, that’s how I read the documentation on the Buienradar component. But if I made a mistake I’d love to hear about it so I can correct it.

  3. I know it seems that way, but it is correct for my situation. It depends on how your cover is set up, what it considers ‘on’ or ‘off’, ‘open’ or ‘closed’. I just took the correct state from the Developer Tools / States.

  4. Yes I agree. I put together a lot of conditions that seem relevant. You can just delete what you deem irrelevant I guess :). I think the important ones I’d hold on to are irradiance, predicted temperature, azimuth/elevation, wind speed, rain.

I’d like to hear your experiences, share tips.

Today i have setup your code. I skipped a couple of statistics sensors and changed some other variables. Just to know there is a simple way for the above_horizon, then your value_template, just use:

    - condition: state
      entity_id: sun.sun
      state: 'above_horizon'

secondly you made up a trigger sun.sun, but i don’t fully understand the completeness of this trigger. Isn’t missing something?

Thanks for posting back. Above-horizon sounds easier indeed.

I think I got the sun trigger from an example I found somewhere in the forums. I thought it was missing something too, but it seems to be working as expected. I wanted to find a trigger that would keep checking the conditions throughout the day when it’s light out. This does that. If you find something more efficient I’d be glad to hear it.

Edit: your post triggered me to read some more about the sun trigger. Perhaps the below topic is related, I think I might have made a similar mistake at the very beginning. If I remember correctly, I started out with azimuth above 150 and below 275 in the trigger. It seems this is not correct, perhaps I should add azimuth above 150 as a trigger and azimuth below 275 as a condition. For fine tuning :slight_smile:

i have made up the following code now:

- alias: Sunscreen down
  initial_state: 'on'
  trigger:
    platform: state
    entity_id: sun.sun
  condition:
    condition: and
    conditions:
    - condition: numeric_state
      entity_id: sun.sun
      value_template: '{{ state.attributes.elevation }}'
      above: 0  ## Sun should be above the horizon, not below
    - condition: state
      entity_id: cover.level
      state: closed
      for:
        minutes: 30  ## Trying to prevent a crazy repetitive up-and-down action
    - condition: sun
      before: sunset
      before_offset: -00:45:00  ## Some time before sunset, there's no point in rolling out anymore
    - condition: numeric_state
      entity_id: sensor.br_wind_force
      below: 7   ## I still have to tune this value 
    - condition: numeric_state
      entity_id: sensor.br_precipitation_forecast_total
      below: 0.1  ## Almost no rain in the next 30 minutes
    - condition: template
      value_template: '{{ now().month > 2 }}'  ## Starting March 
    - condition: template
      value_template: '{{ now().month < 10 }}' ## Ending October
    - condition: numeric_state
      entity_id: sensor.br_irradiance
      above: 300  ## This indicates direct sunlight on my location (as in: not cloudy)
  action:
   - service: cover.set_cover_position
     data:
       entity_id: cover.level
       position: 40
   - service: notify.ios_iphone
     data:
       message: 'Het zonnescherm is naar beneden gedaan ivm de zon'
- alias: Sunscreen up
  initial_state: 'on'
  trigger:
  - platform: sun
    event: sunset
    offset: -00:45:00
  - platform: numeric_state
    entity_id: sensor.br_wind_force
    above: 7
  - platform: numeric_state
    entity_id: sensor.br_precipitation_forecast_total
    above: 0.2
  - platform: numeric_state
    entity_id: sensor.br_irradiance
    below: 100
    for:
     minutes: 5
  condition:
    condition: state
    entity_id: cover.level
    state: open
    for:
      seconds: 30  ## The screen takes some time to fully roll up or down, I don't want it changing direction half way
  action:
   - service: cover.close_cover
     entity_id: cover.level
   - service: notify.ios_iphone
     data:
       message: 'Het zonnescherm is weer ingetrokken'

as it was a sunny day today, the sunscreen went down perfectly :slight_smile:
i am still a bit finetuning, but for now it look likes it is working perfect.
With the ‘position’ parameter you can also set the position (in case of a cover fibaro in Roller Blind mode with Positioning)

2 Likes

Great that it’s working for you too!

I notice you removed the ‘predicted temperature’ as a condition. I added this so when it’s cold outside (like today) the sunlight is not being blocked and is used to heat the living room. Free comfort :sun_with_face:
But perhaps in your situation it’s different?

Yes my situation is different. i removed it, because the sun is hitting the kitchen directly. As i only open the suncreen for 40% it can be done whenever it is warm or cold. there is still a condition for march until oktober.

1 Like

Hoi Emphyrio, Martinvdm,

I’m also trying to get my zonnescherm/sunscreen working. I was looking at the latest code where the sun.sun is used as a trigger.
trigger:
platform: state
entity_id: sun.sun

I also don’t understand why this is used. I believe this trigger is now triggered (…) every minute as one of the attributes changes of this sun.sun entity. Why not just use a time trigger which triggers on an interval like:

trigger:
platform: time
# You can also match on interval. This will match every 5 minutes
minutes: ‘/5’
seconds: 00

Hey Martinvdm,

With the code below, don’t you get a message every 30 minutes now on a sunny day throughout the day?
I applied your code and I seem to get this message every 30 minutes as:

  1. Trigger is triggered every minute or so
  2. conditions (on a sunny day) are all true constantly (except the second condition) which results in all conditions being TRUE every 30 minutes (as after 30 minutes the second condition, see below, also becomes TRUE).

Or do I miss something (or in proper Dunglisch, do I see something over the head (if you know what I’m saying :wink: )

- condition: state
  entity_id: cover.level
  state: closed
  for:
    minutes: 30  ## Trying to prevent a crazy repetitive up-and-down action

I do understand what you mean, i lookup the code again and it look like you are right but it is working just working fine. Today was very sunny; 10:10 sunscreen went down and about 6 Pm went up again probably due to sunset.

I do not get many messages. As said; working fine. Perhaps @Emphyrio know the answer; he made the code initially.

Hi oliesjeik, I agree with you about the sun trigger looking a little strange. I happened to change it to a timed interval, just as you suggested. Just because it made more sense to me, not because it wasn’t working :slight_smile:

I think what you are saying about the condition ‘closed for 30 minutes’ is probably a matter of interpretation what ‘closed’ and ‘open’ means. They are rather counter-intuitive for an awning, because ‘closed’ means it’s rolled all the way out, and ‘open’ means the awning is rolled up (e.g. not providing any shade). And then in my case, the Fibaro switch was also reversed for ‘off’ and ‘on’. Okay, now I’m even confusing myself :slight_smile:

My suggestion: check your states when the awning is rolled up and rolled out. And match the state in your condition. Hope I’m making sense.

Hey Emphyrio,

Indeed, the sun trigger works as well but I believe the interval is more intuitive.
About the close and open states: I also noticed it’s a bit counter-intuitive when I was making my automation :slight_smile:

The difference I believe with my sunscreen and yours is that you actually ‘know’ the state the sunscreen is in (closed or open) while with my sunscreen I don’t. My sunscreen is operated with a remote control (Somfy) and I use a RFlink to control the sunscreen to send a signal to either open or close. However, when I send out a ‘close’ or ‘open’ signal, I actually do not know for certain that the signal arrived and the screen actually opened or closed. It’s like a ‘klik aan/klik uit’ system where there is not feedback if action was actually executed or not.

I probably going to add an extra sensor in the future to check if sunscreen is really open or closed but for the time being, to prevent that e.g. the down automation is triggered every x minutes, I check with a condition if the last trigger time of the close automation is older as the last trigger time of the ‘open automation’ (hope I explain it ok)

I use the following condition for that:

- condition: template
  value_template: '{{as_timestamp(states.automation.sunscreen_down.attributes.last_triggered) | int <= as_timestamp(states.automation.sunscreen_up.attributes.last_triggered) | int }}' # this automation can only be triggered if timestamp of last_triggered time is OLDER than the timestamp of last_triggered time of the "screen up" automation. This condition prevents that the automation is triggered again if sunscreen is already down. Better would be to have a real sensor checking if sunscreen is up or down but currently I don't have a sensor in place. The | int is used to catch the fact that on start up both triggers report 'none' and hence this condition would never become true. The int makes it such that value = 0 for both and hence trigger can be executed.

I also added a few more checks, not sure if they are needed, still experimenting a bit but here is my automation based on your examples:

- alias: Sunscreen down #Sunscreen down/uitklappen
  initial_state: 'on' #on reboot HA or reloading of automations, automation is ON
  trigger:
    - platform: time
      minutes: '/5'
      seconds: 0
  condition:
    condition: and # all conditions need to be TRUE before action is executed.
    conditions:

      # Wather based conditions
    - condition: numeric_state
      entity_id: sun.sun
      value_template: '{{ state.attributes.elevation }}'
      above: 0  # Sun should be above the horizon, not below.
    - condition: sun
      after: sunrise
      after_offset: 02:00:00 # Sunrise for at least 2 hours
    - condition: sun
      before: sunset
      before_offset: -02:30:00 # Some time before sunset, there's no point in rolling out anymore
    - condition: numeric_state
      entity_id: sensor.br_wind_force
      below: 7 # Wind strenght - I still have to tune this value
    - condition: numeric_state
      entity_id: sensor.br_precipitation
      below: 0.1 # Almost no rain at the moment
    - condition: numeric_state
      entity_id: sensor.br_precipitation_forecast_total
      below: 0.1 # Almost no rain in the next 60 minutes is predicted
    - condition: numeric_state
      entity_id: sensor.br_irradiance
      above: 300 # This indicates direct sunlight on my location (as in: not cloudy)

      # Temperature based conditions
    - condition: numeric_state
      entity_id: sensor.br_temperature
      above: 18 # only if outdoor temperature is above x then allowed to roll out
    - condition: numeric_state
      entity_id: sensor.aeotec_dsb05_multisensor_temperature
      above: 22 # only if indoor temperature is above x then allowed to roll out

      # Time based conditions
    - condition: template
      value_template: '{{ now().month > 3 }}' # Starting April
    - condition: template
      value_template: '{{ now().month < 10 }}' # Ending October
    - condition: template
      value_template:  ' {{ as_timestamp(now()) - as_timestamp(states.automation.sunscreen_down.attributes.last_triggered) | int > 1800}}' # prevents that automation is triggered multiple times in a short amount of time. Checks last time automation is triggered, if more then 1800 seconds (30min), condition becomes TRUE
    - condition: template
      value_template: '{{as_timestamp(states.automation.sunscreen_down.attributes.last_triggered) | int <= as_timestamp(states.automation.sunscreen_up.attributes.last_triggered) | int }}' # this automation can only be triggered if timestamp of last_triggered time is OLDER than the timestamp of last_triggered time of the "screen up" automation. This condition prevents that the automation is triggered again if sunscreen is already down. Better would be to have a real sensor checking if sunscreen is up or down but currently I don't have a sensor in place. The | int is used to catch the fact that on start up both triggers report 'none' and hence this condition would never become true. The int makes it such that value = 0 for both and hence trigger can be executed.
  action:
    - service: cover.close_cover #closes/uitklappen the sunscreen - bit counterintuitive naming but close meeans it is folded out in my case)
      data:
        entity_id: cover.zonnescherm
    - service: notify.Telegram #Send message to inform about action
      data:
       message: "Het zonnescherm is naar beneden gedaan ivm de zon"

En voor inklappen:

- alias: Sunscreen up #Sunscreen up/inklappen
  initial_state: 'on' #on reboot HA or reloading of automations, automation is ON
  trigger:

  # Wather based triggers
  - platform: sun
    event: sunset
    offset: -02:30:00 #2,5 hours before sunset, sunscreen is going up again (might want to change depending on location)
  - platform: numeric_state
    entity_id: sensor.br_wind_force
    above: 7 #If wind force becomes to high, sunscreen needs to go up
  - platform: numeric_state
    entity_id: sensor.br_precipitation
    above: 0.01 # Rain at the moment
  - platform: numeric_state
    entity_id: sensor.br_precipitation_forecast_total
    above: 0.2 # Rain predicted in next 60 minutes
  - platform: numeric_state
    entity_id: sensor.br_irradiance
    below: 100
    for:
     minutes: 5 # Sunlight below X for Y minutes
  - platform: numeric_state
    entity_id: sensor.br_temperature
    below: 18 #If outdoor temperature is below x for y minutes then sunscreen can go up again.
    for:
      minutes: 10

  condition:
    condition: and
    conditions:
    - condition: template
      value_template: '{{as_timestamp(states.automation.sunscreen_up.attributes.last_triggered) | int <= as_timestamp(states.automation.sunscreen_down.attributes.last_triggered) | int }}' # this automation can only be triggered if timestamp of last_triggered time is OLDER than the timestamp of last_triggered time of the "screen down" automation. This condition prevents that the automation is triggered again if sunscreen is already up. Better would be to have a real sensor checking if sunscreen is up or down but currently I don't have a sensor in place. The | int is used to catch the fact that on start up both triggers report 'none' and hence this condition would never become true. The int makes it such that value = 0 for both and hence trigger can be executed.

  action:
    - service: cover.open_cover #close/inklappen the sunscreen - seems service is swapped
      entity_id: cover.zonnescherm
    - service: notify.Telegram #Send message to inform about action
      data:
       message: "Het zonnescherm is weer ingetrokken"
5 Likes

@oliesjeik
Any updates on your automation?

What hardware are you using for the screen?