| 
						
						
							
								
							
						
						
					 | 
					 | 
					@ -6,6 +6,26 @@ import math | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					from threading import Thread | 
					 | 
					 | 
					 | 
					from threading import Thread | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					import time | 
					 | 
					 | 
					 | 
					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 | 
					 | 
					 | 
					 | 
					running = False | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					class Battery: | 
					 | 
					 | 
					 | 
					class Battery: | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					 | 
					@ -24,7 +44,7 @@ class Battery: | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    def __init__(self): | 
					 | 
					 | 
					 | 
					    def __init__(self): | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        if self._batteries.__len__() == 0: | 
					 | 
					 | 
					 | 
					        if self._batteries.__len__() == 0: | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            scandir_line(self.pspath, self._update_batteries) | 
					 | 
					 | 
					 | 
					            scandir_line(self.pspath, self._update_batteries) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        start_timer(self.full_update) | 
					 | 
					 | 
					 | 
					        start_timer(self.full_update, self.onerror) | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        self.full_update() | 
					 | 
					 | 
					 | 
					        self.full_update() | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    def connect(self, callback): | 
					 | 
					 | 
					 | 
					    def connect(self, callback): | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					 | 
					@ -33,6 +53,11 @@ class Battery: | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    def disconnect(self, callback): | 
					 | 
					 | 
					 | 
					    def disconnect(self, callback): | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        self.callbacks.remove(callback) | 
					 | 
					 | 
					 | 
					        self.callbacks.remove(callback) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    def onerror(self): | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					        self._batteries = [] | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					        for cb in self.callbacks: | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					            cb() | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    def _update_batteries(self, line): | 
					 | 
					 | 
					 | 
					    def _update_batteries(self, line): | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        bstr = re.match(r"BAT\w+", line) | 
					 | 
					 | 
					 | 
					        bstr = re.match(r"BAT\w+", line) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        if bstr: | 
					 | 
					 | 
					 | 
					        if bstr: | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
					 | 
					@ -163,18 +188,31 @@ class Battery: | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    def get_watt(self): | 
					 | 
					 | 
					 | 
					    def get_watt(self): | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        return self.watt | 
					 | 
					 | 
					 | 
					        return self.watt | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					def acpi_listen(callback): | 
					 | 
					 | 
					 | 
					acpi_tries = 0 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    main = subprocess.Popen(shlex.split("acpi_listen"), stdout=subprocess.PIPE, text=True) | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    awky = subprocess.Popen(shlex.split("grep --line-buffered -E 'battery|ac_adapter'"), | 
					 | 
					 | 
					 | 
					def acpi_listen(callback, onerror): | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                            stdout=subprocess.PIPE, stdin=main.stdout, text=True) | 
					 | 
					 | 
					 | 
					    global acpi_tries | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    while True: | 
					 | 
					 | 
					 | 
					    try: | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        output = awky.stdout.readline() | 
					 | 
					 | 
					 | 
					        main = subprocess.Popen(shlex.split("acpi_listen"), | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        if output == "" and awky.poll() != None: | 
					 | 
					 | 
					 | 
					                                stdout=subprocess.PIPE, text=True) | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            break | 
					 | 
					 | 
					 | 
					        awky = subprocess.Popen(shlex.split("grep --line-buffered -E 'battery|ac_adapter'"), | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        if output: | 
					 | 
					 | 
					 | 
					                                stdout=subprocess.PIPE, stdin=main.stdout, text=True) | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            callback() | 
					 | 
					 | 
					 | 
					        while True: | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    rc = main.poll() | 
					 | 
					 | 
					 | 
					            output = awky.stdout.readline() | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    return rc | 
					 | 
					 | 
					 | 
					            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): | 
					 | 
					 | 
					 | 
					def scandir_line(path, callback): | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    main = subprocess.Popen(shlex.split("ls -1 {}".format(path)), | 
					 | 
					 | 
					 | 
					    main = subprocess.Popen(shlex.split("ls -1 {}".format(path)), | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
					 | 
					@ -204,7 +242,7 @@ def tonumber(asa): | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    except Exception: | 
					 | 
					 | 
					 | 
					    except Exception: | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        return None | 
					 | 
					 | 
					 | 
					        return None | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					def start_timer(callback): | 
					 | 
					 | 
					 | 
					def start_timer(callback, onerror): | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    thread = Thread(target = acpi_listen, args=(callback,)) | 
					 | 
					 | 
					 | 
					    thread = Thread(target = acpi_listen, args=(callback, onerror,)) | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    thread.daemon = True | 
					 | 
					 | 
					 | 
					    thread.daemon = True | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    thread.start() | 
					 | 
					 | 
					 | 
					    thread.start() | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
					 | 
					 | 
					
  |