NOTE
This post is now deprecated and I am no longer supporting its code.
It is replaced by a new approach that doesn’t use a python_script and employs script enhancements that were introduced since this post was first created in November 2019.
Please refer to the new version presented here:
Deprecated post.
BugFix 1:
2020-06-07
The first automation failed to restore timers whose duration exceeded 24 hours. Durations of 24 hours or more appear in this format: 2 days, 6:30:00
as opposed to 54:30:00
. The automation’s template has been enhanced and now properly handles durations expressed in days.
Introduction
Active timers don’t survive a restart of Home Assistant. On startup, previously active
timers are set to idle
and so they don’t resume their (interrupted) countdown.
Here’s a way to automatically resume active timers upon startup. It is suitable for timers whose duration is several minutes or longer (i.e. duration is longer than the time it takes your Home Assistant instance to restart). It consists of:
- One input_text to store the state of all active timers.
- Two automations. One stores the state of active timers. The other resumes them at startup.
- One python_script to perform the actual resuming of active timers.
Step 1 - Input_Text
Create this input_text in your configuration.yaml file:
input_text:
active_timers:
name: Active Timers
Step 2 - Automations
Add the following two automations to wherever you keep them (configuration.yaml or automations.yaml).
The first automation is executed whenever a timer changes state and saves the states of all active timers. This automation requires customization:
- Replace the trigger’s entities with the names of your own timers.
- alias: 'Active Timers Save'
trigger:
platform: state
entity_id:
- timer.timer1
- timer.timer2
- timer.timer3
action:
- service: input_text.set_value
data_template:
entity_id: input_text.active_timers
value: >
{% set ns = namespace(timers = '') %}
{% for t in states.timer | selectattr('state', 'eq', 'active') | list %}
{% set d = t.attributes.duration.split(':') %}
{% if 'day' in d[0] %}
{% set z = d[0].split(', ') %}
{% set h = ((z[0].split()[0] | int) * 24 + (z[1].split(':')[0] | int)) * 3600 %}
{% else %}
{% set h = d[0] | int * 3600 %}
{% endif %}
{% set s = h + (d[1]|int*60) + (d[2]|int) %}
{% set c = ',' if not loop.first else '' %}
{% set ns.timers = ns.timers ~ '{}{} {}'.format(c, t.object_id, t.last_changed.timestamp()|int + s) %}
{% endfor %}
{{ ns.timers }}
NOTE:
The first automation assumes you wish to save/resume all your timers. If you want it to be selective, let me know and I’ll explain how to modify it. Please be aware that simply excluding a timer from the trigger’s entity list is insufficient (because the action’s template is designed to get all active timers, whether you list them in the trigger
or not).
The second automation is triggered at startup and calls the python_script to resume all (previously) active timers.
- alias: 'Active Timers Resume'
trigger:
platform: homeassistant
event: start
action:
service: python_script.active_timers_resume
Step 3 - Python_Script
If you currently do not use the python_script integration, you will have to install it first (it’s easy). Full instructions can be found in its documentation. Here are the basic steps:
- Add
python_script:
to yourconfiguration.yaml
file. - Create the following sub-directory:
config/python_scripts
- Restart Home Assistant.
Create a new file in config/python_scripts
called active_timers_resume.py
with the following contents:
ts = hass.states.get('input_text.active_timers')
if ts is not None and ts.state != 'unknown' and ts.state != '':
timers = ts.state.split(',')
for t in timers:
z = t.split()
duration = int(z[1]) - int(datetime.datetime.now().timestamp())
if duration > 0:
service_data = {'entity_id': 'timer.{}'.format(z[0]), 'duration':'{}'.format(duration)}
hass.services.call('timer', 'start', service_data, False)
Step 4 - Testing
Restart Home Assistant and perform a test:
- Start a timer with a
duration
of 2 minutes (more if it takes a long time for your instance of Home Assistant to restart). - After you’ve confirmed the timer is running, restart Home Assistant.
- After it restarts, check the timer in the States page. It should be
active
and have a shorterduration
.
FWIW, I’ve performed the test a few times and confirmed all active timers are resumed (with shorter durations, of course).
NOTE:
There is one caveat when using this save/resume system. After a restart, active timers are resumed with a new, shorter duration, representing the balance of their original duration. So if the timer’s duration was originally 5 minutes and it was interrupted at the 4 minute mark, it will resume at 4 minutes (minus whatever time it took for Home Assistant to restart). In other words, its new default duration is now 4 minutes. So the next time you start this timer, you will have to set its duration back to 5 minutes otherwise it will use 4 minutes.