Turn lights on depending on sun angle and weather conditions?

I’m still on the learning path of HA and am looking at ways to accomplish a specific scenario. And I need advice from the more experienced HA users on how this can be accompilshed.
Let me explain what I want to do:

Around the time the sun sets I want to switch on a group of lights (using a scene). Not really exciting, is it? ;o) But here comes the complex part…
Since the actual level of light depends not only on the sun angle but also on weather conditions like how cloudy it is. So, what I am trying o accomplish is an automation scenario that looks at the weather condition, triggered by a sunset event minus a one hour (or so) offset.
From then on, until shortly after sunset, it should keep checking the weather and sun angle until a certain combined threshold is reached.
And then the lights should be turned on.

Basically, it is a combination of firing off events at regular intervals from one hour before sunset, checking sun angle and weather conditions, and take action when the threshold is exceeded.

I’ve done some reading about custom python scripts, events, automation, triggers. etc., but I don’t have a complete picture of the solution yet.
I also want to avoid spending a lot of time on custom code, when it turns out to be part of the HA feature set with some clever configuration… ;o)

How should I go about doing that? what elements of HA should I use? I’m not asking for a complete solution (would be nice…) but just some pointers and guidance.

If you can express your combined threshold as a number (that’s a big if in my opinion) you can do this with a single automation and a template trigger.
The template would be something like this

{{ numeric_exression_of_sun - numeric_exression_of_weather < threshold }}

You don’t have to really worry about starting the evaluation at sunset-1 in this case.
Determining the numeric expression of sun could be a linear function of sun elevation, but how you would go about correlating a weather variable is beyond me.

Thanks treno, that’s something to investigate…

Try something like this…

- platform: template
      friendly_name: 'Indoor Lights Auto On'
      value_template: >-
          {%- if is_state("input_boolean.bedtime","off") and is_state("group.household","home") -%}
            {%- if (states.sun.sun.attributes.elevation | int < 10 ) -%}
            {%- elif ( (states.sun.sun.attributes.elevation | int < 25) and (states.sensor.dark_sky_cloud_coverage.state | int > 70)) -%}
            {%- elif (states.sensor.dark_sky_cloud_coverage.state | int > 95) -%}
            {%- else -%}
            {%- endif -%}
          {%- else -%}
          {%- endif -%}
          - sun.sun
          - sensor.dark_sky_cloud_coverage
          - input_boolean.bedtime
          - group.household

Thank you for this example. I’ve included it (with some modifications) in my configuration and will test it.

Thanks - once you get it tuned and working please share your changes! Always looking for new “magic” to frustrate the wife and make the kids think I am Gandalf…


using @jwelter’s example, and assuming cloud coverage is a linear filter between 0 and 100%. At 0% you use the sun elevation only. That means that sun.elevation * (1- (cloud coverage/100)) is a reasonable approximation of the effect of clouds on sunlight. You can then choose a threshold value that you want the lights to come on (let’s say 25 for discussion) then this gives you a general purpose rule for "is it dark enough to turn on the light).

You can implement this as a single template sensor like this:

{{(states.sun.sun.attributes.elevation | float) / (1-(states.sensor.dark_sky_cloud_coverage.state | float/100)) }}

perhaps this is too simplistic an approach, but I’m going to add it to my system and see how it goes.


This openhab thread has a good function I’ve implemented in a python command line, passing in cloud cover from darksky, pressure from wunderground and sun elevation from the sun component.

1 Like

Thanks guys, These are some good examples I can work with. Will post the result after some testing.

Good idea! My binary sensor works and for most rooms the performance is good. Lights come on/off with a bit more intelligence versus just sun elevation.

Thanks, I was looking at this and doesn’t it calculate the wrong way to use for this? or am I missing the point?
i.e. the lower is the sky the sun gets the smaller the number is, say 3 but if there is 99% cloud coverage the sensor number is 299.9999999 (so dark) but if angle still 3 and cloud coverage is 9, then the sensor is 3.297

So I don’t know how I could use this in an automation to turn a light on… at the moment my landing light is turned on using a lux sensor in another room, but if you close the blinds on a sunny day… light comes on and I look like and idiot not gandlaf :smiley:

Would you be willing to share the python command line script you’ve used to replicate this openHAB virtual solar sensor?

If I’m honest, the cloud cover calc was pretty arbitrary and this function was of limited benefit given the formula begins to break down just as you start hitting relevant light levels.

I found it of limited benefit over a simple sunset trigger. Better solution is a light sensor!

This is what i ended up doing… sticking an aeotec multi sensor outside (away from direct sunlight) and have it powered and updates every 60 seconds. Works amazingly well

Where I live (Texas, in the United States) when storms roll in, it can get VERY VERY dark. So a sunset trigger will handle most cases, of course. But, being able to add in cloud cover, storm distance, etc, etc is very helpful.

None of this is as good as a dedicated Lux Meter outside, of course. That’s the route I’ll take eventually. But, for now, the logic I managed to program based on outside weather conditions has been working pretty well. I tweaked it for about a week when I noticed it wasn’t quite correct. It’s still a bit arbitrary, but, fairly close to what I see out the window.

Hi, I was trying to solve this problem for myself - combining sunset and weather conditions to triggering lamps. The formula I found and which works for me is as follow:

abs(elevation/10) * ( (elevation/10) + (1- (cloudiness/100)))

where 10 - your local threshold for sunset.

You can make a table with sun elevation and cloudiness to test it, it will have a staircase shape.
The idea is that sensor returns number smaller than 1 if its getting dark.

1 Like

This is an old thread but I find myself needing this capability as sunset +1/-1 isn’t really working out for me as well as I hoped. I’ve been sort of keeping track of elevation trying to figure out what values to use. I found this website here:

Which I plug in my appropriate values and get a chart from +20 through -20:


One thing I’ve noticed in this thread is (I’m assuming) that everyone responding doesn’t live in an area which has winter. In Canada here, it’s currently “summer” (using that term lightly; more like 2-3 months of warm weather) so the elevation is around 20 (which I’ve been tracking) and based on the chart, as it get closer to winter etc this value will dip to -20 maximum.

How do I account for that in the formulas presented in this thread?

states.sun.sun.attributes.elevation gives you the sun’s elevation moment by moment. It updates every 30 seconds, from what I can see in the code. This gives you a precise way to know the elevation of the sun at every moment. There are variations depending on location, etc. but with trial and error, you could come up with a rule like “if the sun’s elevation is less than X, then it is dark outside.” Though, as people have discussed here you can refine that with weather information.

The page you were looking at gives you a yearly graph telling you at one single specific time in the day what elevation the sun is going to be at: January 1st, at 2PM the sun’s elevation will be …, then January 2nd at 2PM the sun’s elevation will be …, and so on. You’d use a table like that if you need to orient a fixed structure towards the sun, like fixed solar panels. For determining when it is light or dark outside it does not provide you with anything more than what states.sun.sun.attributes.elevation already does.

Thanks for helping me understand this. I tried @majkim formula (substituting my values; using the same website determined @ 6PM) and it seems pretty close to what I see outside.

Perhaps I too may end up looking like Gandalf :slight_smile:

EDIT: in case I forget and need to come back to this, for me this works out to as sensor template:

#### Ambient Light
  - platform: template
        friendly_name: 'Ambient Light'
        value_template: '{{ "%.2f"|format((states.sun.sun.attributes.elevation/24)*((states.sun.sun.attributes.elevation/24)+(1-(states.sensor.dark_sky_cloud_coverage.state|int/100)))) }}'

What threshold are you using to turn on the lights with this sensor?