EDIT:
I have made a new post with a much better control method: Automatic blinds / sunscreen control based on sun platform
Please let me know what you think!
Hi,
I made a template sensor to calculate the incident angle of sunlight based on position of the sun and position of any window in your house. I found that this is quite useful to control things like automatic blinds or sunscreens, which solely depend on the amount of sunlight coming in.
I figured that the amount of direct sunlight hitting the window depends on how âperpendicularâ the sun is with respect to the window. If the sun were to be directly in front of the window at 90 degrees with respect to the window then most sunlight would enter your room. A way to measure this is to consider the window as a plane and itâs normal vector the âbestâ angle of incidence. The closer the sunâs angle of incidence is to your window the more light will enter the room. So I used some basic vector algebra to calculate this âangular similarityâ.
It uses the sun.sun attributes azimuth and elevation to calculate the vector that points to the sun. Then you also need to fill in the elevation/azimuth from your window. Elevation is measured with respect to the center of the window so for a regular kitchen window this is 0 degrees. Azimuth can be found by using sun-earth tools: https://www.sunearthtools.com/dp/tools/pos_earth.php and selecting the polyline mode and measure the azimuth angle of your window (Dir).
# sun-window angular similarity
- platform: template
sensors:
sun_window_ang_similarity:
friendly_name: Sun-window angular similarity
unit_of_measurement: 'degrees'
value_template: >
{% set deg2rad = pi/180 %}
{% set sun_azi = state_attr('sun.sun', 'azimuth') | int %}
{% set sun_ele = state_attr('sun.sun', 'elevation') | int %}
{% set sun_x = cos(sun_azi*deg2rad)*cos(sun_ele*deg2rad) %}
{% set sun_y = sin(sun_azi*deg2rad)*cos(sun_ele*deg2rad) %}
{% set sun_z = sin(sun_ele*deg2rad) %}
{% set win_azi = 153 %}
{% set win_ele = 0 %}
{% set win_x = cos(win_azi*deg2rad)*cos(win_ele*deg2rad) %}
{% set win_y = sin(win_azi*deg2rad)*cos(win_ele*deg2rad) %}
{% set win_z = sin(win_ele*deg2rad) %}
{% set dot = sun_x*win_x + sun_y*win_y + sun_z*win_z %}
{% set norm_win = sqrt(win_x**2 + win_y**2 + win_z**2) %}
{% set norm_sun = sqrt(sun_x**2 + sun_y**2 + sun_z**2) %}
{% set cos_sim = dot/(norm_win*norm_sun) %}
{% set ang_sim = 1 - acos(cos_sim)/pi %}
{{ ang_sim | round(3) }}
This calculates a value between 0 and 1. A value of 1 means that the sun is perfectly perpendicular to your window and you will most likely be blinded. A value of 0 means that no light will enter the window.