Hours of Daylight

OK so I see it’s looking correct even accounting for the time zone difference as UTC sunrise is yesterday’s date and sunset UTC is today’s so when I add 10 hours they are both today and hence it is daylight hours today.

So for yesterday, today and tomorrow sensors I have:

sensor:
  - platform: rest
    resource: !secret daylength_yesterday
    name: "Day Length Yesterday (sunrise-sunset.org)"
    value_template: "{{ value_json.results.day_length }}"
    scan_interval:
      minutes: 60
  - platform: rest
    resource: !secret daylength_today
    name: "Day Length Today (sunrise-sunset.org)"
    value_template: "{{ value_json.results.day_length }}"
    scan_interval:
      minutes: 60
  - platform: rest
    resource: !secret daylength_tomorrow
    name: "Day Length Tomorrow (sunrise-sunset.org)"
    value_template: "{{ value_json.results.day_length }}"
    scan_interval:
      minutes: 60

and it’s reading the secrets file in this format: https://api.sunrise-sunset.org/json?lat=LAT&lng=LNG&date=today
(Today, Yesterday and Tomorrow)

Awesome @pnbruckner

3 Likes

Nope, just wanted to try both formats. Depending on what you need the sensor for, having it already in seconds might be slightly easier to use.

In case you’re still interested, although the REST Sensor doesn’t support templates in the resource parameter, the Command line Sensor does support templates in its command parameter. So, rather than using the REST Sensor, you could use the Command line Sensor with the curl command. So, something like this:

sensor:
  platform: command_line
  name: day_length
  command: curl "-s 'https://api.sunrise-sunset.org/json?lat={{ states.zone.home.attributes.latitude }}&lng={{ states.zone.home.attributes.longitude }}'"
  value_template: "{{ value_json.results.day_length }}"

I discovered today that this sensor does something unexpected with the command relative to templating. It first splits the command at the first space, then it only evaluates the template for everything after the space. Hence, that’s why I have the first double-quote character after the first space (i.e., double-quotes surrounding the arguments of the curl command.)

1 Like

Before deciding what to use. Trying out this without luck.
Any ideas what I am missing?

   - platform: rest
        resource: https://api.sunrise-sunset.org/json?lat=XX.xxx&lng=YY.yy
        name: "Sun Rise and Set"
        json_attributes:
          - sunrise
          - sunset
          - day_length
          - status
        value_template: "{{ value_json.results }}"
        scan_interval:
          minutes: 60

Putting all the results in the state (with value_json.results) may be temporarily interesting, but ultimately, not very useful, IMHO.

What do you mean by “without luck”?

I’m not sure the json_attributes options will work as is, or even at all. At a minimum, I would think you need to change them to results.sunrise, results.sunset, etc., but I’m not sure even that would work.

Without luck = dint work.

Looking at the document, I was hoping it would work. But Ill settle for a several Rest sensors.

Thanks for helping out!

So, I just learned something about the RESTful Sensor. Although there’s no way to make the state (i.e., what comes out of value_template) a dictionary (even if it looks like a dictionary, it’s really always a string), the same is not true for the json_attributes. So, that sheds a new light on this! :slight_smile:

One other comment about what you tried. I tried it myself - i.e., value_template: "{{ value_json.results }}" - and the reason it doesn’t work is because the output is too long. States strings are limited to 255 characters.

So, the following you might find useful:

sensor:
  - platform: rest
    resource: https://api.sunrise-sunset.org/json?lat=XX.xxx&lng=YY.yy
    name: "Sun Rise and Set"
    value_template: "{{ value_json.status }}"
    json_attributes:
      - results
  - platform: template
    sensors:
      sunrise:
        friendly_name: "Sunrise"
        value_template: "{{ states.sensor.sun_rise_and_set.attributes.results.sunrise }}"
      sunset:
        friendly_name: "Sunset"
        value_template: "{{ states.sensor.sun_rise_and_set.attributes.results.sunset}}"
      day_length:
        friendly_name: "Day Length"
        value_template: "{{ states.sensor.sun_rise_and_set.attributes.results.day_length }}"

I just tried this with my lat/lon and got:

{{ states('sensor.sun_rise_and_set') }}
{{ states('sensor.sunrise') }}
{{ states('sensor.sunset') }}
{{ states('sensor.day_length') }}
OK
5:19:08 AM
7:29:18 PM
14:10:10

EDIT: So those values were actually using the example lat/lon from the sunrise-sunset.org website. When I updated with my real lat/lon, I noticed the times are being reported in UTC, not local. Doesn’t matter for day_length, but it does for sunrise and sunset. So, although this can work, some more massaging is necessary to get the sunrise and sunset values into something actually useful.

EDIT 2: It’s probably best to add &formatted=0 to the end of the resource URL. That way the sunrise & sunset times will be full date/time strings, which can then be converted to whatever you want. Also, day_length will be in seconds, again easily convertible to whatever display format you want.

E.g.:

{{ states('sensor.sun_rise_and_set') }}
{{ states('sensor.sunrise') }}
{{ states('sensor.sunset') }}
{{ states('sensor.day_length') }}
{{ as_timestamp(states('sensor.sunrise'))|timestamp_custom('%I:%M:%S %p') }}
{{ as_timestamp(states('sensor.sunset'))|timestamp_custom('%I:%M:%S %p') }}
{{ states('sensor.day_length')|int|timestamp_custom('%H:%M:%S',false) }}

gets:

OK
2018-07-26T10:42:20+00:00
2018-07-27T01:16:23+00:00
52443
05:42:20 AM
08:16:23 PM
14:34:03
1 Like

Actually it does.

I am expecting when 10am ticks over (we are UTC+10) that all the day lengths yesterday, today and tomorrow will shift as currently, they have not shifted since yesterday at 11am when I set it all up… Maybe this is no biggie and I can just roll them forward myself if it’s before 10am but I’ll need to get tomorrow+1

If you have the lat & lon correct, even if you’re not using &formatted=0 (or if you are using &formatted=1) then for the day, the day_length value will be correct. It doesn’t matter that the sunrise and sunset are reported in (partial) UTC.

And when you use &formatted=0, everything is right for the day. Yes, the (complete, aware) datetimes will be in UTC, but they are still correct. Just reformat them into local time if you want.

I think you’re confusing how datetimes are displayed vs what they actually are. I seriously doubt that for some part of the day they will be for another day. If that were so, then the website would be useless.

FWIW, I have the following currently set up:

sensor:
  - platform: rest
    resource: !secret sun_data_url
    name: sun_data
    value_template: "{{ value_json.status }}"
    json_attributes:
      - results
    scan_interval:
      hours: 1
  - platform: template
    sensors:
      sunrise:
        friendly_name: Sunrise
        value_template: "{{ states.sensor.sun_data.attributes.results.sunrise }}"
      sunset:
        friendly_name: Sunset
        value_template: "{{ states.sensor.sun_data.attributes.results.sunset}}"
      day_length:
        friendly_name: Day Length
        value_template: "{{ states.sensor.sun_data.attributes.results.day_length }}"

where the sun_data_url secret is:

https://api.sunrise-sunset.org/json?lat=REDACTED&lng=REDACTED&formatted=0

The values being reported are all correct, and for today, even though we’ve already crossed the boundary you mentioned (which, in my case, is 7:00 PM, since my timezone is -05:00.) I even restarted HA to force an update and they are still correct.

ok so yesterday, and today up till 10am, I had:

Day Length Yesterday: 10:20:09
Today: 10:21:28
Tomorrow: 10:22:50

After 10am this ticked over today to show:
Yesterday: 10:20:09
Today: 10:22:50
Tomorrow: 10:24:12

(Note yesterday hasn’t kicked over at all yet…)

How exactly are you getting those values? Are you using the value being returned in day_length, or are you calculating them from sunrise and sunset? And if the latter, how exactly are you obtaining sunrise and sunset?

Of course everything I said depends on the website actually functioning correctly. :slight_smile:

What I have now I just set up about four hours ago, so it hasn’t even gone through a complete day cycle. I expect the values to update shortly after midnight local. Whatever happens, I can report back tomorrow night after it’s gone a full day.

Well I’m using this:

  - platform: rest
    resource: !secret daylength_yesterday
    name: "Day Length Yesterday (sunrise-sunset.org)"
    value_template: "{{ value_json.results.day_length }}"
    scan_interval:
      minutes: 60
  - platform: rest
    resource: !secret daylength_today
    name: "Day Length Today (sunrise-sunset.org)"
    value_template: "{{ value_json.results.day_length }}"
    scan_interval:
      minutes: 60
  - platform: rest
    resource: !secret daylength_tomorrow
    name: "Day Length Tomorrow (sunrise-sunset.org)"
    value_template: "{{ value_json.results.day_length }}"
    scan_interval:
      minutes: 60

With the URL: daylength_yesterday: https://api.sunrise-sunset.org/json?lat=redacted&lng=redacted&date=yesterday

ditto for today and tomorrow.
Weird thing too is that if I put the URL into a browser yesterday is correct length.

But I think what you are missing (?) is that it’s giving you the UTC day/date so if the UTC date is for the wrong day it’s going to be wrong. You aren’t specifying a date so it’s always going to be today I think and correct.

That’s weird. What you have seems correct. I wonder if that is pointing to another issue. Are you getting any errors? What is the last_updated and last_changed for these entities? (You don’t have to tell us. Just saying you might want to look at that.) Also note that you have scan_interval set to 60 minutes, which is fine, but that means that when the website does switch/shift days, it can take up to that long before your entities will show that. Just something to keep in mind.

Not true. It doesn’t matter if UTC is tomorrow morning, because that translates to tonight (assuming, again, for me, we’re in the 7:00 PM to midnight local time period.) Just because the UTC’s date is tomorrow’s date, doesn’t mean it’s representing tomorrow local. For me, 8:00 PM local today is the same as 1:00 AM UTC tomorrow.

Anyway, enough on that. If the website is reporting the day_length for today, then it doesn’t matter whether you’re using formatted or not, or whether the sunrise and sunset are reported in local or UTC. Again, assuming the website is working correctly.

and I just restarted Home Assistant and it’s updated and showing image

yeah I thought that might be it… it might have missed the 10am switchover amd might refresh at 11ish…
I did change to 1 hour instead of 60 minutes too before I restarted.

but hang on…
it’s getting the info for the UTC date. The UTC date will change from yesterday to today at 10am here (we are +10) so before 10AM if I execute the URL I would expect it to show a different result to if I do it after 10am because the UTC date has changed.
Interestingly, if I search for Sydney on that site, it shows totally different day lengths and sunrise/sunset times in the table! (only a few minutes different but still different)

see also


for today and tomorrow it ticked over at 10:11am, for yesterday at 10:48 when I restarted.

No, it’s getting the info for the lat/lon you give. At least that’s what I assume. The date of the UTC representation of those times doesn’t matter. It’s the date of the local time representation of those times that matters. Let me make this concrete. In your case, where the local timezone is +10:00, the sunset for your “today”, represented in the local timezone, will have your local today’s date, and the time will be what you expect. But, if you take that exact same date/time, and represent it in UTC, the date will be one less (“yesterday”), and the time will be +14 hours. So, e.g., 7:00 AM “today” local is the same date and time as 9:00 PM “yesterday” UTC. It doesn’t matter that the UTC date is yesterday, the date/time still represents your today. Oh well, that’s the best I can do in trying to explain it. If we still disagree, then I guess we’ll have to agree to disagree. :slight_smile:

You can see from the screenshots that’s it’s updating the day length at midnight UTC.

Yep, I definitely see that. I’m just not sure I understand why. It doesn’t make sense to me.

BTW, the fact that yesterday’s day length didn’t change at the same time as the others could simply be explained by the fact that it takes three separate exchanges to get all three values, and the yesterday one might have hiccuped.

I’ll report back what I see on my setup tomorrow. I’ll go ahead and add sensors for yesterday and tomorrow, too, to make it more like yours.

This is weird.

1 Like

You know, I was just looking at the code for the standard sun component, and the annoying part of all of this is, it could provide the current day’s sunrise and sunset as attributes (in addition to the others.) It seems to have all the information available to it. Whoever wrote it, though, apparently just decided not to include them. :frowning:

It uses the Python astral package. And there are functions provided in homeassistant.helpers.sun that can be used to do this (pretty much the same ones that sun.py uses.) Maybe I’ll write a custom component for this. The plus is it doesn’t need to query any website; it appears to be based on some data and equations. Add one to the project list…

(Yeah, I know, this should be done via an issue or pull request. Still really don’t know how to do that.)

1 Like