[node-red] Apply offset on the sun.sun state from Home-assistant?

I have a couple of motion sensors filtered by the state of the sun. The problem is that sometimes is already too dark but the sun is still up, so I want to apply some offsets.
The problem is that the only way to get the sun state from hassio is the state node (as far as I know) and it does not accepts any offset.
I know I can use other node-red nodes to do this task, but then I have to sources of location: home-assistant and node-red. Not to mention that home-assistant way of setting location is much more friendly than all the node-red nodes.


What we really need is a better sun object, something that will take geographic location, elevation, date, and time, and give us “effective output” of the sun’s energy hitting the earth.

The sun entity has several attributes that can help in creating this, including the important one, elevation angle. This is based on location can be used to calculate an effective solar output value.

At negative 18 degrees elevation, the effective output is 0, all values above this give some light, some trig and data relating to atmospheric light blockage by altitude will give a fairly accurate solar energy value that should match a light meter within a percent or 2. This can be made even more accurate by taking the date (or distance to the sun) into account, as it varies slightly throughout the year.

Yes, I will definitively want better offsets for winter and summer.

I am working on a template sensor that will attempt to perform these calculations, I have not looked at the math functions available to me in HA as to what I can do.

Essentially there are major 2 calculations and 1 minor.

1: determine solar energy reaching earth based on distance, which is based on day of the year. (easy)
2: determine angle of elevation at current location (done by sun entity already)
3: determine correction factor for atmospheric refraction, and determine EFFECTIVE angle of elevation
4: use energy output and elevation to determine effective visible light

Then you can look out on a clear day and say “this is when i want the lights to turn on” or off, and check the sensor value, then use that value for automations.

There is also a very simple equation to determine the amount of light blockage due to cloud cover irrespective of precipitation, another template sensor would take the value of the first and determine fairly accurate “realtime” outdoor lighting based on the sun and the weather.

I am going to jot down some numbers/formulas here just in case I lose my note pad. These will be put into the final equation. Some are handled internally by HA, if I can expose them I can save a ton of math.

Sun Surface Radiance = 63156942.6 W/m^2
Sun Radius = 695800000 m

Solar GMA = 357.52911 + JC * (35999.05029 - 0.0001537 * JC)
Solar Eq of Center = SIN(RADIANS(GMA)) * (1.914602 - JC * (0.004817 + 0.000014 * JC)) + SIN(RADIANS(2 * GMA)) * (0.019993 - 0.000101 * JC) + SIN(RADIANS(3 * GMA)) * 0.000289
Solar True Anomaly = GMA + EQC
Earth Orbital Eccentricity = 0.016708634 - JC * (0.000042037 + 0.0000001267 * JC)
Radiation Vector = (1.000001018 * (1 - EOE^2)) / (1 + EOE * COS(STA))

Earth Distance = 149597870700 * radiation_vector
Sea Level Normal Irradiance = Radiance * (Sun Radius / Earth Distance)^2

Determine air mass factor based on elevation angle, compensated for curvature of earth
AM = [ Sin(EA) + 0.50572 * ((EA + 6.07995)^(-1.6364)) ] ^ -1

Adjust solar irradiance with observer height (km) and air mass factor
I * [ (1 - 0.14 * h) * (0.7 ^ (AM ^ 0.678)) + 0.14 * h ]

Also we need “sun path” data. That is, the daily arc of the sun’s sunrise direction vs. sunset direction.
Where I am, this changes a LOT between winter and summer.
I want to lower/raise my window shades automatically-- this depends on the day of the year. I don’t even see the sun in the winter, but in the summer it’s blasting my house and eyes directly from the West.
So…I want the window shades to lower at the time of day when the sun first strikes the windows (and rise 10 minutes before sunset).
I do this crudely be adding 10 minutes a day or so between Feb and July, then decrement back to winter. But I’d like this to be more exact.
Typical calculators yield this data:

Versus July which yields:

1 Like

The sun component actually already provides this! One of the attributes is current azimuth angle, the other one is the elevation angle, which is listed on your graphs as the altitude position (y axis).

Not sure if it has all you need, but check a “sun-position” contribution: https://flows.nodered.org/node/node-red-contrib-sun-position

It contains extended sun nodes as well as a blind-control node which provides automation for blinds based on pretty complex logic. Maybe this is what you want

I really appreciate all the answers here, and the effor people put on them, but my use-case was much more simple than all this.
All I want is to apply an offset to the sunrise state of HA. I discovered that nodered (at least on HA) comes with a time-switch node that lets you route messages based on a time-range, and those time-ranges includes sunset and sunrise events. However, it has some drawbacks:

  • it does not uses the location specified on HA, you have to provide it yourself, so if I update the HA config this will be incorrect
  • It calculates a different time than HA. HA has been quite accurate, so I would say the node-red node is what is wrong. Take a look at the screenshot below:


So it looks that the answer to my question is, no, it is not possible to have an offset to the sun-state on node-red from HA. Maybe my best bet is to read the location data from HA?

For a very simple partially-compensated photometric offset, use the transition across the desired elevation angle instead of the time, winter and summer transition times are different due to the rate of change and distance to earth, so this compensates only against rate of change.

Start at 5 degrees and adjust if necessary. You can also add simple compensation for cloud cover by adding 1 degree for every 10% cloud cover.

something like

if sun.elevation goes from over to under (5 + int(weather.cloud_coverage/10)) while sun.rising=false, then do automation

possibly with a trigger lock to prevent a sudden change in cloud coverage from interfering, so it needs to wait till sunrise if that is what you want… then

if sun.elevation goes from under to over (5 + int(weather.cloud_coverage/10)) while sun.rising=true, then do not do automation

That is very smart. I agree that just adding an offset is probably not enough and too naive, but I wanted to try something simple first (HA is very time consuming, the feedback loop is terrible).

That pseudo-code you posted, how do you suggest to implement it? Are those already available at home assistant?
The only part I don’t get is from over to under (.... how does the things between parens interact with the rest?

I think making a template sensor in HA would do most of it, then an automation to catch the transition, which turns a helper on or off.

The parts in parenthesis would be the template sensor, the automation would use the value as a trigger, plus another “failsafe” trigger if the weather entity becomes unavailable, 15 degrees would catch it well and be equivalent to 100% cloud cover in the template.

Since negative elevation is darker, we can subtract cloud coverage from it and compare it to our expected value

  {%- set clouds = (states.sensor.weatherbit_cloud_coverage.state) | int %}
  {{ states.sun.sun.attributes.elevation - (clouds / 10) | int }}

During sunrise, when this value passes from under 5 to 5 or over as an automation trigger, it turns off the “dark” helper value

During sunset, when this value passes from over 5 to 5 or under as an automation trigger, it turns on the “dark” helper value

Since the helper stage change can only occur after solar noon or midnight, the automations will never interfere with eachother or blink the state. The helper state change can now be used as the trigger for actual lighting controls.

I just finished adding this automation to see what happens, there should be cloud coverage this morning where I am during sunrise.

This is my template sensor code that is giving good numbers

  - platform: template
        friendly_name: Sun Elevation Cloud Adjusted
        value_template: "{{ states.sun.sun.attributes.elevation - ((states.sensor.weatherbit_cloud_coverage.state) | int / 10) | int }}"

The template sensor can be further modified to take weather conditions such as rain or low visibility (like fog) into account, while still keeping it simple. There is a much more complex algorithm which takes an hours worth of cloud coverage data into account, but that would be more useful for a full day solar output automation rather than just sun rise/set.

I adjusted the sensor a bit, so it would graph and correctly be an integer.

  - platform: template
        friendly_name: Sun Elevation Cloud Adjusted
        unit_of_measurement: '°'
        value_template: "{{ ( states.sun.sun.attributes.elevation - ((states.sensor.weatherbit_cloud_coverage.state) | int / 10)) | int }}"

Actual sunrise was around 7:40am. The trigger point happened at 9:31am instead of 8:18am thanks to cloud cover adjustment, but the automation did not fire, I think my condition code is to blame. I made an adjustment for sunset, and I will be driving when it happens so I can compare to when I turned my headlights on.

A few things of note, the cloud coverage does not drop the light as much as an equivalent degree, so I am switching the divisor to 20 instead of 10. 5 degrees in the winter is about 30 minutes before sundown, and that seems a little too aggressive, at least during winter, possibly because of the surface reflectivity of the snow making things brighter, as it is 2 to 3 times higher than with no snow. I am switching it to 4 degrees to see how that works.

What I really need to do is wait for a clear day and a full cloud day and find out at what degree each should trip, then adjust the numbers to match. Interior and exterior light controls may need different trip points.

The automation is still broken due to the rising/set attribute condition, I have had poor luck with state attribute conditions so I might make that a template sensor, since that worked the last time.

Thank you very much. All your calculations make sense to me. I’ll try to implement them into node-red into a custom node/flow and report how well is it working for me.


I already have it. It’s time to test it tonight!

Richie and all:
How can you summon the different sun attributes?

That is, How do I create a switch using the sun azimuth attribute?
This doesn’t work below. Is the variable a .msg, .flow, .global, JSON expression, or $env variable?


Not certain if you’re trying to accurately measure sunrise/sunset, or actual ambient daylight levels. But for less than ten dollars USD you can build an ESPHome sensor with a Wemos D1 Mini clone and a BH1750 ambient light sensor. It’s really simple to assemble, and directly usable as a sensor in Home Assistant (and I would suppose Node Red by extension).

I am just using it for ambient light levels.
Sure, I want to use light sensors for those rooms where I may have the blinds closed, but for common areas like stairs and halls sun level is good enough and does not require a power socket, nor a case

1 Like

There are several reasons why a mathematical/environmental model can be superior to a light sensor, beyond the fact that the model costs $0.

Light sensors require an additional power source and network connection, they require a good source of light through a clean window and correct placement, and potentially individual calibration. A model does not need any of these. Additionally, the model can determine when light is required on the side of the house casting the shadow, which will change during the day, you need multiple light sensors for that.

There are extremely complex models developed by NOAA on supercomputers that can determine ambient light within a percent of reality, but these require too many inputs. A simple model that can get within a few percent specifically during the sun set/rise transition period is good enough for light automations.

After a few clear and cloudy days, observing the time of day when I think additional light is needed, I would say I severely underestimated the impact snow cover has on ambient light levels. When combined with full cloud cover, which reflects the light back down, it actually pushes the transition point past sundown.

I am testing an adjusted model in a template sensor which takes an additional manually controlled input variable to compensate for surface reflectivity. Tonight’s clear sky test got within 4 minutes of my model, but I have only been testing for 1 day so it is too early to see if adjustment is required. Also I would need data from a snow free area with green leaves on the trees to fine tune the other side of the variable, since cloud cover in that case blocks light and has minimal re-reflection from the ground.

1 Like