Automatic blinds / sunscreen control based on sun platform

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?

What does “Distance from the cover to shaded area” mean, exactly? Are we talking about that ‘working area’? From my perspective that working area would be close to the floor, if I’m going by the image. That doesn’t make much sense.

I have an east-facing window (Azmuth 83 deg) that gets a lot of sun in the morning. I just want the shade lowered around 60-70% during those morning hours when the sun is beaming in.

Distance d is the distance in meters to the working area which is normal to the window and at the same height as the bottom of the window. The window and the working area form a 90 degree angle

Thanks, but this automation is clever but way too complex for my needs. I found it didn’t function correctly for my installation. I’ll stick with a simple and reliable timer based off the weather condition.

It’s really not that complicated. It just calculates the height of the blind should be at to cast a shade at distance d. You don’t have to understand how the math works to use it. If you have issues then we can help with that.

Don’t sweat it, I think it’s really neat but overkill for my use case. In my situation it’s much easier to simply hard code the blind to close 70% for a few hours on sunny weekdays.

This is SO amazing - now my blinds close around my house perfectly in line with where the sun is!

I have a couple questions:

I am not sure what the Max/Min Elevation do. I have mine set at min = 5 and max = 90 and this seems to open the shade when the elevation drops below 5. So what does the max do? I set it at 10 and all my blinds opened. What might this be for?

Also I cannot get my blinds to close all the way then the sun is dead on, they go to 10%. Is there a way to adjust this? I have the correct measurements for the size…maybe just tinker with those?

Hi, sorry I missed your message.

Max and min elevation refer to this picture in the description:

So it’s the angle with respect to the horizon. 90 degrees would be fully vertical, 0 degrees is fully horizontal. Tracking is only active if the sun’s elevation angle falls inside the min and max elevation. If it falls outside this range the blind is set to the default value.

Try to use the default values for elevation (min=0 and max=90) and azimuth (min=max=90), as those affect the tracking FOV. (think of FOV like a huge rectangular area in the sky, if the sun is inside the rectangle tracking is active)

1 Like