Find the error in: automation last_triggered with now() or timestamp templates

apparently they are not. It is a matter of being triggered or not, and hence getting set. at startup this is the situation:

after triggering manually (the set conditions aren’t yet met):

so, I need a safeguard for the case the automation hasn’t been triggered yet. And that s why I had the default(0) in there, but that obviously isn’t correct.
Id hate to have it triggered at startup , simply for ‘hacking’ this, I want the automation template to be correct in itself.

What would you do? Other than use the as_timestamp or Find the error in: automation last_triggered with now() or timestamp templates - #4 by petro? Can I take out the default(0) without pain. Seems not to hurt when triggered already, and not to do anything if not…

I need to fix both. The boiler switch seems to behave alright, but it is saved by the fact it triggers on the binary_sensor.workday_sensor, which is set on each startup, so the automation is triggered automatically… I think.

Edit triggering on workday cant be it. Ive added that to the automaton, without result, as I have done with all triggers of the boiler_switch… what is happening here? It keeps saying it never got triggered, even after adding the home assistant startup event… only a manual trigger causes it to showup in the dev-template.

So, I would check to see if it’s a string inside the template. If so convert it. I’d also check to see if it’s None, then just use now(). And lastly assume it’s a datetime object.

{% set last_triggered = state_attr('automation.boiler_switch','last_triggered') %}
{% if last_triggered is string %}
{% set last_triggered = strptime(last_triggered[:-6],"%Y-%m-%dT%H:%M:%S.%f") %}
{% elif last_triggered == None %}
{% set last_triggered = now() %}
{% endif %}
{{ (now()-last_triggered).total_seconds() > 120 }}

That should always work. And if for some reason you need to add another elif, you can pretty easily. Just always overwrite last_triggered and you’ll be good.

All this to avoid using as_timestamp(now())?

“Ease” :wink:

as_timestamp() would have the same issue. In fact, as_timestamp would only affect the last line.

{{ (as_timestamp(now())-as_timestamp(last_triggered)) > 120 }}

Yep, but couldn’t resist some ribbing though! :slight_smile:

1 Like

HI, and thanks again!

this does evaluate to true, when my automation has been triggered. Then again, my own template

        value_template: >
          {{ (now() - 
              state_attr('automation.low_light__hallway_motion_sensors','last_triggered')).total_seconds() > 120 }} 

does too. It doesnt at startup. NO return:

individual test:

It seems to boil down to the quest for the answer why my boiler automation does populate the last_triggered attribute and why the low_light automation doesn’t.
I use restore state for automations, and both are ‘on’.

couldn’t it be, the last_triggered only gets populated if and when the automation truly gets to the action part? I mean, if it is stopped during the condition section, it has in fact been triggered, but no action follows. Would the last_triggered be set in that case? Ive always assumed it would, but maybe this is an edge case ?

just for summarizing the issue:

this works fine:

        value_template: >
          {{ as_timestamp(now()) - 
              as_timestamp(state_attr('automation.low_light__hallway_motion_sensors','last_triggered')) >120 }}

while this doesnt do anything

      - condition: template
        value_template: >
          {{ (now() - 
              state_attr('automation.low_light__hallway_motion_sensors','last_triggered')).total_seconds() > 120 }} 

haha, keep that ribbing, probably rubbing, coming…
while in the act, please think along ? :wink:
appreciated though, love some positive sarcasm

Cringe-worthy …

2 Likes

please let me get back on this automation @petro
Ive given up using the now() variant when needing the last_triggered attribute. It simply would only work if triggered once before… the as_timestamp variant works solidly.

Still have a second issue though.

Ive setup the automation to trigger every 5 minutes:

    trigger:
      - platform: time
        minutes: '/5'
        seconds: 00

I would expect the following template to max on 5 minutes, ie 300, because of that:

      {{ as_timestamp(now()) - 
          as_timestamp(state_attr('automation.low_light__hallway_motion_sensors','last_triggered')) }}

but it only records the timestamp of the automation being actually executed:

is that to be expected? Or does it mean my trigger isn’t working.

could be the trigger is somewhat magical, because I tested another variant with this trigger:

trigger:
  - platform: time
    minutes: '/1'

and it triggered each second…

must add this system is on 84.3 so the new time_pattern isn’t yet needed.

Update

thought id try something that has always lingered in my mind after @NotoriousBDG shared his thoughts on another automation technique: put all conditions in the action part. This was mainly to be able to test the conditions.

I can confirm this also actually updates the last_triggered attributes correctly now. Apparently the last_triggered is in fact last_run, or last_came_into_action…

anyways, extra note to my self: when in need for an automation last_triggered template in an automation, have the conditions set in the action part, so one can truly work with the last_triggered attribute, not depending on the actual full actionability of the automation conditions…

it also enables the possibility using now(), with which I started this thread. So it all boils down to HA/the automation not setting the attribute last_triggered before it arrives at the action part. Which is a real architectural issue imho.

Yeah, once you go into the action section, the “last_triggered” updates. Guilty of the same mistake a few days ago :sweat_smile:

Sorry if I misunderstood your code and necroposting, but the searcher led me here when trying to figure out why my | default(0) doesn’t work for nested as_timestamp(state_attr(<stuff>))

{{ as_timestamp(state_attr("automation.podsumowanie_grzalka_fotowoltaika", "last_triggered") | default(0)) }}

Well, the issue was, as_timestamp() doesn’t like integers, so you have to provide a date format. A foolproof way of getting 0 out of that, regardless of your timezone, is to use or "1970-01-01T00:00:00+00:00" I also tried to use default("1970-01-01T00:00:00+00:00") but no dice. I spent way too much time on this, so I hope it helps another poor soul.

{{ as_timestamp(state_attr("automation.podsumowanie_grzalka_fotowoltaika", "last_triggered") or "1970-01-01T00:00:00+00:00") }}