Close

A better cut at the watchdog script

A project log for Reboot-o-matic

Automatic power-cycling made safer

Nick SayerNick Sayer 10/24/2019 at 15:570 Comments

I thought of a couple of issues with the first script.

If the router is performing a firmware update, the internet may be unreachable for 10 minutes or so, and it would be a disaster to power-cycle the router then. So the script should keep trying for a solid hour to reach an external host before giving up.

I've also expanded the list of hosts. These are all public DNS servers. Again, using them as ping targets is probably not what their owners had in mind, but the script as written is being very gentle (and answering a ping is a lot less work than answering a DNS query). As long as you only run this no more than once every 6 hours or so (and as long as everybody and their brother doesn't run it), I would think it would be acceptable.

#!/usr/bin/python

import RPi.GPIO as GPIO
import sys
import time
import subprocess
import os
import random

hosts = ["1.1.1.1", "1.0.0.1", "8.8.8.8", "8.8.4.4", "8.26.56.26", "8.20.247.20", "9.9.9.9", "149.112.112.112", "64.6.64.6", "64.6.65.6"]
random.shuffle(hosts)

FNULL = open(os.devnull)

start = time.time()
while True:
    for host in hosts:
        res = subprocess.call(["ping", "-c", "3", "-W", "5", host], stdout=FNULL, stderr=FNULL)
        if (res == 0):
            print(host + " is up.")
            sys.exit(0) # it worked. Bail
        else:
            print(host + " is down.")
    if time.time() - start > 60*60:
        break
    time.sleep(5 * 60) # wait 5 minutes

print "All hosts unreachable for 60 minutes - resetting router"

# physical pin 7
reset_pin = 4

# Perform the reset operation
GPIO.setmode(GPIO.BCM)
GPIO.setup(pin, GPIO.OUT, initial=GPIO.LOW)
time.sleep(2)
GPIO.cleanup()

sys.exit(1)

Discussions