Incident Angle of Sunlight

It’s very complicated, but it could be done using for example the open source database of Open Topography. I’ve seen it used in some PV installation tools to calculate the forecasted production for example.

Hi Stefan,

thanks a lot for posting this - I’ve been trying to reuse your template for my particular setup but I might need a bit of help to make it actually work correctly - let me try to explain:

I have a “bioclimatic pergola” with movable roof slats:

I’m trying to set up an automation that will keep them perfectly aligned with the angle of the sun (same as in the photo) to minimize the amount of shade they are casting. In the photo I’m facing almost directly north (27 NW), with the east to my right. In the morning when the sun if effectively shining perpendicular to the slats all I need is to set their angle to the same elevation as the sun and I’m good however at noon when the sun is directly behind me (at azimuth 207) I need them to be vertical to minimize the shade while I no longer care about the sun’s elevation.

I’ve been trying to come up with a formula combining the azimuth and elevation of the sun to come up with the slat angle but no luck so far although I’m pretty sure it’s pretty basic trigonometry. If I use your sensor set to azimuth 207 and 0 elevation, I never get incidence of 1 however I assume that’s due to your setup working in 3 dimensions to the plane of the window…

Is there a simple way to (re)use what you come up with for this application? I feel like it should actually be a simpler version of the formula, not a more complicated one…


Hello @Plawa,

Interesting you should ask this. I am currently working on a very similar problem that involves tilting a solar panel towards the sun to optimize production. In general, to minimize the angle of incidence (AOI) with the sun you require knowledge of both solar azimuth and elevation. Luckily for us, HA has this information in the sun.sun integration.

This paper explains the technical details really well: Rotation Angle for the Optimum Tracking of One-Axis Trackers

I will post the details of my project, including all the maths and templates pretty soon, hopefully today. You can then look, or I can help you, to adapt it to your project.

1 Like

Hi Stefan, thanks for the link to the paper, that was exactly the bit I needed, specifically this formula:

R = tan-1 [ tan θz sin (γs - γa ) ]

θz - Zenith (i.e. 90 - elevation)
γs - azimuth of the sun
γa - azimuth of the pergola

This is how I implemented it as a template sensor:

  - unique_id: pergola_slat_angle
    name: "Pergola Slat Angle"
    unit_of_measurement: "°"
    icon: mdi:angle-acute
    state: >
        {% set slat_azimuth = 207 %} 
        {% set min_slat_angle = 0 %}
        {% set max_slat_angle = 135 %}
        {% set deg2rad = pi/180 %}
        {% set sun_zenith = iif((state_attr('sun.sun', 'elevation') | float) < 0, 90, 90 - (state_attr('sun.sun', 'elevation') | float)) %}
        {% set ground_angle = (atan(tan(sun_zenith*deg2rad)*sin((sun_azimuth - slat_azimuth) * deg2rad))/deg2rad) | abs%}
        {% set over_axis = iif(sun_azimuth > slat_azimuth,-1,1) %}
        {% set slat_angle = (90 - ground_angle*over_axis) | round(0) %}
        {% set slat_angle = iif(slat_angle < min_slat_angle,min_slat_angle,slat_angle) %}
        {% set slat_angle = iif(slat_angle > max_slat_angle,max_slat_angle,slat_angle) %}

I first calculate the offset from vertical, then adjust it pos/neg based on the position of the sun relative to the axis of the pergola and then constrain it within the set min/max angle.

This angle is the used by a script that sets the pergola to that desired angle however it first needs to be translated into % for the tilt service:

service: cover.set_cover_tilt_position
  tilt_position: >-
    {% set min_angle = 0 %} 
    {% set max_angle = 135 %}
    {% set slat_percent = ((states('sensor.pergola_slat_angle') | int - min_angle)/(max_angle-min_angle)*100) |round(0)  %} 
  entity_id: cover.pergola_roof

It seems to work exactly as expected in all my simulated scenarios but I still need to run it through its paces on a sunny day…

Thanks for the nudge!

1 Like

Great to hear, looks very similar to how I implemented it for my project. Indeed the paper gives pretty much everything you need.

One tip, be careful with atan. Its range is limited between [-90, 90]. When you exceed it starts counting from 0 degrees again instead of 90. I suddenly remembered that when earlier today my solar panels started pointing away from the sun instead of tracking it…

As an alternative you could use atan2, which has a range of [-180, 180] :slight_smile:

ps, in your normalization formula under service: you are not subtracting min_angle from pergola_slat_angle. Doesn’t matter now because it’s 0 degrees anyway, but in case you might ever change it

Fixed the % calculation, thanks!

1 Like

Sorry for this possible off -topic, but do you actually have positionable solar panels? Must confess I never saw those for domestic use, and most certainly would be interested if you could provide a link to those.

Sorry, it’s a DIY project. Homeassistjoenka (from DD discord) built the mechanics and electronics, I wrote the solar tracker software.

1 Like

btw I finally posted my project here:

1 Like

I wanted to let you all know I have made a new post with a much better control method:

Automatic blinds / sunscreen control based on sun platform