Is there really no standardized way for an automation to find out exactly when it was triggered?
An event trigger has trigger.event.time_fired, and I suppose for a state trigger you could use trigger.to_state.last_updated. But say a template trigger has nothing as far as I can tell, and if you run an automation manually (for testing purposes) you get less than nothing (though this is probably a bug: traces show neither this nor trigger!?).
Is there really no standardized way to accomplish this?
The closest generic way I’ve come up with so far is states[this.entity_id].attributes.last_triggered
But that value is not reliable, as it may change during the execution of actions if another trigger comes in. So you would have to store it in a variable, which seems kind of ridiculous…?
The last_triggered attribute of the automation entity stores the last time the action block was reached. If an automation triggers but conditions block execution, it’s not updated.
I guess you know that though. What are you wanting to achieve?
Hmm, not sure I did know that. As the name is literally last_triggered, my assumption was that this was at the time the trigger fired without taking anything else into account. That’d still make the attribute unreliable for automations in mode parallel, but for mode queued I guess the attribute does not change until the executor actually gets around to the next run in the queue?
My specific use case right now is simply that I need to calculate how much time has elapsed since the automation started. The automation begins with downloading a large chunk of data which may take a second or two, and I need to be able to time for some other calculations regarding to the media position of the media player which triggers the automation.
If the following doesn’t work, I might not be understanding what you want to do.
You are in a running automation and you want to know the time between when it began running and when it finishes?
Would this work:
action:
- variables:
invoke_timestamp: "{{ as_timestamp(now()) }}"
# Here you put your automation code, downloading a file and whatever
# else it does.
- variables:
finish_timestamp: "{{ as_timestamp(now()) }}"
run_time_in_seconds: "{{ finish_timestamp - invoke_timestamp}}"
Yes. I know how to do the calculation. What baffles me is specifically that there is no 100% reliable way to find out when an automation was triggered, unless you yourself manually store this in a variable at the beginning. Which is what I currently do and your code also does.
Personally I feel like it ought to be available as an attribute on this.
The trigger object is created when one of the automation’s triggers has fired. If you run an automation manually via the UI or using automation.trigger, none of its triggers are exercised so no trigger object is created. That explains why the trace shows the trigger object is null. It’s by design; not a bug.
After manually running an automation, its trace shows that this has properties. However, this.attributes.last_triggered show the last (previous; not latest) time the automation executed its actions. So for your purposes neither object contains what you want (the current time upon starting the actions).
The trace does not show the trigger object to be null. It does not show trigger at all, nor does it show this. Both should exist, though the trigger only contains a single key platform which is null. They clearly do exist as I can stuff them into variables.
As a personal opinion, I think the approach of storing the timestamp in a cleanly named variable yourself is probably the better option. I would stick with that approach in my automations even if the trigger variable had a “time_triggered” element.
The reasons are: (1) it’s portable if your code ever moves to a script or a non-state-triggered template sensor, which won’t be provided a trigger variable, or if you end up triggering it in an environment where there is no trigger variable; (2) it’s more flexible, since you know exactly what the starting timestamp is and you can extract it in the middle of the automation if that’s more useful; and (3) it seems a little extra to have the platform hand you a timestamp in the trigger variable (or some other way) each time the automation is invoked, when most automations are never going to use it and you can get it via the standard time calls in Jinja.
All that aside, it’s a valid feature suggestion since the devs are going to have a much more educated opinion than I do. I can certainly understand a difference of opinions here.
I produced two trace files for an automation I had run manually. Both contained what I stated in my previous post. I wouldn’t say it if I hadn’t checked first.
The example you posted has no triggers. Is that by design or what?
FWIW, I have never examined the trace of a triggerless automation.
I dunno. My only guess would be that “run manually” means something completely different to you than it does to me. To me it would imply choosing “Run actions” from the … menu.
That should still produce a trigger variable, as the documented way check for “Run actions” is trigger.platform == none which would error out if trigger was not an object.
Yes, because why would it need a trigger when the bug in traces only apply to when the automation is running manually? Again, as in “Run actions” from the … menu.