Automatic blinds / sunscreen control based on sun platform

Thanks for the tip. Proper logic to determine whether the sun is coming through the window is really all im looking for

Thanks to your question I just realized there is a mistake in the FOV calculation.

The calculation:
{% set gamma = deg2rad * (win_azi - sun_azi) %}

Should be:
{% set gamma = deg2rad * ((win_azi - sun_azi + 180) % 360 - 180) %}

This template will work as a condition for your automations (set win_azi to your window azimuth ofcourse)

{% set win_azi = 330 %}
{% set sun_azi = state_attr('sun.sun', 'azimuth') %}
{% set sun_ele = state_attr('sun.sun', 'elevation') %}
{% set sw_diff = (win_azi - sun_azi + 180) % 360 - 180 %}
{{ (sw_diff | abs < 90) and (sun_ele > 0) }}

Glad I could help :rofl:. Thanks for the template. I’m guessing if true close, if false open. Simple as that?

Yes indeed

Thanks :slight_smile: this works.

One last thing - I’d like to send a notification when the blinds are set. This works using the

service: notify.slack
data:
  target: "#debug"
  message: "{{ cover_entity }} set to {{ cover_height }}"

Unfortunately this translates to
{'entity_id': 'cover.kitchen'} set to 0

Is there a better one to use to get the name of the entity?

Yes, it’s just a python dict. So {{ cover_entity['entity_id'] }} should work.

1 Like

gah I didn’t think of that. Still too new to the HA automations section, I’ve been using Nodered sofar.

1 Like

Visibly it seems to be closing the blind early. The template is returning true but the sun is not close to shining through the window.

Visibly the sun i shining through windows on the right side of my house and the one that incorrectly fired is in the back of my house. I think the sun needs to make it more to the back of my house to be accurate
image
You can see the sun is shining more on the right side of the house and hasnt made its way to the back

image

This is the current sun position as of making this post, and the automation just fired on a window azimuth of 196

By default the FOV is 180 degrees, 90 degrees left and right from the window. So if your window has an azimuth of 196 the template will return True in range [106,286]. You can reduce the FOV to whatever you like ofcourse.

Ok that makes more sense. In the template you gave:

{% set win_azi = 330 %}
{% set sun_azi = state_attr('sun.sun', 'azimuth') %}
{% set sun_ele = state_attr('sun.sun', 'elevation') %}
{% set sw_diff = (win_azi - sun_azi + 180) % 360 - 180 %}
{{ (sw_diff | abs < 90) and (sun_ele > 0) }}

Which is the fov?

The number 90 in the last line. If you want independent FOV for left and right you’ll have to change that line a little bit (check out the blueprint code which has that)

Looks like the left and right fov is the most intense part of the math you did.

This seems to be the part of the code i need where one if statement is if its on the left and the other if it has passed the right.

{%- if gamma < azi_left or gamma > azi_right or alpha < elev_low or alpha > elev_high -%}
            {{ clipv(h2perc(h) | round(0) | int , 0, 100) }}
        {% else %}  
            {{ clipv(h2perc(def_h) | round(0) | int , 0, 100) }}
        {% endif %}

Seems gamma is sw_diff as in the template u gave earlier and you have also those two other macros which ic an use. However h and def_h confuse me. I assume these are different for me since i have dumb blinds. def_h would be the height of my blind, 2.1 meters, and h… idk about that one. I thot h was if i had smart blinds, so i’m unsure how to make the edit. Here is what i have so far:

{% set sun_azi = state_attr('sun.sun', 'azimuth') %}
{% set sun_ele = state_attr('sun.sun', 'elevation') %}
{% set sw_diff = (win_azi - sun_azi + 180) % 360 - 180 %}
{% set azi_left = 30 %}
{% set azi_right = 60 %}
{% set def_h = 2.1 %}
{% set d = 0.5 %}
{% set h = (d / cos(sw_diff)) * tan(sun_ele ) %} 
{% if sw_diff < azi_left or sw_diff > azi_right or sun_ele < 0 or sun_ele > 90 %}
        {{ clipv(h2perc(h) | round(0) | int , 0, 100) }}
{% else %}  
        {{ clipv(h2perc(def_h) | round(0) | int , 0, 100) }}
{% endif %}

Lost my true/false statement too. I have no idea what clipv1 and h2perc do. Maybe i don’t need any of that?

{% set sun_azi = state_attr('sun.sun', 'azimuth') %}
{% set sun_ele = state_attr('sun.sun', 'elevation') %}
{% set sw_diff = (win_azi - sun_azi + 180) % 360 - 180 %}
{% set azi_left = 30 %}
{% set azi_right = 60 %}
{{ sw_diff < azi_left or sw_diff > azi_right or sun_ele < 0 or sun_ele > 90 }}

Am I on track here?

{% set win_azi = 330 %}
{% set sun_azi = state_attr('sun.sun', 'azimuth') %}
{% set sun_ele = state_attr('sun.sun', 'elevation') %}
{% set sw_diff = (win_azi - sun_azi + 180) % 360 - 180 %}
{% set azi_left = 30 %}
{% set azi_right = 60 %}
{{ (sw_diff < azi_left) and (sw_diff > -azi_right) and (sun_ele > 0)}}
2 Likes

In case anyone wonders how to use the custom_template to turn it into a sensor:

Add this to your configuration (wherever you have it)

template:
  - sensor:
    - name: calculated_cover_position
      unit_of_measurement: "%"
      state: >
        {% from 'auto_sun_blind.jinja' import auto_sun_blind %}
        {{ auto_sun_blind(azimuth=245, distance=0.1, height=2.30, min_height=1.10, def_height=100, fov_left=45, fov_right=45, elev_min=0, elev_max=90) }}

with the right values for your covers, ofcourse.

1 Like

Been playing a bit more with the custom template - it kept going just from 100 to 0 to 100, so I figured I was doing something wrong.

Question: on the docs you specify min_height as “The minimum height in meters when the blinds are fully open. This will be 0 in most cases.” - do you mean the bottom height of the window? (in my case, some of the windows are at 1.10m height up to 2.3m height)

So, is it better to specify 1.10 as min_height and 2.3 as height, or 0 and 1.20 respectively?

Do you have distance set to 0? That could cause it to go from 0 to 100.

I would just use 0 and 1.20. That minimum height was intended to be a bit more flexible in defining the height of the window, but it’s not really needed I suppose. We might as well remove it to prevent confusion.

1 Like

It was set at 0.10 (10cm), which is the minimum also in the slider. I guess I need to keep it a bit bigger than that :wink:

I have uploaded a python notebook to github where you can play around with the settings and simulate the behaviour, if you want to test it :wink:

1 Like

Thanks! I’m definitely gonna play with that to get the best values :wink:

One thing I’m searching on is a better way to handle the exceptions / conditions.
I have eg. a condition on room temperature - if the room temp > X, the automation can run.

Ofcourse, if then during the day the temperature drops, the automation will never run again and never open the blinds. Currently I’m using a max value of the room temp. but is there some more graceful way to handle this?