Enhanced Sun component

Too late now but maybe using the reload
image
might have fixed it…

I did all that first

HACS :roll_eyes:

For anyone that might be interested, I think I have the binary_sensor for elevation working. You configure it like this:

binary_sensor:
  - platform: sun2
    monitored_conditions:
      - type: elevation
        name: <name> # optional
        above: <threshold> # optional

You can create as many as you like. If you don’t specify a threshold it defaults to -0.833, the same as sunrise/sunset. Also the default name is “Above Horizon” if above is -0.833, or “Above N” (where the N part will be “minus N” if it’s negative), resulting in an entity_id like binary_sensor.above_horizon, or binary_sensor.above_3 or binary_sensor.above_minus_5_125.

The idea is it will change to 'on' whenever the sun’s elevation becomes a value above the threshold, and change to 'off' whenever the sun’s elevation becomes the threshold (or lower.)

When HA starts the state is set accordingly. Now here’s where the main reason for doing this comes in. It will then calculate when it should change next, and not update until then. I.e., it figures out exactly when it should change, rather than constantly comparing a value against a periodically updating sensor. The result is it’s much more efficient, and it changes right when it needs to, not on some sample point that might be minutes from when the threshold was actually reached.

Now, in the grand scheme of things, maybe these advantages aren’t all that important or significant. However, one big advantage might be that you don’t need to create any other sun related entities (whether that be sun.sun or any of my sun2 entities) for this to work. It’s completely stand-alone. So, if all you care about is knowing when the sun is above a certain elevation, possibly for use in an automation trigger and/or condition, then this can be much less of a burden on the system (and database) because you don’t need any of the sun entities that change a lot during the day. (Now, of course, if you do want to display elevation, etc., that’s another story. :slightly_smiling_face:)

Thoughts?

4 Likes

HI Phil,
Thanks for this! please let me ask if I understand correctly and could use:

binary_sensor:
  - platform: sun2
    monitored_conditions:
      - type: elevation
        name: Sun is up # optional
#        above: <threshold> # optional

using the default elevation threshold and still feel all the relieve for the system? Or would I need to specify the threshold to benefit from your new binary_sensor.

btw, this is already working with version 1.4? Because I see:

52

Hi Marius,

Yes, that configuration would be perfectly acceptable and would create binary_sensor.sun_is_up that changes around -0.833 degrees.

This entity does not depend on sun.sun, nor any of the other sun2 sensors. So, to “feel all the relieve” you’d need to remove those (or at least any you don’t otherwise need or want) from your configuration.

I’ll also state, automation sun triggers and conditions are completely independent as well, meaning they don’t depend on sun.sun either.

Does that answer your questions?

Thanks!
glad I got it right :wink: Understand about taking out the other stuff.

only issue left is the error message…

Oh, sorry, meant to answer that, too. No, it’s not in the release yet.

Before releasing I’m trying to decide whether or not to include a next_change attribute, for this binary sensor as well as the elevation regular sensor, since both are implemented by figuring out when they should update next. It looks like this:

You can see that the -60 binary sensor will update next later today, the -70 won’t until Nov. 29 (when the sun finally dips below -70), and the -80 won’t at all (since the sun’s elevation never gets to -80 here.)

Do you think this attribute would be useful? Or would it just take up more space in the database for no good reason?

I think it would be useful and I would configure logger not to add to db as well.

1 Like

Nice going with this!

As a side note, would it be a good idea to also track the moon, and its phases ?
This way, the custom card, Lovelace: Sun Card could display the moon.

Basically making this a sun and moon integration.

Just my 2 cents.
Cheers.

If you (or anyone) would like to give the new stuff a try (before I release it), you can find it on this github branch. I’ve simplified the config for the elevation binary sensor a bit. See the doc for details.

FWIW, the config you posted above would now look like this:

binary_sensor:
  - platform: sun2
    monitored_conditions:
      - elevation:
          name: Sun is up

Thanks! :slightly_smiling_face:

Yes, that has been asked for before. I just haven’t spent any time looking at it yet, other than to check that the astral package does indeed have a moon_phase() method. But that seems to be the extent of moon related functionality.

I wasn’t aware of that custom card.

Phil,
I’m probably being really cheeky here.
I’ve seen your sun component(s) and I see you are releasing another one soon but …
I’m interested in the calculations.
I want to write a spreadsheet (populated by VB and the appropriate calcs) to list (for a given location and elevation) the azimuth of sunrise and sunsets throughout the year. Using the horizontal co-ordinate system I presume ???
Also (the ideal would be) to calculate azimuth’s for a given (but adjustable) elevation, to (for example) work out that to minimise heat loading (through windows etc.), shade should be provided from ‘this’ angle for a (say) 30° elevation. (Elevations between should require ‘less shade’ but over the arc of the rising and falling azimuths)
I’ve seen the calcs for elevation which use lattitude and local solar time, which I assume must be calculated for the particular longitude (it’s not clear on that)
Now (again presumably) I could do all this iteratively and record just the values closest to -0.86 and (say) 30° (so 4 values a day) based on 1 minute intervals, but that’s nearly 526,000 calculations
at 1 calc every 2 seconds thats 12.18 days per location or elevation.
Is there a quicker way ?

Wow, you must think I know something about how this stuff works! :laughing:

I’m just using the astral package that HA uses, and I’m “brute forcing” some of my algorithms because I don’t really know. E.g., the astral package has a time_at_elevation function that I tried to use to calculate when to update the elevation sensor when the elevation has changed by a certain amount. Turns out that function returns too imprecise of a result which doesn’t really agree with the solar_elevation function (that does the opposite of calculating an elevation at a given time.) So I ended up doing a binary search! lol

Yeah, I suppose an inteligent binary search may help here.
I used to do somthing similar for water weir calculations to get accurate flow calculations.
Oh well I might have to set up a workstation and dedicate it to the task.
To think, this only started out as part of a dinner conversation where someone stated that their sunrise azimuth varied by nearly 40°. I didn’t believe them (and still don’t) :crazy_face:
Thanks anyway

I’ve written test scripts to try out my ideas. I run it in a HA virtual environment so I can use that infrastructure. If you’re interested, the scripts start like this:

import datetime as dt
import sys

from astral import Location
import pytz

if len(sys.argv) < 5:
    print(f'{sys.argv[0]} latitude longitude timezone elevation')
    sys.exit(1)

latitude = float(sys.argv[1])
longitude = float(sys.argv[2])
timezone = sys.argv[3]
elevation = float(sys.argv[4])
info = ("", "", latitude, longitude, timezone, elevation)

location = Location(info)
tz = pytz.timezone(timezone)

cur_time = tz.localize(dt.datetime(YEAR, MONTH, DATE))
end_time = cur_time + dt.timedelta(days=DAYS)

while cur_time < end_time:
    value = location.SOME_ASTRAL_METHOD(cur_time)
    ...
1 Like

Ah ! That is interesting !
Can’t do much with it at the moment but I’ll bookmark that and come back to it
Cheers

:beer:

1 Like

Sorry, any guides or thoughts on the calculation of local solar time or can I just do a longitude offset from GMT ?

Nope, don’t even know what “local solar time” is. The astral package (in general) takes times as Python datetime objects, either time zone aware, or assumes they are local time.

As you can see in my script above I’m turning naive times into time zone aware datetime assuming local time:

tz = pytz.timezone(timezone)

cur_time = tz.localize(dt.datetime(YEAR, MONTH, DATE))

EDIT: Wait, do you mean you want to know time relative to solar noon? You can find solar noon with:

location.solar_noon(cur_time.date())

This will return when the sun is at its highest elevation for the given (local) date as a time zone aware datetime object in local time.

No, Local solar time should be 12:00 when the Sun is at it’s zenith (solar noon)
The zenith changes throughout the year and wobbles a bit even at Greenwich so I’ll have to do some more reading. Dang !

Hang on that doesn’t make sense even to me (shows how little I know)

MUCH more reading required