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.
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)
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.
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. 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ā ā¦
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. 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.
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.
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
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