Keep running even when connection is down

This commit is contained in:
Mike Cifelli 2021-05-25 11:59:19 -04:00
parent c9195b13cf
commit 9d6be61051
2 changed files with 84 additions and 22 deletions

View File

@ -1,6 +1,8 @@
#! /usr/bin/env python3 #! /usr/bin/env python3
import os import os
import sys
from string import Template from string import Template
from subprocess import check_call from subprocess import check_call
@ -12,7 +14,8 @@ CURRENT_DIR = os.path.dirname(os.path.realpath(__file__))
EXEC_PATH = os.path.join(CURRENT_DIR, EXEC) EXEC_PATH = os.path.join(CURRENT_DIR, EXEC)
SERVICE_TEMPLATE = os.path.join(CURRENT_DIR, SERVICE) SERVICE_TEMPLATE = os.path.join(CURRENT_DIR, SERVICE)
SERVICE_FILE = os.path.join(SYSTEM_DIR, SERVICE) SERVICE_FILE = os.path.join(SYSTEM_DIR, SERVICE)
EXEC_START = f'python3 {EXEC}' PYTHON = sys.executable
EXEC_START = f'{PYTHON} {EXEC}'
with open(SERVICE_TEMPLATE) as f: with open(SERVICE_TEMPLATE) as f:
serviceTemplate = Template(f.read()) serviceTemplate = Template(f.read())

View File

@ -3,30 +3,89 @@ from subprocess import CalledProcessError, check_output
from sys import exit from sys import exit
from time import sleep from time import sleep
INITIAL_DELAY_IN_SECONDS = 40
PING_INTERVAL_IN_SECONDS = 80 PING_INTERVAL_IN_SECONDS = 80
signal(SIGTERM, lambda signum, frame: exit(0))
class WifiKeepalive:
def getDefaultRoute(): def __init__(self):
routes = check_output(['route', '-n']).decode('utf-8').splitlines() self.defaultRoute = self.getDefaultWifiRoute()
defaults = [r.split()[1] for r in routes if r.startswith('0.0.0.0')] self.initialDelay = INITIAL_DELAY_IN_SECONDS
self.pingInterval = PING_INTERVAL_IN_SECONDS
self.isConnected = True
self.pingCommand = 'ping -c 1 -W 2 -n'
def run(self):
sleep(self.initialDelay)
while self.isRunning():
self.keepalive()
sleep(self.pingInterval)
def isRunning(self):
return True
def keepalive(self):
if self.defaultRoute:
self.pingDefaultRoute()
else:
self.attemptWifiConnection()
def pingDefaultRoute(self):
if not self.isConnected:
print('Connected to Wifi', flush=True)
self.isConnected = True
isPingSuccess = self.ping()
if not isPingSuccess:
self.defaultRoute = self.getDefaultWifiRoute()
def attemptWifiConnection(self):
if self.isConnected:
print('No Wifi Connection', flush=True)
self.isConnected = False
self.defaultRoute = self.getDefaultWifiRoute()
def ping(self):
try:
check_output([*self.pingCommand.split(), self.defaultRoute])
except CalledProcessError as e:
return False
return True
def getDefaultWifiRoute(self):
defaults = [
r['gateway'] for r in self.getRoutes() if self.isDefaultWifiRoute(r)
]
return defaults[0] if defaults else None return defaults[0] if defaults else None
def getRoutes(self):
outputLines = check_output(
['route', '-n']
).decode('utf-8').splitlines()[2:]
def keepalive(defaultRoute): routes = map(lambda r: self.parseRoute(r), outputLines)
while True:
sleep(PING_INTERVAL_IN_SECONDS) return routes
ping(defaultRoute)
def parseRoute(self, routeLine):
destination, gateway, _, _, _, _, _, interface = routeLine.split()
return {'destination': destination, 'gateway': gateway, 'interface': interface}
def isDefaultWifiRoute(self, route):
return route['destination'] == '0.0.0.0' and route['interface'].startswith('w')
def ping(address): def main():
try: signal(SIGTERM, lambda s, f: exit(0))
check_output(['ping', '-c', '1', address]) WifiKeepalive().run()
except CalledProcessError as e:
pass
defaultRoute = getDefaultRoute() if __name__ == '__main__':
keepalive(defaultRoute) if defaultRoute else print('No default route') main()