Esempio n. 1
0
 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
Esempio n. 2
0
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
Esempio n. 3
0
    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 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
Esempio n. 5
0
 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
Esempio n. 6
0
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)
Esempio n. 7
0
def show():
    """Update pi-topPULSE with the contents of the display buffer."""

    global _pixel_map
    global _rotation
    global _show_enabled

    wait_counter = 0

    attempt_to_show_early = not _show_enabled
    if attempt_to_show_early:
        PTLogger.info("Can't update pi-topPULSE LEDs more than 50/s. Waiting...")

    pause_length = 0.001

    # Scale wait time to _max_freq
    wait_counter_length = ceil(float(1 / float(_max_freq * pause_length)))

    while not _show_enabled:
        if wait_counter >= wait_counter_length:
            # Timer hasn't reset for some reason - force override
            _enable_show_state()
            break
        else:
            sleep(pause_length)
            wait_counter = wait_counter + 1

    if attempt_to_show_early:
        PTLogger.debug("pi-topPULSE LEDs re-enabled.")

    _sync_with_device()

    rotated_pixel_map = _get_rotated_pixel_map()
    avg_rgb = _get_avg_colour()

    _initialise()

    PTLogger.debug("LED data:")
    # For each col
    for x in range(_w):
        # Write col to LED matrix
        # Start with col no., so LED matrix knows which one it belongs to
        pixel_map_buffer = chr(x)
        # Get col's frame buffer, iterating over each pixel
        for y in range(_h + 1):
            if y == _h:
                # Ambient lighting bytes
                byte0, byte1 = _rgb_to_bytes_to_send(avg_rgb)
            else:
                byte0, byte1 = _rgb_to_bytes_to_send(rotated_pixel_map[x][y])

            pixel_map_buffer += chr(byte0)
            pixel_map_buffer += chr(byte1)

        # Write col to LED matrix
        arr = bytearray(pixel_map_buffer, 'Latin_1')
        _write(arr)

        # Prevent another write if it's too fast
        _disable_show_state()
Esempio n. 8
0
def _check_and_set_serial_config():

    reboot_required = False

    version = get_debian_version()
    if isinstance(version, int):
        if int(version) > 8:
            PTLogger.debug(
                "UART baud rate does not need to be configured for ptpulse...")
        else:
            if UART.boot_config_correctly_configured(
                    expected_clock_val=1627604,
                    expected_baud_val=460800) is True:
                PTLogger.debug("Baud rate is already configured for ptpulse")
            else:
                PTLogger.debug(
                    "Baud rate NOT already configured for ptpulse, configuring..."
                )
                UART.configure_in_boot_config(init_uart_clock=1627604,
                                              init_uart_baud=460800)
                reboot_required = True
    else:
        PTLogger.warning(
            "Unable to detect OS version - cannot determine if UART baud rate needs to be configured for ptpulse..."
        )

    if UART.enabled() is True:
        PTLogger.debug("UART is already enabled")
    else:
        PTLogger.debug("UART NOT already enabled, enabling...")
        UART.set_enable(True)  # UART.configure_in_boot_config(enable_uart=1)
        reboot_required = True

    reboot_required = (UART.remove_serial_from_cmdline() or reboot_required)
    return reboot_required
Esempio n. 9
0
def _initialise():
    """INTERNAL. Initialise the matrix."""

    global _initialised
    global _serial_device
    global _pixel_map

    if not _initialised:
        if configuration.mcu_enabled():
            if not path.exists('/dev/serial0'):
                err_str = "Could not find serial port - are you sure it's enabled?"
                raise serialutil.SerialException(err_str)

            PTLogger.debug("Opening serial port...")

            _serial_device = Serial("/dev/serial0", baudrate=250000, timeout=2)

            if _serial_device.isOpen():
                PTLogger.debug("OK.")
            else:
                PTLogger.info("Error: Failed to open serial port!")
                exit()

            _initialised = True
        else:
            PTLogger.info("Error: pi-topPULSE is not initialised. Call ptpulse.configuration.initialise() ptpulse.configuration.enable_device()")
            exit()
    def disconnect(self):

        PTLogger.debug("I2C: Disconnecting...")

        self._write_device.close()
        self._read_device.close()

        self._lock_file_handle.close()
Esempio n. 11
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 update_peripheral_state(self, peripheral, enable):
        if enable:
            PTLogger.info("Enabling peripheral: " + peripheral.name)

        else:
            PTLogger.info("Disabling peripheral: " + peripheral.name)

        peripheral_enabled = self.get_peripheral_enabled(peripheral)
        valid = (enable != peripheral_enabled)

        if valid:
            if 'pi-topPULSE' in peripheral.name:
                if 'ptpulse' in self._custom_imported_modules:
                    is_v1_hub = (self._host_device_id == DeviceID.pi_top) or (self._host_device_id == DeviceID.pi_top_ceed)

                    if self._host_device_id == DeviceID.pi_top_v2:
                        self.configure_v2_hub_pulse(peripheral, enable)
                    elif is_v1_hub or self._host_device_id == DeviceID.unknown:
                        self.configure_v1_hub_pulse(peripheral, enable)
                    else:
                        PTLogger.error("Not a valid configuration")
                else:
                    self.show_pulse_install_package_message()
            elif 'pi-topSPEAKER' in peripheral.name:
                if 'ptspeaker' in self._custom_imported_modules:
                    is_v1_hub = (self._host_device_id == DeviceID.pi_top) or (self._host_device_id == DeviceID.pi_top_ceed)

                    if self._host_device_id == DeviceID.pi_top_v2:
                        # CHECK THAT SPEAKER IS V2
                        if peripheral.name == 'pi-topSPEAKER-v2':
                            self.enable_v2_hub_v2_speaker(peripheral)
                        else:
                            PTLogger.warning("Unable to initialise V1 speaker with V2 hardware")
                            # Mark as enabled even if a reboot is required
                            # to prevent subsequent attempts to enable
                            self.add_enabled_peripheral(peripheral)
                            self.emit_unsupported_hardware_message()
                    elif is_v1_hub or self._host_device_id == DeviceID.unknown:
                        if enable is True:
                            if peripheral.name == 'pi-topSPEAKER-v2':
                                self.enable_v1_hub_v2_speaker(peripheral)
                            else:
                                self.enable_v1_hub_v1_speaker(peripheral)
                        else:
                            self.remove_enabled_peripheral(peripheral)
                    else:
                        PTLogger.error("Not a valid configuration")
                else:
                    self.show_speaker_install_package_message()
            elif 'pi-topPROTO+' in peripheral.name:
                # Nothing to do - add to list of peripherals
                self.add_enabled_peripheral(peripheral)

            else:
                PTLogger.error("Peripheral name not recognised")
        else:
            PTLogger.debug("Peripheral state was already set")
Esempio n. 13
0
def _get_addr_for_bit(bit):
    if bit in [0, 1, 2, 3]:
        PTLogger.debug("bit:  " + str(bit))
        addr = int(pow(2, bit))
        PTLogger.debug("addr: " + str(addr))
        return addr
    else:
        PTLogger.warning("Internal ERROR: invalid bit; cannot get address")
        return -1
Esempio n. 14
0
    def set_value(property_name, value_to_set):
        PTLogger.debug("Checking " + property_name + " setting in " +
                       _BootConfig.BOOT_CONFIG_FILE + "...")

        property_updated = False
        property_found = False

        temp_file = common_functions.create_temp_file()

        with open(temp_file, 'w') as output_file:

            last_char = ""
            with open(_BootConfig.BOOT_CONFIG_FILE, 'r') as input_file:

                for line in input_file:
                    line_to_write = line

                    line_to_find = str(property_name + "=")
                    desired_line = str(line_to_find + str(value_to_set))

                    if line_to_find in line_to_write:
                        property_found = True

                        if (common_functions.is_line_commented(line_to_write)):
                            line_to_write = common_functions.get_uncommented_line(
                                line_to_write)
                            property_updated = True

                        if desired_line not in line_to_write:
                            line_to_write = desired_line + "\n"
                            property_updated = True

                    output_file.write(line_to_write)
                    last_char = line_to_write[-1]

            if (property_found is False):
                line_to_append = ""
                if last_char != "\n":
                    line_to_append += "\n"

                line_to_append += desired_line + "\n"

                # Append if not found
                output_file.write(line_to_append)
                property_updated = True

        if (property_updated is True):
            PTLogger.info("Updating " + _BootConfig.BOOT_CONFIG_FILE +
                          " to set " + property_name + " setting...")
            copy(temp_file, _BootConfig.BOOT_CONFIG_FILE)

        else:
            PTLogger.debug(property_name + " setting already set in " +
                           _BootConfig.BOOT_CONFIG_FILE)

        return property_updated
    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]
Esempio n. 16
0
    def _setup_i2c(self):
        try:
            PTLogger.debug("Setting up i2c connection to battery")
            self._bus = SMBus(self._bus_no)

            PTLogger.debug("Testing comms with battery")
            return self._refresh_state()
        except:
            PTLogger.warning("Unable to find pi-topHUB battery")

        return False
    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 attempt_disable_peripheral_by_name(self, current_peripheral_name):
        current_peripheral = Peripheral(name=current_peripheral_name)

        if current_peripheral.id == PeripheralID.unknown:
            PTLogger.warning("Peripheral " + current_peripheral_name + " not recognised")

        elif self.get_peripheral_enabled(current_peripheral):
            PTLogger.debug("updating peripheral state")
            self.update_peripheral_state(current_peripheral, False)

        else:
            PTLogger.warning("Peripheral " + current_peripheral_name + " already disabled")
Esempio n. 19
0
    def stop_listening(self):

        PTLogger.info("Closing responder socket...")

        self._continue = False
        if self._thread.is_alive():
            self._thread.join()

        self._zmq_socket.close()
        self._zmq_context.destroy()

        PTLogger.debug("Closed responder socket.")
    def write_word(self, register_address: int, word_value: int):

        if (word_value > 0xFFFF):
            PTLogger.warning(
                "Possible unintended overflow writing value to register " +
                hex(register_address))

        PTLogger.debug("I2C: Writing word " + str(word_value) + " to " +
                       hex(register_address))

        high, low = self._split_word(word_value)
        self._run_transaction([register_address, high & 0xFF, low & 0xFF], 0)
    def read_unsigned_word(self, register_address: int):

        result_array = self._run_transaction([register_address], 2)

        if (len(result_array) != 2):
            return None

        result = self._join_word(result_array[0], result_array[1])

        PTLogger.debug("I2C: Read word " + str(result) + " from " +
                       hex(register_address))

        return result
Esempio n. 22
0
    def _main_thread_loop(self):
        while self._run_main_thread:
            FNULL = open(devnull, 'w')

            PTLogger.debug("Running xprintidle...")

            try:
                xprintidle_resp = check_output(['xprintidle'], stderr=FNULL)
            except CalledProcessError as exc:
                PTLogger.warning(
                    "Unable to call xprintidle - have non-network local connections been added to X server access control list?"
                )
                break

            PTLogger.debug("Got xprintidle response...")
            xprintidle_resp_str = xprintidle_resp.decode("utf-8")

            try:
                idletime_ms = int(xprintidle_resp_str)
            except:
                PTLogger.warning(
                    "Unable to convert xprintidle response to integer")
                break

            PTLogger.debug("Parsed xprintidle response to integer")
            PTLogger.info("MS since idle: " + str(idletime_ms))

            if (self._idle_timeout_s > 0):
                timeout_expired = (idletime_ms > (self._idle_timeout_s * 1000))
                idletime_reset = (idletime_ms < self.previous_idletime)

                PTLogger.debug("Timeout Expired?: " + str(timeout_expired))
                PTLogger.debug("Idletime Reset?: " + str(idletime_reset))

                timeout_already_expired = (self.previous_idletime >
                                           (self._idle_timeout_s * 1000))

                if timeout_expired and not timeout_already_expired:
                    self._emit_idletime_threshold_exceeded()
                    self._cycle_sleep_time = self.SENSITIVE_CYCLE_SLEEP_TIME
                elif idletime_reset and timeout_already_expired:
                    self._emit_exceeded_idletime_reset()
                    self._cycle_sleep_time = self.DEFAULT_CYCLE_SLEEP_TIME

                self.previous_idletime = idletime_ms

            for i in range(5):
                sleep(self._cycle_sleep_time / 5)

                if (self._run_main_thread is False):
                    break
Esempio n. 23
0
    def _process_current_and_charging_state_i2c_resp(self, resp):
        if resp < -2500 or resp > 2500:
            PTLogger.debug("Invalid current: " + str(resp) + "mA")
            return False

        if resp <= -10:
            self.set_charging_state(0)
        else:
            charging_state = 2 if (self._state._battery_time == 0) else 1  # charging state
            self.set_charging_state(charging_state)

        self.set_current(resp)

        return True
    def auto_initialise_peripherals(self):
        addresses = I2C.get_connected_device_addresses()

        for peripheral in self._enabled_peripherals:
            if format(peripheral.addr, 'x') not in addresses:
                PTLogger.debug("Peripheral " + peripheral.name + " was enabled but not detected.")
                self.remove_enabled_peripheral(peripheral)
                self.attempt_disable_peripheral_by_name(peripheral.name)

        for address in addresses:
            current_peripheral = Peripheral(addr=int(address, 16))

            if current_peripheral.id != PeripheralID.unknown:
                self.attempt_enable_peripheral_by_name(current_peripheral.name)
Esempio n. 25
0
def _finalise_wav_file(file_path):
    """INTERNAL. Update the WAV file header with the size of the data."""

    size_of_data = _get_size(file_path) - 44

    if size_of_data <= 0:
        PTLogger.info("Error: No data was recorded!")
        remove(file_path)
    else:
        with open(file_path, 'rb+') as file:

            PTLogger.debug("Updating header information...")

            _update_header_in_file(file, 4, size_of_data + 36)
            _update_header_in_file(file, 40, size_of_data)
Esempio n. 26
0
def _read_device_state():
    """INTERNAL. Read from the I2C bus to get the current state of the pulse. Caller should handle exceptions"""

    try:
        PTLogger.debug("Connecting to bus...")
        i2c_bus = SMBus(_bus_id)

        current_state = i2c_bus.read_byte(_device_addr) & 0x0F

        return int(current_state)

    except:
        PTLogger.warning("Error: There was a problem reading from the device")
        # Best to re-raise as we can't recover from this
        raise
Esempio n. 27
0
    def _get_battery_data(self, data_to_get):
        reattempt_sleep_s = float(_cycle_sleep_time / self._i2c_ctr.max)

        self._i2c_ctr.reset()
        while not self._i2c_ctr.maxed():
            self._i2c_ctr.increment()
            successful_read, resp, register = self._attempt_read(data_to_get)
            if successful_read:
                return self._parse_response(resp, register)
            else:
                PTLogger.debug("Unsuccessful read...")
            sleep(reattempt_sleep_s)

        # Value was not fetched
        PTLogger.debug("Unable to read from I2C after multiple attempts")
        return False
Esempio n. 28
0
    def stop_listening(self):
        PTLogger.info("Closing publisher socket...")

        try:
            self._socket_lock.acquire()

            self._shutting_down = True

            self._zmq_socket.close()
            self._zmq_context.destroy()
            PTLogger.debug("Closed publisher socket.")

        except zmq.error.ZMQError as e:
            PTLogger.error("Error starting the publish server: " + str(e))
            PTLogger.info(traceback.format_exc())

        finally:
            self._socket_lock.release()
    def wait_for_device_identification(self):

        PTLogger.debug("Waiting for device id to be established...")

        time_waited = 0
        while (time_waited < 5):

            device_id = self.get_device_id()
            if (device_id == DeviceID.unknown):

                sleep(0.25)
                time_waited += 0.25

            else:
                PTLogger.debug("Got device id (" + str(device_id) +
                               "). Waited " + str(time_waited) + " seconds")
                return

        PTLogger.warning("Timed out waiting for device identification.")
Esempio n. 30
0
    def _send_message(self, message_id, parameters):

        message = Message.from_parts(message_id, parameters)

        try:
            self._socket_lock.acquire()

            if (self._shutting_down is True):
                return

            self._zmq_socket.send_string(message.to_string())
            PTLogger.debug("Published message: " + message.message_friendly_string())

        except zmq.error.ZMQError as e:
            PTLogger.error("Communication error in publish server: " + str(e))
            PTLogger.info(traceback.format_exc())

        finally:
            self._socket_lock.release()