Keep running even when connection is down
This commit is contained in:
parent
c9195b13cf
commit
9d6be61051
5
install
5
install
|
@ -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())
|
||||||
|
|
|
@ -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()
|
||||||
|
|
Loading…
Reference in New Issue