Automation last_triggered attribute changed in 0.95?

This thing is giving me déjà vu; this came up in some other thread as well. It seems to me this is par for the restoration process. It always restores a datetime object as a string. Only after the automation is triggered again will last_triggered contain a proper datetime object. It’s this quirk that prevented the use of arithmetic with datetime objects in that other thread (that I can’t find right now) because, after a restart, the attribute contains is no longer a datetime object but a string.

Yep, that’s how I know about it. I’m sure I either read that discussion or took part in it. :slight_smile:

FWIW, I think this line of code:

            self._last_triggered = state.attributes.get('last_triggered')

should be this:

            self._last_triggered = state.attributes.get('last_triggered')
            if self._last_triggered:
                self._last_triggered = dt_util.parse_datetime(self._last_triggered)
1 Like

I realize you already have many irons in the fire but can we impose on you to create a PR to patch this bug?

If I recall correctly, the guy who wrote the code was adamant against this change. I vaguely remember a ‘half assed argument’ between people about this and nothing getting done.

Given that the first time the automation runs, its last_triggered attribute is assigned a datetime object, not a string, I’m going to have to agree that the argument against the change was ‘half-assed’.

I don’t understand how changing the attribute’s type, on restart, can be considered anything else other than a bug. Any date arithmetic now needs to first test if it’s dealing with a string or datetime object. :man_facepalming:

well, they use the timestamp string for a lot of things and they account for it in many places. So I think the choice for this was by design. Which is why they don’t want to change it.

If this was “by design”, then it was a poor design indeed. Not only does it not make sense, and make the system more difficult to use, I can site other locations in the code where a datetime that is saved as a string (because it is “JSON serialized”) is properly converted back to a datetime when restored.

I just tried a quick search in the issues & PRs and couldn’t find the discussion to which you referred. If you could find it that might be helpful. But in any case, at some point I may submit a PR anyway. In my mind it is, at best, a deficiency.

I found the thread. It would appear all of us discussing this issue today were discussing it back in April. :slight_smile: Small wonder this topic gave me a sense of déjà vu! The discussion begins at (approximately) this post.

Somewhere along the way I said I’d raise it as an Issue but, clearly, it ‘slipped my mind’ …

@123 @petro

Thanks for the link, but I still don’t see a reference to the author claiming not converting back to a datetime is the correct behavior. I did see this:

Does that mean there wasn’t such a discussion???

It’s possible. I talk so much on this that everything in the past tends to mesh together. I’ve had so many conversations about this and other startup oddities that I honestly can’t be 100% certain the convo took place. I just recalled a similar convo. But it might have been about last_changed / last_updated?

EDIT: Also if this PR does go through, it might screw people’s automations up. I know as_timestamp works with last_triggered as a string. We’d want to verify that the behavior stays the same if it changes to a date time. I think it will but you never know.

No problem. I can certainly understand that. :slight_smile: If/when I do submit a PR, and if there was such a conversation, it would be nice to reference it, but no biggie either way.

@nanobra1n

So the problem is that upon restart, last_triggered's value is a string and that causes the template’s date arithmetic to fail (it needs two datetime objects to work).

I believe you’ll need to enhance your automation and have it test if last_triggered is a string. If it is, you can use strptime to first convert it to a datetime object. The resulting datetime object can then be used with your existing date arithmetic.

if you do, remember the last_triggered in its current implementation is only set when the action block is executed. And not, as the name might suggest, immediately when the automation is triggered.

It needs to go past the condition block, and actually fire the action.

Reason enough, at least for some automations, to have conditions in the action block and not in the condition block.

Good idea. I wish I would have thought of that. Lol! :smile:

If it helps, restoring an automation’s last_triggered attribute was added in this PR by kellerza about 2 1/2 years ago. Ring any bells?

Thanks everyone for the educational discussion, especially @pnbruckner, @Mariusthvdb for their suggestions.

@123: I am struggling with the string - datetime object conversion

{% set last_triggered = "2019-06-27T23:07:11.734137+00:00" %}
{% set test = strptime(last_triggered,"") %}
{{ test is string }}

True

You can solve this, of course, however you like. I guess I’m wondering, what about what I suggested above did not do what you were looking for?

Oh, I did implement your suggestion. I just used @123 's suggestion as a learning opportunity for myself. that unfortunately didn’t go far :wink:

Just an FYI. I submitted a PR to fix the bug that restores an automation’s last_triggered attribute as a string instead of a datetime. See: https://github.com/home-assistant/home-assistant/pull/24951

2 Likes