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
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 __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
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)
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)
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()
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)
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)
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
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')
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
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)
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)
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()
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
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) """
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
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]
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()
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)
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
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')
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()
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]
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")
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
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.'
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)
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)
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
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()
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]
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 []
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
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
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()
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)
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()
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
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()
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 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 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)
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))
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')
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
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()