diff --git a/python/meson.build b/python/meson.build index 8dcb557..7bb0407 100644 --- a/python/meson.build +++ b/python/meson.build @@ -5,7 +5,7 @@ project( ).stdout().strip('\n'), # 'online.fxreader.uv', # ['c', 'cpp'], - version: '0.1.5.27', + version: '0.1.5.28', # default_options: [ # 'cpp_std=c++23', # # 'prefer_static=true', diff --git a/python/online/fxreader/pr34/commands.py b/python/online/fxreader/pr34/commands.py index 280aafa..9bd2af5 100644 --- a/python/online/fxreader/pr34/commands.py +++ b/python/online/fxreader/pr34/commands.py @@ -2047,6 +2047,152 @@ def loginctl(argv: list[str]) -> None: raise NotImplementedError +class Battery: + def __init__( + self, + should_start=None, + ): + if should_start is None: + should_start = False + + assert isinstance(should_start, bool) + + self.last_check = None + self.period = 10 + self.is_running = should_start + + def check_is_needed(self): + now = datetime.datetime.now(tz=datetime.timezone.utc) + + is_needed = None + + if self.last_check is None: + is_needed = True + else: + if (now - self.last_check).total_seconds() >= self.period: + is_needed = True + else: + is_needed = False + + if is_needed: + self.last_check = now + + return is_needed + + def run(self): + while True: + self.check() + + time.sleep(self.period) + + def terminate(self): + self.is_running = False + + def wait(self, *args, **kwargs): + if self.is_running: + raise NotImplementedError + + def poll(self): + if self.is_running: + return None + else: + return 0 + + @property + def percentage_low(self) -> int: + try: + return int( + subprocess.check_output( + r""" + cat /etc/UPower/UPower.conf | grep -Po '^PercentageLow=\d+' + """, + shell=True, + ) + .decode('utf-8') + .strip() + .split('=')[1] + ) + except: + logger.exception('') + return 15 + + @property + def percentage_critical(self) -> int: + try: + return int( + subprocess.check_output( + r""" + cat /etc/UPower/UPower.conf | grep -Po '^PercentageCritical=\d+' + """, + shell=True, + ) + .decode('utf-8') + .strip() + .split('=')[1] + ) + except: + logger.exception('') + return 10 + + def check(self): + try: + if not self.check_is_needed(): + return + + t1 = subprocess.check_output( + ['upower', '-d'], + timeout=1, + ).decode('utf-8') + t2 = [o for o in t1.splitlines() if 'percentage' in o.lower()] + t4 = [o for o in t1.splitlines() if 'state' in o.lower()] + t3 = float(t2[0].split(':')[1].strip()[:-1]) + # t5 = any(['discharging' in o.lower() for o in t4]) + state = [[o2.strip() for o2 in o.lower().split()][1] for o in t4][1] + + t5 = state != 'charging' + # t5 = True + if t3 < self.percentage_critical: + logging.error( + json.dumps( + dict( + msg='too low', + t3=t3, + t5=t5, + state=state, + ) + ) + ) + if t5: + subprocess.check_call(['systemctl', 'suspend']) + elif t3 < self.percentage_low: + msg = 'battery near low' + logging.error( + json.dumps( + dict( + msg=msg, + t3=t3, + t5=t5, + state=state, + ) + ) + ) + if t5: + subprocess.check_call( + [ + 'notify-send', + '-t', + '%d' % (5 * 1000), + msg, + '% 5.2f' % t3, + ] + ) + else: + pass + print('\r%s % 5.2f%% %s' % (datetime.datetime.now().isoformat(), t3, str(t5)), end='') + except Exception: + logging.error(traceback.format_exc()) + + def desktop_services(argv): parser = optparse.OptionParser() parser.add_option( @@ -2185,127 +2331,6 @@ def desktop_services(argv): return len(t3) > 0 and t4 - class Battery: - def __init__( - self, - should_start=None, - ): - if should_start is None: - should_start = False - - assert isinstance(should_start, bool) - - self.last_check = None - self.period = 10 - self.is_running = should_start - - def check_is_needed(self): - now = datetime.datetime.now(tz=datetime.timezone.utc) - - is_needed = None - - if self.last_check is None: - is_needed = True - else: - if (now - self.last_check).total_seconds() >= self.period: - is_needed = True - else: - is_needed = False - - if is_needed: - self.last_check = now - - return is_needed - - def run(self): - while True: - self.check() - - time.sleep(self.period) - - def terminate(self): - self.is_running = False - - def wait(self, *args, **kwargs): - if self.is_running: - raise NotImplementedError - - def poll(self): - if self.is_running: - return None - else: - return 0 - - @property - def percentage_low(self) -> int: - try: - return int( - subprocess.check_output( - r""" - cat /etc/UPower/UPower.conf | grep -Po '^PercentageLow=\d+' - """, - shell=True, - ) - .decode('utf-8') - .strip() - .split('=')[1] - ) - except: - logger.exception('') - return 15 - - @property - def percentage_critical(self) -> int: - try: - return int( - subprocess.check_output( - r""" - cat /etc/UPower/UPower.conf | grep -Po '^PercentageCritical=\d+' - """, - shell=True, - ) - .decode('utf-8') - .strip() - .split('=')[1] - ) - except: - logger.exception('') - return 10 - - def check(self): - try: - if not self.check_is_needed(): - return - - t1 = subprocess.check_output( - ['upower', '-d'], - timeout=1, - ).decode('utf-8') - t2 = [o for o in t1.splitlines() if 'percentage' in o.lower()] - t4 = [o for o in t1.splitlines() if 'state' in o.lower()] - t3 = float(t2[0].split(':')[1].strip()[:-1]) - t5 = any(['discharging' in o.lower() for o in t4]) - if t3 < self.percentage_critical and t5: - logging.error(json.dumps(dict(msg='too low', t3=t3, t5=t5))) - subprocess.check_call(['systemctl', 'suspend']) - elif t3 < self.percentage_low and t5: - msg = 'battery near low' - logging.error(json.dumps(dict(msg=msg, t3=t3, t5=t5))) - subprocess.check_call( - [ - 'notify-send', - '-t', - '%d' % (5 * 1000), - msg, - '% 5.2f' % t3, - ] - ) - else: - pass - print('\r%s % 5.2f%% %s' % (datetime.datetime.now().isoformat(), t3, str(t5)), end='') - except Exception: - logging.error(traceback.format_exc()) - class Backlight: class Direction(enum.Enum): increase = 'increase'