Templated Sun trigger

Hello,

I try to provide different offsets for the Sun trigger, depending on winter/summer time. I edit the automation, enter YAML editor and write the following:

platform: sun
event: sunset
offset: {{ '06:00' if now().timetuple().tm_isdst else '07:30' }}

and hit the Save button. However when I try to check whether the changes were saved - I see they they were not.

What is wrong?

Two things:

  1. Syntax error.
    The template is missing outer quotes. Wrap the template in double-quotes.
  2. Logic error.
    now().timetuple().tm_isdst does not report true/false. It reports 1 when DST is in effect and -1 otherwise. The values 1 and -1 are not substitutes for true/false when used in an if statement. Add a test to check if the result is greater than zero (assuming you want the comparison to be true for '06:00').
offset: "{{ '06:00' if now().timetuple().tm_isdst > 0 else '07:30' }}"

Thank you very much @123 ,

When I try to save what you have suggested I get this errror message on the bottom of the page:

Message malformed: offset {{ '06:00' if now().timetuple().tm_isdst > 0 else '07:30' }} should be format 'HH:MM', 'HH:MM:SS' or 'HH:MM:SS.F' for dictionary value @ data['offset']

Do you know what is wrong now? Thank you!

Yes. It’s one more mistake that I should have noticed first because it overshadows the other two mistakes: you can’t template a Sunset Trigger’s offset option.

Given that you won’t be able to template it, tell me what you are trying to do and maybe I can think of another way to achieve it.

I appears you want it to trigger 6 hours after sunset if DST is in effect and 7.5 hours after sunset if it’s standard time. Is that correct?

Yes, That’s correct. Here is my full automation in its current sate:

- id: '1611603474835'
  alias: Turn Sockets Off
  description: Turn the sockets off
  trigger:
  - platform: sun
    event: sunset
    offset: 06:00
  condition:
  - condition: state
    entity_id: binary_sensor.jewish_calendar_issur_melacha_in_effect
    state: 'on'
  action:
  - data: {}
    entity_id: switch.sockets
    service: switch.turn_off
  mode: single

Calculating a time with an offset isn’t difficult. The computed time can be used with a Time Trigger.

However, in this case the time is sunset which is reported in the next_setting attribute of the sun.sun entity. It changes to tomorrow’s sunset date and time right after today’s sunset occurs. That little detail makes computing the time a bit more complicated.

Currently, I don’t have the time to devise the required template to perform the calculation so I offer you this quick 'n dirty solution.

- id: '1611603474835'
  alias: Turn Sockets Off
  description: Turn the sockets off
  trigger:
  - platform: sun
    event: sunset
    offset: '06:00'
  condition:
  - condition: state
    entity_id: binary_sensor.jewish_calendar_issur_melacha_in_effect
    state: 'on'
  action:
  - delay:
      minutes: "{{ 0 if now().timetuple().tm_isdst > 0 else 90 }}"
  - service: switch.turn_off
    target:
      entity_id: switch.sockets
  mode: single

It triggers at sunset plus 6 hours, just like it always did. However, there’s a computed delay in the action. If DST is in effect, it doesn’t wait and immediately turns off the switch. If it’s standard time, it waits for 90 minutes (6 hours after sunset + 90 minutes = 7.5 hours) and then turns off the switch.

Caveat:
The drawback of this technique is that if you restart Home Assistant, or reload automations, while a delay is counting down, the delay is canceled and the automation will not reach the part where it turn offs the switch. All this to say that this is not the most robust way to achieve your goal and the only thing good about it is that it’s easy to implement.

1 Like

OK, the calculation wasn’t as onerous as I had expected:

{{ (state_attr('sun.sun', 'next_setting') | as_datetime +
    timedelta(days = -1, hours = 6 if now().timetuple().tm_isdst > 0 else 7.5)).isoformat() }}

How the template works

  • It gets the value of next_setting and converts it to a datetime object.
  • After today’s sunset has occurred, the value of next_setting will be tomorrow’s sunset date and time. To compensate for that, we subtract 1 day from the value.
  • We also add 6 or 7.5 hours depending on whether DST is in effect today.
  • Finally, we convert the appearance of the date and time into ISO format.

Because we are using tomorrow’s sunset time, the computed turn-off time is actually different by a few minutes (0-3 minutes) than if we had used today’s actual sunset time. Hopefully that tiny difference is acceptable for your requirements.

Now that we can compute the desired time, here’s a more robust way to turn off the switch 6 or 7.5 hours after sunset.

Template Sensor

  • Create a State-based Template Sensor, called sensor.sockets_off, that computes the time when the sockets should be turned off (based on whether DST is in effect or not). The sensor’s device_class must be set to timestamp.
template:
  - sensor:
      - name: Sockets Off
        device_class: timestamp
        state: >
          {{ (state_attr('sun.sun', 'next_setting') | as_datetime +
              timedelta(days = -1, hours = 6 if now().timetuple().tm_isdst > 0 else 7.5)).isoformat() }}

Automation

  • Create an automation with a Time Trigger that uses sensor.sockets_off. It will trigger when the current date and time matches the value of sensor.sockets_off.
- id: '1611603474835'
  alias: Turn Sockets Off
  description: Turn the sockets off
  trigger:
  - platform: time
    at: sensor.sockets_off
  condition:
  - condition: state
    entity_id: binary_sensor.jewish_calendar_issur_melacha_in_effect
    state: 'on'
  action:
  - service: switch.turn_off
    target:
      entity_id: switch.sockets
  mode: single

Restarting Home Assistant, or reloading automations, will not prevent this automation from turning off the switch at the scheduled time … unless, of course, the restart/reload occurs at the scheduled time. FWIW, there’s a way to mitigate that as well.

1 Like

Besides the template technical aspects explained by Taras, already, I’m curious of what you’re trying to achieve, here?

I wanted to have different sunset offsets depending whether now it is summer or winter time…

Hehe, yes, I got that, but why?
Just to be sure that the sun elevation is not what you’re actually looking for…

Long winter evenings have different routines than summer evenings… No, sun elevation is not what is needed, thank you!

1 Like