Automation time trigger from template sensor

Hello,

I am trying to set an automation trigger based on a time from a template sensor:

- id: '1626701165811'
  alias: Green Light - Off
  description: ''
  trigger:
  - platform: time
    at: sensor.greenlight_off_time
  condition: []
  action:
  - service: light.turn_off
    target:
      entity_id: light.sonoff_green

The sensor:

sensor:
  - platform: template
    sensors:
      greenlight_off_time:
        friendly_name: "Heure extinction"
        value_template: >
          {{ states('sensor.greenlight_off_timestamp')|int|timestamp_local }}
        icon_template: mdi:lightbulb-off

homeassistant:
  customize:
    sensor.greenlight_off_time:
      device_class: timestamp

But it doesn’t work trigger whereas the sensor show in lovelace as a proper datetime class sensor.

If you are using the latest version of Home Assistant (2021.7.X), try this:

sensor:
  - platform: template
    sensors:
      greenlight_off_time:
        friendly_name: "Heure extinction"
        value_template: "{{ as_datetime(states('sensor.greenlight_off_timestamp')) }}"
        icon_template: mdi:lightbulb-off

Hello,

It doesn’t work any better sadly.

I have now:

greenlight_on:
        value_template: >
          {% set ns = as_timestamp(state_attr('sun.sun','next_setting')) %}
          {% set illumination_delay = states('input_number.greenlight_on_delay')|float * 60 %}
          {{ as_datetime(ns|timestamp_local) + timedelta(seconds = illumination_delay)  }}
        icon_template: mdi:lightbulb-on
        device_class: timestamp

Along with

- id: '1626701115745'
  alias: Green Light - On
  description: ''
  trigger:
  - platform: time
    at: sensor.greenlight_on_time
  condition: []
  action:
  - service: light.turn_on
    target:
      entity_id: light.sonoff_green

If I don’t add device_class: timestamp it shows as a string in lovelace, with it, I have a proper “relative time” displayed, meaning to me that this does the job, as the documentation states “The Entity ID of a sensor with the “timestamp” device class.”

You have defined sensor.greenlight_on but are triggering from sensor.greenlight_on_time…?

True, because this is my last try to trigger it with that sensor:

      greenlight_on_time:
        value_template: >
          {{ as_timestamp(states('sensor.greenlight_on')) | timestamp_custom('%H:%M:%S') }}

Here is the full example:

sensor:
  - platform: template
    sensors:
      greenlight_off:
        value_template: >
          {% set ns = as_timestamp(state_attr('sun.sun','next_setting')) - 60*60*24 %}
          {% set illumination_duration = states('input_number.greenlight_duration')|float * 60 * 60 %}
          {{ as_datetime(ns|timestamp_local) + timedelta(seconds = illumination_duration) - timedelta(seconds = states('sensor.daylight_timestamp')|float) }}
        icon_template: mdi:lightbulb-off
        device_class: timestamp

      greenlight_off_time:
        value_template: >
          {{ as_timestamp(states('sensor.greenlight_off')) | timestamp_custom('%H:%M:%S') }}

The automation:

- id: '1626701165811'
  alias: Green Light - Off
  description: ''
  trigger:
  - platform: time
    at: sensor.greenlight_off
  condition: []
  action:
  - service: light.turn_off
    target:
      entity_id: light.sonoff_green
  mode: single

The result:

Peek 20-07-2021 22-07

Works for me.
Did you check the automation was not fired?

In the example I presented, I focused on the template itself and forgot to add device_class: timestamp to the Template Sensor’s configuration. Sorry about that.

Every timestamp sensor that I have seen, presents the date, time, and timezone. For example:

However, the output from this calculation:

{% set ns = as_timestamp(state_attr('sun.sun','next_setting')) - 60*60*24 %}
{% set illumination_duration = states('input_number.greenlight_duration')|float * 60 * 60 %}
{{ as_datetime(ns|timestamp_local) + timedelta(seconds = illumination_duration) - timedelta(seconds = states('sensor.daylight_timestamp')|float) }}

doesn’t include the timezone and looks like this:

2021-07-19 21:37:29

It makes me wonder how well it serves as a time reference for a Time Trigger when it lacks a timezone. :thinking:

1 Like

@koying it never triggered

Thanks mate.

I added as_local and it now works. As a developer, I find it a rather complicated way to calculate and format a date to get it working in automations …

{{ as_local(as_datetime(ns|timestamp_local) + timedelta(seconds = illumination_duration) - timedelta(seconds = states('sensor.daylight_timestamp')|float)) }}
  1. It’s complicated because you made it complicated. There’s no need to convert from timestamps to datetime objects to time strings so many times. The calculation could have been done using timestamps and converted once at the very end.

  2. When I suggested using as_datetime (recently introduced in version 2021.7) I didn’t suggest using it the way the calculation mixes UTC and local time (and loses the timezone in the process).

I am curious on how you would make it simpler.

{% set myts = ns + illumination_duration - states('sensor.daylight_timestamp')|float %}
{{ as_datetime(myts) }}

Gives the error: TypeError: argument 1 must be str, not float. And I haven’t found how to transtype a float or int to string.

EDIT: it is possible to cast float to string using (|string). But it doesn’t work:

{{ myts|string }} return the float representation as a string (eg. 1626877820.603383)

But

  • {{ as_datetime(myts|string) }} or {{ myts | string | timestamp_local | as_datetime }} both return “None”

  • {{ myts | timestamp_local | as_datetime }} gives a datetime without timezone

  • {{ myts | timestamp_local | as_datetime | as_local }} works

The following template’s output is in UTC with the timezone. Home Assistant has no trouble converting it to local time (assuming Home Assistant’s timezone has been set correctly).

{{ as_datetime(state_attr('sun.sun','next_setting'))
   - timedelta(days = 1)
   + timedelta(seconds = states('input_number.greenlight_duration') | float * 60 * 60)
   - timedelta(seconds = states('sensor.daylight_timestamp') | float) }}

Sample output format:

2021-07-22 00:43:33.394761+00:00
1 Like

I see, direct datetime object calculation. Even simpler using hours for input_number.greenlight_duration:

{{ as_local(as_datetime(state_attr('sun.sun','next_setting'))
   - timedelta(days = 1)
   + timedelta(hours = states('input_number.greenlight_duration') | float)
   - timedelta(seconds = states('sensor.daylight_timestamp') | float)) }}

Yes; I had left it in seconds but if the input_number’s value is actually hours then your modification is preferable.

Did you find that the addition of as_local was necessary? The template is being used in a Template Sensor whose device_class is timestamp therefore UTC with timezone ought to be sufficient without the added step of converting to local time.