Reboot modem on Internet down

TL;DR: I’ve built the following “package” (Packages - Home Assistant) that detects if my Internet goes down and then reboots my modem until service is restored.

Rather than relying on a single Internet endpoint to determine if my connection is down, I’ve created 3x ping-based binary-sensors. If any one of them is unreachable for 1m AND the other 2 are also unreachable, my “reboot_modem” script is called. My modem is plugged into a z-wave plug.

The script turns off the plug, waits 30s, turns the plug back on and waits 2m. If the selected ping-based binary-sensor is still not connected, it repeats these events.

Question: My automation has all 3 ping-based binary-sensors as triggers. In my mind, this means that if the Internet does go down, this automation would be called 3x and the script could also be running 3 versions? What is the best way to put a “lock” on the script to ensure only a single instance of it runs? I did find a custom component that creates a variable (GitHub - snarky-snark/home-assistant-variables: A custom Home Assistant component for declaring and setting generic variable entities dynamically.). I would set/unset this at the start and end of the script. Would appreciate any other thoughts on this.

binary_sensor:
  - platform: ping
    name: Google
    host: 8.8.8.8
    scan_interval: 5

  - platform: ping
    name: Cloudflare
    host: 1.1.1.1
    scan_interval: 5

  - platform: ping
    name: Quad9
    host: 9.9.9.9
    scan_interval: 5

automation:
  - alias: internet down
    description: "internet down call script to reboot modem"
    mode: single
    trigger:
      - platform: state
        entity_id:
          - binary_sensor.google
          - binary_sensor.cloudflare
          - binary_sensor.quad9
        from: "on"
        to: "off"
        for:
          hours: 0
          minutes: 1
          seconds: 0
    condition:
      - condition: and
        conditions:
          - condition: state
            entity_id: binary_sensor.google
            state: "off"
          - condition: state
            entity_id: binary_sensor.cloudflare
            state: "off"
          - condition: state
            entity_id: binary_sensor.quad9
            state: "off"
    action:
      - service: script.reboot_modem
        data: {}

script:
  reboot_modem:
    alias: reboot modem every 2m until connected
    sequence:
      - service: switch.turn_off
        data: {}
        target:
          entity_id: switch.modem_plug
      - delay:
          hours: 0
          minutes: 0
          seconds: 30
          milliseconds: 0
      - service: switch.turn_on
        data: {}
        target:
          entity_id: switch.modem_plug
      - delay:
          hours: 0
          minutes: 2
          seconds: 0
          milliseconds: 0
      - repeat:
          until:
            - condition: state
              entity_id: binary_sensor.cloudflare
              state: "on"
          sequence: []
    mode: single

2 Likes

Have you considered using a binary sensor group that way you could set the group to be ‘all’ therefore all pings have to be down for automation to run.

Also are you sure your router is capable of powering up, booting, negotiating and establishing an internet connection and HA reliably pinging all 3 in only 2 minutes? As my router can take at least 5 mins for this to all take place.

1 Like

I had not… that fits this perfectly! In my inline comments I noted how a group responds to a single/multiple entity being on/off. In this case, the group will only turn “off” when all of the ping sensors fail (exactly what I wanted). Similarly, it will turn “on” when one of the ping sensors succeeds – this my condition for exiting the repeat on the script.

Here is my revised “package”.

binary_sensor:
  - platform: ping
    name: Google
    host: 8.8.8.8
    scan_interval: 5

  - platform: ping
    name: Cloudflare
    host: 1.1.1.1
    scan_interval: 5

  - platform: ping
    name: Quad9
    host: 9.9.9.9
    scan_interval: 5
    
group:
  # group state is 'on' if at least one member is on
  # otherwise group state is 'off'
  internet_ping:
    entities:
      - binary_sensor.google
      - binary_sensor.cloudflare
      - binary_sensor.quad9  

automation:
  - alias: internet down
    description: "internet down call script to reboot modem"
    mode: single
    trigger:
      - platform: state
        entity_id:
          - group.internet_ping 
        from: "on"
        to: "off"
        for:
          hours: 0
          minutes: 1
          seconds: 0
    action:
      - service: script.reboot_modem
        data: {}

script:
  reboot_modem:
    alias: reboot modem every 2m until connected
    sequence:
      - service: switch.turn_off
        data: {}
        target:
          entity_id: switch.modem_plug
      - delay:
          hours: 0
          minutes: 0
          seconds: 30
          milliseconds: 0
      - service: switch.turn_on
        data: {}
        target:
          entity_id: switch.modem_plug
      - delay:
          hours: 0
          minutes: 3
          seconds: 0
          milliseconds: 0
      - repeat:
          until:
            - condition: state
              entity_id: group.internet_ping
              state: "on"
          sequence: []
    mode: single
2 Likes

Did something similar… Seems to work =)

Using a Zigbee smartplug that the router sits on since my router sometimes cracks up and freezes wifi. I have a bunch of Shelly plugs but not for this…

Added the Ping integration in HA. Added 3 binary ping sensors like above - Google, Cloudflare, Quad. Then created a group for those 3 sensors and if any sensor is up / has internet connectivity / can ping its host then there is connectivity. Added an automation on top of that which trigs on the group going from Connected to Unconnected for more than 60s, which then toggles the Zigbee smartplug to restart the router.

Zigbee smartplug configured to always start with power after a power failure.





4 Likes

Magical. Thank you!!!
1 question: did you use name or ip? like www.google.com or 8.8.8.8?

I used IP.

1 Like