def shutdown(self): PTLogger.info("Shutting down the hub") if (self._hub_connected()): self._active_hub_module.shutdown() else: PTLogger.warning( "Attempted to call shutdown when there was no active hub")
def _initialise_v2_hub_v2_speaker(): # Disable I2S enabled = False reboot_required = False i2s_mode_current, i2s_mode_next = I2S.get_states() if i2s_mode_current is True: # If in I2S mode if i2s_mode_next is True: PTLogger.debug("I2S appears to be enabled - disabling...") I2S.set_state(False) reboot_required = True else: PTLogger.debug("Initialising pi-topSPEAKER v2...") _enable_i2c_if_disabled() enabled = True reboot_required = (HDMI.set_hdmi_drive_in_boot_config(2) or reboot_required) enabled = enabled and not reboot_required v2_hub_hdmi_to_i2s_required = True return enabled, reboot_required, v2_hub_hdmi_to_i2s_required
def get_device_id(self): if (self._hub_connected()): return self._active_hub_module.get_device_id() else: PTLogger.debug( "Attempted to call get_device_id when there was no active hub") return DeviceID.unknown
def start(self): PTLogger.info("Starting idle time monitor...") if self._main_thread is None: self._main_thread = Thread(target=self._main_thread_loop) self._run_main_thread = True self._main_thread.start()
def _write_device_state(state): """INTERNAL. Send the state bits across the I2C bus""" try: PTLogger.debug("Connecting to bus...") i2c_bus = SMBus(_bus_id) state_to_send = 0x0F & state PTLogger.debug("Writing new state: " + _get_bit_string(state_to_send)) i2c_bus.write_byte_data(_device_addr, 0, state_to_send) result = _verify_device_state(state_to_send) if result is True: PTLogger.debug("OK") else: PTLogger.warning("Error: New state could not be verified") return result except: PTLogger.warning("Error: There was a problem writing to the device") return False
def _process_voltage_i2c_resp(self, resp): if resp <= 20000 and resp >= 0: self.set_voltage(resp) return True else: PTLogger.debug("Invalid voltage: " + str(resp) + "mV") return False
def _sync_with_device(): """INTERNAL. Send the sync frame to tell the device that LED data is expected.""" _initialise() PTLogger.debug("Sync data:") _write(_sync)
def enable_device(): enabled = False reboot_required = False v2_hub_hdmi_to_i2s_required = False is_pi_top = (_host_device_id == DeviceID.pi_top) is_pi_top_ceed = (_host_device_id == DeviceID.pi_top_ceed) hub_is_v1 = (is_pi_top or is_pi_top_ceed) is_pi_top_v2 = (_host_device_id == DeviceID.pi_top_v2) if is_pi_top_v2: reboot_required = _initialise_v2_hub_pulse() if (reboot_required is False): v2_hub_hdmi_to_i2s_required = True elif hub_is_v1 or (_host_device_id == DeviceID.unknown): reboot_required = _initialise_v1_hub_pulse() else: PTLogger.error("Error - unrecognised device ID '" + str(_host_device_id) + "' - unsure how to initialise " + speaker_type_name) if (reboot_required is False): _reset_device_state(True) enabled = True return enabled, reboot_required, v2_hub_hdmi_to_i2s_required
def _add_state_change_to_send_class_to_stack(pending_state_change_to_send): valid_type = (pending_state_change_to_send._type is not None) valid_operation = (pending_state_change_to_send._operation is not None) if valid_type and valid_operation: _append_to_queued_state_change_to_sends(pending_state_change_to_send) else: PTLogger.info("Unable to process state change - invalid type or operation")
def _process_charging_time_i2c_resp(self, resp): if resp <= 2400 and resp >= 0: self.set_time(resp) return True else: PTLogger.debug("Invalid, not less than or equal to 2400: " + str(resp)) return False
def _get_state_from_hub(self, init=False, process_state=True): valid = False get_state_ctr = Counter(5) do_extra_read = init while not valid and not get_state_ctr.maxed(): valid, resp_bin_str = self._attempt_get_state() if do_extra_read and valid: valid = False do_extra_read = False if not valid: get_state_ctr.current += 1 sleep(_cycle_sleep_time) if valid: if process_state: self._process_spi_resp(resp_bin_str, init=init) else: PTLogger.error("Unable to communicate with hub. " + "init: " + str(init) + ", resp_bin_str: " + str(resp_bin_str)) return valid
def blank_screen(self): PTLogger.info("Blanking screen") if (self._hub_connected()): self._active_hub_module.blank_screen() else: PTLogger.warning( "Attempted to call blank_screen when there was no active hub")
def transceive_and_process(self): state_change_to_send = self.pop_from_queue() self._update_state_from_pending_state_change(state_change_to_send) # Should this be here? # Set bits to send according to state variables if state_change_to_send is not None: # Pi's current state bits_to_send = self._parse_state_to_bits() else: # Probe for hub's state bits_to_send = 255 hub_response_bstring = self._transceive_spi(bits_to_send) byte_type = self._determine_byte(hub_response_bstring) # Determine if received byte represents device ID or state if byte_type == SPIResponseType.device_id: PTLogger.debug("Valid response from hub - DEVICE ID") self._process_device_id(hub_response_bstring) elif byte_type == SPIResponseType.state: self._process_spi_resp(hub_response_bstring) # State update has been sent to hub: perform another transceive to sync states self._get_state_from_hub(process_state=False) else: PTLogger.warning("Invalid response from hub") return False return True
def _signal_handler(signal, frame): """INTERNAL. Handles signals from the OS to exit.""" PTLogger.info("\nQuitting...") stop() off() exit(0)
def _process_capacity_i2c_resp(self, resp): if resp <= 100 and resp >= 0: self.set_capacity(resp) return True else: PTLogger.debug("Invalid, not less than or equal to 100") return False
def change_screen_state(spi_screen_operation): if is_initialised(): _add_state_change_to_send_to_stack(SPIStateChangeType.screen, spi_screen_operation) if not _main_thread.is_alive(): communicate() else: PTLogger.error("Unable to change screen state - run initialise() first!")
def get_battery_state(self): if (self._hub_connected()): return self._active_hub_module.get_battery_state() else: PTLogger.warning( "Attempted to call get_battery_state when there was no active hub" ) return None
def add_module_if_available(self, module_name): cfg_module_str = str(module_name + ".configuration") try: i = import_module(cfg_module_str) self._custom_imported_modules[module_name] = i except ImportError as exc: PTLogger.warning("Error: failed to import " + cfg_module_str + " settings module (" + str(exc) + ")")
def disconnect(self): PTLogger.debug("I2C: Disconnecting...") self._write_device.close() self._read_device.close() self._lock_file_handle.close()
def start(self): if not self.is_initialised(): PTLogger.error("Unable to start pi-top peripheral management - run initialise() first!") return False self._run_main_thread = True self._main_thread.start() return True
def disable_hdmi_to_i2s_audio(self): PTLogger.info("Switching HDMI to I2S mux off") if (self._hub_connected()): self._active_hub_module.disable_hdmi_to_i2s_audio() else: PTLogger.warning( "Attempted to call disable_hdmi_to_i2s_audio when there was no active hub" )
def _set_timeout_in_file(self): if path.exists(self.CONFIG_FILE): remove(self.CONFIG_FILE) file = open(self.CONFIG_FILE, 'w') file.write(str(self._idle_timeout_s) + "\n") file.close() PTLogger.info("Idletime set in config: " + str(self._idle_timeout_s))
def set_poweroff_service_states(self, v1_service_enabled, v2_service_enabled): v1_status_str = "enable" if v1_service_enabled else "disable" v2_status_str = "enable" if v2_service_enabled else "disable" ret_code1 = call(["systemctl", v1_status_str, "pt-poweroff-v1.service"]) PTLogger.info("systemctl " + v1_status_str + " pt-poweroff-v1.service " + str(ret_code1)) ret_code2 = call(["systemctl", v2_status_str, "pt-poweroff-v2.service"]) PTLogger.info("systemctl " + v2_status_str + " pt-poweroff-v2.service " + str(ret_code2))
def _process_device_id(self, resp): device_id = resp[5:8] if device_id == "000": PTLogger.info("Hub reports it's a pi-top v1") self._state.set_device_id(DeviceID.pi_top) elif device_id == "001": PTLogger.info("Hub reports it's a CEED") self._state.set_device_id(DeviceID.pi_top_ceed)
def set_brightness(self, brightness): PTLogger.info("Setting brightness to " + str(brightness)) if (self._hub_connected()): self.unblank_screen() self._active_hub_module.set_brightness(brightness) else: PTLogger.warning( "Attempted to call set_brightness when there was no active hub" )
def decrement_brightness(self): PTLogger.info("Decrementing brightness") if (self._hub_connected()): self.unblank_screen() self._active_hub_module.decrement_brightness() else: PTLogger.warning( "Attempted to call decrement_brightness when there was no active hub" )
def _initialise_v2_hub_pulse(): if HDMI.set_as_audio_output() is False: PTLogger.warning("Failed to configure HDMI output") HDMI_reboot = HDMI.set_hdmi_drive_in_boot_config(2) UART_reboot = _check_and_set_serial_config() I2S_reboot = _check_and_set_I2S_config(False) return HDMI_reboot or UART_reboot or I2S_reboot
def read_unsigned_byte(self, register_address: int): result_array = self._run_transaction([register_address], 1) if (len(result_array) != 1): return None PTLogger.debug("I2C: Read byte " + str(result_array[0]) + " from " + hex(register_address)) return result_array[0]
def write_byte(self, register_address: int, byte_value: int): if (byte_value > 0xFF): PTLogger.warning( "Possible unintended overflow writing value to register " + hex(register_address)) PTLogger.debug("I2C: Writing byte " + str(byte_value) + " to " + hex(register_address)) self._run_transaction([register_address, byte_value & 0xFF], 0)
def initialise(state): global _battery_state_handler try: _battery_state_handler = BatteryStateHandler(state) return True except Exception as e: PTLogger.error("Error initialising I2C. " + str(e)) PTLogger.info(traceback.format_exc()) _battery_state_handler = None return False