Virtual light sensor

For me, personally, I like to leave it at -6 and 90 (min, max) despite the fact that the sun never gets to 90degrees where I live either. The reason is, at 90 degrees (i.e. directly overhead) the sun will indeed produce the most solar radiation/light/heat than it will in any other location in the sky. So, it is a true maximum.

This way I can look at sunlight percentage as the percentage of sunlight getting through compared to the maximum anywhere on earth. What’s nice about that is then 20% is roughly when you’d want outside lights to come on/off no matter where in the world you live. If you change the maximum, you’re still going to want the lights on at roughly the same brightness/sunlight level as me, but your number will be quite a bit higher than mine.

It also affects how the cloud cover factors in. With the formula above I did extensive testing using a wunderground weather station near me that happened to provide Solar Radiation in W/m^2 and, using a known maximum W/m^2 for 100%, I was able to make a second sensor that fairly accurately tracked the readings from that weather station.

It’s useful either way, of course. And if it makes more sense for you to set the max at 66 degrees, then, by all means you should. I just wanted to make the argument for using a more “universal” number in case you weren’t aware of the potential positive aspects of doing so.

3 Likes

Thanks for the details @swiftlyfalling, this makes sense.

I’ll move this back to 90, and see how I go hooking this into my existing lighting.

I’ve found that turning outside lights off at > 23 and on at < 20 works great to get the lights on during any time there are thick, dark, clouds, or when the sun is too low to make enough light.

For interior lights, I’ve found every room needs it’s own setting, since the lighting is different in each room depending on how many windows there are and which direction they face. Ultimately, I found that having a lux sensor in each room was an easier way to go for interior lighting, instead of trying to find the best cutoff point for each room. So, I really just use it for exterior lighting these days.

I imagine I could just choose an indoor sensor for a room that gets good outside light and use it to determine outside light, but this formula works so well I haven’t felt the need to change it.

1 Like

very nice indeed, testing as we speak. with the Open weather map cloud percentage. Will see tonight when the lights go off (hardware light sensor) what setting that is. Used to check against sun elevation, but this might be more adequate.

btw you can leave out the entity_id’s, since they are in the template itself. No complaints are thrown.

3 Likes

What is your experience, is it more adequate as sun elevation? Which wheater platform are you using?

I’ve been using it for about two months and it works very well.

I’m in the UK and using DarkSky and I have set the maximum and minimum elevation appropriately:

{%- set min_elevation = -6 %}     {# set this to official sun elevation for end of twighlight #}
{%- set max_elevation = 64 %}     {# set this to the maximum noon sun elevation (minimum is 15 degrees) #}

For each light that responds to it I have an input_number that sets the threshold brightness before it is considered dark in that room. I did that so that I could play with the numbers but have never needed to change it from almost the first day.

Thanks, i’ll give it a try. I have input_number as well for max. brightness but currently I’m only using sun elevation so slowly get them up to the selected level.

Hello, i would like to use a template sensor like that. But now, if darksky stop api, how can i use another api ?

The only portion of this that uses DarkSky is the cloud coverage data. If you can find another weather source for cloud coverage, this can be adapted to use it instead.

OpenWeatherMap is one such integration.

Ok thanks. But cloud coverage value is always the same over all api ? % 0 for clear and 100 for cloud ? I don’t know if replace :

 sensor.dark_sky_cloud_coverage 

by

sensor.openweathermap_cloud

is enough?

I don’t use the openweathermap platform, so I’m not sure what the sensor entities are called. However, I did confirm that cloud coverage on that platform is represented the same as it is in DarkSky: 0 meaning no clouds, 100 means complete cloud coverage.

Ok thanks !! so i just need to find another sensor with this parameter to replace darksky cloud coveage sensor.

right. add the openweathermap integration, check and see what the entity id is for cloud coverage, then edit this template to use that entity id.

1 Like

Trying your code as we speak, with the usage of OpenWeather instead of Dark Sky:

- platform: openweathermap
  api_key: my_API_key
  monitored_conditions:
     - clouds

and than replace “sensor.dark_sky_cloud_coverage” by “sensor.huis_cloud_coverage” in the code of @swiftlyfalling .

I will report back, after some days… Thanks!

I’m using openweathermap myself, now, and it’s working wonderfully.

I have been working on the code of @swiftlyfalling and trying to add Solar Irradiance into the code. By that the sunlight% will depend on:

  1. Solar Irradiance senor
  2. Cloud Coverage senor
  3. Sun Elevation senor

I found (assume) that the max Solar Irradiance we can get is 1.000 W/m2 (see here). That means that the calculation can be really simple; just divide the number by 10 to get the percentage. So; 402 W/m2 is equal to 40.2% Irradiance. Next, I subtract the Irradiance% from the Cloud Coverage% to get an adjusted percentage for the impact of clouds on the sunlight.

I have set the max_elevation at 70 degr, because it is maximum 61degr in my place at the world. Find your max here.

The rest of the code is same as @swiftlyfalling wrote:

    sunlight_pct: #https://community.home-assistant.io/t/virtual-light-sensor/31975/34
      friendly_name: "Percentage of Sunlight"
      entity_id:
        - sun.sun
        - sensor.huis_cloud_coverage
        - sensor.br_irradiance
      value_template: >-
        {%- set irradiance = states('sensor.br_irradiance') | float %} 
        {%- set irradiance_pct = irradiance / 10 %} {# max irradiance = 1.000, so  irradiance/10 = pct. See https://en.wikipedia.org/wiki/Solar_irradiance#:~:text=Average%20annual%20solar%20radiation%20arriving,level%20on%20a%20clear%20day #}
        {%- set elevation = state_attr('sun.sun','elevation') | float %}
        {%- set cloud_coverage = states('sensor.huis_cloud_coverage') | float %}
        {%- set adjusted_clouds = cloud_coverage -  irradiance_pct %}
        {%- set cloud_factor = (1 - (0.75 * ( adjusted_clouds / 100) ** 3 )) %}
        {%- set min_elevation = -6 %}
        {%- set max_elevation = 70 %} {# find max_elevation at https://www.suncalc.org/#}
        {%- set adjusted_elevation = elevation - min_elevation %}
        {%- set adjusted_elevation = [adjusted_elevation,0] | max %}
        {%- set adjusted_elevation = [adjusted_elevation,max_elevation - min_elevation] | min %}
        {%- set adjusted_elevation = adjusted_elevation / (max_elevation - min_elevation) %}
        {%- set adjusted_elevation = adjusted_elevation %}
        {%- set adjusted_elevation = adjusted_elevation * 100 %}
        {%- set brightness = adjusted_elevation * cloud_factor %}
        {{ brightness | round }}
      unit_of_measurement: '%'
      device_class: 'illuminance'

And the outcome is a nice virtual light sensor:

Thanks again @swiftlyfalling for your awesome work !!!

4 Likes

How to create the solar irradiance sensor?
How to find the value of max_elevation in the suncalc.org site?
My coordinates are:

latitude: 42.0472856
longitude: 13.4308795

instead of moving your questions from Automations to turn on lights based on actual season
you could also try to find them yourself and check the weather integrations for irradiance of course…

you might end up at Weatherbit, which has it all.

I moved here because i was thinking these are two different topics (also if i can use them in the previous topic). BTW i found the climacell integration has already the solar irradiance, so my problem here is solved, but not the max_elevation…

max_elevation can be found at https://www.suncalc.org/. Type in your coordinates here and hit [apply]:

image

Then scroll down and look for the date for Jun Solstice
image
Adjust the current date/time to this date and set Azimuth at 180degr (by adjusting time with the time-slider)
image
The Altitude will be your max_elevation. Most likely 70degr :smiley:

This explains a bit more:

1 Like