Re-trigger automation without state change

I’ve router restart automation. However, the issue is if the re-start doesn’t restore internet, I want the automation to run again as the ping sensor continued to be in state of off. The following automation doesn’t do that but runs only once in the first failure (when the state changed to ‘off’ for the first time). How to fix this so for example … may be after 5 mins it should again do the restart if the ping has not be restored

alias: Restart Router if Internet down
description: ""
trigger:
  - platform: state
    entity_id:
      - binary_sensor.ping_google
    to: "off"
    for:
      hours: 0
      minutes: 0
      seconds: 10
condition:
  - condition: state
    entity_id: binary_sensor.ping_isp_gateway
    state: "off"
    for:
      hours: 0
      minutes: 0
      seconds: 10
action:
  - service: switch.turn_off
    data: {}
    target:
      entity_id: switch.router_switch
  - delay:
      hours: 0
      minutes: 0
      seconds: 10
      milliseconds: 0
  - service: switch.turn_on
    data: {}
    target:
      entity_id: switch.router_switch
  - alias: "Call a service 'Notifications: Send a notification with sms on xxxx"
    service: notify.sms
    data:
      message: Router restart automation completed
      target: +xxxx
mode: single

I would duplicate the PING as OFF into condition, create another input boolean to set ON at the end of initial automation run, and also trigger on the same input boolean when it is on for 5 minutes.
(input boolean is off state initially)
automation

  • trigger: input boolean as on for 60 seconds, ping is off for 10 seconds
  • condition: ping is off
  • action: toogle input boolean, restart router

I sort of understood the concept but went over couple of times how to code the logic… but… would you please able to update my code

You don’t need to re-run the entire automation. In your action section, you can have a repeat: with while: and you can loop the router turn off/on sequence while the ping sensor stays off.

The example in the documentation even shows a method to limit the number of times that the sequence is repeated so that you don’t indefinitely reboot your router if it isn’t solving the problem.

I created another automation to call the first if it remains in the state every minute. Is this better than the loop as with loop I won’t be able to control how quickly the routine should run or with that be through the delay (to be added) at the end of automation?

alias: Test
description: ""
trigger:
  - platform: time_pattern
    minutes: /2
condition:
  - alias: Google ping remained off for at least 2 mins
    condition: state
    entity_id: binary_sensor.ping_google
    state: "off"
    for:
      hours: 0
      minutes: 1
      seconds: 0
action:
  - service: automation.trigger
    data:
      skip_condition: true
    target:
      entity_id: automation.restart_router_if_ping_fails

Why do you think you have more control over timing and delays by triggering another automation?

The delays that you’d add inside the while: loop are the same delays that you have in your automation already.

Generally, forcing the execution of an automation is bad practice. If you need to run some set of actions on demand, those actions should be a script not an automation.

Another comment on your original code: how often do your ping sensors update? If they don’t update faster than every 10 seconds, there’s no need for the 10 second for: clause in your automation. And if the Google and isp_gateway sensors both have the same refresh rate, having the same for: of 10 seconds on each is going to leave you with a race condition where the gateway sensor may not quite have reached 10 seconds when the condition is checked, and your automation never runs.

Ok, tried the while loop, isn’t triggering ???

alias: New automation
description: ""
trigger:
  - platform: state
    entity_id:
      - binary_sensor.ping_google
    to: "off"
    for:
      hours: 0
      minutes: 0
      seconds: 10
condition:
  - condition: state
    entity_id: binary_sensor.ping_isp_gateway
    state: "off"
    for:
      hours: 0
      minutes: 0
      seconds: 10
action:
  - service: switch.turn_off
    data: {}
    target:
      entity_id: switch.router_switch
  - delay:
      hours: 0
      minutes: 0
      seconds: 10
      milliseconds: 0
  - service: switch.turn_on
    data: {}
    target:
      entity_id: switch.router_switch
  - alias: "Call a service 'Notifications: Send a notification with sms on xx"
    service: notify.sms
    data:
      message: Router restart automation completed
      target: xx
  - repeat:
      sequence:
        - service: switch.turn_off
          data: {}
          target:
            entity_id: switch.router_switch
        - delay:
            hours: 0
            minutes: 0
            seconds: 10
            milliseconds: 0
        - service: switch.turn_on
          data: {}
          target:
            entity_id: switch.router_switch
        - alias: >-
            Call a service 'Notifications: Send a notification with sms on
            xx
          service: notify.sms
          data:
            message: Router restart automation completed
            target: xx
      while:
        - condition: state
          entity_id: binary_sensor.ping_google
          state: "off"
          for:
            hours: 0
            minutes: 0
            seconds: 30
mode: single

You could just duplicate the trigger:

alias: Restart Router if Internet down
description: ""
trigger:
  - platform: state
    entity_id:
      - binary_sensor.ping_google
    to: "off"
    for:
      hours: 0
      minutes: 0
      seconds: 10
  - platform: state
    entity_id:
      - binary_sensor.ping_google
    to: "off"
    for:
      hours: 0
      minutes: 0
      seconds: 60 # or however long it takes your router to restart.
condition:
  - condition: state
    entity_id: binary_sensor.ping_isp_gateway
    state: "off"
    for:
      hours: 0
      minutes: 0
      seconds: 10
action:
  - service: switch.turn_off
    data: {}
    target:
      entity_id: switch.router_switch

What is turning the switch back on?

Hey Tom,
Your double trigger is working… but it triggers twice only. I want to make it better so it should restart multiple attempts as Rick suggested but the while loop is not working.

1 Like

Your race condition observation was a good point, while family at home can’t actually disconnect internet to test it so I was forcing it via Dev tool to change the sensor state and in one instance I wasn’t fast enough (within 10 secs) and the automation didn’t trigger :frowning:

Triggering has nothing to do with the while loop. I think you mean to say the actions within the while loop are not being executed? That would be because you set the conditions to only execute the loop while the sensor has been on for 30 seconds, yet you trigger the automation (and therefore first test that condition) when it has only been on for 10 seconds.


alias: New automation
description: ""
trigger:
  - platform: state
    entity_id:
      - binary_sensor.ping_google
    to: "off"
    for:
      hours: 0
      minutes: 0
      seconds: 10
condition:
  - condition: state
    entity_id: binary_sensor.ping_isp_gateway
    state: "off"
    for:
      hours: 0
      minutes: 0
      seconds: 10
action:
  - repeat:
      sequence:
        - service: switch.turn_off
          data: {}
          target:
            entity_id: switch.router_switch
        - delay:
            hours: 0
            minutes: 0
            seconds: 10
            milliseconds: 0
        - service: switch.turn_on
          data: {}
          target:
            entity_id: switch.router_switch
        - alias: >-
            Call a service 'Notifications: Send a notification with sms on
            xx
          service: notify.sms
          data:
            message: Router restart automation completed
            target: xx
        - delay:
            hours: 0
            minutes: 0
            seconds: 60
            milliseconds: 0
      while:
        - condition: state
          entity_id: binary_sensor.ping_google
          state: "off"
mode: single

1 Like

Here’s what I would recommend; this changes your triggers and conditions so that you don’t have to worry about any race conditions, and this exits out of the router restart loop after 20 attempts. It will notify you and will let you know if it was successful.

alias: New automation
description: ""
trigger:
  - platform: state
    entity_id:
      - binary_sensor.ping_google
      - binary_sensor.ping_isp_gateway
    to: "off"
    for:
      hours: 0
      minutes: 0
      seconds: 10
condition:
  - condition: state
    entity_id:
      - binary_sensor.ping_google
      - binary_sensor.ping_isp_gateway
    state: "off"
    for:
      hours: 0
      minutes: 0
      seconds: 10
action:
  - repeat:
      sequence:
        - service: switch.turn_off
          data: {}
          target:
            entity_id: switch.router_switch
        - delay:
            hours: 0
            minutes: 0
            seconds: 10
            milliseconds: 0
        - service: switch.turn_on
          data: {}
          target:
            entity_id: switch.router_switch
        - delay:
            hours: 0
            minutes: 0
            seconds: 60
            milliseconds: 0
      while:
        - condition: state
          entity_id: binary_sensor.ping_google
          state: "off"
        - condition: template
          value_template: "{{ repeat.index <= 20 }}"
  - if:
      - condition: state
        entity_id: binary_sensor.ping_google
        state: "off"
    then:
      - alias: >-
          Call a service 'Notifications: Send a notification with sms on
          xx
        service: notify.sms
        data:
          message: Router restart automation stopped after 20 attempts
          target: xx
    else:
      - alias: >-
          Call a service 'Notifications: Send a notification with sms on
          xx
        service: notify.sms
        data:
          message: Router restart automation completed
          target: xx
mode: single

Just tested… it worked. Thanks :+1:,
Battery dying will test the improved solution later and then accept this or the later one as a solution.