Read sunset offset at a given time?

Hi,

Is it possible to read the sunset offset at a given time? We can set it actively by using the offset: 'time' but i need to calculate the offset at a given moment if possible. I can template the solar angle at a given time by

  solar_angle:
    friendly_name: 'Sun Angle'
    unit_of_measurement: '°'
    value_template: >
      {{ '%+.1f'|format(state_attr('sun.sun','elevation')) }}

would that be possible likewise for offset also?

I ask because I have external light sensors (non-smart) that switch on/off my lights at the desired darkness level, and I want to capture that moment in solar angle and offset, to use lateran in automations.

thx

The offset is just the difference between now() and the next sunset time.

This will give you the offset to the next sunset in seconds:

{{ as_timestamp(states.sun.sun.attributes.next_setting) - as_timestamp(now()) }}

Edit: and this will give it to you in HH:MM:SS

{{ (as_timestamp(states.sun.sun.attributes.next_setting) - as_timestamp(now())) | timestamp_custom('%H:%M:%S', 0) }}

1 Like

thanks you, never though it to be the simple… cool.
will test tonight :wink:

Then the only thing that’ll matter is the angle. The offset will change through the year, but you’ll and up with a log showing that :wink:

a yes, of course… forgot about that…

Still, very nice to be aware of things, and be able to template them into HA :+1:

not sure I understand yet… when the docs say:

automation:
  trigger:
    platform: sun
    # Possible values: sunset, sunrise
    event: sunset
    # Optional time offset. This example is 45 minutes.
    offset: '-00:45:00'

doesn’t this mean 45 minutes before next sunset? I d need a previous_sunset. I’d need the template to state the time after the previous sunset.

was having a look in @pnbruckner 's cc but there’s no previous_sunset either… trying to get my head around this

If you set an offset of -45 minutes (-00:45:00) it will trigger 45 minutes before every sunset. e.g. 45 minutes before the the next sunset and 45 minutes before the next one after that etc…

You’re right, my template above returns a positive time, if you used it as it is it would trigger 45 minutes after every sunset.

To convert it to a negative use this:

-{{ (as_timestamp(states.sun.sun.attributes.next_setting) - as_timestamp(now())) | timestamp_custom('%H:%M:%S', 0) }}

understand that… :wink:

what I can’t grasp though, is if I check, let’s say 45 minutes after the previous sunset, I could use the template which calculates using the next sunset, and show me +00:45:00

Sorry, I don’t understand what you mean.

probably my bad. glad you’re helping here.

What I am trying to establish is at any given moment, to read the offset to the previous sunset of that moment, and not the offset of that moment to the next sunset.

Ah ok now I understand. My template works for times before sunset but not after.

Maybe at midday each day store the sunset time in an input_datetime and use that in the template.

yes, have to give something like the a thought.
Maybe that could be a nice addition to @pnbruckner s custom component, will asl about that.
thanks for helping me!

trying to ‘record’ it :slight_smile:

If I understand correctly, you want to trigger an automation some amount of time after sunset. Of course, if the offset was constant you could just do:

trigger:
  platform: sun
  event: sunset
  offset: '00:45:00'

But I believe you’re looking for a way to use a dynamically calculated offset, and unfortunately sun.sun’s next_setting attribute changes at sunset to tomorrow’s sunset.

You could use my CC with the sunset attribute enabled. This attribute is constant throughout an entire day, changing at midnight. As long as the calculated offset doesn’t go past midnight, you could do something like:

trigger:
  platform: template
  value_template: >
    {{ (as_timestamp(state_attr('sun.sun', 'sunset')) + N_SECONDS)
       |timestamp_custom('%H:%M') == states('sensor.time') }}

where N_SECONDS would be some expression that evaluates to the number of seconds you wanted the offset to be.

Would this work? Or do you need the offset to possibly go beyond midnight?

HI, thanks!

Yes, what I am trying to accomplish is this:
lets say sun sets at 1800 hours. My light_level sensors switches in at 18.45 and turns on the lights. Id like to template that positive offset of 45 minutes from the sunset automatically.

I can do the same with the sun angle on each moment of the day:

value_template: >
  {{ '%+.1f'|format(state_attr('sun.sun','elevation')) }}

Hope to be able to do something like that for the offset.
example automation to do that:

    data_template:
      message: >
        {{as_timestamp(now()) | timestamp_custom("%X") }}: Parking is set and safely lit 
         while Solar angle is {{states('sensor.solar_angle')}} and Offset is {{template_offset}}

so id just like to find out what the offset is, rather than set it, as you do in your template with + n_seconds

Ok, I guess I misunderstood what you said here and in the other thread (for my CC.) I thought you were looking to trigger an automation at some dynamically calculated offset from sunset.

If you just want to figure out how long it has been since the last sunset (at some time determined by some other mechanism), then yes, there is no current attribute I’m aware of that would tell you when the previous sunset was (especially after midnight.) My CC could be fairly easily extended to add a prev_sunset attribute I suppose. Although as others have suggested, you could have an automation that runs, say at midnight, that saves the value of the next sunset (i.e., “today’s”, from either the standard sun component or my CC) into an input_datetime, and then use that. Actually, since these attributes are really strings (which are compatible with the as_timestamp function), it would probably be easier to save to an input_text.

EDIT: Actually, if you triggered the automation at sunset, and had it save the current time (i.e., now()), that should give you the time of the previous sunset until the next sunset happens (when the time is updated again.)

do i understand correctly that your component has an attribute sunset that is valid for the whole day? wouldn’t that than allow for something like offset = sunset - now() ? (never mind the correct syntax , this is only the idea)

the sunset would never go past midnight, so id always stay within the 24 hours of one day

i think that would be easiest, might I throw in a feature request for that :wink: no need for extra input_texts or automations if it were available like that!

this would be what I need, call it last_sunset, and then use that to calculate the offset when the light_sensor kicks in with the now() of that moment: offset = now() - last_sunset.

think that’s what I posted above already…

No, that would not work between midnight and sunset, because at midnight it gets updated to the new day’s sunset. From sunset to midnight it is effectively the date/time of the previous sunset. But after midnight (and until sunset) it is the date/time of the next sunset, just like next_rising. The difference between these two attributes is that next_rising updates at sunset, whereas sunset updates at midnight. next_rising always tells you when the next sunset will be, whereas sunset always tells you when today’s sunset will be or was. What you’re looking for is an attribute that also updates at sunset and always tells you when the previous sunset was (which is effectively the date/time of when next_rising is updated, which is why capturing the current time at sunset would give you the same thing.)

Easiest for you, not for me. :wink: So far you’re the only one that I’m aware of that is looking for such a feature. If I had infinite time on my hands I’d consider doing this, but I don’t, and I have a few other things I’m trying to do right now that I think more people will benefit from, so they’re taking priority.

It really comes down to what time period during a given day do you want to be able to calculate the time since the last sunset. If you just need that to work between sunset and midnight, then you can do this with my current CC using the sunset attribute. But if you want the calculations to be valid between midnight and sunset as well, then I’d suggest what I did before: use a simple automation that triggers at sunset and captures the current time in an input_text.

yes, that was what I am looking for, and hoping to be able to use your component for. would this work:

{{(as_timestamp(now()) - as_timestamp(state_attr('sun.sun','sunset')))| timestamp_custom('%H:%M:%S', 0) }}

would lead to:

##############################################################################################################
# using @pnbruckner cc sun.py
# https://github.com/pnbruckner/homeassistant-config/blob/master/custom_components/sun.py
##############################################################################################################

      sunset_offset:
        friendly_name: Sunset offset
        value_template: >
          {{(as_timestamp(now()) - 
             as_timestamp(state_attr('sun.sun','sunset')))| timestamp_custom('%H:%M:%S', 0) }}

and

automation:

  - alias: 'Notify outside daylight'
    id: 'Notify outside daylight'
#    initial_state: on
    trigger:
      platform: state
      entity_id: binary_sensor.outside_daylight_sensor
#      to: 'off'
    condition: 
      condition: template
      value_template: >
        {{is_state('input_boolean.notify_system', 'on')}}
    action:
      service: notify.notify
      data_template:
        message: >
          {{as_timestamp(now()) | timestamp_custom("%X") }}: 
          Daylight {{states('binary_sensor.outside_daylight_sensor') }}: Outside lights are powered 
          {{'on, ' if is_state('binary_sensor.outside_daylight_sensor', 'off') else 'off, '}}
          Solar angle is {{states('sensor.solar_angle')}} and Offset is {{states('sensor.sunset_offset')}}.

Mostly, but you’ve fallen into the “don’t count on now() to update a template sensor” trap again. :wink: In this particular case (unless you want to use sensor.sunset_offset elsewhere) you’re probably better off just moving the calculation into the automation action.

Also, the second parameter of timestamp_custom is supposed to be a boolean, so it should be false, not 0. (BTW, the preferred boolean values in jinja are lower case false & true, not the Python spelling of capitalized False and True, although either works.)