Template won't trigger automation

Hi There,

I’ve added a custom sensor that return the dusk time.
I’m using this sensor to trigger my automation to close the blinds.
But i’ve tried several templates forms to try to trigger the automation, but with no succes.
Is the output from the sensor wrong to trigger an automation?
The output is for example:

2020-03-14T19:19:56+01:00

Automation:

- id: '1575148683669'
  alias: 'Blinds: Close blinds'
  description: Close blinds at dusk
  trigger:
  - platform: template
    value_template: '{{ as_timestamp(now()) == as_timestamp(states.sensor.dusk.state)
      }}'
  condition: []
  action:
  - data:
      entity_id:
      - cover.ikea_tradfri_kadrilj_links
      - cover.ikea_tradfri_kadrilj_rechts
    service: cover.close_cover
  - data:
      message: Blinds are closing at {{ now().strftime('%H:%M') }}
      title: Blinds
    service: notify.mobile_app_iphone_van_koen

Anyone can inform me?

Many thanks!

now() returns a time with microseconds so they’re more than likely never going to be exactly the same. Try changing == to >=.

  - platform: template
    value_template: >
      {{ as_timestamp(now()) >= as_timestamp(states('sensor.dusk')) }}

EDIT: See comments below about probably needing to use sensor.time instead of now().

EDIT 2: Not sure why this is marked as the solution. As I said, I had overlooked the issue of updating. (If a template trigger’s template has no recognizable entity IDs, it will be evaluated whenever any entity in the system changes state. However, this template does have a recognizable entity ID – sensor.dusk – and, hence, will only re-evaluate when that sensor changes, not when time changes. So this solution will not work as-is.)

1 Like

or filter with int like

as_timestamp(now())|int == as_timestamp(states('sensor.dusk'))int

?

The function now() won’t update the trigger, see https://www.home-assistant.io/docs/configuration/templating/#templates-without-entities-using-now

Use sensor.time instead. https://www.home-assistant.io/integrations/time_date/

Not quite true, I agree it shouldn’t but… See

The eye opener is towards the bottom

It’s true for the trigger used here. It will only update on restart of home assistant or if sensor.dusk changes. As there is no integer division like in the one (undocumented and possibly unreliable) exception in your link.

I would not rely on that sort of trigger in case the exception is fixed in some future release.

1 Like

I concur

I would use sensor time (as an entity id) and check as Phil suggests for >=

I only point it out because it shocked me and you ‘may’ run into circumstances where the usage makes a member “defensive” because “it works”.
Hopefully the github issue will raise some clarity.

Yep, I thought of that after I posted my suggestion. If there were no recognized entities then it would have worked, because in that case it gets re-evaluated for every state change in the system. Well, it would “work” if sensor.time was in the system, since that causes a state_changed event every minute. It’s better to use sensor.time directly, though, as you suggest. Even then one must consider that sensor.time only updates every minute, so it wouldn’t exactly match a time with non-zero seconds, so again, >=, or at least some other pre-processing like not including the seconds and microseconds in the comparison.

Thank you everyone for your extensive information. Surely i’m helped with the information you guys told here. Now let’s see tonight if my blinds will close :blush:

  1. If the template is changed to use sensor.time, then the template will be evaluated every minute.

  2. If the test is changed from == to >= then the template will return true each minute after dusk.

So the combination of these two changes will cause the cover to be closed every minute after dusk. That’s probably not the desired behavior. I’m wrong. See pnbrucker’s explanation below or Template Trigger documentation.

I believe you will need to use == and a slightly more sophisticated time test. The now() function returns a datetime object. If the dusk value is also a datetime object, you can directly compare their respective hours and minutes.

I’ve tried to convert it to a datetime object, but then the automation won’t be triggered…

That did the trick!

{{ as_timestamp(states('sensor.time'))|int >= as_timestamp(states('sensor.dusk'))|int }}

If it isn’t a datetime object already then I advise against converting it into one. There are other ways to compare the time.

There was never any question it would not do the trick. The question is do you mind that it causes your automation’s action to execute every single minute after dusk? I’m wrong. See pnbruckner’s post below or Template Trigger documentation.

I think the best bet is a) to use sensor.time, b) compare hours and minutes only and c) add some logic to make sure it does not trigger every minute - the easiest one is to check if the blinds are closed.
I presume that when the blinds are closed, their state is ‘closed’
Something like this

value_template: >
  {% set time = states('sensor.time') %}
  {% set dusk = states('sensor.dusk') %}
  {{
    (
      is_state('cover.ikea_tradfri_kadrilj_links', 'open') or
      is_state('cover.ikea_tradfri_kadrilj_rechts', 'open')
    )
    and
    (time[:2]|int == dusk.hour) and (time[3:5]|int == dusk.minute)
  }}

It will trigger exactly when it’s dusk and the blinds are open.
It won’t survive HA restarts though :wink: but there are ways to make it smarter.

That’s not true. Once a template trigger fires (because the expression evaluates to true), it will not fire again (under normal circumstances) until the expression first evaluates to false, and then back to true. To put that another way, it will only fire the first time the expression evaluates to true, and then after that only when it changes from false to true.

2 Likes

yes, exactly as the docs say. good catch!

What can I say other than than thanks for setting me straight. My understanding of its operation was wrong; I thought the template was evaluated ‘as-is’ each time. I didn’t realize the Template Trigger’s “state” (so to speak) must toggle.

I confirmed it for myself using this:

  trigger:
    - platform: template
      value_template: "{{ states('sensor.time') > '0' }}"
  action:
    - service: input_boolean.toggle
      entity_id: input_boolean.toggler

The template always evaluate to true. The automation’s behavior is as you described, upon reloading the automation, it initially triggers and toggles the input_boolean. However, that’s the first and last time it triggers the automation (or until the automation is reloaded or HA is restarted).

Here are the results of two successive tests. Initially the input_boolean was on and then, after loading the automation, it was turned off and remained that way (i.e no further toggling) until I reloaded the automation. Then it was turned on and remained that way.

Screenshot from 2020-03-16 11-09-37

I’ll correct my previous erroneous posts to prevent misleading anyone.


Relevant excerpt from the docs:

Being a boolean expression the template must evaluate to false (or anything other than true) before it will fire again.

@pnbruckner, @123

Hmmm ! not sure, obviously Teras has done the test and the logic is sound but …

I have lights that have a timer (- delay: in a script actually) and the script is called when the light is switched on. This works.
The script is also turned off when the light goes off.

The issue was when the light goes through a brightness change during the day (scheduled) this has to use light.turn_on to brightness: x
And it resets the timer again
The workaround for me was to specify the trigger state to be from: ‘off’ to: ‘on’
So the light had not been through a true - false - true but it still fired the script
I realise that this is a completely separate instance and not “apples with apples” but it’s still a quirk in the ‘rules’ as far as I understood them at the time.

Just tested this again and something Changed as it no longer restarts the timer
Apologies to ALL (just in case it was my own idiot testing methodologies :thinking: )