Sure, that will help even in the event of a disorderly shutdown (power failure and no UPS).
Anyone using this approach should be aware that there’s a (slim) chance of some timers failing to be restored. Here’s the corner-case: if the time_pattern is every 5 minutes and a timer starts during that interval (i.e. between two polls), immediately followed by a power-failure, its information won’t be stored (and so it will not get restored upon startup). Reducing the time_pattern’s period (say, to 1 minute) will help.
My host machine is protected by a UPS, so I lean towards the event-based approach (homeassistant_stop).
Eh. You’re right. I was thinking about the mqtt.publish service, and assumed there was a mqtt.subscribe type service that I could just read the current message from the topic. my bad.
Shoot. Yeah, according to the Automation Trigger documentation, that is supposed to work. That’s what I was planning on using. Crap. The time trigger option kinda sucks. Maybe you can do a state change on the group.restored_timers, but my experience with groups is that it is the sum of the entities. So if one timer is active, then the group would probably show as active, and the automation wouldn’t trigger after setting a second timer. Bummer. You could hard code the state change trigger for entities you want to track, but you have to make sure that you update that… I might go with this option. I don’t have that many timers, and I’ll just have to remember to update it when needed. I guess I’ll notice when the new timer doesn’t restart after a reboot.
We’ve come full circle and returned to the first example I had posted, using a State Trigger with a list of timers.
I agree with you that explicitly listing the timers in the State Trigger is one of those tasks one is likely to forget to do. It doesn’t make the solution as transparent as with an Event Trigger for shutdown. However, the upside is that the State Trigger is event-based and won’t run needlessly like a Time_Pattern Trigger.
The use of a State Trigger will require a small change in the automation’s logic I’ve created. I’ll post it after I’ve tested the revised version.
I’ve already created the required MQTT Sensor for receiving the published timer information. I had to change my proposed format, for the published information, to make it easier to import as an attribute.
All that remains is to create an automation to read the sensor (at startup) and determine if any timers need to be started.
Ok. I dug into the code and worked out a solution updating the timer component. You can install it by using custom components. Just copy the timer directory and drop it into your custom_components directory. Or if you don’t have one, create a custom_components directed to your config directory. Home Assistant will use this code instead of the built in code. You shouldn’t experience any change in behavior unless you turn on the restore functionality in your config.
Let me know if you experience any issues. I tried to test for any situtation I could think of, but I am limited by my own experience.
The component defaults to using the same behavior for the built-in timer, but has the ability to turn on the restore functionality. There is also a restore_timeout in case you have a long period of time that occurs when Home Assistant is down. It won’t restore the state if more time has passed than you want. The default is 15 minutes.
Can you explain the design reasoning for restore_timeout? Based on its described functionality, it appears to be a ‘grace period’ for expiration. If a timer’s duration expired before Home Assistant restarted, this option allows for an extension of the duration. Please correct me if I’ve misinterpreted it.
What sort of timer applications do you envision would allow their duration to be extended? My point being that if I create a 30-minute timer, under what circumstances would it be acceptable to let it run for up to an additional (say) 15 minutes?
Any thoughts of making a Pull Request to incorporate your timer enhancements into the main code-base?
Yes. It is a grace period. Maybe that is a better name for it. When I was writing up the readme, I was thinking that restore_timeout might be a little confusing. restore_grace_period might be better.
So in my situation, I am setting up a timer to turn something off. If HA restarts during the time that it should have finished, I still want that something to turn off. Unless it’s like the next day or something, because I’ve probably manually intervened by that time. It will only be delayed for an additional 15 minutes late if HA was not available during that time to execute the finished event and trigger your automation. When HA starts up, the event will be triggered immediately. If HA was down for too long, then the event will be ignored.
Yeah, it would be awesome if it was accepted as a Pull Request… I just have no idea how to go about doing that. Do I fork the repo first? My experience with git is in small groups or by myself where I just create a branch and merge it. I don’t have the permissions to create a branch on the main repo.
It would be awesome if you could get this merged to core. I believe you do fork the HA repo, create a branch with your changes and then create a PR to the main repo, linking your fork branch. Someone else will correct me if I have that wrong
@123 Thanks for the inspiration. I changed the name of restore_timeout to restore_grace_period. Hopefully that is clearer for anyone who wants to use this.
Also thanks for the encouragement for submitting the pull request. That means a lot coming from you. I see you all over this forum. I don’t mean to take anything away from your solution. I had already started looking at the base code when you posted your solution and wanted to see if I could get it working, plus I thought it would be a cleaner solution.
I still need to look into writing the automated tests. I got slammed with a bunch of other things and haven’t had the time… It’s still on my todo list. :-/
A simpler solution that splits the decision about restarting to the timer consumer is as follows.
(Also needs a PR to timer)
For the timer add a state attribute: ExpectedEventAt
This is set to the time when the timer should expire.
If the timer is paused this should be set to None
When it is continued it should be set to the ExpectedEventAt based on remaining time.
When the timer expires it should be set to None
If a restart happens the user of the timer can see if the timer was active and based on the ExpectedEventtAt time could decide:
Ignore - i.e your grace time use case.
Restart the timer with the time needed to reach the new orignal ExpectedEventAt time.
Call the actions you would normally do when the timer expired.
I just looked at the code … the state of the timer (which is persistent unless you have an inital value)
has an attribute:
finishes_at=2021-07-15T01:40:02+00:00
Whis is what I called the ExpetedEvetAt time.
FWIW, I posted a means of automatically saving and restoring active/paused timers (employs two automations):
It uses last_changed and remaining (available for both active and paused timers) to determine how much longer the timer should run after Home Assistant is restarted again.
Normally, it won’t restart a timer whose duration expired while Home Assistant was offline. However, to satisfy requests to modify this behavior, near the end of the thread I offered a modification that allows even expired timers to be restarted for just one second so that they’re allowed to generate a ‘finished’ event (and trigger any associated automation listening for that event).
Personally, I don’t use many timers, and the host machine is protected by a UPS, but I do use this system to ensure active timers are restored.