Example #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
Example #2
0
    def __init__(self,addr,version=AUTODETECT):
        Peripheral.__init__(self,addr)
        if version==AUTODETECT:
            svcs = self.discoverServices()
            if _TI_UUID(0xAA70) in svcs:
                version = SENSORTAG_2650
            else:
                version = SENSORTAG_V1

        fwVers = self.getCharacteristics(uuid=AssignedNumbers.firmwareRevisionString)
        if len(fwVers) >= 1:
            self.firmwareVersion = fwVers[0].read().decode("utf-8")
        else:
            self.firmwareVersion = u''

        if version==SENSORTAG_V1:
            self.IRtemperature = IRTemperatureSensor(self)
            self.accelerometer = AccelerometerSensor(self)
            self.humidity = HumiditySensor(self)
            self.magnetometer = MagnetometerSensor(self)
            self.barometer = BarometerSensor(self)
            self.gyroscope = GyroscopeSensor(self)
            self.keypress = KeypressSensor(self)
            self.lightmeter = None
        elif version==SENSORTAG_2650:
            self._mpu9250 = MovementSensorMPU9250(self)
            self.IRtemperature = IRTemperatureSensorTMP007(self)
            self.accelerometer = AccelerometerSensorMPU9250(self._mpu9250)
            self.humidity = HumiditySensorHDC1000(self)
            self.magnetometer = MagnetometerSensorMPU9250(self._mpu9250)
            self.barometer = BarometerSensorBMP280(self)
            self.gyroscope = GyroscopeSensorMPU9250(self._mpu9250)
            self.keypress = KeypressSensor(self)
            self.lightmeter = OpticalSensorOPT3001(self)
            self.battery = BatterySensor(self)
Example #3
0
 def __init__(self, addr):
     print("Press the Angel Sensor's button to continue...")
     while True:
         try:
             Peripheral.__init__(self, addr, addrType=ADDR_TYPE_PUBLIC)
         except BTLEException:
             time.sleep(0.5)
             continue
         break
Example #4
0
    def __init__(self, addr):
        Peripheral.__init__(self, addr, addrType=ADDR_TYPE_RANDOM)

        # Thingy configuration service not implemented
        self.battery = BatterySensor(self)
        self.environment = EnvironmentService(self)
        self.ui = UserInterfaceService(self)
        self.motion = MotionService(self)
        self.sound = SoundService(self)
Example #5
0
class Nuimo(object):

    SERVICE_UUIDS = [
        UUID('0000180f-0000-1000-8000-00805f9b34fb'), # Battery
        UUID('f29b1525-cb19-40f3-be5c-7241ecb82fd2'), # Sensors
        UUID('f29b1523-cb19-40f3-be5c-7241ecb82fd1')  # LED Matrix
    ]

    CHARACTERISTIC_UUIDS = {
        UUID('00002a19-0000-1000-8000-00805f9b34fb'): 'BATTERY',
        UUID('f29b1529-cb19-40f3-be5c-7241ecb82fd2'): 'BUTTON',
        UUID('f29b1528-cb19-40f3-be5c-7241ecb82fd2'): 'ROTATION',
        UUID('f29b1527-cb19-40f3-be5c-7241ecb82fd2'): 'SWIPE',
        UUID('f29b1526-cb19-40f3-be5c-7241ecb82fd2'): 'FLY',
        UUID('f29b1524-cb19-40f3-be5c-7241ecb82fd1'): 'LED_MATRIX'
    }

    NOTIFICATION_CHARACTERISTIC_UUIDS = [
        'BATTERY', # Uncomment only if you are not using the iOS emulator (iOS does't support battery updates without authentication)
        'BUTTON',
        'ROTATION',
        'SWIPE',
        'FLY']

    # Notification data
    NOTIFICATION_ON = struct.pack("BB", 0x01, 0x00)
    NOTIFICATION_OFF = struct.pack("BB", 0x00, 0x00)

    def __init__(self, mac_address):
        self.macAddress = mac_address
        self.delegate=NuimoDelegate(self)

    def set_delegate(self, delegate):
        self.delegate = delegate

    def connect(self):
        self.peripheral = Peripheral(self.macAddress, addrType='random')
        # Retrieve all characteristics from desired services and map them from their UUID
        characteristics = list(itertools.chain(*[self.peripheral.getServiceByUUID(uuid).getCharacteristics() for uuid in Nuimo.SERVICE_UUIDS]))
        characteristics = dict((c.uuid, c) for c in characteristics)
        # Store each characteristic's value handle for each characteristic name
        self.characteristicValueHandles = dict((name, characteristics[uuid].getHandle()) for uuid, name in Nuimo.CHARACTERISTIC_UUIDS.items())
        # Subscribe for notifications
        for name in Nuimo.NOTIFICATION_CHARACTERISTIC_UUIDS:
            self.peripheral.writeCharacteristic(self.characteristicValueHandles[name] + 1, Nuimo.NOTIFICATION_ON, True)
        self.peripheral.setDelegate(self.delegate)

    def wait_for_notifications(self):
        self.peripheral.wait_for_notifications(1.0)

    def display_led_matrix(self, matrix, timeout, brightness=1.0):
        matrix = '{:<81}'.format(matrix[:81])
        bites = list(map(lambda leds: reduce(lambda acc, led: acc + (1 << led if leds[led] not in [' ', '0'] else 0), range(0, len(leds)), 0), [matrix[i:i+8] for i in range(0, len(matrix), 8)]))
        self.peripheral.writeCharacteristic(self.characteristicValueHandles['LED_MATRIX'], struct.pack('BBBBBBBBBBBBB', bites[0], bites[1], bites[2], bites[3], bites[4], bites[5], bites[6], bites[7], bites[8], bites[9], bites[10], max(0, min(255, int(255.0 * brightness))), max(0, min(255, int(timeout * 10.0)))), True)
Example #6
0
 def __init__(self, peripheral):
   self.mac = peripheral.addr
   self.sent_alert = False
   self.amb_temp = None
   self.temp_job_id = None
   self.peripheral = Peripheral(peripheral)
   self.characteristics = {}
    def __init__(self, mac):
        self.conn = Peripheral(mac)
        self.conn.setDelegate(self)
        self.count = 0
        self.buffin = [None]*10
        self.got1 = False
        print('connected')
        
        self.service = self.conn.getServiceByUUID(_LBN_UUID(0x10))
        self.serial = self.service.getCharacteristics(_LBN_UUID(0x11)) [0]
        
        #print(self.serial.propertiesToString())

        # Turn on notificiations
        self.conn.writeCharacteristic(0x2f, '\x01\x00', False)
        
        i = 0
        while True:
            #print(self.serial.read())
            self.write("a" * 60)
            #self.write("a" * 5)
            #self.sendCmd(LightBlueBean.MSG_ID_CC_ACCEL_READ)
            
            self.conn.waitForNotifications(1)
            time.sleep(1)
        self.conn.disconnect()
Example #8
0
 def __init__(self, address, pincode):
     print("Connecting to %s..." % address)
     self.pincode = pincode
     self.periph = Peripheral(address)
     self._ipcamservice()
     self.name = self.periph.getCharacteristics(uuid=0x2a00)[0].read().decode() # wellknown name characteristic
     print("Connected to '%s'" % self.name)
Example #9
0
    def write(self, characteristic, data):
        try:
            dev = Peripheral(self, self.addrType)

            services = sorted(dev.services, key=lambda s: s.hndStart)

            print_status("Searching for characteristic {}".format(characteristic))
            char = None
            for service in services:
                if char is not None:
                    break

                for _, c in enumerate(service.getCharacteristics()):
                    if str(c.uuid) == characteristic:
                        char = c
                        break

            if char:
                if "WRITE" in char.propertiesToString():
                    print_success("Sending {} bytes...".format(len(data)))

                    wwrflag = False

                    if "NO RESPONSE" in char.propertiesToString():
                        wwrflag = True

                    try:
                        char.write(data, wwrflag)
                        print_success("Data sent")
                    except Exception as err:
                        print_error("Error: {}".format(err))

                else:
                    print_error("Not writable")

            dev.disconnect()

        except Exception as err:
            print_error(err)

        try:
            dev.disconnect()
        except Exception:
            pass

        return None
 def __init__(self,address):
     """
     address is the yeelight blue ble hardware address
     """
     self.data = dict()
     self.address = address
     self.delegate = YeelightService.NotifyDelegate()
     self.peripher = Peripheral(deviceAddr = address)
     self.service = self.peripher.getServiceByUUID(YeelightService.SERVICE)
     self.peripher.withDelegate(self.delegate)
Example #11
0
    def __init__(self, addr ):
        if addr and len(addr) != 17 :
            raise Exception( 'ERROR: device address must be in the format NN:NN:NN:NN:NN:NN' )
        Peripheral.__init__(self, addr)
        if addr:
            logger.info( 'connected to {}'.format( addr ) )
#        self.svcs = self.discoverServices()

        self.name = ''
        self.modelNumber = None
        self.serialNumber = None
        self.firmwareRevision = None
        self.hardwareRevision = None
        self.softwareRevision = None
        self.manufacturer = None
        
        self.temperature = None
        self.humidity = None
        self.battery = None
Example #12
0
 def __init__(self, addr):
     log.debug('connetion...')
     Peripheral.__init__(self, addr)
     log.debug('discovery...')
     self.discoverServices()
     self.notify_ch = None
     s = self.getServiceByUUID('fff0')
     self.cccd, = s.getCharacteristics('fff2')
     self.cccn, = s.getCharacteristics('fff1')
     log.debug('cccd: uuid=%s, commonName=%s, properties=%s' % (
         self.cccd.uuid,
         self.cccd.uuid.getCommonName(), 
         self.cccd.propertiesToString()))
     log.debug('cccn: uuid=%s, commonName=%s, properties=%s' % (
         self.cccn.uuid,
         self.cccn.uuid.getCommonName(), 
         self.cccn.propertiesToString()))
     self.cccd.write(b'\x01\x00')
     self.cccn.write(b'\x01\x00')
Example #13
0
    def enumerate_services(self):
        print_status("Starting enumerating {} ({} dBm) ...".format(self.addr, self.rssi))

        try:
            dev = Peripheral(self, self.addrType)

            services = sorted(dev.services, key=lambda s: s.hndStart)

            data = []
            for service in services:
                if service.hndStart == service.hndEnd:
                    continue

                data.append([
                    "{:04x} -> {:04x}".format(service.hndStart, service.hndEnd),
                    self._get_svc_description(service),
                    "",
                    "",
                ])

                for _, char in enumerate(service.getCharacteristics()):
                    desc = self._get_char_description(char)
                    props = char.propertiesToString()
                    hnd = char.getHandle()
                    value = self._get_char(char, props)

                    data.append([
                        "{:04x}".format(hnd), desc, props, value
                    ])

            dev.disconnect()

            return data

        except Exception as err:
            print_error(err)

        try:
            dev.disconnect()
        except Exception as err:
            print_error(err)

        return None
Example #14
0
 def connect(self):
     self.peripheral = Peripheral(self.macAddress, addrType='random')
     # Retrieve all characteristics from desires services and map them from their UUID
     characteristics = list(itertools.chain(*[self.peripheral.getServiceByUUID(uuid).getCharacteristics() for uuid in Nuimo.SERVICE_UUIDS]))
     characteristics = dict((c.uuid, c) for c in characteristics)
     # Store each characteristic's value handle for each characteristic name
     self.characteristicValueHandles = dict((name, characteristics[uuid].getHandle()) for uuid, name in Nuimo.CHARACTERISTIC_UUIDS.items())
     # Subscribe for notifications
     for name in Nuimo.NOTIFICATION_CHARACTERISTIC_UUIDS:
         self.peripheral.writeCharacteristic(self.characteristicValueHandles[name] + 1, Nuimo.NOTIFICATION_ON, True)
     self.peripheral.setDelegate(self.delegate)
Example #15
0
    def __init__(self, mac_address, timeout=0.5, debug=False):
        FORMAT = '%(asctime)-15s %(name)s (%(levelname)s) > %(message)s'
        logging.basicConfig(format=FORMAT)
        log_level = logging.WARNING if not debug else logging.DEBUG
        self._log = logging.getLogger(self.__class__.__name__)
        self._log.setLevel(log_level)

        self._log.info('Connecting to ' + mac_address)
        Peripheral.__init__(self, mac_address, addrType=ADDR_TYPE_RANDOM)
        self._log.info('Connected')

        self.timeout = timeout
        self.mac_address = mac_address
        self.state = None
        self.queue = Queue()
        self.heart_measure_callback = None
        self.heart_raw_callback = None
        self.accel_raw_callback = None

        self.svc_1 = self.getServiceByUUID(UUIDS.SERVICE_MIBAND1)
        self.svc_2 = self.getServiceByUUID(UUIDS.SERVICE_MIBAND2)
        self.svc_heart = self.getServiceByUUID(UUIDS.SERVICE_HEART_RATE)

        self._char_auth = self.svc_2.getCharacteristics(
            UUIDS.CHARACTERISTIC_AUTH)[0]
        self._desc_auth = self._char_auth.getDescriptors(
            forUUID=UUIDS.NOTIFICATION_DESCRIPTOR)[0]

        self._char_heart_ctrl = self.svc_heart.getCharacteristics(
            UUIDS.CHARACTERISTIC_HEART_RATE_CONTROL)[0]
        self._char_heart_measure = self.svc_heart.getCharacteristics(
            UUIDS.CHARACTERISTIC_HEART_RATE_MEASURE)[0]

        # Enable auth service notifications on startup
        self._auth_notif(True)
        # Let band to settle
        self.waitForNotifications(0.1)
Example #16
0
 def __init__(self, addr):
     ## @var l
     # System logger handle
     self.l = logging.getLogger('system')
     self.l.debug('[BLE_HR] WAIT_TIME {}'.format(self.WAIT_TIME))
     ## @var connected
     # Indicates if sensor is currently connected
     self.connected = False
     self.state = 0
     ## @var heart_rate
     # Measured heart rate
     self.heart_rate = 0
     ## @var time_stamp
     # Time stamp of the measurement, initially set by the constructor to "now", later overridden by time stamp of the notification with measurement.
     self.time_stamp = time.time()
     self.l.info('[BLE_HR] State = {}'.format(self.state))
     threading.Thread.__init__(self)
     ## @var addr
     # Address of the heart rate sensor
     self.addr = addr
     self.l.info('[BLE_HR] Connecting to {}'.format(addr))
     self.state = 1
     self.l.info('[BLE_HR] State = {}'.format(self.state))
     Peripheral.__init__(self, addr, addrType='random')
     self.connected = True
     self.state = 2
     self.l.info('[BLE_HR] State = {}'.format(self.state))
     ## @var name
     # Name of the heart rate sensor
     self.name = self.get_device_name()
     self.l.info('[BLE_HR] Connected to {}'.format(self.name))
     self.l.debug('[BLE_HR] Setting notification handler')
     self.delegate = HR_Delegate()
     self.l.debug('[BLE_HR] Setting delegate')
     self.withDelegate(self.delegate)
     self.l.debug('[BLE_HR] Enabling notifications')
     self.set_notifications()
Example #17
0
    def reconnect(self, addr):
        #Loop here until reconnected (Thread is doing nothing anyways...)
        while True:
            try:
                # print(f"{self.connection_index}: reconnecting to", addr)

                # devices = scanner.scan(2)
                # for d in devices:
                # if d.addr in bt_addrs:
                # if bt_addrs_isConnected[d.addr]:
                # continue

                # p = Peripheral(addr)
                # #Reset configurations of connection/peripheral (overhead code)
                # self.connection = p
                # self.connection.withDelegate(NotificationDelegate(self.connection_index))
                # self.s = self.connection.getServiceByUUID(BLE_SERVICE_UUID)
                # self.c = self.s.getCharacteristics()[0]

                # connections[self.connection_index] = self.connection

                # print("Reconnected to ", addr, '!')
                # self.c.write(("H").encode()) #Need to handshake with beetle again to start sending data
                # flag = True
                # self.isConnected = True
                # return True
                p = Peripheral(addr)
                #Reset configurations of connection/peripheral (overhead code)
                self.connection = p
                self.connection.withDelegate(
                    NotificationDelegate(self.connection_index))
                self.s = self.connection.getServiceByUUID(BLE_SERVICE_UUID)
                self.c = self.s.getCharacteristics()[0]

                connections[self.connection_index] = self.connection

                print("Reconnected to ", addr, '!')

                connections[self.connection_index] = self.connection
                sleep(1.5)
                self.c.write(("H").encode(
                ))  #Need to handshake with beetle again to start sending data
                self.isConnected = True
                return True
            except:
                pass
                # print(self.connection_index, "Error when reconnecting..")
            sleep(delayWindow[randint(
                0, 3)])  #Delay to avoid hoarding all the processing power
Example #18
0
def newPetition(device):
    p = Peripheral(device)

    print(p.getServices())
    """
    c = p.getCharacteristics(uuid=STATUS_UUID)[0]
    user = p.getCharacteristics(uuid=USER_UUID)[0]
    status = p.getCharacteristics(uuid=STATUS_UUID)[0]
    """
    c = p.getCharacteristics(uuid=ANNOUNCE_UUID)[0]
    status = p.getCharacteristics(uuid=STATUS_UUID)[0]
    user_ble = p.getCharacteristics(uuid=USER_UUID)[0]
    user = user_ble.read()
    user_name = str(user, 'ascii')[1:]
    print(user_name)
    occupied_ble = p.getCharacteristics(uuid=OCCUPIED_UUID)[0]
    occupied = int(occupied_ble.read())
    if occupied == 1:
        print("This spot is occupied")
        release_spot = releaseSpot(user_name, 1)
        if release_spot:
            status.write(b'1')
            c.write(b'1')
        else:
            status.write(b'3')
            c.write(b'1')
    elif occupied == 0:
        print("This spot is free")
        use_spot = useSpot(user_name, 1)
        if use_spot:
            status.write(b'1')
            c.write(b'1')
        else:
            status.write(b'3')
            c.write(b'1')
    else:
        pass

    p.disconnect()
    sleep(10)
    """
Example #19
0
 def get_connection(self):
     global pool_cometblue
     with self.lock:
         if self.connection == None:
             _LOGGER.debug("wait for free slot " + self.mac)
             pool_cometblue.acquire()
             _LOGGER.debug("acquired slot " + self.mac)
             _LOGGER.debug("connect to " + self.mac)
             try:
                 self.connection = Peripheral(self.mac, "public")
             except:
                 _LOGGER.debug("release free slot " + self.mac)
                 pool_cometblue.release()
                 raise
             try:
                 _LOGGER.debug("send pin to " + self.mac)
                 self.connection.writeCharacteristic(
                     0x0047,
                     self.pin.to_bytes(4, byteorder='little'),
                     withResponse=True)
             except:
                 self.disconnect()
                 raise
         return self.connection
Example #20
0
 def connect(self):
     # Auto-discover device on first connection
     if (self.MacAddr is None):
         scanner     = Scanner().withDelegate(DefaultDelegate())
         searchCount = 0
         while self.MacAddr is None and searchCount < 50:
             devices      = scanner.scan(0.1) # 0.1 seconds scan period
             searchCount += 1
             for dev in devices:
                 ManuData = dev.getValueText(255)
                 SN = parseSerialNumber(ManuData)
                 if (SN == self.SN):
                     self.MacAddr = dev.addr # exits the while loop on next conditional check
                     break # exit for loop
         
         if (self.MacAddr is None):
             print("ERROR: Could not find device.")
             return
     
     # Connect to device
     if (self.periph is None):
         self.periph = Peripheral(self.MacAddr)
     if (self.curr_val_char is None):
         self.curr_val_char = self.periph.getCharacteristics(uuid=self.uuid)[0]
Example #21
0
class RobotController():

    def __init__(self, address):

        self.robot = Peripheral(YOUR_ADDRESS)
        print("connected")

        # keep state for keypresses
        self.pressed = {"up": False, "down": False, "right": False, "left": False}
        # TODO get service from robot
        # TODO get characteristic handles from service/robot
        # TODO enable notifications if using notifications

        keyboard.hook(self.on_key_event)

    def on_key_event(self, event):
        # print key name
        print(event.name)
        # if a key unrelated to direction keys is pressed, ignore
        if event.name not in self.pressed: return
        # if a key is pressed down
        if event.event_type == keyboard.KEY_DOWN:
            # if that key is already pressed down, ignore
            if self.pressed[event.name]: return
            # set state of key to pressed
            self.pressed[event.name] = True
            # TODO write to characteristic to change direction
        else:
            # set state of key to released
            self.pressed[event.name] = False
            # TODO write to characteristic to stop moving in this direction

    def __enter__(self):
        return self
    def __exit__(self, exc_type, exc_value, traceback):
        self.robot.disconnect()
Example #22
0
    def __init__(self,
                 mac,
                 device_info_cache_ttl=3600,
                 measurement_cache_ttl=10,
                 retries=3,
                 retry_delay=lambda x: 2**(x * 0.5),
                 iface=0,
                 firmware_version=None):
        """
        Initialize a Mi Flora Poller for the given MAC address.

        Arguments:
            mac (string): MAC address of the sensor to be polled
            device_info_cache_ttl (int): Maximum age of the device info data before it will be polled again
            measurement_cache_ttl (int): Maximum age of the measurement data before it will be polled again
            retries (int): number of retries for errors in the Bluetooth communication
            retry_delay (fn): delay function returning seconds of delay dependent on retry number
            iface (int): number of the Bluetooth adapter to be used, 0 means "/dev/hci0"

        """
        self._mac = mac
        self._iface = iface
        self._lock = threading.Lock()
        self._peripheral = Peripheral()
        self._firmware_version = firmware_version

        # Decorate
        retry_fcn = retry(retries, BTLEException, retry_delay,
                          self.reconnect_on_disconnect)
        self.read = retry_fcn(self._peripheral.readCharacteristic)
        self.write = retry_fcn(self._peripheral.writeCharacteristic)
        self._fetch_device_info = cached_ttl(device_info_cache_ttl)(
            self._fetch_device_info)
        self._fetch_measurement = cached_ttl(measurement_cache_ttl)(
            self._fetch_measurement)
        self._fetch_name = cached_ttl(device_info_cache_ttl)(self._fetch_name)
Example #23
0
File: bm.py Project: Movsun/unamur
def sendBle(mac, action, client):
    try:
        if mac in myList:
            pwr = myList[mac]
        else:
            print('connecting to ' + mac + '...')
            p = Peripheral(mac, 'random')
            print('connected')
            w = p.getCharacteristics(uuid=write_uuid)[0]
            r = p.getCharacteristics(uuid=read_uuid)[0]
            pwr = PWR(p, w, r)
            myList[mac] = pwr
        if action == '2':
            read_and_pub(client=client, topic='0000'+mac.replace(':', ''), peripheral=pwr.p)
        else:
            print('sending command : ' + action)
            pwr.w.write(action)
            time.sleep(0.05)
            print('reading reply')
            print(pwr.r.read())
    except Exception as e:
        print('error ', e)
        myList.pop(mac, None)
        pass
Example #24
0
    def create_connection(self, addr: str):
        # Creates a handle to a Peripheral and adds it to active_connections
        try:
            assert addr in self.devs_in_range
            dev_addr = addr.upper()
            dev_addr_type = self.devs_in_range[dev_addr].addrType
            dev_name = self.get_dev_name(dev_addr)

            Utils.logger.info(
                f'Creating connection to {dev_addr_type} address: {dev_addr}')

            dev = Peripheral(dev_addr, dev_addr_type, self.ble_device)

            self.active_connections[dev_name] = dev
            self._chrcs_cache[dev_name] = dev.getCharacteristics()

        except TimeoutError:
            Utils.logger.error(f'Device {addr} not responding.')

        except Exception as e:
            Utils.logger.error(f'An error occurred. {e}')

        except AssertionError:
            Utils.logger.error(f'Device {addr} not in range right now')
Example #25
0
    def __init__(self, mac):
        self.conn = Peripheral(mac)
        self.conn.setDelegate(self)
        self.count = 0
        print('connected')

        self.service = self.conn.getServiceByUUID(_LBN_UUID(0x10))
        self.serial = self.service.getCharacteristics(_LBN_UUID(0x11))[0]

        #print(self.serial.propertiesToString())

        # Turn on notificiations
        self.conn.writeCharacteristic(0x2f, '\x01\x00', False)

        i = 0
        while True:
            #print(self.serial.read())
            self.write("a" * 60)
            #self.write("a" * 5)
            #self.sendCmd(LightBlueBean.MSG_ID_CC_ACCEL_READ)

            self.conn.waitForNotifications(1)
            time.sleep(1)
        self.conn.disconnect()
Example #26
0
    def __init__(self, mac_address: str, max_workers: int = 10):
        logger.debug("Init Sphero Core")
        self.mac_address = mac_address
        self.delegate = SpheroDelegate()
        self.peripheral = Peripheral(self.mac_address, ADDR_TYPE_RANDOM)
        self.peripheral.setDelegate(self.delegate)

        self.ch_api_v2 = self.get_characteristic(
            uuid=SpheroCharacteristic.api_v2.value)
        # Initial api descriptor
        # Need for getting response from sphero
        desc = self.get_descriptor(
            self.ch_api_v2,
            GenericCharacteristic.client_characteristic_configuration.value)
        desc.write(b"\x01\x00", withResponse=True)

        self._sequence = 0

        self._executor = ThreadPoolExecutor(max_workers=max_workers)
        self._running = Event()  # disable receiver thread
        self._running.set()
        self._notify_futures = {}  # features of notify
        self._executor.submit(self._receiver)
        logger.debug("Sphero Core: successful initialization")
class Wave():
    UUID_DATETIME     = UUID(0x2A08)
    UUID_HUMIDITY     = UUID(0x2A6F)
    UUID_TEMPERATURE  = UUID(0x2A6E)
    UUID_RADON_ST_AVG = UUID("b42e01aa-ade7-11e4-89d3-123b93f75cba")
    UUID_RADON_LT_AVG = UUID("b42e0a4c-ade7-11e4-89d3-123b93f75cba")

    def __init__(self, SerialNumber):
        self.periph            = None
        self.datetime_char     = None
        self.humidity_char     = None
        self.temperature_char  = None
        self.radon_st_avg_char = None
        self.radon_lt_avg_char = None

    def connect(self):
        scanner     = Scanner().withDelegate(DefaultDelegate())
        # This Scanner must be an external function that scans the Bluetooth for a device
        self.periph = Peripheral(BTAddress)
        self.datetime_char     = self.periph.getCharacteristics(uuid=self.UUID_DATETIME)[0]
        self.humidity_char     = self.periph.getCharacteristics(uuid=self.UUID_HUMIDITY)[0]
        self.temperature_char  = self.periph.getCharacteristics(uuid=self.UUID_TEMPERATURE)[0]
        self.radon_st_avg_char = self.periph.getCharacteristics(uuid=self.UUID_RADON_ST_AVG)[0]
        self.radon_lt_avg_char = self.periph.getCharacteristics(uuid=self.UUID_RADON_LT_AVG)[0]
Example #28
0
    def connect(self):
        """Establishes connection with the specified Ganglion board."""
        self.ganglion = Peripheral(self.mac_address, 'random')

        self.service = self.ganglion.getServiceByUUID(BLE_SERVICE)

        self.char_read = self.service.getCharacteristics(BLE_CHAR_RECEIVE)[0]

        self.char_write = self.service.getCharacteristics(BLE_CHAR_SEND)[0]

        self.char_discon = self.service.getCharacteristics(BLE_CHAR_DISCONNECT)[0]

        self.ble_delegate = GanglionDelegate(self.max_packets_skipped)
        self.ganglion.setDelegate(self.ble_delegate)

        self.desc_notify = self.char_read.getDescriptors(forUUID=0x2902)[0]

        try:
            self.desc_notify.write(b"\x01")
        except Exception as e:
            print("Something went wrong while trying to enable notification: " + str(e))
            sys.exit(2)

        print("Connection established")
Example #29
0
    def readData(self):
        print("reading data from device " + self.__mac)

        p = Peripheral(self.__mac, iface=0)
        p.withDelegate(self.__delegate)

        try:
            battery = p.readCharacteristic(BATTERY_HANDLE)
            self.__lastBattery = battery[0]
        except:
            print("failed to read battery from " + self.__mac)

        p.writeCharacteristic(TEMP_HUM_WRITE_HANDLE, TEMP_HUM_WRITE_VALUE)
        if not p.waitForNotifications(3.0):
            print("failed to read data from " + self.__mac)

        print('Temperature is ' + str(self.__lastTemp))
        print('Humidity is ' + str(self.__lastHum))
        print('Battery is ' + str(self.__lastBattery))

        try:
            p.disconnect()
        except:
            pass
Example #30
0
    def connect(self):
        while len(self.connection_threads) < len(self.modules_MACs):
            print 'Scanning ...'
            devices = self.scanner.scan(2)
            for d in devices:
                if d.addr in self.modules_MACs:
                    p = Peripheral(d)
                    self.connected_modules.append(p)
                    print 'Module ' + d.addr + ' connected. Assigned ID = ' + str(len(self.connected_modules)-1)
                    t = ConnectionHandlerThread(len(self.connected_modules)-1, self.connected_modules, self.api)
                    t.start()
                    self.connection_threads.append(t)
                    # time.sleep(3)

        print 'All devices are connected.'
Example #31
0
	def __init__(self, addr, version=AUTODETECT):
		Peripheral.__init__(self, addr)
		if version == AUTODETECT:
			svcs = self.discoverServices()
			if _TI_UUID(0xAA70) in svcs:
				version = SENSORTAG_2650
			else:
				version = SENSORTAG_V1

		fwVers = self.getCharacteristics(
			uuid=AssignedNumbers.firmwareRevisionString)
		if len(fwVers) >= 1:
			self.firmwareVersion = fwVers[0].read().decode("utf-8")
		else:
			self.firmwareVersion = u''

		if version == SENSORTAG_V1:
			self.IRtemperature = IRTemperatureSensor(self)
			self.accelerometer = AccelerometerSensor(self)
			self.humidity = HumiditySensor(self)
			self.magnetometer = MagnetometerSensor(self)
			self.barometer = BarometerSensor(self)
			self.gyroscope = GyroscopeSensor(self)
			self.keypress = KeypressSensor(self)
			self.lightmeter = None
		elif version == SENSORTAG_2650:
			self._mpu9250 = MovementSensorMPU9250(self)
			self.IRtemperature = IRTemperatureSensorTMP007(self)
			self.accelerometer = AccelerometerSensorMPU9250(self._mpu9250)
			self.humidity = HumiditySensorHDC1000(self)
			self.magnetometer = MagnetometerSensorMPU9250(self._mpu9250)
			self.barometer = BarometerSensorBMP280(self)
			self.gyroscope = GyroscopeSensorMPU9250(self._mpu9250)
			self.keypress = KeypressSensor(self)
			self.lightmeter = OpticalSensorOPT3001(self)
			self.battery = BatterySensor(self)
    def run(self):
        try:
            monotime = 0.0

            self.SBrickPeripheral = Peripheral()
            self.SBrickPeripheral.connect(self.sBrickAddr)
            service = self.SBrickPeripheral.getServiceByUUID('4dc591b0-857c-41de-b5f1-15abda665b0c')
            characteristics = service.getCharacteristics('02b8cbcc-0e25-4bda-8790-a15f53e6010f')
            for characteristic in characteristics:
                if characteristic.uuid == '02b8cbcc-0e25-4bda-8790-a15f53e6010f':
                    self.characteristicRemote = characteristic

            if self.characteristicRemote is None:
                return

            self.emit('sbrick_connected')

            self.need_authentication = self.get_need_authentication()
            self.authenticated = not self.need_authentication
            if self.need_authentication:
                if self.password_owner is not None:
                    self.authenticate_owner(self.password_owner)

            while not self.stopFlag:
                if self.authenticated:
                    if monotonic.monotonic() - monotime >= 0.05:
                        self.send_command()
                        monotime = monotonic.monotonic()
                    self.eventSend.wait(0.01)
                    for channel in self.brickChannels:
                        if channel.decrement_run_timer():
                            monotime = 0.0
                            self.drivingLock.release()
                            # print("stop run normal")
                            self.emit("sbrick_channel_stop", channel.channel)
                        if channel.decrement_brake_timer():
                            self.drivingLock.release()
                            # print("stop brake timer")
                            monotime = 0.0
                            self.emit("sbrick_channel_stop", channel.channel)

            if self.authenticated:
                self.stop_all()
                self.send_command()
            self.SBrickPeripheral.disconnect()
            self.emit('sbrick_disconnected_ok')
        except BTLEException as ex:
            self.emit("sbrick_disconnected_error", ex.message)
Example #33
0
    def start(self):
        # init btle ElementReader
        el = BtleNode(self._producer.onBtleData, None, None)
        em = ElementReader(el)

        class MyDelegate(DefaultDelegate):
            def __init__(self):
                DefaultDelegate.__init__(self)
                
            def handleNotification(self, cHandle, data):
                # TODO: this should handle incorrect format caused by packet losses
                try:
                    em.onReceivedData(data[2:])
                except ValueError as e:
                    print "Decoding value error: " + str(e)
                # connect ble
        
        while not self._p:
            try:
                self._p = Peripheral(self._addr, "random")
            except BTLEException as e:
                print "Failed to connect: " + str(e) + "; trying again"
                self._p = None

        # tell rfduino we are ready for notifications
        self._p.setDelegate(MyDelegate())

        self._p.writeCharacteristic(self._p.getCharacteristics(uuid = self._receive_uuid)[0].valHandle + 1, "\x01\x00")
        self._loop.create_task(self.btleNotificationListen())
        
        if self._security:
            # send our public key if configured to do so
            print "security on, sending our public key"
            interest = self._producer.makePublicKeyInterest()
            # write characteristics
            data = interest.wireEncode().toRawStr()
            num_fragments = int(math.ceil(float(len(data)) / 18))
            print "length of data: " + str(len(data)) + "; number of fragments: " + str(num_fragments)
            current = 0
            for i in range(0, num_fragments - 1):
                fragment = struct.pack(">B", i) + struct.pack(">B", num_fragments) + data[current:current + 18]
                current += 18
                self._p.writeCharacteristic(self._p.getCharacteristics(uuid = self._send_uuid)[0].valHandle, fragment)
                print " ".join(x.encode('hex') for x in fragment)
            fragment = struct.pack(">B", num_fragments - 1) + struct.pack(">B", num_fragments) + data[current:]
            self._p.writeCharacteristic(self._p.getCharacteristics(uuid = self._send_uuid)[0].valHandle, fragment)

            print " ".join(x.encode('hex') for x in fragment)
Example #34
0
 def get_characteristics(self, mac_address, service_uuid):
     p = Peripheral(mac_address)
     chList = p.getCharacteristics()
     chList = p.getCharacteristics(uuid=service_uuid)
     print("Handle      UUID        Properties")
     print("----------------------------------")
     for ch in chList:
         print("0x" + format(ch.getHandle(), '02x') + "   " + str(ch.uuid) +
               "    " + ch.propertiesToString())
     p.disconnect()
def charge_cap_model(MAC_addr):

    # Check if MAC address was given
    if MAC_addr is None:
        raise TypeError("Must pass MAC address.")

    Discharge = 0
    button_service_uuid = UUID('000015231212efde1523785feabcd123')
    button_char_uuid = UUID('000015241212efde1523785feabcd123')

    led_service_uuid = UUID('000016231212efde1523785feabcd123')
    led_char_uuid = UUID('000016241212efde1523785feabcd123')

    p = Peripheral(MAC_addr, "random")
    B_service = p.getServiceByUUID(button_service_uuid)
    L_service = p.getServiceByUUID(led_service_uuid)
    volt = 0.0
    lim = 45
    Pos = 0
    Neg = 0
    Down = 1
    Up = 1

    try:
        ch = B_service.getCharacteristics(button_char_uuid)[0]
        LedWrite = L_service.getCharacteristics(led_char_uuid)[0]
        if (ch.supportsRead()):
            while 1:
                val = binascii.b2a_hex(ch.read())
                if (val == "01"):
                    if (Down == 1):
                        Pos = 0
                        Down = 0
                        Up = 1
                    Pos = Pos + 1
                    volt = 24 * (1 - math.exp(-Pos * 0.50))
                    Discharge = volt
                elif (val == "00"):
                    if (Up == 1):
                        Neg = 0
                        Up = 0
                        Down = 1
                    Neg = Neg + 1
                    volt = Discharge * (math.exp(-Neg * 0.50))
                    if (Neg >= lim):
                        volt = 0.0
                print("{:.6}".format(volt))
                if (volt > 23.95):
                    LedWrite.write(str("\x01"))
                else:
                    LedWrite.write(str("\x00"))
                time.sleep(0.5)

    finally:
        p.disconnect()
def peripheral_with_retries(addr: str, retries: int) -> Peripheral:
    exc = None

    for _ in range(retries):
        try:
            return Peripheral(addr)
        except BTLEException as e:
            if exc is not None:
                e.__cause__ = exc

            exc = e

        print(f"retrying connection to {addr}")
        time.sleep(1)

    raise exc
Example #37
0
def run():
    global totalDevicesConnected
    devices = scanner.scan(3)
    for d in devices:
        if d.addr in bt_addrs:
            if bt_addrs_isConnected[d.addr]:
                continue
            addr = d.addr
            idx = bt_addrs[addr]
            bt_addrs_isConnected[addr] = True
            print(addr, 'found!')
            try:
                p = Peripheral(addr)
                connections[idx] = p
                t = ConnectionHandlerThread(idx)
                t.daemon = True #Set to true so can CTRL-C the program easily
                t.start()
                connection_threads[idx] = t
                totalDevicesConnected += 1
            except: #Raised when unable to create connection
                print('Error in connecting device')
    # concount = 0
    # while True:
        # if concount == 2:
            # break
        # for addr in bt_addrs:
            # if bt_addrs_isConnected[addr]:
                # continue
            # idx = bt_addrs[addr]
            # bt_addrs_isConnected[addr] = True
            # print(addr, 'found!')
            # try:
                # p = Peripheral(addr)
                # connections[idx] = p
                # t = ConnectionHandlerThread(idx)
                # t.daemon = True #Set to true so can CTRL-C the program easily
                # t.start()
                # connection_threads[idx] = t
                # totalDevicesConnected += 1
                # concount += 1
                # sleep(1)
            # except: #Raised when unable to create connection
                # print('Error in connecting device')
    if preprocessFlag:
        ppT = PreprocessorThread(time())
        ppT.daemon = True
        ppT.start()
Example #38
0
class BluepyAdapter(AbstractBleAdapter):
    STOP_NOTIFY = object()

    def __init__(self, mac_address):
        logger.debug("Init Bluepy Adapter")
        super().__init__(mac_address)
        self.delegate = BluepyDelegate(self.packet_collector)
        self.peripheral = Peripheral(self.mac_address, ADDR_TYPE_RANDOM)
        self.peripheral.setDelegate(self.delegate)

        self.ch_api_v2 = self._get_characteristic(uuid=SpheroCharacteristic.api_v2.value)
        # Initial api descriptor
        # Need for getting response from sphero
        desc = self._get_descriptor(self.ch_api_v2, GenericCharacteristic.client_characteristic_configuration.value)
        desc.write(b"\x01\x00", withResponse=True)

        self._executor.submit(self._receiver)
        logger.debug("Bluepy Adapter: successful initialization")

    def close(self):
        super().close()
        # ignoring any exception
        # because it does not matter
        with contextlib.suppress(Exception):
            self.peripheral.disconnect()

    def write(self, packet: Packet, *, timeout: float = 10, raise_api_error: bool = True) -> Packet:
        logger.debug(f"Send {packet}")
        self.ch_api_v2.write(packet.build(), withResponse=True)

        response = self.packet_collector.get_response(packet, timeout=timeout)
        if raise_api_error and response.api_error is not Api2Error.success:
            raise PySpheroApiError(response.api_error)
        return response

    def _receiver(self):
        logger.debug("Start receiver")

        sleep = 0.05
        while self._running.is_set():
            self.peripheral.waitForNotifications(sleep)

        logger.debug("Stop receiver")

    def _get_characteristic(self, uuid: int or str) -> Characteristic:
        return self.peripheral.getCharacteristics(uuid=uuid)[0]

    def _get_descriptor(self, characteristic: Characteristic, uuid: int or str) -> Descriptor:
        return characteristic.getDescriptors(forUUID=uuid)[0]
Example #39
0
    def on_command(self, topic, value):
        from bluepy import btle
        import binascii
        from bluepy.btle import Peripheral
        _, _, device_name, _ = topic.split('/')

        bot = self.devices[device_name]

        value = value.decode('utf-8')

        # It needs to be on separate if because first if can change method

        _LOGGER.debug("Setting %s on %s device '%s' (%s)", value, repr(self),
                      device_name, bot["mac"])
        try:
            bot["bot"] = Peripheral(bot["mac"], "random")
            hand_service = bot["bot"].getServiceByUUID(
                "cba20d00-224d-11e6-9fb8-0002a5d5c51b")
            hand = hand_service.getCharacteristics(
                "cba20002-224d-11e6-9fb8-0002a5d5c51b")[0]
            if value == STATE_ON:
                hand.write(binascii.a2b_hex("570101"))
            elif value == STATE_OFF:
                hand.write(binascii.a2b_hex("570102"))
            elif value == "PRESS":
                hand.write(binascii.a2b_hex("570100"))
            bot["bot"].disconnect()
        except btle.BTLEException as e:
            logger.log_exception(
                _LOGGER, "Error setting %s on %s device '%s' (%s): %s", value,
                repr(self), device_name, bot["mac"],
                type(e).__name__)
            return []

        try:
            return self.update_device_state(device_name, value)
        except btle.BTLEException as e:
            logger.log_exception(
                _LOGGER,
                "Error during update of %s device '%s' (%s): %s",
                repr(self),
                device_name,
                bot["mac"],
                type(e).__name__,
                suppress=True)
            return []
Example #40
0
    def connect_to_ble_device(self, dev:  ScanEntry) -> Peripheral :
        """
        Connect to a BLE device. 
        This is used to discover services running on this device 
        """

        DBG("Connecting to {}".format(dev.addr), logLevel=LogLevel.DEBUG)

        ## Try connecting 
        try:
            self.connected_peripherals.append(dev.addr) 
            peripheral =  Peripheral(dev, timeout=self.ble_timeout)
            return peripheral
        except Exception as e:
            DBG("Connecting to {} failed".format(dev.addr), logLevel=LogLevel.ERR) 
            logging.exception(e)
            return None 
Example #41
0
 def send_ir(self, key, ir_data):
     self._lock.acquire()
     sent = False
     p = None
     try:
         p = Peripheral(self._mac, "public")
         ch_list = p.getCharacteristics()
         for ch in ch_list:
             if str(ch.uuid) == SERVICE_UUID:
                 sequence = self.get_sequence()
                 if p.writeCharacteristic(ch.getHandle(), b'\x55' + bytes(len(a2b_hex(key)) + 3, [sequence]) + b'\x03' + a2b_hex(key),
                                          True):
                     data = ch.read()
                     if len(data) == 5 and data[4] == 1:
                         sent = True
                     else:
                         send_list = []
                         packet_count = int(len(ir_data) / 30) + 1
                         if len(data) % 30 != 0:
                             packet_count = packet_count + 1
                         send_list.append(
                             b'\x55' + bytes(len(a2b_hex(key)) + 5, [sequence]) + b'\x00' + bytes([0, packet_count]) + a2b_hex(key))
                         i = 0
                         while i < packet_count - 1:
                             if len(ir_data) - i * 30 < 30:
                                 send_ir_data = ir_data[i * 30:]
                             else:
                                 send_ir_data = ir_data[i * 30:(i + 1) * 30]
                             send_list.append(
                                 b'\x55' + bytes([int(len(send_ir_data) / 2 + 4), sequence]) + b'\x00' + bytes([i + 1]) + a2b_hex(
                                     send_ir_data))
                             i = i + 1
                         error = False
                         for j in range(len(send_list)):
                             r = p.writeCharacteristic(ch.getHandle(), send_list[j], True)
                             if not r:
                                 error = True
                                 break
                         if not error:
                             sent = True
                 break
     except Exception as ex:
         print("Unexpected error: {}".format(ex))
     finally:
         if not p:
             p.disconnect()
         self._lock.release()
     return sent
Example #42
0
class BluetoothPoller:
    _DATA_MODE_LISTEN = bytes([0x01, 0x00])

    def __init__(self, address: str, label: str, results: List[SensorValues],
                 iface: int):
        self.peripheral = Peripheral(deviceAddr=address, iface=iface)
        self.peripheral.withDelegate(
            ValueDelegate(label=label, results=results))

    def wait_for_notification(self, handle: int, timeout=1.0):
        self.peripheral.writeCharacteristic(handle,
                                            BluetoothPoller._DATA_MODE_LISTEN)
        return self.peripheral.waitForNotifications(timeout)

    def disconnect(self):
        self.peripheral.disconnect()
Example #43
0
def btn6_clicked():
    off = c.get()  #按下去才get到entry的值
    a1 = off[0:2]
    a2 = off[2:4]
    a6 = '0x' + a1
    a9 = '0x' + a2
    a7 = int(a6, 16)
    a8 = int(a9, 16)
    a3 = int('0x07', 16)
    a4 = int('0x35', 16)
    a5 = a7 + a8 + a3 + a4
    checksum = hex(a5)[-2:]
    r = 'AA0735' + off + str(checksum) + '55'
    print(r)
    with Peripheral('C1:8F:CC:DC:57:19', 'random') as p:
        ch = p.getCharacteristics(uuid=TX_CHAR_UUID)[0]
        val = binascii.a2b_hex(r)  #定时开启插座
        ch.write(val)
Example #44
0
def btn7_clicked():
    on = d.get()
    a1 = on[0:2]
    a2 = on[2:4]
    a6 = '0x' + a1
    a9 = '0x' + a2
    a7 = int(a6, 16)
    a8 = int(a9, 16)
    a3 = int('0x07', 16)
    a4 = int('0x31', 16)
    a5 = a7 + a8 + a3 + a4
    checksum = hex(a5)[-2:]
    r = 'AA0731' + on + str(checksum) + '55'
    with Peripheral('C1:8F:CC:DC:57:19', 'random') as p:
        ch = p.getCharacteristics(uuid=TX_CHAR_UUID)[0]
        val = binascii.a2b_hex(r)
        ch.write(val)
        p.disconnect()
Example #45
0
    def connect(self):
        """ Connect to the board and configure it. Note: recreates various objects upon call. """
        print("Init BLE connection with MAC: " + self.port)
        print("NB: if it fails, try with root privileges.")
        self.gang = Peripheral(self.port, 'random')  # ADDR_TYPE_RANDOM

        print("Get mainservice...")
        self.service = self.gang.getServiceByUUID(BLE_SERVICE)
        print("Got:" + str(self.service))

        print("Get characteristics...")
        self.char_read = self.service.getCharacteristics(BLE_CHAR_RECEIVE)[0]
        print("receive, properties: " + str(self.char_read.propertiesToString()) +
              ", supports read: " + str(self.char_read.supportsRead()))

        self.char_write = self.service.getCharacteristics(BLE_CHAR_SEND)[0]
        print("write, properties: " + str(self.char_write.propertiesToString()) +
              ", supports read: " + str(self.char_write.supportsRead()))

        self.char_discon = self.service.getCharacteristics(BLE_CHAR_DISCONNECT)[0]
        print("disconnect, properties: " + str(self.char_discon.propertiesToString()) +
              ", supports read: " + str(self.char_discon.supportsRead()))

        # set delegate to handle incoming data
        self.delegate = GanglionDelegate(self.scaling_output)
        self.gang.setDelegate(self.delegate)

        # enable AUX channel
        if self.aux:
            print("Enabling AUX data...")
            try:
                self.ser_write(b'n')
            except Exception as e:
                print("Something went wrong while enabling aux channels: " + str(e))

        print("Turn on notifications")
        # nead up-to-date bluepy, cf https://github.com/IanHarvey/bluepy/issues/53
        self.desc_notify = self.char_read.getDescriptors(forUUID=0x2902)[0]
        try:
            self.desc_notify.write(b"\x01")
        except Exception as e:
            print("Something went wrong while trying to enable notification: " + str(e))

        print("Connection established")
    def load_data(self):
        data = None

        if self.get_address() is not None:

            try:
                sensor = Peripheral(self.get_address())
                #Read battery and firmware version attribute
                data = unpack(
                    '<xB5s',
                    sensor.readCharacteristic(
                        terrariumMiFloraSensor.__MIFLORA_FIRMWARE_AND_BATTERY))
                data = {'battery': data[0], 'firmware': data[1]}

                #Enable real-time data reading
                sensor.writeCharacteristic(
                    terrariumMiFloraSensor.__MIFLORA_REALTIME_DATA_TRIGGER,
                    bytearray([0xa0, 0x1f]), True)
                #Read plant data
                data['temperature'], data['light'], data['moisture'], data[
                    'fertility'] = unpack(
                        '<hxIBHxxxxxx',
                        sensor.readCharacteristic(
                            terrariumMiFloraSensor.__MIFLORA_GET_DATA))
                # Close connection...
                sensor.disconnect()

                # Clean up
                data['temperature'] = float(data['temperature']) / 10.0
                data['light'] = float(data['light'])
                data['moisture'] = float(data['moisture'])
                data['fertility'] = float(data['fertility'])
                data['battery'] = float(data['battery'])
                data['firmware'] = data['firmware'].decode('utf8')

            except Exception as ex:
                logger.warning(
                    'Error getting new data from {} sensor \'{}\'. Error message: {}'
                    .format(self.get_type(), self.get_name(), ex))

        return data
Example #47
0
def main():
    print("[*] starting SINK FLOOD Sloan SmartFaucet and SmartFlushometer tool")
    while True:
        found_devices = lescan()
        if found_devices:
            target = menu_pick_device(found_devices)
            if not target:
                continue
            p = Peripheral(target['dev'].addr)
            #p = Peripheral('08:6b:d7:20:9d:4b')
            while target:
                attack = menu_pick_attack(target)
                run_sink_flood(attack, target, p)
            else:
                print("[*] target not found. have you tried turning it off and on again?")
                continue
        else:
            print("[*] something's not write. exiting.")
            exit()
Example #48
0
    def __connect(self):
        self.__peripheral = Peripheral(self.__address)
        self.__peripheral.setDelegate(self)
        characteristics = self.__peripheral.getCharacteristics()
        self.__ch = next(iter(filter(lambda x: binascii.b2a_hex(x.uuid.binVal)
                           .startswith(self.WRITE_CHAR_UUID),
                           characteristics)))

        # Register notification
        self.__peripheral.writeCharacteristic(
            0x16,
            binascii.a2b_hex('0100'))

        # Auth
        self.__write_cmd(
            self.COMMAND_STX +
            self.AUTH_CMD +
            self.AUTH_ON +
            self.COMMAND_ETX * 15)

        # Get status
        self.__request_status()
Example #49
0
    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
Example #50
0
def main():

    global g_mainloop
    global g_command

    # Reset camera to prevent black/pink images on first run through
    pygame.camera.init()
    cam = pygame.camera.Camera(pygame.camera.list_cameras()[0])
    cam.start()
    img = cam.get_image()
    pygame.image.save(img, IMG_NAME)
    cam.stop()
    pygame.camera.quit()
    img = None

    # Initialize GPIO
    in_success = mraa.Gpio(SUCCESS_PIN)
    in_failure = mraa.Gpio(FAILURE_PIN)
    in_status_0 = mraa.Gpio(STATUS_PIN_0)
    in_status_1 = mraa.Gpio(STATUS_PIN_1)
    doorbell = mraa.Gpio(DOORBELL_PIN)
    reed_outer = mraa.Gpio(REED_OUTER_PIN)
    reed_inner = mraa.Gpio(REED_INNER_PIN)
    deny_button = mraa.Gpio(DENY_PIN)
    approve_button = mraa.Gpio(APPROVE_PIN)
    prev_success = 0
    prev_failure = 0
    prev_approve = 0
    prev_doorbell = 0
    prev_deny = 0

    # Set direction of GPIO
    in_success.dir(mraa.DIR_IN)
    in_failure.dir(mraa.DIR_IN)
    in_status_0.dir(mraa.DIR_IN)
    in_status_1.dir(mraa.DIR_IN)
    doorbell.dir(mraa.DIR_IN)
    reed_outer.dir(mraa.DIR_IN)
    reed_inner.dir(mraa.DIR_IN)
    deny_button.dir(mraa.DIR_IN)
    approve_button.dir(mraa.DIR_IN)
    
    # Create Bluetooth connections to the RFduinos on the doors
    if DEBUG > 0:
        print 'Connecting to RFduinos...'
    inner_door = Peripheral(INNER_ADDR, 'random')
    outer_door = Peripheral(OUTER_ADDR, 'random')
    
    # Create handles to the Bluetooth read and write characteristics
    inner_r_ch = inner_door.getCharacteristics(uuid=READ_UUID)[0]
    inner_w_ch = inner_door.getCharacteristics(uuid=WRITE_UUID)[0]
    outer_r_ch = outer_door.getCharacteristics(uuid=READ_UUID)[0]
    outer_w_ch = outer_door.getCharacteristics(uuid=WRITE_UUID)[0]
    
    # Set up camera
    pygame.camera.init()
    cam = pygame.camera.Camera(pygame.camera.list_cameras()[0])
    
    # Connect to Twitter
    if DEBUG > 0:
        print 'Connecting to Twitter...'
    tf = TweetFeed({'app_key': APP_KEY, \
                    'app_secret': APP_SECRET, \
                    'oauth_token': OAUTH_TOKEN, \
                    'oauth_token_secret': OAUTH_TOKEN_SECRET})

    # Send a good morning Tweet
    tf.tweet(ONLINE_MSG)

    # Register 'ctrl+C' signal handler
    signal.signal(signal.SIGINT, signalHandler)

    # Main loop
    g_mainloop = True
    if DEBUG > 0:
        print 'Starting door'
    while g_mainloop:
        
        # Poll pins for success or failure (falling edge)
        state_success = in_success.read()
        state_failure = in_failure.read()
        state_doorbell = doorbell.read()
        state_deny = deny_button.read()
        state_approve = approve_button.read()
        
        # Look for success in access panel
        if (state_success == 0) and (prev_success == 1):
            openDoor(inner_door, inner_w_ch, reed_inner)
            person_ind = (2 * in_status_1.read()) + in_status_0.read()
            if person_ind == 0:
                if DEBUG > 0:
                    print 'Success!'
                    print 'No one in particular.'
                tf.tweet(SUCCESS_MSG)
            else:
                if DEBUG > 0:
                    print 'Success!'
                    print 'Person = ' + NAMES[person_ind - 1]
                tf.tweet(SUCCESS_MSG + NAMES[person_ind - 1])

        # Look for failure in access panel
        elif (state_failure == 0) and (prev_failure == 1):
            if DEBUG > 0:
                print 'Fail.'
            tf.tweetPhoto(cam, FAILURE_MSG)
            
        # Look for doorbell push
        elif (state_doorbell == 0) and (prev_doorbell == 1):
            if DEBUG > 0:
                print 'Doorbell pressed.'
            openDoor(outer_door, outer_w_ch, reed_outer)
            
        # Look for deny button push
        elif (state_deny == 0) and (prev_deny == 1):
            if DEBUG > 0:
                print 'DENIED. Go away, and never come back.'
            openDoor(outer_door, outer_w_ch, reed_outer)
            
        # Look for an approve button push
        elif (state_approve == 0) and (prev_approve == 1):
            if DEBUG > 0:
                print 'APPROVED. You may enter.'
            openDoor(inner_door, inner_w_ch, reed_inner)
        
        prev_success = state_success
        prev_failure = state_failure
        prev_doorbell = state_doorbell
        prev_deny = state_deny
        prev_approve = state_approve

        # Wait a bit before next cycle
        time.sleep(0.01)
                
    # Outside of main loop. Cleanup and cuddles.
    if DEBUG > 0:
        print 'Cleaning up.'

    pygame.camera.quit()
    pygame.quit()
def TI_UUID(val):
    return UUID("%08X-0451-4000-b000-000000000000" % (0xF0000000+val))

config_uuid = TI_UUID(0xAA72)
data_uuid = TI_UUID(0xAA71)

sensorOn  = struct.pack("B", 0x01)
sensorOff = struct.pack("B", 0x00)

if len(sys.argv) != 2:
  print "Fatal, must pass device address:", sys.argv[0], "<device address>"
  quit()

try:
  print "Info, trying to connect to:", sys.argv[1]
  p = Peripheral(sys.argv[1])

except BTLEException:
  print "Fatal, unable to connect!"
  
except:
  print "Fatal, unexpected error!"
  traceback.print_exc()
  raise

else:

  try:
    print "Info, connected and turning sensor on!"
    ch = p.getCharacteristics(uuid=config_uuid)[0]
    ch.write(sensorOn, withResponse=True)
Example #52
0
        fft_input = binascii.unhexlify(fft_input)
        longueur = len(fft_input)
        dft_treated = []
        for i in range(0, 20):
            dft_treated.append(ord(fft_input[i]))
        for i in range(0, longueur, 5):
            self.read_val(dft_treated, i)

if __name__ == "__main__":
    rx_uuid = UUID(0x2221)
    sample_size = 128
    # p = Peripheral("D9:35:6A:75:9F:9D", "random") # Rfduino sur usb
    continuer = True
    while(continuer):
        try:
            p = Peripheral("D1:7F:06:ED:66:DC", "random")  # Rfduino sur pcb
            continuer = False
        except:
            print "Module bluetooth deja connecte, nouvel essai dans 3 sec..."
            time.sleep(3)
    p.withDelegate(MyDelegate())
    Analyser.set_p(p)
    print " device connected..."

    try:
        p.getServices()
        ch = p.getCharacteristics(uuid=rx_uuid)[0]
        print ("notify characteristic with uuid 0x" + rx_uuid.getCommonName())
        cccid = btle.AssignedNumbers.client_characteristic_configuration
        # Ox000F : handle of Client Characteristic Configuration descriptor Rx - (generic uuid 0x2902)
        p.writeCharacteristic(0x000F, struct.pack('<bb', 0x01, 0x00), False)
import binascii
import struct
import time
from bluepy.btle import UUID, Peripheral

uuid = UUID("d96a513d-a6d8-4f89-9895-ca131a0935cb")

p = Peripheral("00:07:80:77:C4:5A", "public")

try:
    ch = p.getCharacteristics()[0]
    if (ch.supportsRead()):
        while 1:
            val = binascii.b2a_hex(ch.read())
            print str(val) + ""
            time.sleep(1)

finally:
    p.disconnect()
import sys
from bluepy.btle import UUID, Peripheral

temp_uuid = UUID(0x2A00)

if len(sys.argv) != 2:
  print "Fatal, must pass device address:", sys.argv[0], "<device address>"
  quit()

p = Peripheral(sys.argv[1])

try:
    ch = p.getCharacteristics(uuid=temp_uuid)[0]
    if (ch.supportsRead()):
            print ch.read()

finally:
    p.disconnect()
class YeelightService:
    """
    YeelightService is the yeelight control util for python

    author zhaohui.sol
    """

    SERVICE = "0000FFF0-0000-1000-8000-00805F9B34FB"

    CHAR_CONTROL = "0000FFF1-0000-1000-8000-00805F9B34FB"

    CHAR_DELAY = "0000FFF2-0000-1000-8000-00805F9B34FB"

    CHAR_DELAY_QUERY = "0000FFF3-0000-1000-8000-00805F9B34FB"

    CHAR_DELAY_NOTIFY = "0000FFF4-0000-1000-8000-00805F9B34FB"

    CHAR_QUERY = "0000FFF5-0000-1000-8000-00805F9B34FB"

    CHAR_NOTIFY = "0000FFF6-0000-1000-8000-00805F9B34FB"

    CHAR_COLOR_FLOW = "0000FFF7-0000-1000-8000-00805F9B34FB"

    CHAR_NAME = "0000FFF8-0000-1000-8000-00805F9B34FB"

    CHAR_NAME_NOTIFY = "0000FFF9-0000-1000-8000-00805F9B34FB"

    CHAR_COLOR_EFFECT = "0000FFFC-0000-1000-8000-00805F9B34FB"

    class NotifyDelegate(DefaultDelegate):

        def __init__(self):
            DefaultDelegate.__init__(self)
            self.queue = list()

        def register(self,callback):
            self.queue.append(callback)

        def deregister(self,callback):
            self.queue.remove(callback)

        def handleNotification(self,handle,data):
            logging.warning("notify data %s from %s." % (data,handle))
            res = dict()
            res['data'] = data
            res['handle'] = handle
            for c in self.queue:
                c(res)


    def __init__(self,address):
        """
        address is the yeelight blue ble hardware address
        """
        self.data = dict()
        self.address = address
        self.delegate = YeelightService.NotifyDelegate()
        self.peripher = Peripheral(deviceAddr = address)
        self.service = self.peripher.getServiceByUUID(YeelightService.SERVICE)
        self.peripher.withDelegate(self.delegate)

    def __character_by_uuid__(self,uuid):
        '''
        get character by a special uuid
        '''
        characters = self.service.getCharacteristics(forUUID=uuid)
        return characters[0] if characters else None

    def __write_character__(self,uuid,strdata):
        '''
        write data to a special uuid
        '''
        logging.info(u"write %s to %s." % (strdata,uuid))
        character = self.__character_by_uuid__(uuid)
        if character:
            character.write(strdata)
        else:
            pass

    def __read_character__(self,uuid):
        '''
        read data from a special uuid,may be it's wrong
        '''
        logging.info(u"read data from %s." % uuid)
        character = self.__character_by_uuid__(uuid)
        if character:
            return character.read()
        else:
            return None

    def __notify_character__(self,_to,_write):
        '''
        write data to the uuid and wait data notify
        '''
        res = dict()
        def callback(data):
            for k in data:
                res[k] = data[k]
        self.delegate.register(callback)
        self.__write_character__(_to,_write)
        if self.peripher.waitForNotifications(5):
            logging.info("notify incoming.")
            self.delegate.deregister(callback)
            return res
        else:
            logging.warning("notify timeout.")
            self.delegate.deregister(callback)
            return None

    def __format_request__(self,strdata,length = 18):
        '''
        format the data to a special length
        '''
        if strdata and length >= len(strdata) > 0:
            l = len(strdata)
            strdata += "".join(["," for i in range(length - l)])
            return strdata
        else:
            return "".join(["," for i in range(length)])

    def turn_on(self, brightness = 100):
        '''
        turn on the light with white and full brightness
        '''
        self.control(255,255,255,brightness)

    def turn_off(self):
        '''
        turn off the light
        '''
        self.control(0,0,0,0)

    def control(self,r,g,b,a):
        '''
        turn on the light with special color
        '''
        assert 0 <= r <= 255
        assert 0 <= g <= 255
        assert 0 <= b <= 255
        assert 0 <= a <= 100
        self.__write_character__(YeelightService.CHAR_CONTROL,self.__format_request__("%d,%d,%d,%d"%(r,g,b,a),18))

    def delay_on(self,mins = 5):
        '''
        turn on the light with a min param delay
        '''
        assert 0 < mins < 24 * 60
        self.__write_character__(YeelightService.CHAR_DELAY,self.__format_request__("%d,1" % mins,8))

    def delay_off(self,mins = 5):
        '''
        turn off the light with a min param delay
        '''
        assert 0 < mins < 24 * 60
        self.__write_character__(YeelightService.CHAR_DELAY,self.__format_request__("%d,0" % mins,8))

    def delay_status(self):
        '''
        query the delay status , this method return a raw dict with two key 'handle' and 'data'
        see http://www.yeelight.com/download/yeelight_blue_message_interface_v1.0.pdf
        '''
        return self.__notify_character__(YeelightService.CHAR_DELAY_QUERY,self.__format_request__("RT",2))

    def control_status(self):
        '''
        query the light status , this method return a raw dict with two key 'handle' and 'data'
        see http://www.yeelight.com/download/yeelight_blue_message_interface_v1.0.pdf
        '''
        return self.__notify_character__(YeelightService.CHAR_QUERY,self.__format_request__("S",1))

    def start_color_flow(self,flows):
        '''
        start color flow with a list of params, each param should contain 5 element which is r,g,b,brightness,delay
        see http://www.yeelight.com/download/yeelight_blue_message_interface_v1.0.pdf
        '''
        assert len(flows) <= 9
        for i,e in enumerate(flows):
            assert len(e) == 5
            assert 0 <= e[0] <= 255
            assert 0 <= e[1] <= 255
            assert 0 <= e[2] <= 255
            assert 0 <= e[3] <= 100
            assert 0 <= e[4] <= 10
            self.__write_character__(YeelightService.CHAR_COLOR_FLOW,self.__format_request__("%d,%d,%d,%d,%d,%d" % (i,e[0],e[1],e[2],e[3],e[4]),20))
        self.__write_character__(YeelightService.CHAR_COLOR_FLOW,self.__format_request__("CB",20))

    def stop_color_flow(self):
        '''
        stop color flow
        '''
        self.__write_character__(YeelightService.CHAR_COLOR_FLOW,self.__format_request__("CE",20))

    def effect_smooth(self):
        '''
        make the color change smooth
        '''
        self.__write_character__(YeelightService.CHAR_COLOR_EFFECT,self.__format_request__("TS",2))

    def effect_immediate(self):
        '''
        make the color changes immediate
        '''
        self.__write_character__(YeelightService.CHAR_COLOR_EFFECT,self.__format_request__("TE",2))

    def effect_current_color(self):
        '''
        use the current color as a default startup color
        '''
        self.__write_character__(YeelightService.CHAR_COLOR_EFFECT,self.__format_request__("DF",2))
Example #56
0
    global de
    for u, s in de.services.items():
        if u == uuid:
            return s
    print('no such service uuid: %s' % uuid)
    return None

def lsc(serv):
    for c in serv.getCharacteristics():
        print('handle=%-3s valHandle=%-3s supportsRead=%-5s uuid=%s properties=%s' % (
                c.handle,
                c.valHandle,
                c.supportsRead(),
                str(c.uuid),
                c.propertiesToString()))

def handler(handle, data):
    print('handler(handle=%s, data=%s)' % (repr(handle), repr(data)))
    
print('connecting to %s...' % addr)
de = Peripheral(addr)
print('connected, discovering services...')
de.discoverServices()
print('commands:')
print('  lss()            list services')
print('  service(uuid)    get service object')
print('  lsc(service)     list characteristics for a service')
print('  char(serv, uuid) get a characteristic by uuid')


Example #57
0
class Yeelight(DefaultDelegate):
    WRITE_CHAR_UUID = b"aa7d3f34"  # -2d4f-41e0-807f-52fbf8cf7443"

    COMMAND_STX = "43"
    COMMAND_ETX = "00"

    AUTH_CMD = "67"
    AUTH_ON = "02"

    POWER_CMD = "40"
    POWER_ON = "01"
    POWER_OFF = "02"

    COLOR_CMD = "41"
    RGB_MODE = "65"

    BRIGHT_CMD = "42"

    COLORTEMP_CMD = "43"
    TEMP_MODE = "65"

    STATUS_CMD = "44"

    COLORFLOW_CMD = "4a"

    SLEEP_CMD = "7f03"

    def __init__(self, address):
        DefaultDelegate.__init__(self)
        self.__address = address
        self.__connect()

    # Override
    def handleNotification(self, handle, data):
        if handle == 21:
            format = (
                '!xx' # 4345 header
                'B' # switch: 01=on 02=off
                'B' # mode: 01=rgb 02=warm
                'BBBx' # RGB
                'B' # Brightness
                'H' # temp 2byte 1700 ~ 6500
                'xxxxxxx'
            )
            (switch, mode, r, g, b,
             brightness, temp) = struct.unpack(format, data)
            if switch != 4:
                self._switch = switch
                self._mode = mode
                self._rgb = '{:02x}{:02x}{:02x}'.format(r, g, b)
                self._temp = temp
                self._brightness = brightness

    def disconnect(self, *args, **kwargs):
        return self.__peripheral.disconnect(*args, **kwargs)

    def __connect(self):
        self.__peripheral = Peripheral(self.__address)
        self.__peripheral.setDelegate(self)
        characteristics = self.__peripheral.getCharacteristics()
        self.__ch = next(iter(filter(lambda x: binascii.b2a_hex(x.uuid.binVal)
                           .startswith(self.WRITE_CHAR_UUID),
                           characteristics)))

        # Register notification
        self.__peripheral.writeCharacteristic(
            0x16,
            binascii.a2b_hex('0100'))

        # Auth
        self.__write_cmd(
            self.COMMAND_STX +
            self.AUTH_CMD +
            self.AUTH_ON +
            self.COMMAND_ETX * 15)

        # Get status
        self.__request_status()

    def __write_cmd(self, value):
        for _ in range(3):
            try:
                self.__ch.write(binascii.a2b_hex(value))
                self.__peripheral.waitForNotifications(1.0)
            except BTLEException as e:
                error = e
                self.__connect()
            else:
                break
        else:
            raise error

    def __request_status(self):
        self.__write_cmd(
            self.COMMAND_STX +
            self.STATUS_CMD +
            self.COMMAND_ETX * 16
        )

    @property
    def switch(self):
        self.update_status()
        return self._switch

    @property
    def brightness(self):
        self.update_status()
        return self._brightness

    @property
    def temp(self):
        self.update_status()
        return self._temp

    @property
    def rgb(self):
        self.update_status()
        return self._rgb

    @property
    def mode(self):
        self.update_status()
        return self._mode

    def poweron(self):
        self.__write_cmd(
            self.COMMAND_STX +
            self.POWER_CMD +
            self.POWER_ON +
            self.COMMAND_ETX * 15)

    def poweroff(self):
        self.__write_cmd(
            self.COMMAND_STX +
            self.POWER_CMD +
            self.POWER_OFF +
            self.COMMAND_ETX * 15)

    def set_rgb(self, rgb):
        self.__write_cmd(
            self.COMMAND_STX +
            self.COLOR_CMD +
            rgb + '00' +
            self.RGB_MODE +
            self.COMMAND_ETX * 11)

    def set_brightness(self, value):
        self.__write_cmd(
            self.COMMAND_STX +
            self.BRIGHT_CMD +
            ('%02x' % value) +
            self.COMMAND_ETX * 15)
        # Bypass bug
        self.__request_status()

    def set_temp(self, value):
        if not 1700 <= value <= 6500 and 0.0 <= value <= 1.0:
            value = int(1700 + value * 4800)

        self.__write_cmd(
            self.COMMAND_STX +
            self.COLORTEMP_CMD +
            ('%04x' % value) +
            self.TEMP_MODE +
            self.COMMAND_ETX * 13)

    def set_sleep(self, minute):
        self.__write_cmd(
            self.COMMAND_STX +
            self.SLEEP_CMD +
            ('%02x' % minute) +
            self.COMMAND_ETX * 14
        )

    def update_status(self):
        self.__peripheral.waitForNotifications(0.01)
class SBrickCommunications(threading.Thread, IdleObject):
    def __init__(self, sbrick_addr):
        threading.Thread.__init__(self)
        IdleObject.__init__(self)

        self.lock = threading.RLock()
        self.drivingLock = threading.RLock()
        self.eventSend = threading.Event()

        self.sBrickAddr = sbrick_addr
        self.owner_password = None

        self.brickChannels = [
            SBrickChannelDrive(0, self.eventSend),
            SBrickChannelDrive(1, self.eventSend),
            SBrickChannelDrive(2, self.eventSend),
            SBrickChannelDrive(3, self.eventSend),
        ]
        self.SBrickPeripheral = None
        self.stopFlag = False
        self.characteristicRemote = None
        self.need_authentication = False
        self.authenticated = False
        self.channel_config_ids = dict()

    def set_channel_config_id(self, channel, config_id):
        self.channel_config_ids[config_id] = channel
        self.brickChannels[channel].set_config_id(config_id)

    def terminate(self):
        self.stopFlag = True

    def is_driving(self):
        locked = self.drivingLock.acquire(False)
        if locked:
            self.drivingLock.release()
        return not locked

    def connect_to_sbrick(self, owner_password):
        self.owner_password = owner_password
        self.start()

    def run(self):
        try:
            monotime = 0.0

            self.SBrickPeripheral = Peripheral()
            self.SBrickPeripheral.connect(self.sBrickAddr)
            service = self.SBrickPeripheral.getServiceByUUID('4dc591b0-857c-41de-b5f1-15abda665b0c')
            characteristics = service.getCharacteristics('02b8cbcc-0e25-4bda-8790-a15f53e6010f')
            for characteristic in characteristics:
                if characteristic.uuid == '02b8cbcc-0e25-4bda-8790-a15f53e6010f':
                    self.characteristicRemote = characteristic

            if self.characteristicRemote is None:
                return

            self.emit('sbrick_connected')

            self.need_authentication = self.get_need_authentication()
            self.authenticated = not self.need_authentication
            if self.need_authentication:
                if self.password_owner is not None:
                    self.authenticate_owner(self.password_owner)

            while not self.stopFlag:
                if self.authenticated:
                    if monotonic.monotonic() - monotime >= 0.05:
                        self.send_command()
                        monotime = monotonic.monotonic()
                    self.eventSend.wait(0.01)
                    for channel in self.brickChannels:
                        if channel.decrement_run_timer():
                            monotime = 0.0
                            self.drivingLock.release()
                            # print("stop run normal")
                            self.emit("sbrick_channel_stop", channel.channel)
                        if channel.decrement_brake_timer():
                            self.drivingLock.release()
                            # print("stop brake timer")
                            monotime = 0.0
                            self.emit("sbrick_channel_stop", channel.channel)

            if self.authenticated:
                self.stop_all()
                self.send_command()
            self.SBrickPeripheral.disconnect()
            self.emit('sbrick_disconnected_ok')
        except BTLEException as ex:
            self.emit("sbrick_disconnected_error", ex.message)

    def get_channel(self, channel):
        if isinstance(channel, six.integer_types):
            return self.brickChannels[channel]
        if isinstance(channel, six.string_types):
            return self.brickChannels[self.channel_config_ids[channel]]
        return None

    def drive(self, channel, pwm, reverse, time, brake_after_time=False):
        with self.lock:
            ch = self.get_channel(channel)
            if ch is not None:
                ch.drive(pwm, reverse, time, brake_after_time)
                self.emit("sbrick_drive_sent", ch.channel, time)
            self.eventSend.set()

    def stop(self, channel, braked=False):
        with self.lock:
            ch = self.get_channel(channel)
            if ch is not None:
                ch.stop(braked)
                self.emit("sbrick_drive_sent", ch.channel, -2)
            self.eventSend.set()

    def stop_all(self):
        with self.lock:
            for channel in self.brickChannels:
                channel.stop()
            self.eventSend.set()

    def change_pwm(self, channel, pwm, change_reverse=False):
        with self.lock:
            ch = self.get_channel(channel)
            if ch is not None:
                ch.set_pwm(pwm, change_reverse)
            self.eventSend.set()

    def change_reverse(self, channel, reverse):
        with self.lock:
            ch = self.get_channel(channel)
            if ch is not None:
                ch.set_reverse(reverse)
            self.eventSend.set()

    def send_command(self):
        with self.lock:
            # try:
            drivecmd = bytearray([0x01])
            brakecmd = bytearray([0x00])
            for channel in self.brickChannels:
                drivecmd = channel.get_command_drive(drivecmd)
                brakecmd = channel.get_command_brake(brakecmd)
            if len(drivecmd) > 1:
                self.drivingLock.acquire()
                self.characteristicRemote.write(drivecmd, True)
                self.print_hex_string("drive sent", drivecmd)

            if len(brakecmd) > 1:
                self.characteristicRemote.write(brakecmd, True)
                self.print_hex_string("brake sent", brakecmd)
                # return True
                # except Exception as ex:
                #     self.emit("sbrick_disconnected_error",ex.message)
                #     return False

    def disconnect_sbrick(self):
        with self.lock:
            self.stopFlag = True

    @staticmethod
    def print_hex_string(what, strin):
        out = what + " -> "
        for chrx in strin:
            out = "%s %0X" % (out, chrx)
        print(out)

    def get_voltage(self):
        with self.lock:
            try:
                self.characteristicRemote.write(b"\x0f\x00")
                value = self.characteristicRemote.read()
                valueint = struct.unpack("<H", value)[0]
                return (valueint * 0.83875) / 2047.0
            except BTLEException as ex:
                self.emit("sbrick_disconnected_error", ex.message)

    def get_temperature(self):
        with self.lock:
            try:
                self.characteristicRemote.write(b"\x0f\x0e")
                value = self.characteristicRemote.read()
                valueint = struct.unpack("<H", value)[0]
                return valueint / 118.85795 - 160
            except BTLEException as ex:
                self.emit("sbrick_disconnected_error", ex.message)

    def get_thermal_limit(self):
        with self.lock:
            try:
                self.characteristicRemote.write(b'\x15')
                value = self.characteristicRemote.read()
                valueint = struct.unpack("<H", value)[0]
                return valueint / 118.85795 - 160
            except BTLEException as ex:
                self.emit("sbrick_disconnected_error", ex.message)

    def get_watchdog_timeout(self):
        with self.lock:
            try:
                self.characteristicRemote.write(b'\x0e')
                value = self.characteristicRemote.read()
                return struct.unpack("<B", value)[0] * 0.1
            except BTLEException as ex:
                self.emit("sbrick_disconnected_error", ex.message)

    def get_authentication_timeout(self):
        with self.lock:
            try:
                self.characteristicRemote.write(b'\x09')
                value = self.characteristicRemote.read()
                return struct.unpack("<B", value)[0] * 0.1
            except BTLEException as ex:
                self.emit("sbrick_disconnected_error", ex.message)

    def get_power_cycle_counter(self):
        with self.lock:
            try:
                self.characteristicRemote.write(b'\x28')
                value = self.characteristicRemote.read()
                return struct.unpack("<I", value)[0]
            except BTLEException as ex:
                self.emit("sbrick_disconnected_error", ex.message)

    def get_uptime(self):
        with self.lock:
            try:
                self.characteristicRemote.write(b'\x29')
                value = self.characteristicRemote.read()
                seconds = struct.unpack("<I", value)[0] * 0.1
                minutes = seconds // 60
                hours = minutes // 60
                return "%02d:%02d:%02d" % (hours, minutes % 60, seconds % 60)
            except BTLEException as ex:
                self.emit("sbrick_disconnected_error", ex.message)

    def get_hardware_version(self):
        try:
            return self.SBrickPeripheral.readCharacteristic(0x000c).decode("utf-8")
        except BTLEException as ex:
            self.emit("sbrick_disconnected_error", ex.message)

    def get_software_version(self):
        try:
            return self.SBrickPeripheral.readCharacteristic(0x000a).decode("utf-8")
        except BTLEException as ex:
            self.emit("sbrick_disconnected_error", ex.message)

    def get_brick_id(self):
        with self.lock:
            try:
                self.characteristicRemote.write(b'\x0a')
                value = self.characteristicRemote.read()
                return "%0X %0X %0X %0X %0X %0X" % (
                    value[0], value[1], value[2], value[3], value[4], value[5])
            except BTLEException as ex:
                self.emit("sbrick_disconnected_error", ex.message)

    def get_need_authentication(self):
        with self.lock:
            try:
                self.characteristicRemote.write(b'\x02')
                value = self.characteristicRemote.read()
                return struct.unpack("<B", value)[0] == 1
            except BTLEException as ex:
                self.emit("sbrick_disconnected_error", ex.message)

    def get_is_authenticated(self):
        with self.lock:
            try:
                self.characteristicRemote.write(b'\x03')
                value = self.characteristicRemote.read()
                return struct.unpack("<B", value)[0] == 1
            except BTLEException as ex:
                self.emit("sbrick_disconnected_error", ex.message)

    def get_user_id(self):
        with self.lock:
            try:
                self.characteristicRemote.write(b'\x04')
                value = self.characteristicRemote.read()
                return struct.unpack("<B", value)[0] == 1
            except BTLEException as ex:
                self.emit("sbrick_error", ex.message)

    def authenticate_owner(self, password):
        with self.lock:
            try:
                self.authenticated = False
                cmd = bytearray([0x05, 0x00])
                for ch in password:
                    cmd.append(ord(ch))
                self.characteristicRemote.write(cmd)
                self.authenticated = True
            except BTLEException as ex:
                self.emit("sbrick_error", ex.message)

    def authenticate_guest(self, password):
        with self.lock:
            try:
                self.authenticated = False
                cmd = bytearray([0x05, 0x01])
                for ch in password:
                    cmd.append(ord(ch))
                self.characteristicRemote.write(cmd)
                self.authenticated = True
            except BTLEException as ex:
                self.emit("sbrick_error", ex.message)

    def clear_owner_password(self):
        with self.lock:
            try:
                self.characteristicRemote.write(b'\x06\x00')
            except BTLEException as ex:
                self.emit("sbrick_error", ex.message)

    def clear_guest_password(self):
        with self.lock:
            try:
                self.characteristicRemote.write(b'\x06\x01')
            except BTLEException as ex:
                self.emit("sbrick_error", ex.message)

    def set_owner_password(self, password):
        with self.lock:
            try:
                cmd = bytearray([0x07, 0x00])
                for ch in password:
                    cmd.append(ord(ch))
                self.characteristicRemote.write(cmd)
            except BTLEException as ex:
                self.emit("sbrick_error", ex.message)

    def set_guest_password(self, password):
        with self.lock:
            try:
                cmd = bytearray([0x07, 0x01])
                for ch in password:
                    cmd.append(ord(ch))
                self.characteristicRemote.write(cmd)
            except BTLEException as ex:
                self.emit("sbrick_error", ex.message)

    def set_authentication_timeout(self, seconds):
        with self.lock:
            try:
                cmd = bytearray([0x08, seconds / 0.1])
                self.characteristicRemote.write(cmd)
            except BTLEException as ex:
                self.emit("sbrick_error", ex.message)
class LightBlueBean(DefaultDelegate):
    # https://github.com/PunchThrough/bean-documentation/blob/master/app_message_types.md
    MSG_ID_SERIAL_DATA        = 0x0000
    MSG_ID_BT_SET_ADV         = 0x0500
    MSG_ID_BT_SET_CONN        = 0x0502
    MSG_ID_BT_SET_LOCAL_NAME  = 0x0504
    MSG_ID_BT_SET_PIN         = 0x0506
    MSG_ID_BT_SET_TX_PWR      = 0x0508
    MSG_ID_BT_GET_CONFIG      = 0x0510
    MSG_ID_BT_ADV_ONOFF       = 0x0512
    MSG_ID_BT_SET_SCRATCH     = 0x0514
    MSG_ID_BT_GET_SCRATCH     = 0x0515
    MSG_ID_BT_RESTART         = 0x0520
    MSG_ID_GATING             = 0x0550
    MSG_ID_BL_CMD             = 0x1000
    MSG_ID_BL_FW_BLOCK        = 0x1001
    MSG_ID_BL_STATUS          = 0x1002
    MSG_ID_CC_LED_WRITE       = 0x2000
    MSG_ID_CC_LED_WRITE_ALL   = 0x2001
    MSG_ID_CC_LED_READ_ALL    = 0x2002
    MSG_ID_CC_LED_DATA        = 0x2082
    MSG_ID_CC_ACCEL_READ      = 0x2010
    MSG_ID_CC_ACCEL_DATA      = 0x2090
    MSG_ID_CC_TEMP_READ       = 0x2011
    MSG_ID_CC_TEMP_DATA       = 0x2091
    MSG_ID_CC_BATT_READ       = 0x2015
    MSG_ID_CC_BATT_DATA       = 0x2095
    MSG_ID_AR_SET_POWER       = 0x3000
    MSG_ID_AR_GET_CONFIG      = 0x3006
    MSG_ID_DB_LOOPBACK        = 0xFE00
    MSG_ID_DB_COUNTER         = 0xFE01
    
    def __init__(self, mac):
        self.conn = Peripheral(mac)
        self.conn.setDelegate(self)
        self.count = 0
        self.buffin = [None]*10
        self.got1 = False
        print('connected')
        
        self.service = self.conn.getServiceByUUID(_LBN_UUID(0x10))
        self.serial = self.service.getCharacteristics(_LBN_UUID(0x11)) [0]
        
        #print(self.serial.propertiesToString())

        # Turn on notificiations
        self.conn.writeCharacteristic(0x2f, '\x01\x00', False)
        
        i = 0
        while True:
            #print(self.serial.read())
            self.write("a" * 60)
            #self.write("a" * 5)
            #self.sendCmd(LightBlueBean.MSG_ID_CC_ACCEL_READ)
            
            self.conn.waitForNotifications(1)
            time.sleep(1)
        self.conn.disconnect()
        
    def write(self, data):
        self.sendCmd(LightBlueBean.MSG_ID_SERIAL_DATA, data)

    def sendCmd(self, cmd, data = ""):
        # https://github.com/PunchThrough/bean-documentation/blob/master/serial_message_protocol.md
        gst = struct.pack("!BxH", len(data)+2, cmd) + data
        crc = struct.pack("<H", crc16(gst, 0xFFFF))
        gst += crc
        
        gt_qty = len(gst)/19
        if len(gst) % 19 != 0:
            gt_qty += 1
        
        #amnt = len(gst) / gt_qty
        optimal_packet_size = 19
        
        for ch in xrange(0, gt_qty):
            data = gst[:optimal_packet_size]
            gst = gst[optimal_packet_size:]
            
            gt = 0
            if ch == 0:
                gt = 0x80
            gt |= self.count << 5
            gt |= gt_qty - ch - 1
            
            gt = struct.pack("B", gt) + data
        
            #print("<", hexdump(gt))
            self.serial.write(gt)
            #time.sleep(0.1)
        
        self.count = (self.count + 1) % 4

    def writeRaw(self, data):
        self.conn.writeCharacteristic(0x0b, data, False)

    def handleNotification(self, cHandle, data):
        #print(">", hexdump(data))
        gt = struct.unpack("B", data[0]) [0]
        #gt_cntr = gt & 0x60
        gt_left = gt & 0x1F
        
        if gt & 0x80:
            self.got1 = True
            self.buffin = self.buffin[:gt_left+1]
            
        self.buffin[gt_left] = data[1:]
        
        if self.got1 and not self.buffin.count(None):
            #print("Got ", len(self.buffin), "packets")
            self.buffin.reverse()
            self.buffin = ''.join(self.buffin)
            
            crc_ = crc16(self.buffin[:-2], 0xFFFF)
            dlen, cmd = struct.unpack("!BxH", self.buffin[:4])
            crc = struct.unpack("<H", self.buffin[-2:]) [0]
            if crc == crc_:
                print(self.buffin[4:-2])
            else:
                print("CRC check failure")
            
            self.buffin = [None]*10
            self.got1 = False
Example #60
0
import struct
import time
from bluepy.btle import UUID, Peripheral

# Message constants
MSG_LOCK = 0x10
MSG_UNLOCK = 0x11
MSG_STATE_REQ = 0x12

# Define read and write UUIDs
read_uuid = UUID(0x2221)
write_uuid = UUID(0x2222)

# Create a connection to the RFduino
#p = Peripheral("F9:D8:C2:B9:77:E9", "random")
p = Peripheral("D4:2C:92:60:C2:D5", "random")


try:

    # Create handles for read and write characteristics
    w_ch = p.getCharacteristics(uuid=write_uuid)[0]
    r_ch = p.getCharacteristics(uuid=read_uuid)[0]

    # Tell the Lockitron to lock
    msg = struct.pack('i', MSG_LOCK)
    print "Writing: " + str(msg)
    w_ch.write(msg)

finally:
    p.disconnect()