Catch up on missed triggers following a restart?

I’ve been making lots of changes to my configuration lately and I’ve run into several situations where my time-based triggers don’t fire because the system is busy at exactly the "at: " time. I’m migrating from an ISY994 that had a “catch up x mins” option following a reboot that would run any triggers that may have been missed, but I haven’t seen an option like that in Home Assistant and I can only think of a couple of ways to do it:

  • Add a script for each time-based automation that checks “after: xxx” and triggers the appropriate automation, all to be run on homeassistant.start
  • Arbitrarily add some more trigger conditions for +2 mins, +4 mins, etc. to make sure that I catch up eventually

Both seem a little hokey to me. Is there a better way?

My Z-Wave network takes 2-3 minutes to come up following a reboot, so it’s pretty easy to miss triggers during that time, especially when they’re based on sunset or bedtime.

1 Like

I don’t think it’s possible. How would HA know that a trigger should have fired while it was off?
If your triggers are only based on time (i.e. not based on a device behaviour) then you could create an automation / script that runs all automations that are time triggered at HA start.
your startup automation will look something like this:

- alias: Run Time Based Automations at HA Start
  initial_state: true
  trigger:
    - platform: homeassistant
      event: start
  action:
  - service: automation.trigger
    data:
      entity_id: automation.automation_alias

I know that it can’t accurately predict what should have run and didn’t, but it would be helpful to have a configurable “catch up” timer that basically goes back in time and triggers (or re-triggers) automations whose triggers are “close”. I think your program would just indiscriminately run anything regardless of whether it should have run a minute ago or should run 5 hours from now, so it would lead to all sorts of unexpected behavior. For instance, I have an automation that turns on a light around sunset and it only makes sense to execute that if it’s in close proximity to sunset. Turning lights off at random times would be equally wrong.

I don’t have a lot of time-triggered automations, so I’m leaning toward adding scripts with time-based conditions that run at startup.

Just how often are you rebooting your production system to need a “catch up” timer???

I’m still building my “production system”, and every time I add or modify something in configuration.yaml or need to re-discover something, I need to restart HASS. I’m sure that it’ll go down over time, and not having a light turn on or off isn’t the end of the world, but I’m always looking for more automation and reliability. It may not be a big deal for folks who have had their systems up and running for years, but I’m only three weeks in and learning by doing :).

Most recently, I’ve been trying to get attractive and functional Lovelace views working and that’s required lots of template experiments, which I don’t think can be reloaded dynamically. Before that, it was getting presence working well, and before that it was adding ISY994, Elk, etc.

Not even a “catch-up”, but just to still be able to execute triggers based on timers and “state since [time]” that haven’t happened yet, but Home Assistant was restarted between the initial trigger and the end time.

My bathroom fan hasn’t turned off several times, because I restarted HA :slight_smile:

Yep :). The ISY allows me to write a program like:

if time is between x and y, turn on light

and then I can mark that program “run on startup”, where it will evaluate the “if” clause and do the right thing if it’s within that time period. That’s really preferable to an indiscriminate “catch up” window, and doesn’t require any additional coding.

The more I think about it, I think I can just add a conditions clause with “after” and “before” in each time-based automation and add the homeassistant/start trigger. That way, it would pass the condition if the trigger fires as expected, and would also do the right thing if Hass is restarted. It just won’t cover that small period of time when I’m reloading automations (a second or less).

That raises the question: are “after” and “before” conditions inclusive of the exact time? In other words, will the following pass at 15:00 and at 02:00 (from the Conditions example)?

condition:
  condition: time
  after: '15:00:00'
  before: '02:00:00'

It sounds like the answer is “yes”, based on the later verbiage:

In the example above, the condition window is from 3pm to 2am.

Here’s an example that I think should work. Original automations:

- id: 'Espresso Machine on'
  alias: Espresso machine on
  initial_state: true
  trigger:
    - platform: time
      at: '05:30:00'
  condition: []
  action:
    - data:
        entity_id: switch.dnh_espresso_machine
      service: switch.turn_on

- id: 'Espresso Machine off'
  alias: Espresso machine off
  initial_state: true
  trigger:
    - platform: time
      at: '12:00:00'
  condition: []
  action:
    - data:
        entity_id: switch.dnh_espresso_machine
      service: switch.turn_off

Conditions added to do the right thing on restart:

- id: 'Espresso Machine on'
  alias: Espresso machine on
  initial_state: true
  trigger:
    - platform: time
      at: '05:30:00'
    - platform: homeassistant
      event: start
  condition:
    - condition: time
      after: '05:30:00'
    - condition: time
      before: '12:00:00'
  action:
    - data:
        entity_id: switch.dnh_espresso_machine
      service: switch.turn_on

- id: 'Espresso Machine off'
  alias: Espresso machine off
  initial_state: true
  trigger:
    - platform: time
      at: '12:00:00'
    - platform: homeassistant
      event: start
  condition:
    - condition: time
      after: '12:00:00'
  action:
    - data:
        entity_id: switch.dnh_espresso_machine
      service: switch.turn_off

Does that seem sane? I originally had a single automation that used the trigger to decide what do, but I can’t rely on that anymore and had to break it up into two more explicit automations.

To answer my own question about the inclusive nature of “after:”, yes, this works fine:

- id: 'test'
  alias: test
  initial_state: true
  trigger:
    - platform: time
      at: '15:20:00'
  condition:
    condition: time
    after: '15:20:00'
  action:
    - data:
        title: test
        message: 'test'
      service: notify.pushover

I think you’ll need to split that into 2 conditions… one after 15 and another before2. Things spanning days (midnight) don’t work in one condition.

Yeah, I thought that was weird, but it’s just the example from here. None of my programs have weird day-crossings like that.

Gaaaaa… I wonder if that’s changed… seems you CAN do this. Oops!

That’s funny. I never trusted that condition either. I always made two separate time conditions. Glad to hear it works as expected.

Proving that it actually works is left as an exercise for the reader, but at least the documentation says that it should.

1 Like

I played around with this more today and found that the following wasn’t reliable for my Z-Wave devices:

- platform: homeassistant
  event: start

It would trigger and try to control a Z-Wave device, but the trigger always happened just before Z-Wave component started and the command didn’t go through. I could probably add a short delay and get it to work, but I settled on this instead:

- platform: event
  event_type: zwave.network_ready

It takes 2-3mins for my Z-Wave network to become “ready”, but this is just a failsafe. There may be other devices that won’t work right away, so keep that in mind if you’re looking for an appropriate trigger.

I’m looking for this same feature that existed in my old HomeSeer system that’s called ‘Power Failure Recovery Settings’ (link below). The premise is fairly simple. Specify a number of hours to go back and run any time based triggers that fall within that timeframe.

https://forums.homeseer.com/forum/hs4-products/hs4-plugins/lighting-primary-technology-plug-ins-aa/mns-insteon-mnsandler/1554302-still-trying-to-understand-include-power-fail-recovery?p=1554359#post1554359

I’ve realized that this is now a more needed feature. I have the following automation that will not run if the trigger has been missed. Not even if manually ran. This is due to the the fact that the trigger IDs will never be met until the next day!

alias: Lighting - Porch Patio String
description: ""
trigger:
  - platform: sun
    event: sunset
    id: sunset
  - platform: event
    event_type: timer.finished
    event_data:
      entity_id: timer.porch_patio_bbq_string
    id: PorchPatioStringOff
condition: []
action:
  - choose:
      - conditions:
          - condition: trigger
            id: sunset
        sequence:
          - service: light.turn_on
            data: {}
            target:
              entity_id:
                - light.porch_light
                - light.patio_string_lights
                - light.bbq_string_lights
          - service: timer.start
            data: {}
            target:
              entity_id: timer.porch_patio_bbq_string
      - conditions:
          - condition: trigger
            id: PorchPatioStringOff
        sequence:
          - service: light.turn_off
            data: {}
            target:
              entity_id:
                - light.bbq_string_lights
                - light.patio_string_lights
                - light.porch_light
mode: single