From 3ef8177f40bda44e29270e16547f3c92c5ecdaf4 Mon Sep 17 00:00:00 2001 From: JezerM Date: Mon, 2 Aug 2021 10:22:51 -0600 Subject: [PATCH] Added fallback on acpi_listen error or termination --- web-greeter/bridge/__init__.py | 2 + web-greeter/utils/battery.py | 68 ++++++++++++++++++++++++++-------- 2 files changed, 55 insertions(+), 15 deletions(-) diff --git a/web-greeter/bridge/__init__.py b/web-greeter/bridge/__init__.py index d005d9e..7f5f11b 100644 --- a/web-greeter/bridge/__init__.py +++ b/web-greeter/bridge/__init__.py @@ -111,6 +111,8 @@ def user_to_dict(user): def battery_to_dict(battery): if (not battery): return dict() + if (len(battery._batteries) == 0): + return dict() return dict( name = battery.get_name(), level = battery.get_level(), diff --git a/web-greeter/utils/battery.py b/web-greeter/utils/battery.py index ae6e2de..a7e6e35 100644 --- a/web-greeter/utils/battery.py +++ b/web-greeter/utils/battery.py @@ -6,6 +6,26 @@ import math from threading import Thread import time +from logging import ( + getLogger, + DEBUG, + Formatter, + StreamHandler, +) + +log_format = ''.join([ + '%(asctime)s [ %(levelname)s ] %(filename)s %(', + 'lineno)d: %(message)s' +]) +formatter = Formatter(fmt=log_format, datefmt="%Y-%m-%d %H:%M:%S") +logger = getLogger("battery") +logger.propagate = False +stream_handler = StreamHandler() +stream_handler.setLevel(DEBUG) +stream_handler.setFormatter(formatter) +logger.setLevel(DEBUG) +logger.addHandler(stream_handler) + running = False class Battery: @@ -24,7 +44,7 @@ class Battery: def __init__(self): if self._batteries.__len__() == 0: scandir_line(self.pspath, self._update_batteries) - start_timer(self.full_update) + start_timer(self.full_update, self.onerror) self.full_update() def connect(self, callback): @@ -33,6 +53,11 @@ class Battery: def disconnect(self, callback): self.callbacks.remove(callback) + def onerror(self): + self._batteries = [] + for cb in self.callbacks: + cb() + def _update_batteries(self, line): bstr = re.match(r"BAT\w+", line) if bstr: @@ -163,18 +188,31 @@ class Battery: def get_watt(self): return self.watt -def acpi_listen(callback): - main = subprocess.Popen(shlex.split("acpi_listen"), stdout=subprocess.PIPE, text=True) - awky = subprocess.Popen(shlex.split("grep --line-buffered -E 'battery|ac_adapter'"), - stdout=subprocess.PIPE, stdin=main.stdout, text=True) - while True: - output = awky.stdout.readline() - if output == "" and awky.poll() != None: - break - if output: - callback() - rc = main.poll() - return rc +acpi_tries = 0 + +def acpi_listen(callback, onerror): + global acpi_tries + try: + main = subprocess.Popen(shlex.split("acpi_listen"), + stdout=subprocess.PIPE, text=True) + awky = subprocess.Popen(shlex.split("grep --line-buffered -E 'battery|ac_adapter'"), + stdout=subprocess.PIPE, stdin=main.stdout, text=True) + while True: + output = awky.stdout.readline() + if output == "" and awky.poll() != None: + break + if output: + callback() + logger.warning("acpi_listen terminated") + if acpi_tries < 5: + acpi_tries += 1 + logger.debug("Restarting acpi_listen") + return acpi_listen(callback, onerror) + else: + raise Exception("acpi_listen exceeded 5 restarts") + except Exception as err: + logger.error("Battery error: " + err.__str__()) + onerror() def scandir_line(path, callback): main = subprocess.Popen(shlex.split("ls -1 {}".format(path)), @@ -204,7 +242,7 @@ def tonumber(asa): except Exception: return None -def start_timer(callback): - thread = Thread(target = acpi_listen, args=(callback,)) +def start_timer(callback, onerror): + thread = Thread(target = acpi_listen, args=(callback, onerror,)) thread.daemon = True thread.start()