示例#1
1
class RileyLink(PacketRadio):
    def __init__(self):
        self.peripheral = None
        self.pa_level_index = PA_LEVELS.index(0x84)
        self.data_handle = None
        self.logger = getLogger()
        self.address = None
        if os.path.exists(RILEYLINK_MAC_FILE):
            with open(RILEYLINK_MAC_FILE, "r") as stream:
                self.address = stream.read()
        self.service = None
        self.response_handle = None
        self.notify_event = Event()
        self.initialized = False

    def connect(self, force_initialize=False):
        try:
            if self.address is None:
                self.address = self._findRileyLink()

            if self.peripheral is None:
                self.peripheral = Peripheral()

            try:
                state = self.peripheral.getState()
                if state == "conn":
                    return
            except BTLEException:
                pass

            self._connect_retry(3)

            self.service = self.peripheral.getServiceByUUID(RILEYLINK_SERVICE_UUID)
            data_char = self.service.getCharacteristics(RILEYLINK_DATA_CHAR_UUID)[0]
            self.data_handle = data_char.getHandle()

            char_response = self.service.getCharacteristics(RILEYLINK_RESPONSE_CHAR_UUID)[0]
            self.response_handle = char_response.getHandle()

            response_notify_handle = self.response_handle + 1
            notify_setup = b"\x01\x00"
            self.peripheral.writeCharacteristic(response_notify_handle, notify_setup)

            while self.peripheral.waitForNotifications(0.05):
                self.peripheral.readCharacteristic(self.data_handle)

            if self.initialized:
                self.init_radio(force_initialize)
            else:
                self.init_radio(True)
        except BTLEException:
            if self.peripheral is not None:
                self.disconnect()
            raise

    def disconnect(self, ignore_errors=True):
        try:
            if self.peripheral is None:
                self.logger.info("Already disconnected")
                return
            self.logger.info("Disconnecting..")
            if self.response_handle is not None:
                response_notify_handle = self.response_handle + 1
                notify_setup = b"\x00\x00"
                self.peripheral.writeCharacteristic(response_notify_handle, notify_setup)
        except BTLEException:
            if not ignore_errors:
                raise
        finally:
            try:
                if self.peripheral is not None:
                    self.peripheral.disconnect()
                    self.peripheral = None
            except BTLEException:
                if ignore_errors:
                    self.logger.exception("Ignoring btle exception during disconnect")
                else:
                    raise

    def get_info(self):
        try:
            self.connect()
            bs = self.peripheral.getServiceByUUID(XGATT_BATTERYSERVICE_UUID)
            bc = bs.getCharacteristics(XGATT_BATTERY_CHAR_UUID)[0]
            bch = bc.getHandle()
            battery_value = int(self.peripheral.readCharacteristic(bch)[0])
            self.logger.debug("Battery level read: %d", battery_value)
            version, v_major, v_minor = self._read_version()
            return { "battery_level": battery_value, "mac_address": self.address,
                    "version_string": version, "version_major": v_major, "version_minor": v_minor }
        except BTLEException as btlee:
            raise PacketRadioError("Error communicating with RileyLink") from btlee
        finally:
            self.disconnect()

    def _read_version(self):
        version = None
        try:
            if os.path.exists(RILEYLINK_VERSION_FILE):
                with open(RILEYLINK_VERSION_FILE, "r") as stream:
                    version = stream.read()
            else:
                response = self._command(Command.GET_VERSION)
                if response is not None and len(response) > 0:
                    version = response.decode("ascii")
                    self.logger.debug("RL reports version string: %s" % version)

                    try:
                        with open(RILEYLINK_VERSION_FILE, "w") as stream:
                            stream.write(version)
                    except IOError:
                        self.logger.exception("Failed to store version in file")

            if version is None:
                return "0.0", 0, 0

            try:
                m = re.search(".+([0-9]+)\\.([0-9]+)", version)
                if m is None:
                    raise PacketRadioError("Failed to parse firmware version string: %s" % version)

                v_major = int(m.group(1))
                v_minor = int(m.group(2))
                self.logger.debug("Interpreted version major: %d minor: %d" % (v_major, v_minor))

                return version, v_major, v_minor

            except Exception as ex:
                raise PacketRadioError("Failed to parse firmware version string: %s" % version) from ex

        except IOError:
            self.logger.exception("Error reading version file")
        except PacketRadioError:
            raise

        response = self._command(Command.GET_VERSION)
        if response is not None and len(response) > 0:
            version = response.decode("ascii")
            self.logger.debug("RL reports version string: %s" % version)
            try:
                m = re.search(".+([0-9]+)\\.([0-9]+)", version)
                if m is None:
                    raise PacketRadioError("Failed to parse firmware version string: %s" % version)

                v_major = int(m.group(1))
                v_minor = int(m.group(2))
                self.logger.debug("Interpreted version major: %d minor: %d" % (v_major, v_minor))

                return (version, v_major, v_minor)
            except PacketRadioError:
                raise
            except Exception as ex:
                raise PacketRadioError("Failed to parse firmware version string: %s" % version) from ex

    def init_radio(self, force_init=False):
        try:
            version, v_major, v_minor = self._read_version()

            if v_major < 2:
                self.logger.error("Firmware version is below 2.0")
                raise PacketRadioError("Unsupported RileyLink firmware %d.%d (%s)" %
                                        (v_major, v_minor, version))

            if not force_init:
                if v_major == 2 and v_minor < 3:
                    response = self._command(Command.READ_REGISTER, bytes([Register.SYNC1, 0x00]))
                else:
                    response = self._command(Command.READ_REGISTER, bytes([Register.SYNC1]))
                if response is not None and len(response) > 0 and response[0] == 0xA5:
                    return

            self._command(Command.RADIO_RESET_CONFIG)
            self._command(Command.SET_SW_ENCODING, bytes([Encoding.MANCHESTER]))
            frequency = int(433910000 / (24000000 / pow(2, 16)))
            self._command(Command.SET_PREAMBLE, bytes([0x66, 0x65]))
            self._command(Command.UPDATE_REGISTER, bytes([Register.FREQ0, frequency & 0xff]))
            self._command(Command.UPDATE_REGISTER, bytes([Register.FREQ1, (frequency >> 8) & 0xff]))
            self._command(Command.UPDATE_REGISTER, bytes([Register.FREQ2, (frequency >> 16) & 0xff]))
            self._command(Command.UPDATE_REGISTER, bytes([Register.PKTCTRL1, 0x20]))
            self._command(Command.UPDATE_REGISTER, bytes([Register.PKTCTRL0, 0x00]))
            self._command(Command.UPDATE_REGISTER, bytes([Register.FSCTRL1, 0x06]))
            self._command(Command.UPDATE_REGISTER, bytes([Register.MDMCFG4, 0xCA]))
            self._command(Command.UPDATE_REGISTER, bytes([Register.MDMCFG3, 0xBC]))
            self._command(Command.UPDATE_REGISTER, bytes([Register.MDMCFG2, 0x06]))
            self._command(Command.UPDATE_REGISTER, bytes([Register.MDMCFG1, 0x70]))
            self._command(Command.UPDATE_REGISTER, bytes([Register.MDMCFG0, 0x11]))
            self._command(Command.UPDATE_REGISTER, bytes([Register.DEVIATN, 0x44]))
            self._command(Command.UPDATE_REGISTER, bytes([Register.MCSM0, 0x18]))
            self._command(Command.UPDATE_REGISTER, bytes([Register.FOCCFG, 0x17]))
            self._command(Command.UPDATE_REGISTER, bytes([Register.FSCAL3, 0xE9]))
            self._command(Command.UPDATE_REGISTER, bytes([Register.FSCAL2, 0x2A]))
            self._command(Command.UPDATE_REGISTER, bytes([Register.FSCAL1, 0x00]))
            self._command(Command.UPDATE_REGISTER, bytes([Register.FSCAL0, 0x1F]))
            self._command(Command.UPDATE_REGISTER, bytes([Register.TEST1, 35]))
            self._command(Command.UPDATE_REGISTER, bytes([Register.TEST0, 0x09]))
            self._command(Command.UPDATE_REGISTER, bytes([Register.PATABLE0, PA_LEVELS[self.pa_level_index]]))
            self._command(Command.UPDATE_REGISTER, bytes([Register.FREND0, 0x00]))
            self._command(Command.UPDATE_REGISTER, bytes([Register.SYNC1, 0xA5]))
            self._command(Command.UPDATE_REGISTER, bytes([Register.SYNC0, 0x5A]))

            response = self._command(Command.GET_STATE)
            if response != b"OK":
                raise PacketRadioError("Rileylink state is not OK. Response returned: %s" % response)

            self.initialized = True

        except PacketRadioError as rle:
            self.logger.error("Error while initializing rileylink radio: %s", rle)
            raise

    def tx_up(self):
        if self.pa_level_index < len(PA_LEVELS) - 1:
            self.pa_level_index += 1
            self._set_amp(self.pa_level_index)

    def tx_down(self):
        if self.pa_level_index > 0:
            self.pa_level_index -= 1
            self._set_amp(self.pa_level_index)

    def set_tx_power(self, tx_power):
        if tx_power is None:
            return
        elif tx_power == TxPower.Lowest:
            self._set_amp(0)
        elif tx_power == TxPower.Low:
            self._set_amp(PA_LEVELS.index(0x12))
        elif tx_power == TxPower.Normal:
            self._set_amp(PA_LEVELS.index(0x60))
        elif tx_power == TxPower.High:
            self._set_amp(PA_LEVELS.index(0xC8))
        elif tx_power == TxPower.Highest:
            self._set_amp(PA_LEVELS.index(0xC0))

    def get_packet(self, timeout=5.0):
        try:
            self.connect()
            return self._command(Command.GET_PACKET, struct.pack(">BL", 0, int(timeout * 1000)),
                                 timeout=float(timeout)+0.5)
        except PacketRadioError as rle:
            self.logger.error("Error while receiving data: %s", rle)
            raise

    def send_and_receive_packet(self, packet, repeat_count, delay_ms, timeout_ms, retry_count, preamble_ext_ms):

        try:
            self.connect()
            return self._command(Command.SEND_AND_LISTEN,
                                  struct.pack(">BBHBLBH",
                                              0,
                                              repeat_count,
                                              delay_ms,
                                              0,
                                              timeout_ms,
                                              retry_count,
                                              preamble_ext_ms)
                                              + packet,
                                  timeout=30)
        except PacketRadioError as rle:
            self.logger.error("Error while sending and receiving data: %s", rle)
            raise

    def send_packet(self, packet, repeat_count, delay_ms, preamble_extension_ms):
        try:
            self.connect()
            result = self._command(Command.SEND_PACKET, struct.pack(">BBHH", 0, repeat_count, delay_ms,
                                                                   preamble_extension_ms) + packet,
                                  timeout=30)
            return result
        except PacketRadioError as rle:
            self.logger.error("Error while sending data: %s", rle)
            raise

    def _set_amp(self, index=None):
        try:
            self.connect()
            if index is not None:
                self.pa_level_index = index
            self._command(Command.UPDATE_REGISTER, bytes([Register.PATABLE0, PA_LEVELS[self.pa_level_index]]))
            self.logger.debug("Setting pa level to index %d of %d" % (self.pa_level_index, len(PA_LEVELS)))
        except PacketRadioError:
            self.logger.exception("Error while setting tx amplification")
            raise


    def _findRileyLink(self):
        scanner = Scanner()
        found = None
        self.logger.debug("Scanning for RileyLink")
        retries = 10
        while found is None and retries > 0:
            retries -= 1
            for result in scanner.scan(1.0):
                if result.getValueText(7) == RILEYLINK_SERVICE_UUID:
                    self.logger.debug("Found RileyLink")
                    found = result.addr
                    try:
                        with open(RILEYLINK_MAC_FILE, "w") as stream:
                            stream.write(result.addr)
                    except IOError:
                        self.logger.warning("Cannot store rileylink mac radio_address for later")
                    break

        if found is None:
            raise PacketRadioError("Could not find RileyLink")

        return found

    def _connect_retry(self, retries):
        while retries > 0:
            retries -= 1
            self.logger.info("Connecting to RileyLink, retries left: %d" % retries)

            try:
                self.peripheral.connect(self.address)
                self.logger.info("Connected")
                break
            except BTLEException as btlee:
                self.logger.warning("BTLE exception trying to connect: %s" % btlee)
                try:
                    p = subprocess.Popen(["ps", "-A"], stdout=subprocess.PIPE)
                    out, err = p.communicate()
                    for line in out.splitlines():
                        if "bluepy-helper" in line:
                            pid = int(line.split(None, 1)[0])
                            os.kill(pid, 9)
                            break
                except:
                    self.logger.warning("Failed to kill bluepy-helper")
                time.sleep(1)

    def _command(self, command_type, command_data=None, timeout=10.0):
        try:
            if command_data is None:
                data = bytes([1, command_type])
            else:
                data = bytes([len(command_data) + 1, command_type]) + command_data

            self.peripheral.writeCharacteristic(self.data_handle, data, withResponse=True)

            if not self.peripheral.waitForNotifications(timeout):
                raise PacketRadioError("Timed out while waiting for a response from RileyLink")

            response = self.peripheral.readCharacteristic(self.data_handle)

            if response is None or len(response) == 0:
                raise PacketRadioError("RileyLink returned no response")
            else:
                if response[0] == Response.COMMAND_SUCCESS:
                    return response[1:]
                elif response[0] == Response.COMMAND_INTERRUPTED:
                    self.logger.warning("A previous command was interrupted")
                    return response[1:]
                elif response[0] == Response.RX_TIMEOUT:
                    return None
                else:
                    raise PacketRadioError("RileyLink returned error code: %02X. Additional response data: %s"
                                         % (response[0], response[1:]), response[0])
        except Exception as e:
            raise PacketRadioError("Error executing command") from e
示例#2
0
    def __get_services_and_chars(self):
        for device in self.__devices_around:
            try:
                if self.__devices_around.get(
                        device) is not None and self.__devices_around[
                            device].get('scanned_device') is not None:
                    log.debug('Connecting to device: %s', device)
                    if self.__devices_around[device].get('peripheral') is None:
                        address_type = self.__devices_around[device][
                            'device_config'].get('addrType', "public")
                        peripheral = Peripheral(
                            self.__devices_around[device]['scanned_device'],
                            address_type)
                        self.__devices_around[device][
                            'peripheral'] = peripheral
                    else:
                        peripheral = self.__devices_around[device][
                            'peripheral']
                    try:
                        log.info(peripheral.getState())
                    except BTLEInternalError:
                        peripheral.connect(
                            self.__devices_around[device]['scanned_device'])
                    try:
                        services = peripheral.getServices()
                    except BTLEDisconnectError:
                        self.__check_and_reconnect(device)
                        services = peripheral.getServices()
                    for service in services:
                        if self.__devices_around[device].get(
                                'services') is None:
                            log.debug(
                                'Building device %s map, it may take a time, please wait...',
                                device)
                            self.__devices_around[device]['services'] = {}
                        service_uuid = str(service.uuid).upper()
                        if self.__devices_around[device]['services'].get(
                                service_uuid) is None:
                            self.__devices_around[device]['services'][
                                service_uuid] = {}

                            try:
                                characteristics = service.getCharacteristics()
                            except BTLEDisconnectError:
                                self.__check_and_reconnect(device)
                                characteristics = service.getCharacteristics()

                            if self.__config.get('buildDevicesMap', False):
                                for characteristic in characteristics:
                                    descriptors = []
                                    self.__check_and_reconnect(device)
                                    try:
                                        descriptors = characteristic.getDescriptors(
                                        )
                                    except BTLEDisconnectError:
                                        self.__check_and_reconnect(device)
                                        descriptors = characteristic.getDescriptors(
                                        )
                                    except BTLEGattError as e:
                                        log.debug(e)
                                    except Exception as e:
                                        log.exception(e)
                                    characteristic_uuid = str(
                                        characteristic.uuid).upper()
                                    if self.__devices_around[device][
                                            'services'][service_uuid].get(
                                                characteristic_uuid) is None:
                                        self.__check_and_reconnect(device)
                                        self.__devices_around[device][
                                            'services'][service_uuid][
                                                characteristic_uuid] = {
                                                    'characteristic':
                                                    characteristic,
                                                    'handle':
                                                    characteristic.handle,
                                                    'descriptors': {}
                                                }
                                    for descriptor in descriptors:
                                        log.debug(descriptor.handle)
                                        log.debug(str(descriptor.uuid))
                                        log.debug(str(descriptor))
                                        self.__devices_around[device][
                                            'services'][service_uuid][
                                                characteristic_uuid][
                                                    'descriptors'][
                                                        descriptor.
                                                        handle] = descriptor
                            else:
                                for characteristic in characteristics:
                                    characteristic_uuid = str(
                                        characteristic.uuid).upper()
                                    self.__devices_around[device]['services'][
                                        service_uuid][characteristic_uuid] = {
                                            'characteristic': characteristic,
                                            'handle': characteristic.handle
                                        }

                    if self.__devices_around[device]['is_new_device']:
                        log.debug('New device %s - processing.', device)
                        self.__devices_around[device]['is_new_device'] = False
                        self.__new_device_processing(device)
                    for interest_char in self.__devices_around[device][
                            'interest_uuid']:
                        characteristics_configs_for_processing_by_methods = {}

                        for configuration_section in self.__devices_around[
                                device]['interest_uuid'][interest_char]:
                            characteristic_uuid_from_config = configuration_section[
                                'section_config'].get("characteristicUUID")
                            if characteristic_uuid_from_config is None:
                                log.error(
                                    'Characteristic not found in config: %s',
                                    pformat(configuration_section))
                                continue
                            method = configuration_section[
                                'section_config'].get('method')
                            if method is None:
                                log.error('Method not found in config: %s',
                                          pformat(configuration_section))
                                continue
                            characteristics_configs_for_processing_by_methods[
                                method.upper()] = {
                                    "method":
                                    method,
                                    "characteristicUUID":
                                    characteristic_uuid_from_config
                                }
                        for method in characteristics_configs_for_processing_by_methods:
                            data = self.__service_processing(
                                device,
                                characteristics_configs_for_processing_by_methods[
                                    method])
                            for section in self.__devices_around[device][
                                    'interest_uuid'][interest_char]:
                                converter = section['converter']
                                converted_data = converter.convert(
                                    section, data)
                                self.statistics[
                                    'MessagesReceived'] = self.statistics[
                                        'MessagesReceived'] + 1
                                log.debug(data)
                                log.debug(converted_data)
                                self.__gateway.send_to_storage(
                                    self.get_name(), converted_data)
                                self.statistics[
                                    'MessagesSent'] = self.statistics[
                                        'MessagesSent'] + 1
            except BTLEDisconnectError:
                log.debug('Connection lost. Device %s', device)
                continue
            except Exception as e:
                log.exception(e)
示例#3
0
class RileyLink(PacketRadio):
    def __init__(self):
        self.peripheral = None
        self.pa_level_index = PA_LEVELS.index(0x84)
        self.data_handle = None
        self.logger = getLogger()
        self.packet_logger = get_packet_logger()
        self.address = g_rl_address
        self.service = None
        self.response_handle = None
        self.notify_event = Event()
        self.initialized = False
        self.manchester = ManchesterCodec()

    def connect(self, force_initialize=False):
        try:
            if self.address is None:
                self.address = self._findRileyLink()

            if self.peripheral is None:
                self.peripheral = Peripheral()

            try:
                state = self.peripheral.getState()
                if state == "conn":
                    return
            except BTLEException:
                pass

            self._connect_retry(3)

            self.service = self.peripheral.getServiceByUUID(
                RILEYLINK_SERVICE_UUID)
            data_char = self.service.getCharacteristics(
                RILEYLINK_DATA_CHAR_UUID)[0]
            self.data_handle = data_char.getHandle()

            char_response = self.service.getCharacteristics(
                RILEYLINK_RESPONSE_CHAR_UUID)[0]
            self.response_handle = char_response.getHandle()

            response_notify_handle = self.response_handle + 1
            notify_setup = b"\x01\x00"
            self.peripheral.writeCharacteristic(response_notify_handle,
                                                notify_setup)

            while self.peripheral.waitForNotifications(0.05):
                self.peripheral.readCharacteristic(self.data_handle)

            if self.initialized:
                self.init_radio(force_initialize)
            else:
                self.init_radio(True)
        except BTLEException as be:
            if self.peripheral is not None:
                self.disconnect()
            raise PacketRadioError("Error while connecting") from be
        except Exception as e:
            raise PacketRadioError("Error while connecting") from e

    def disconnect(self, ignore_errors=True):
        try:
            if self.peripheral is None:
                self.logger.info("Already disconnected")
                return
            self.logger.info("Disconnecting..")
            if self.response_handle is not None:
                response_notify_handle = self.response_handle + 1
                notify_setup = b"\x00\x00"
                self.peripheral.writeCharacteristic(response_notify_handle,
                                                    notify_setup)
        except Exception as e:
            if not ignore_errors:
                raise PacketRadioError("Error while disconnecting") from e
        finally:
            try:
                if self.peripheral is not None:
                    self.peripheral.disconnect()
                    self.peripheral = None
            except BTLEException as be:
                if ignore_errors:
                    self.logger.exception(
                        "Ignoring btle exception during disconnect")
                else:
                    raise PacketRadioError("Error while disconnecting") from be
            except Exception as e:
                raise PacketRadioError("Error while disconnecting") from e

    def get_info(self):
        try:
            self.connect()
            bs = self.peripheral.getServiceByUUID(XGATT_BATTERYSERVICE_UUID)
            bc = bs.getCharacteristics(XGATT_BATTERY_CHAR_UUID)[0]
            bch = bc.getHandle()
            battery_value = int(self.peripheral.readCharacteristic(bch)[0])
            self.logger.debug("Battery level read: %d", battery_value)
            version, v_major, v_minor = self._read_version()
            return {
                "battery_level": battery_value,
                "mac_address": self.address,
                "version_string": version,
                "version_major": v_major,
                "version_minor": v_minor
            }
        except Exception as e:
            raise PacketRadioError("Error communicating with RileyLink") from e
        finally:
            self.disconnect()

    def _read_version(self):
        global g_rl_version, g_rl_v_major, g_rl_v_minor
        version = None
        try:
            if g_rl_version is not None:
                return g_rl_version, g_rl_v_major, g_rl_v_minor
            else:
                response = self._command(Command.GET_VERSION)
                if response is not None and len(response) > 0:
                    version = response.decode("ascii")
                    self.logger.debug("RL reports version string: %s" %
                                      version)
                    g_rl_version = version

            if version is None:
                return "0.0", 0, 0

            try:
                m = re.search(".+([0-9]+)\\.([0-9]+)", version)
                if m is None:
                    raise PacketRadioError(
                        "Failed to parse firmware version string: %s" %
                        version)

                g_rl_v_major = int(m.group(1))
                g_rl_v_minor = int(m.group(2))
                self.logger.debug("Interpreted version major: %d minor: %d" %
                                  (g_rl_v_major, g_rl_v_minor))

                return g_rl_version, g_rl_v_major, g_rl_v_minor

            except Exception as ex:
                raise PacketRadioError(
                    "Failed to parse firmware version string: %s" %
                    version) from ex

        except PacketRadioError:
            raise
        except Exception as e:
            raise PacketRadioError("Error while reading version") from e

    def init_radio(self, force_init=False):
        try:
            version, v_major, v_minor = self._read_version()

            if v_major < 2:
                self.logger.error("Firmware version is below 2.0")
                raise PacketRadioError(
                    "Unsupported RileyLink firmware %d.%d (%s)" %
                    (v_major, v_minor, version))

            if not force_init:
                if v_major == 2 and v_minor < 3:
                    response = self._command(Command.READ_REGISTER,
                                             bytes([Register.PKTLEN, 0x00]))
                else:
                    response = self._command(Command.READ_REGISTER,
                                             bytes([Register.PKTLEN]))
                if response is not None and len(
                        response) > 0 and response[0] == 0x50:
                    return

            self._command(Command.RADIO_RESET_CONFIG)
            self._command(Command.SET_SW_ENCODING, bytes([Encoding.NONE]))
            self._command(Command.SET_PREAMBLE, bytes([0x66, 0x65]))
            #self._command(Command.SET_PREAMBLE, bytes([0, 0]))

            frequency = int(433910000 / (24000000 / pow(2, 16)))
            self._command(Command.UPDATE_REGISTER,
                          bytes([Register.FREQ0, frequency & 0xff]))
            self._command(Command.UPDATE_REGISTER,
                          bytes([Register.FREQ1, (frequency >> 8) & 0xff]))
            self._command(Command.UPDATE_REGISTER,
                          bytes([Register.FREQ2, (frequency >> 16) & 0xff]))
            # self._command(Command.UPDATE_REGISTER, bytes([Register.FREQ0, 0x5f]))
            # self._command(Command.UPDATE_REGISTER, bytes([Register.FREQ1, 0x14]))
            # self._command(Command.UPDATE_REGISTER, bytes([Register.FREQ2, 0x12]))

            self._command(Command.UPDATE_REGISTER,
                          bytes([Register.DEVIATN, 0x44]))
            # self._command(Command.UPDATE_REGISTER, bytes([Register.DEVIATN, 0x44]))

            self._command(Command.UPDATE_REGISTER,
                          bytes([Register.PKTCTRL1, 0x20]))
            self._command(Command.UPDATE_REGISTER,
                          bytes([Register.PKTCTRL0, 0x00]))
            self._command(Command.UPDATE_REGISTER,
                          bytes([Register.PKTLEN, 0x50]))
            # self._command(Command.UPDATE_REGISTER, bytes([Register.PKTCTRL1, 0x60]))
            # self._command(Command.UPDATE_REGISTER, bytes([Register.PKTCTRL0, 0x04]))

            self._command(Command.UPDATE_REGISTER,
                          bytes([Register.FSCTRL1, 0x06]))
            # self._command(Command.UPDATE_REGISTER, bytes([Register.FSCTRL1, 0x06]))

            self._command(Command.UPDATE_REGISTER,
                          bytes([Register.MDMCFG4, 0xCA]))
            self._command(Command.UPDATE_REGISTER,
                          bytes([Register.MDMCFG3, 0xBC]))
            self._command(Command.UPDATE_REGISTER,
                          bytes([Register.MDMCFG2, 0x06]))
            self._command(Command.UPDATE_REGISTER,
                          bytes([Register.MDMCFG1, 0x70]))
            self._command(Command.UPDATE_REGISTER,
                          bytes([Register.MDMCFG0, 0x11]))
            self._command(Command.UPDATE_REGISTER,
                          bytes([Register.MCSM0, 0x18]))
            # self._command(Command.UPDATE_REGISTER, bytes([Register.MDMCFG4, 0xDA]))
            # self._command(Command.UPDATE_REGISTER, bytes([Register.MDMCFG3, 0xB5]))
            # self._command(Command.UPDATE_REGISTER, bytes([Register.MDMCFG2, 0x12]))
            # self._command(Command.UPDATE_REGISTER, bytes([Register.MDMCFG1, 0x23]))
            # self._command(Command.UPDATE_REGISTER, bytes([Register.MDMCFG0, 0x11]))
            # self._command(Command.UPDATE_REGISTER, bytes([Register.MCSM0, 0x18]))

            self._command(Command.UPDATE_REGISTER,
                          bytes([Register.FOCCFG, 0x17]))
            self._command(Command.UPDATE_REGISTER,
                          bytes([Register.FSCAL3, 0xE9]))
            self._command(Command.UPDATE_REGISTER,
                          bytes([Register.FSCAL2, 0x2A]))
            self._command(Command.UPDATE_REGISTER,
                          bytes([Register.FSCAL1, 0x00]))
            self._command(Command.UPDATE_REGISTER,
                          bytes([Register.FSCAL0, 0x1F]))
            self._command(Command.UPDATE_REGISTER,
                          bytes([Register.TEST1, 0x31]))
            self._command(Command.UPDATE_REGISTER,
                          bytes([Register.TEST0, 0x09]))
            # self._command(Command.UPDATE_REGISTER, bytes([Register.FOCCFG, 0x17]))
            # self._command(Command.UPDATE_REGISTER, bytes([Register.FSCAL3, 0xE9]))
            # self._command(Command.UPDATE_REGISTER, bytes([Register.FSCAL2, 0x2A]))
            # self._command(Command.UPDATE_REGISTER, bytes([Register.FSCAL1, 0x00]))
            # self._command(Command.UPDATE_REGISTER, bytes([Register.FSCAL0, 0x1F]))
            # self._command(Command.UPDATE_REGISTER, bytes([Register.TEST2, 0x81])) ## register not defined on RL
            # self._command(Command.UPDATE_REGISTER, bytes([Register.TEST1, 0x35]))
            # self._command(Command.UPDATE_REGISTER, bytes([Register.TEST0, 0x09]))

            self._command(
                Command.UPDATE_REGISTER,
                bytes([Register.PATABLE0, PA_LEVELS[self.pa_level_index]]))
            self._command(Command.UPDATE_REGISTER,
                          bytes([Register.FREND0, 0x00]))
            #self._command(Command.UPDATE_REGISTER, bytes([Register.SYNC1, 0xA5]))
            #self._command(Command.UPDATE_REGISTER, bytes([Register.SYNC0, 0x5A]))
            # self._command(Command.UPDATE_REGISTER, bytes([Register.PATABLE0, PA_LEVELS[self.pa_level_index]]))
            # self._command(Command.UPDATE_REGISTER, bytes([Register.FREND0, 0x00]))
            self._command(Command.UPDATE_REGISTER,
                          bytes([Register.SYNC1, 0xA5]))
            self._command(Command.UPDATE_REGISTER,
                          bytes([Register.SYNC0, 0x5A]))

            response = self._command(Command.GET_STATE)
            if response != b"OK":
                raise PacketRadioError(
                    "Rileylink state is not OK. Response returned: %s" %
                    response)

            self.initialized = True

        except Exception as e:
            raise PacketRadioError(
                "Error while initializing rileylink radio: %s", e)

    def tx_up(self):
        try:
            if self.pa_level_index < len(PA_LEVELS) - 1:
                self.pa_level_index += 1
                self._set_amp(self.pa_level_index)
        except Exception as e:
            raise PacketRadioError("Error while setting tx up") from e

    def tx_down(self):
        try:
            if self.pa_level_index > 0:
                self.pa_level_index -= 1
                self._set_amp(self.pa_level_index)
        except Exception as e:
            raise PacketRadioError("Error while setting tx down") from e

    def set_tx_power(self, tx_power):
        try:
            if tx_power is None:
                return
            elif tx_power == TxPower.Lowest:
                self._set_amp(0)
            elif tx_power == TxPower.Low:
                self._set_amp(PA_LEVELS.index(0x1D))
            elif tx_power == TxPower.Normal:
                self._set_amp(PA_LEVELS.index(0x84))
            elif tx_power == TxPower.High:
                self._set_amp(PA_LEVELS.index(0xC8))
            elif tx_power == TxPower.Highest:
                self._set_amp(PA_LEVELS.index(0xC0))
        except Exception as e:
            raise PacketRadioError("Error while setting tx level") from e

    def get_packet(self, timeout=5.0):
        try:
            self.connect()
            result = self._command(Command.GET_PACKET,
                                   struct.pack(">BL", 0, int(timeout * 1000)),
                                   timeout=float(timeout) + 0.5)
            if result is not None:
                return result[0:2] + self.manchester.decode(result[2:])
            else:
                return None
        except Exception as e:
            raise PacketRadioError("Error while getting radio packet") from e

    def send_and_receive_packet(self, packet, repeat_count, delay_ms,
                                timeout_ms, retry_count, preamble_ext_ms):
        try:
            self.connect()
            data = self.manchester.encode(packet)
            result = self._command(
                Command.SEND_AND_LISTEN,
                struct.pack(">BBHBLBH", 0, repeat_count, delay_ms, 0,
                            timeout_ms, retry_count, preamble_ext_ms) + data,
                timeout=30)
            if result is not None:
                return result[0:2] + self.manchester.decode(result[2:])
            else:
                return None
        except Exception as e:
            raise PacketRadioError(
                "Error while sending and receiving data") from e

    def send_packet(self, packet, repeat_count, delay_ms,
                    preamble_extension_ms):
        try:
            self.connect()
            data = self.manchester.encode(packet)
            result = self._command(
                Command.SEND_PACKET,
                struct.pack(">BBHH", 0, repeat_count, delay_ms,
                            preamble_extension_ms) + data,
                timeout=30)
            return result
        except Exception as e:
            raise PacketRadioError("Error while sending data") from e

    def _set_amp(self, index=None):
        try:
            if index is not None:
                previous_level = self.pa_level_index
                self.pa_level_index = index
                if PA_LEVELS[previous_level] == PA_LEVELS[index]:
                    return
            self.connect()
            self._command(
                Command.UPDATE_REGISTER,
                bytes([Register.PATABLE0, PA_LEVELS[self.pa_level_index]]))
            self.packet_logger.debug("Setting pa to %02X (%d of %d)" %
                                     (PA_LEVELS[self.pa_level_index],
                                      self.pa_level_index, len(PA_LEVELS)))
        except PacketRadioError:
            self.logger.exception("Error while setting tx amplification")
            raise

    def _findRileyLink(self):
        global g_rl_address
        scanner = Scanner()
        g_rl_address = None
        self.logger.debug("Scanning for RileyLink")
        retries = 10
        while g_rl_address is None and retries > 0:
            retries -= 1
            for result in scanner.scan(1.0):
                if result.getValueText(7) == RILEYLINK_SERVICE_UUID:
                    self.logger.debug("Found RileyLink")
                    g_rl_address = result.addr

        if g_rl_address is None:
            raise PacketRadioError("Could not find RileyLink")

        return g_rl_address

    def _connect_retry(self, retries):
        while retries > 0:
            retries -= 1
            self.logger.info("Connecting to RileyLink, retries left: %d" %
                             retries)

            try:
                self.peripheral.connect(self.address)
                self.logger.info("Connected")
                break
            except BTLEException as btlee:
                self.logger.warning("BTLE exception trying to connect: %s" %
                                    btlee)
                try:
                    p = subprocess.Popen(["ps", "-A"], stdout=subprocess.PIPE)
                    out, err = p.communicate()
                    for line in out.splitlines():
                        if "bluepy-helper" in line:
                            pid = int(line.split(None, 1)[0])
                            os.kill(pid, 9)
                            break
                except:
                    self.logger.warning("Failed to kill bluepy-helper")
                time.sleep(1)

    def _command(self, command_type, command_data=None, timeout=10.0):
        try:
            if command_data is None:
                data = bytes([1, command_type])
            else:
                data = bytes([len(command_data) + 1, command_type
                              ]) + command_data

            self.peripheral.writeCharacteristic(self.data_handle,
                                                data,
                                                withResponse=True)

            if not self.peripheral.waitForNotifications(timeout):
                raise PacketRadioError(
                    "Timed out while waiting for a response from RileyLink")

            response = self.peripheral.readCharacteristic(self.data_handle)

            if response is None or len(response) == 0:
                raise PacketRadioError("RileyLink returned no response")
            else:
                if response[0] == Response.COMMAND_SUCCESS:
                    return response[1:]
                elif response[0] == Response.COMMAND_INTERRUPTED:
                    self.logger.warning("A previous command was interrupted")
                    return response[1:]
                elif response[0] == Response.RX_TIMEOUT:
                    return None
                else:
                    raise PacketRadioError(
                        "RileyLink returned error code: %02X. Additional response data: %s"
                        % (response[0], response[1:]), response[0])
        except PacketRadioError:
            raise
        except Exception as e:
            raise PacketRadioError("Error executing command") from e
class BleVestDevice(VestDevice):
    def __init__(self, deviceAddr):
        try:
            self._peripheral = Peripheral(deviceAddr)
            serviceUUID = UUID("713d0000-503e-4c75-ba94-3148f18d941e")
            characteristicUUID = UUID("713d0003-503e-4c75-ba94-3148f18d941e")
            s = self._peripheral.getServiceByUUID(serviceUUID)
            self._characteristic = s.getCharacteristics(characteristicUUID)[0]
        except Exception as e:
            print("Error: " + str(e))
            
    def __isValidState(self):        
        return self._peripheral.getState() == "conn"
    
    def __write(self, byteArr):
        self._peripheral.writeCharacteristic(self._characteristic.getHandle(), byteArr)
            
    def set_pin(self, index, intensity):
        """Sets a pin to a given intensity.
        index: an integer from 0 - 6
        intensity: an integer from 0 - 255
        """
        if self.__isValidState():
            rList=[0,index,intensity]
            self.__write(bytes(rList))
            
    def set_frequency(self,frequency):
        """Sets the frequency of the entire vest.
        frequency.
        """
        if self.__isValidState():
            rList=[4, frequency & (255), (frequency & (255 << 8)) >> 8, (frequency & (255 << 16)) >> 16, (frequency & (255 << 24)) >> 24]
            b = bytes(rList)
            self.__write(b)
    
    def mute(self):
        """Stops all motors on the vest from vibrating"""
        if self.__isValidState():
            rList=[3]
            self.__write(bytes(rList))
    
    def set_motor(self,index,rotation):
        """
        Sets a given motor index to a given target rotation.
        """
        if self.__isValidState():
            rList = [11,index,rotation]
            self.__write(bytes(rList))
            
    def set_motor_speed(self,speed):
        """
        Changes how long it takes to move 1 degree per millisecond.
        """
        if speed <= 0:
            raise ValueError("speed must be greater than 0.")
        rList = [12,speed]
        self.__write(bytes(rList))

    def set_pins_batched(self, values = dict):
        for pin in values:
            self.set_pin(pin, values[pin])
示例#5
0
import struct
from bluepy.btle import Scanner, DefaultDelegate, Peripheral

device = Peripheral()

device.connect('78:A3:52:00:04:2D')
services = device.getServices()
characteristics = device.getCharacteristics()
descriptors = device.getDescriptors()
state = device.getState()

#displays all services
for service in services:
   print(service)

print("Handle   UUID                                Properties")
print("-------------------------------------------------------")                     
for ch in characteristics:
    print("  0x"+ format(ch.getHandle(),'02X')  +"   "+str(ch.uuid) +" " + ch.propertiesToString())
    if ch.uuid == '19b10011-e8f2-537e-4f6c-d104768a1214':
        print(struct.unpack('i', ch.read())[0])
示例#6
0
class RileyLink:
    def __init__(self, address=None):
        self.peripheral = None
        self.data_handle = None
        if address is None:
            if os.path.exists(RILEYLINK_MAC_FILE):
                with open(RILEYLINK_MAC_FILE, "r") as stream:
                    address = stream.read()
        self.address = address
        self.service = None
        self.response_handle = None
        self.notify_event = Event()

    def connect(self, force_initialize=False):
        try:
            if self.address is None:
                self.address = self._findRileyLink()

            if self.peripheral is None:
                self.peripheral = Peripheral()

            try:
                state = self.peripheral.getState()
                if state == "conn":
                    return
            except BTLEException:
                pass

            self._connect_retry(3)

            self.service = self.peripheral.getServiceByUUID(
                RILEYLINK_SERVICE_UUID)
            data_char = self.service.getCharacteristics(
                RILEYLINK_DATA_CHAR_UUID)[0]
            self.data_handle = data_char.getHandle()

            char_response = self.service.getCharacteristics(
                RILEYLINK_RESPONSE_CHAR_UUID)[0]
            self.response_handle = char_response.getHandle()

            response_notify_handle = self.response_handle + 1
            notify_setup = b"\x01\x00"
            self.peripheral.writeCharacteristic(response_notify_handle,
                                                notify_setup)

            while self.peripheral.waitForNotifications(0.05):
                self.peripheral.readCharacteristic(self.data_handle)

            self.init_radio(force_initialize)
        except BTLEException:
            if self.peripheral is not None:
                self.disconnect()
            raise

    def disconnect(self, ignore_errors=True):
        try:
            if self.peripheral is None:
                logging.info("Already disconnected")
                return
            logging.info("Disconnecting..")
            if self.response_handle is not None:
                response_notify_handle = self.response_handle + 1
                notify_setup = b"\x00\x00"
                self.peripheral.writeCharacteristic(response_notify_handle,
                                                    notify_setup)
        except BTLEException:
            if not ignore_errors:
                raise
        finally:
            try:
                if self.peripheral is not None:
                    self.peripheral.disconnect()
                    self.peripheral = None
            except BTLEException as btlee:
                if ignore_errors:
                    logging.warning(
                        "Ignoring btle exception during disconnect: %s" %
                        btlee)
                else:
                    raise

    def get_info(self):
        try:
            self.connect()
            bs = self.peripheral.getServiceByUUID(XGATT_BATTERYSERVICE_UUID)
            bc = bs.getCharacteristics(XGATT_BATTERY_CHAR_UUID)[0]
            bch = bc.getHandle()
            battery_value = int(self.peripheral.readCharacteristic(bch)[0])
            logging.debug("Battery level read: %d", battery_value)
            version, v_major, v_minor = self._read_version()
            return {
                "battery_level": battery_value,
                "mac_address": self.address,
                "version_string": version,
                "version_major": v_major,
                "version_minor": v_minor
            }
        except BTLEException as btlee:
            raise RileyLinkError(
                "Error communicating with RileyLink") from btlee
        finally:
            self.disconnect()

    def _read_version(self):
        version = None
        try:
            if os.path.exists(RILEYLINK_VERSION_FILE):
                with open(RILEYLINK_VERSION_FILE, "r") as stream:
                    version = stream.read()
            else:
                response = self._command(Command.GET_VERSION)
                if response is not None and len(response) > 0:
                    version = response.decode("ascii")
                    logging.debug("RL reports version string: %s" % version)

                    try:
                        with open(RILEYLINK_VERSION_FILE, "w") as stream:
                            stream.write(version)
                    except IOError:
                        logging.exception("Failed to store version in file")

            if version is None:
                return "0.0", 0, 0

            try:
                m = re.search(".+([0-9]+)\\.([0-9]+)", version)
                if m is None:
                    raise RileyLinkError(
                        "Failed to parse firmware version string: %s" %
                        version)

                v_major = int(m.group(1))
                v_minor = int(m.group(2))
                logging.debug("Interpreted version major: %d minor: %d" %
                              (v_major, v_minor))

                return version, v_major, v_minor

            except Exception as ex:
                raise RileyLinkError(
                    "Failed to parse firmware version string: %s" %
                    version) from ex

        except IOError:
            logging.exception("Error reading version file")
        except RileyLinkError:
            raise

        response = self._command(Command.GET_VERSION)
        if response is not None and len(response) > 0:
            version = response.decode("ascii")
            logging.debug("RL reports version string: %s" % version)
            try:
                m = re.search(".+([0-9]+)\\.([0-9]+)", version)
                if m is None:
                    raise RileyLinkError(
                        "Failed to parse firmware version string: %s" %
                        version)

                v_major = int(m.group(1))
                v_minor = int(m.group(2))
                logging.debug("Interpreted version major: %d minor: %d" %
                              (v_major, v_minor))

                return (version, v_major, v_minor)
            except RileyLinkError:
                raise
            except Exception as ex:
                raise RileyLinkError(
                    "Failed to parse firmware version string: %s" %
                    version) from ex

    def init_radio(self, force_init=False):
        try:
            version, v_major, v_minor = self._read_version()

            if v_major < 2:
                logging.error("Firmware version is below 2.0")
                raise RileyLinkError(
                    "Unsupported RileyLink firmware %d.%d (%s)" %
                    (v_major, v_minor, version))

            if not force_init:
                if v_major == 2 and v_minor < 3:
                    response = self._command(Command.READ_REGISTER,
                                             bytes([Register.SYNC1, 0x00]))
                else:
                    response = self._command(Command.READ_REGISTER,
                                             bytes([Register.SYNC1]))
                if response is not None and len(
                        response) > 0 and response[0] == 0xA5:
                    return

            self._command(Command.RADIO_RESET_CONFIG)
            self._command(Command.SET_SW_ENCODING,
                          bytes([Encoding.MANCHESTER]))
            frequency = int(433910000 / (24000000 / pow(2, 16)))
            self._command(Command.SET_PREAMBLE, bytes([0x66, 0x65]))
            self._command(Command.UPDATE_REGISTER,
                          bytes([Register.FREQ0, frequency & 0xff]))
            self._command(Command.UPDATE_REGISTER,
                          bytes([Register.FREQ1, (frequency >> 8) & 0xff]))
            self._command(Command.UPDATE_REGISTER,
                          bytes([Register.FREQ2, (frequency >> 16) & 0xff]))
            self._command(Command.UPDATE_REGISTER,
                          bytes([Register.PKTCTRL1, 0x20]))
            self._command(Command.UPDATE_REGISTER,
                          bytes([Register.PKTCTRL0, 0x00]))
            self._command(Command.UPDATE_REGISTER,
                          bytes([Register.FSCTRL1, 0x06]))
            self._command(Command.UPDATE_REGISTER,
                          bytes([Register.MDMCFG4, 0xCA]))
            self._command(Command.UPDATE_REGISTER,
                          bytes([Register.MDMCFG3, 0xBC]))
            self._command(Command.UPDATE_REGISTER,
                          bytes([Register.MDMCFG2, 0x06]))
            self._command(Command.UPDATE_REGISTER,
                          bytes([Register.MDMCFG1, 0x70]))
            self._command(Command.UPDATE_REGISTER,
                          bytes([Register.MDMCFG0, 0x11]))
            self._command(Command.UPDATE_REGISTER,
                          bytes([Register.DEVIATN, 0x44]))
            self._command(Command.UPDATE_REGISTER,
                          bytes([Register.MCSM0, 0x18]))
            self._command(Command.UPDATE_REGISTER,
                          bytes([Register.FOCCFG, 0x17]))
            self._command(Command.UPDATE_REGISTER,
                          bytes([Register.FSCAL3, 0xE9]))
            self._command(Command.UPDATE_REGISTER,
                          bytes([Register.FSCAL2, 0x2A]))
            self._command(Command.UPDATE_REGISTER,
                          bytes([Register.FSCAL1, 0x00]))
            self._command(Command.UPDATE_REGISTER,
                          bytes([Register.FSCAL0, 0x1F]))
            self._command(Command.UPDATE_REGISTER,
                          bytes([Register.TEST1, 0x31]))
            self._command(Command.UPDATE_REGISTER,
                          bytes([Register.TEST0, 0x09]))
            self._command(Command.UPDATE_REGISTER,
                          bytes([Register.PATABLE0, 0x84]))
            self._command(Command.UPDATE_REGISTER,
                          bytes([Register.SYNC1, 0xA5]))
            self._command(Command.UPDATE_REGISTER,
                          bytes([Register.SYNC0, 0x5A]))

            response = self._command(Command.GET_STATE)
            if response != b"OK":
                raise RileyLinkError(
                    "Rileylink state is not OK. Response returned: %s" %
                    response)

        except RileyLinkError as rle:
            logging.error("Error while initializing rileylink radio: %s", rle)
            raise

    def get_packet(self, timeout=5.0):
        try:
            self.connect()
            return self._command(Command.GET_PACKET,
                                 struct.pack(">BL", 0, int(timeout * 1000)),
                                 timeout=float(timeout) + 0.5)
        except RileyLinkError as rle:
            logging.error("Error while receiving data: %s", rle)
            raise

    def send_and_receive_packet(self, packet, repeat_count, delay_ms,
                                timeout_ms, retry_count, preamble_ext_ms):

        logging.debug("sending packet: %s" % packet.hex())
        try:
            self.connect()
            return self._command(
                Command.SEND_AND_LISTEN,
                struct.pack(">BBHBLBH", 0, repeat_count, delay_ms, 0,
                            timeout_ms, retry_count, preamble_ext_ms) + packet,
                timeout=30)
        except RileyLinkError as rle:
            logging.error("Error while sending and receiving data: %s", rle)
            raise

    def send_packet(self, packet, repeat_count, delay_ms,
                    preamble_extension_ms):
        try:
            self.connect()
            result = self._command(
                Command.SEND_PACKET,
                struct.pack(">BBHH", 0, repeat_count, delay_ms,
                            preamble_extension_ms) + packet,
                timeout=30)
            return result
        except RileyLinkError as rle:
            logging.error("Error while sending data: %s", rle)
            raise

    def _findRileyLink(self):
        scanner = Scanner()
        found = None
        logging.debug("Scanning for RileyLink")
        retries = 10
        while found is None and retries > 0:
            retries -= 1
            for result in scanner.scan(1.0):
                if result.getValueText(7) == RILEYLINK_SERVICE_UUID:
                    logging.debug("Found RileyLink")
                    found = result.addr
                    try:
                        with open(RILEYLINK_MAC_FILE, "w") as stream:
                            stream.write(result.addr)
                    except IOError:
                        logging.warning(
                            "Cannot store rileylink mac address for later")
                    break

        if found is None:
            raise RileyLinkError("Could not find RileyLink")

        return found

    def _connect_retry(self, retries):
        while retries > 0:
            retries -= 1
            logging.info("Connecting to RileyLink, retries left: %d" % retries)
            try:
                self.peripheral.connect(self.address)
                logging.info("Connected")
                break
            except BTLEException as btlee:
                logging.warning("BTLE exception trying to connect: %s" % btlee)
                time.sleep(2)

    def _command(self, command_type, command_data=None, timeout=10.0):
        if command_data is None:
            data = bytes([1, command_type])
        else:
            data = bytes([len(command_data) + 1, command_type]) + command_data

        self.peripheral.writeCharacteristic(self.data_handle,
                                            data,
                                            withResponse=True)

        if not self.peripheral.waitForNotifications(timeout):
            raise RileyLinkError(
                "Timed out while waiting for a response from RileyLink")

        response = self.peripheral.readCharacteristic(self.data_handle)

        if response is None or len(response) == 0:
            raise RileyLinkError("RileyLink returned no response")
        else:
            if response[0] == Response.COMMAND_SUCCESS:
                return response[1:]
            elif response[0] == Response.COMMAND_INTERRUPTED:
                logging.warning("A previous command was interrupted")
                return response[1:]
            elif response[0] == Response.RX_TIMEOUT:
                return None
            else:
                raise RileyLinkError(
                    "RileyLink returned error code: %02X. Additional response data: %s"
                    % (response[0], response[1:]), response[0])
示例#7
0
from bluepy.btle import Scanner, Peripheral
import signal

scanner = Scanner()
devices = scanner.scan(3)
addr = None

for d in devices:
    for (adtype, desc, value) in d.getScanData():
        if adtype == 9 and value == 'CC2650 SensorTag':
            print('SensorTag: {}, RSSI: {}dB'.format(d.addr, d.rssi))
            addr = d.addr

if addr != None:
    # 接続開始
    tag = Peripheral(addr)
    # 接続状態の確認 状態が`conn`なら接続できている
    print('State: {}'.format(tag.getState()))
    print('Press Ctrl+C to exit.')
    signal.pause()

print('SensorTag not found.')