def disconnect(self): PTLogger.debug("I2C: Disconnecting...") if self._write_device is not None: self._write_device.close() if self._read_device is not None: self._read_device.close()
def run_command_background(command_str: str, print_output=False) -> Popen: PTLogger.debug("Function: run_command_background(command_str=%s)" % command_str) return Popen(split(command_str), env=__get_env(), stderr=None if print_output else DEVNULL, stdout=None if print_output else DEVNULL)
def write_n_bytes(self, register_address: int, byte_list: list): """ Base function to write to an I2C device """ PTLogger.debug( "I2C: Writing byte/s " + str(byte_list) + " to " + hex(register_address) ) self.__run_transaction([register_address] + byte_list, 0)
def connect(self): PTLogger.debug( "I2C (SMBus): Connecting to address " + hex(self._device_address) + " on bus " + str(self._bus_number) ) self._bus = SMBus(self._bus_number)
def write_n_bytes(self, register_address: int, byte_list: list): """ Base function to write to an I2C device """ PTLogger.debug( "I2C: Writing byte/s " + str(byte_list) + " to " + hex(register_address) ) self._bus.write_i2c_block_data( self._device_address, register_address, byte_list)
def __init__(self, id, _single_purpose=False): self.path = "/tmp/%s.lock" % id self._thread_lock = Lock() self._single_purpose = _single_purpose lock_file_already_existed = exists(self.path) self.__lock_file_handle = open(self.path, "w") if not lock_file_already_existed: chmod(self.path, S_IWUSR | S_IWGRP | S_IWOTH) PTLogger.debug("Creating PTLock with path: {}".format(self.path))
def __connect_to_socket(self): self.__zmq_context = zmq.Context() self.__zmq_socket = self.__zmq_context.socket(zmq.REQ) self.__zmq_socket.sndtimeo = _TIMEOUT_MS self.__zmq_socket.rcvtimeo = _TIMEOUT_MS try: self.__zmq_socket.connect("tcp://127.0.0.1:3782") PTLogger.debug("pt-device-manager request client is ready") except zmq.error.ZMQError as e: PTLogger.error("Error starting the request client: " + str(e)) PTLogger.info(format_exc()) raise
def is_locked(self): if self.__locked_by_self: return self.__locked_by_self lock_status = False try: flock(self.__lock_file_handle, LOCK_EX | LOCK_NB) flock(self.__lock_file_handle, LOCK_UN) except BlockingIOError: lock_status = True PTLogger.debug("Lock file at {} is {}locked".format( self.path, "not " if not lock_status else "")) return lock_status
def get_list_of_displays() -> int: def represents_int(s): try: int(s) return True except ValueError: return False displays = [ f.replace('X', ':') for f in listdir("/tmp/.X11-unix/") if represents_int(f.replace('X', '')) ] PTLogger.debug("List of displays found: {}".format(displays)) return displays
def __connect_to_socket(self): self.__zmq_context = zmq.Context() self.__zmq_socket = self.__zmq_context.socket(zmq.SUB) self.__zmq_socket.setsockopt_string(zmq.SUBSCRIBE, "") try: self.__zmq_socket.connect("tcp://127.0.0.1:3781") PTLogger.debug("pt-device-manager subscribe client is ready") except zmq.error.ZMQError as e: PTLogger.error("Error starting the subscribe client: " + str(e)) PTLogger.info(format_exc()) return False return True
def __read_n_bytes( self, register_address: int, number_of_bytes: int, signed: bool = False, little_endian: bool = False, ): """ Base function to read from an I2C device :param register_address: Register address to target for reading :param number_of_bytes: Number of bytes to attempt to read from register address :param signed: Indicates whether or not the value could potentially have a negative value, and is therefore represented with a signed number representation :param little_endian: Indicates whether the data to be read is in little-endian byte-order :return: result: The response from the read attempt via I2C """ # Read from device result_array = self.__run_transaction( [register_address], number_of_bytes ) # Check response length is correct if len(result_array) != number_of_bytes: return None # Invert byte ordering, if appropriate if little_endian: result_array.reverse() # Convert array into integer result = join_bytes(result_array) # Process signed number if appropriate if signed: if result & (1 << ((8 * number_of_bytes) - 1)): result = -(1 << (8 * number_of_bytes)) + result PTLogger.debug( "I2C: Read " + str(number_of_bytes) + " bytes from " + hex(register_address) + " (" + ( "Signed," if signed else "Unsigned,") + ("LE" if little_endian else "BE") + ")" ) PTLogger.debug(str(result_array) + " : " + str(result)) return result
def run_command(command_str: str, timeout: int, check: bool = True, capture_output: bool = True, log_errors: bool = True) -> str: PTLogger.debug( f"Function: run_command(command_str={command_str}, timeout={timeout}, check={check}, capture_output={capture_output}, \ log_errors={log_errors})") resp_stdout = None try: resp = run(split(command_str), check=check, capture_output=capture_output, timeout=timeout, env=__get_env()) if capture_output: resp_stdout = str(resp.stdout, 'utf8') resp_stderr = str(resp.stderr, 'utf8') PTLogger.debug(f"run_command(" f"command_str='{command_str}', " f"timeout={timeout}, " f"check='{check}', " f"capture_output='{capture_output}'" f") stdout:\n{resp_stdout}") PTLogger.debug(f"run_command(" f"command_str='{command_str}', " f"timeout={timeout}, " f"check='{check}', " f"capture_output='{capture_output}'" f") stderr:\n{resp_stderr}") if not check: PTLogger.debug(f"run_command(" f"command_str='{command_str}', " f"timeout={timeout}, " f"check='{check}', " f"capture_output='{capture_output}'" f") exit code: {resp.returncode}") except (CalledProcessError, TimeoutExpired) as e: if log_errors: PTLogger.error(str(e)) raise e except Exception as e: if log_errors: PTLogger.error(str(e)) return resp_stdout
def release(self) -> bool: """ Attempt to release lock """ if not self._thread_lock.locked(): PTLogger.debug("Attempting to release thread lock, which is currently already acquired.") if not self.is_locked(): PTLogger.debug(f"Attempting to release lock file ({self.path}), which is currently already globally acquired.") PTLogger.debug("Releasing thread lock") self._thread_lock.release() PTLogger.debug("Releasing lock file at {}".format(self.path)) flock(self.__lock_file_handle, LOCK_UN) self.__locked_by_self = False
def acquire(self) -> bool: """ Block until lock can be acquired """ if self._thread_lock.locked(): PTLogger.debug("Attempting to acquire thread lock, which is currently already acquired.") if self.is_locked(): PTLogger.debug(f"Attempting to acquire lock file ({self.path}), which is currently already globally acquired.") PTLogger.debug("Acquiring thread lock") self._thread_lock.acquire() PTLogger.debug("Acquiring lock file at {}".format(self.path)) flock(self.__lock_file_handle, LOCK_EX) self.__locked_by_self = True
def connect(self, read_test=True): PTLogger.debug( "I2C: Connecting to address " + hex(self._device_address) + " on " + self._device_path ) self._read_device = iopen(self._device_path, "rb", buffering=0) self._write_device = iopen(self._device_path, "wb", buffering=0) ioctl(self._read_device, self.I2C_SLAVE, self._device_address) ioctl(self._write_device, self.I2C_SLAVE, self._device_address) if read_test is True: PTLogger.debug("I2C: Test read 1 byte") self._read_device.read(1) PTLogger.debug("I2C: OK")
def disconnect(self): PTLogger.debug("I2C (SMBus): Disconnecting...") self._bus.close()
def get_first_display() -> int: displays = get_list_of_displays() first_display = displays[0] if len(displays) > 0 else None PTLogger.debug("First display is: {}".format(first_display)) return first_display