Esempio n. 1
0
    def cancel_notify(self, packet: Packet):
        future: Future = self._notify_futures.pop(packet.id, None)
        if future is None:
            raise PySpheroRuntimeError("Future not found")

        logger.debug(f"[NOTIFY_WORKER {packet}] Cancel")
        future.cancel()
Esempio n. 2
0
    def notify(self,
               packet: Packet,
               callback: Callable,
               sleep_time: float = 0.1,
               timeout: float = 10):
        packet_id = packet.id
        if packet_id in self._notify_futures:
            raise PySpheroRuntimeError("Notify thread already exists")

        def worker():
            logger.debug(f"[NOTIFY_WORKER {packet}] Start")

            while self._running:
                response = self._get_response(packet,
                                              sleep_time=sleep_time,
                                              timeout=timeout)
                logger.debug(f"[NOTIFY_WORKER {packet}] Received {response}")
                if callback(response) is SpheroCore.STOP_NOTIFY:
                    logger.debug(
                        f"[NOTIFY_WORKER {packet}] Received STOP_NOTIFY")
                    self._notify_futures.pop(packet_id, None)
                    break

        future = self._executor.submit(worker)
        self._notify_futures[packet_id] = future
        return future
Esempio n. 3
0
    def stop_notify(self):
        if self._notify_future is None:
            raise PySpheroRuntimeError("Future not found")

        logger.debug(f"[NOTIFY_WORKER] Cancel")
        self._notify_future.cancel()
        self._notify_future = None
Esempio n. 4
0
    def _find_characteristic(self, characteristic: str):
        found_characteristic = None
        for uuid in self._device.discover_characteristics().keys():
            if str(uuid) == characteristic:
                found_characteristic = uuid

        if not found_characteristic:
            raise PySpheroRuntimeError(f"Characteristic {characteristic} not found")

        return found_characteristic
Esempio n. 5
0
    def append_raw_data(self, data: List[int]):
        for b in data:
            logger.debug(f"Received {b:#04x}")
            self._data.append(b)

            # packet always ending with end byte
            if b == Packet.end:
                if len(self._data) < 6:
                    raise PySpheroRuntimeError(f"Very small packet {[hex(x) for x in self.data]}")
                self._build_packet()
Esempio n. 6
0
    def _find_characteristic(self, characteristic: str):
        found_characteristic = None
        self._device.services_resolved()
        for service in self._device.services:
            for ch in service.characteristics:
                if str(ch.uuid) == characteristic:
                    found_characteristic = ch

        if not found_characteristic:
            raise PySpheroRuntimeError(f"Characteristic {characteristic} not found")

        return found_characteristic
Esempio n. 7
0
    def from_response(cls, response_data: List[int]) -> "Packet":
        """
        Create packet from raw data
        :param response_data: raw data from peripheral
        :return Packet: response packet
        """
        response_data = Packet._unescape_response_data(response_data)
        start, flags, *data, checksum, end = response_data
        if start != cls.start or end != cls.end:
            raise PySpheroRuntimeError(
                f"Bad response packet: wrong start or end byte (start: {start:#04x}, end: {end:#04x})"
            )

        target_id = None
        if flags & Flag.command_has_target_id.value:
            target_id = data.pop(0)

        source_id = None
        if flags & Flag.command_has_source_id.value:
            source_id = data.pop(0)

        device_id, command_id, sequence, *data = data

        packet = cls(
            flags=flags,
            target_id=target_id,
            source_id=source_id,
            device_id=device_id,
            command_id=command_id,
            sequence=sequence,
            data=data,
        )

        calc_checksum = packet.checksum
        if calc_checksum != checksum:
            raise PySpheroRuntimeError(
                f"Bad response checksum. (Expected: {checksum:#04x}, obtained: {calc_checksum:#04x})"
            )

        return packet
Esempio n. 8
0
    def _find_api_v2(self):
        ch_api_v2 = None
        self._device.services_resolved()
        for service in self._device.services:
            for characteristic in service.characteristics:
                if str(characteristic.uuid
                       ) == SpheroCharacteristic.api_v2.value:
                    ch_api_v2 = characteristic

        if not ch_api_v2:
            raise PySpheroRuntimeError("Sphero v2 characteristic not found")

        return ch_api_v2
Esempio n. 9
0
    def _unescape_response_data(response_data) -> List[int]:
        raw_data = []

        iter_response_data = iter(response_data)
        for b in iter_response_data:
            # escaping byte allowing escaping start/end/escaping bytes
            if b == Packet.escape:
                # next byte is escaping
                b = next(iter_response_data, None)
                if b not in Packet.escaped_bytes:
                    raise PySpheroRuntimeError(f"Bad escaping byte {b:#04x}")

                b |= Packet.escape_mask

            raw_data.append(b)

        return raw_data
Esempio n. 10
0
    def handleNotification(self, handle: int, data: List[int]):
        """
        handleNotification getting raw data from peripheral and save it.
        This function may be called several times. Therefore, the state is stored inside the class.

        :param handle:
        :param data: raw data
        :return:
        """
        for b in data:
            logger.debug(f"Received {b:#04x}")
            self.data.append(b)

            # packet always ending with end byte
            if b == Packet.end:
                if len(self.data) < 6:
                    raise PySpheroRuntimeError(
                        f"Very small packet {[hex(x) for x in self.data]}")
                self.build_packet()