def connect(self): if self._is_connected is True: return self._device = btle.Peripheral(self._device_mac) svc = self._device.getServiceByUUID(btle.UUID(RemoteBLE.SERVICE_UUID)) self._char = svc.getCharacteristics(btle.UUID(RemoteBLE.CHAR_UUID))[0] self._is_connected = True
def startChIdNotifyer(self, chId): ''' start GATT notification mode on server for denoted characteristic ''' if self.dev is None: logger.error('no ble device for notifying on %d' % chId) return elif self.dev.getState(): logger.info('starting notification on %s dev=%s' % (chId, self.dev.getState())) if chId >= chANA1ST: # finding which chan hand = self._getAnaMap(chId - chANA1ST) if hand: #hand = anamap[chId - chANA1ST] charist = self.dev.getCharacteristics(hand - 1, hand)[0] #self.notifying[hand] = chId self.startNotification(charist) return elif chId == chDIGI: service = self.dev.getServiceByUUID(btle.UUID(AIOS_SVR)) elif chId in [chTEMP, chHUMI, chECO2, chTVOC]: service = self.dev.getServiceByUUID(btle.UUID(ENV_SVR)) elif chId == chBAT: service = self.dev.getServiceByUUID(btle.UUID(BAS_SVR)) if chId in CHARS: logger.info('getCharacteristics:%s on %s' % (CHARS[chId], service)) charist = service.getCharacteristics(CHARS[chId]) if charist: self.startNotification(charist[0]) else: logger.error( "no BLE characteristic for %s with uuid:%s in %s" % (chId, btle.UUID(CHARS[chId]), service))
def GetRadonValue(): if Verbose: print("Connecting...") DevBT = btle.Peripheral(RadonEyeBTAddress, "random") RadonEye = btle.UUID("00001523-1212-efde-1523-785feabcd123") RadonEyeService = DevBT.getServiceByUUID(RadonEye) # Write 0x50 to 00001524-1212-efde-1523-785feabcd123 if Verbose: print("Writing...") uuidWrite = btle.UUID("00001524-1212-efde-1523-785feabcd123") RadonEyeWrite = RadonEyeService.getCharacteristics(uuidWrite)[0] RadonEyeWrite.write(bytes("\x50")) # Read from 3rd to 6th byte of 00001525-1212-efde-1523-785feabcd123 if Verbose: print("Reading...") uuidRead = btle.UUID("00001525-1212-efde-1523-785feabcd123") RadonEyeValue = RadonEyeService.getCharacteristics(uuidRead)[0] RadonValue = RadonEyeValue.read() RadonValue = struct.unpack('<f', RadonValue[2:6])[0] if picoCurie: Unit = "pCi/L" else: Unit = "Bq/m^3" RadonValue = RadonValue * 37 if OnlyValue: print("%0.2f" % (RadonValue)) else: print("%s - Radon Value: %0.2f %s" % (time.strftime("%Y-%m-%d [%H:%M:%S]"), RadonValue, Unit))
def run_forever(self): print 'starting Espruino' # Connect, set up notifications atexit.register(self.close) self.p = btle.Peripheral(self.mac, "random") self.p.setDelegate(NUSRXDelegate(self.callback)) nus = self.p.getServiceByUUID( btle.UUID("6E400001-B5A3-F393-E0A9-E50E24DCCA9E")) nustx = nus.getCharacteristics( btle.UUID("6E400002-B5A3-F393-E0A9-E50E24DCCA9E"))[0] nusrx = nus.getCharacteristics( btle.UUID("6E400003-B5A3-F393-E0A9-E50E24DCCA9E"))[0] nusrxnotifyhandle = nusrx.getHandle() + 1 self.p.writeCharacteristic(nusrxnotifyhandle, b"\x01\x00", withResponse=True) command = self.read_js_to_send(self.filename) while len(command) > 0: nustx.write(command[0:20]) command = command[20:] while True: self.wait_sec(120)
def _getAnaMap(self, anaChan=None): if not self.anamap: hand = 9999 descr = None #time.sleep(0.1) if self.dev: descr = self.dev.getDescriptors( ) # also having the characteristics if not descr: logger.warning("no descriptors for dev %s" % self.dev) for des in descr: if des.uuid == btle.UUID( CHARS[chANA1ST]): # it is an analog channel charist hand = des.handle #logger.debug('des:%s , %s' % (hand,des.uuid)); if des.handle > hand and (des.uuid == btle.UUID( CHARS[dscPRESFORM])): # look for presentation format #time.sleep(0.1) datPresForm = des.read() logger.debug( 'DescrPresForm hand:%d dat:%s uuid %s' % (des.handle, tls.bytes_to_hex(datPresForm), des.uuid)) chan = datPresForm[5] self.anamap[chan] = hand logger.debug('(A%d) ana hand:%s with presfrm:%s ' % (chan, hand, des)) hand = 9999 if self.anamap and anaChan in self.anamap: return self.anamap[anaChan] return None
class MotionService(): """ """ serviceUUID = btle.UUID('00000000-0001-11e1-9ab4-0002a5d5c51b') orient_char_uuid = btle.UUID("04000000-0001-11e1-ac36-0002a5d5c51b") CCCD_UUID = 0x2902 def __init__(self, periph): self.periph = periph self.motion_service = None self.orient_char = None self.orient_cccd = None def enable(self): """ Enables the class by finding the service and its characteristics. """ global m_orient_handle if self.motion_service is None: self.motion_service = self.periph.getServiceByUUID( self.serviceUUID) if self.orient_char is None: self.orient_char = self.motion_service.getCharacteristics( self.orient_char_uuid)[0] m_orient_handle = self.orient_char.getHandle() self.orient_cccd = self.orient_char.getDescriptors( forUUID=self.CCCD_UUID)[0] def set_orient_notification(self, state): if self.orient_cccd is not None: if state == True: self.orient_cccd.write(b"\x01\x00", True) else: self.orient_cccd.write(b"\x00\x00", True)
def write_to_characteristic(servID, charaID, data, para): serviceID = btle.UUID(servID)# to get the UUID in proper format for service serv = para.getServiceByUUID(serviceID)# get the service characteristicID = btle.UUID(charaID)# get characteristic ID in proper format chara = serv.getCharacteristics(characteristicID)[0] #get the characteristic encoded = (data.encode())# data should be sent in bytes format chara_value = chara.write(encoded)
def read_characteristic(servID, charaID, para): serviceID = btle.UUID(servID)# to get the UUID in proper format for service serv = para.getServiceByUUID(serviceID)# get the service characteristicID = btle.UUID(charaID)# get characteristic ID in proper format chara = serv.getCharacteristics(characteristicID)[0] #get the characteristic chara_value = chara.read() chara_value_decoded = (chara_value.decode()) return(binascii.b2a_hex(chara_value))
def _readDigitals(self): ''' get aios GATT representation of digital bit values and settings ''' if self.dev and self.dev.getState() == 'conn': service = self.dev.getServiceByUUID(btle.UUID(AIOS_SVR)) chT = service.getCharacteristics(btle.UUID(CHARS[chDIGI])) if chT: bts = self.read(chT[0]) logger.debug('reading digitals:%s' % tls.bytes_to_hex(bts)) return bts return None
def connect(): #dev=btle.Peripheral("1c:0f:ea:24:f1:4e") dev = btle.Peripheral("1C:0F:99:E4:2E:BF") driveCmd = btle.UUID("0000ffe5-0000-1000-8000-00805f9b34fb") driveService = dev.getServiceByUUID(driveCmd) driveUuidConfig = btle.UUID("0000ffe9-0000-1000-8000-00805f9b34fb") global driveConfig driveConfig = driveService.getCharacteristics(driveUuidConfig)[0] return "ok"
def _sendDigBits(self): nbits = len(self.digmods) if nbits <= 0: return bitsbuf = bytearray((nbits >> 2) + (1 if (nbits & 3) else 0)) for bt in range(nbits): bit2 = self.digmods[bt] if bit2 == mdOUT and self.bitvals[bt]: bit2 |= 1 bitsbuf[bt >> 2] |= bit2 << ((bt & 3) * 2) if self.dev: service = self.dev.getServiceByUUID(btle.UUID(AIOS_SVR)) chT = service.getCharacteristics(btle.UUID(CHARS[chDIGI])) self.write(chT[0], bytes(bitsbuf))
def lightShow(): print('Let me show you some magic LEDs') ioSensor = btle.UUID(IO_SERVICE_UUID) ioService = blueWand.getServiceByUUID(ioSensor) print('DEBUG io: {}'.format(ioService)) led = btle.UUID(LED_CHAR_UUID) ledConfig = ioService.getCharacteristics(led)[0] # Blink the LED's print('DEBUG: led: {}'.format(ledConfig)) ledConfig.write(bytes('07', 'UTF-8')) sleep(5) ledConfig.write(bytes('00', 'UTF-8')) sleep(0.5)
def get_data(dev): time.sleep(4) print 'Looking for user tags...' LairdMessage = btle.UUID('a6d81c26-3f48-48be-9eb8-b4a60c7dbe14') service = dev.getServiceByUUID(LairdMessage) LairdValue = btle.UUID('0001') value = service.getCharacteristics(LairdValue)[0] val = value.read() print 'User tags: ' + val try: time.sleep(4) dev.disconnect() print '1st attempt | Sucessfully disconnected with peripheral' except: print 'Unable to disconnect with peripheral' return val
class WaveGen2(Device): """ On 2nd Gen Wave, temperature and humidity are updated every 5 minutes. Radon measurements are updated once every hour. """ KEY = WAVE_GEN_2_KEY MODEL_NUMBER = WAVE_GEN_2_MODEL_NUMBER LABEL = WAVE_GEN_2_LABEL RAW_DATA_FORMAT = WAVE_GEN_2_RAW_DATA_FORMAT DATA_UUID = btle.UUID(WAVE_GEN_2_UUID_DATA) SENSOR_CAPABILITIES = { SENSOR_HUMIDITY_KEY: True, SENSOR_RADON_SHORT_TERM_AVG_KEY: True, SENSOR_RADON_LONG_TERM_AVG_KEY: True, SENSOR_TEMPERATURE_KEY: True, SENSOR_ATMOSPHERIC_PRESSURE_KEY: False, SENSOR_CO2_KEY: False, SENSOR_VOC_KEY: False, } def _parse_data(self, data): self._measurements[SENSOR_HUMIDITY_KEY] = HumiditySensor(data[1] / 2.0) self._measurements[ SENSOR_RADON_SHORT_TERM_AVG_KEY] = RadonShortTermAverageSensor( parse_radon_data(data[4])) self._measurements[ SENSOR_RADON_LONG_TERM_AVG_KEY] = RadonLongTermAverageSensor( parse_radon_data(data[5])) self._measurements[SENSOR_TEMPERATURE_KEY] = TemperatureSensor( data[6] / 100.0)
def connect_and_read(self): if self.debug: print('Services') for service in self.wave_device.services: print(service) print('Characteristics') for ch in self.wave_device.getCharacteristics(): print(ch.getHandle(), ch.uuid, ch.propertiesToString()) service = self.wave_device.getServiceByUUID(btle.UUID('b42e4a8e-ade7-11e4-89d3-123b93f75cba')) measurement = {} for ch in service.getCharacteristics(): name = ch.uuid.getCommonName() if name == 'b42e4dcc-ade7-11e4-89d3-123b93f75cba': raw = ch.read() data = unpack('BBBBHHHHHHHH', raw) measurement['sensor_version'] = data[0] measurement['humidity'] = data[1] / 2.0 measurement['radon_short_term_avg'] = self.conv2radon(data[4]) measurement['radon_long_term_avg'] = self.conv2radon(data[5]) measurement['temperature'] = data[6] / 100.0 measurement['timestamp'] = datetime.now().isoformat() measurement['id'] = str(uuid4()) self.wave_device.disconnect() return measurement
def connect(mac=None): maxRetry = 3 global DOTTIS logging.debug("Get bluettoth connection for : " + str(mac)) if mac in DOTTIS and not DOTTIS[mac]['connection'] is None: logging.debug("Found it in cache") return if mac not in DOTTIS: DOTTIS[mac] = {} DOTTIS[mac]['connection'] = None DOTTIS[mac]['display'] = {} i = 0 while True: i = i + 1 try: logging.debug("(" + str(i) + ") Try connect to " + str(mac)) DOTTIS[mac]['connection'] = btle.Peripheral(mac, iface=_device) break except Exception as err: if i >= maxRetry: logging.error('Connection error on ' + str(mac) + ' => ' + str(err)) return logging.debug("Wait " + str(i) + " second before retry") time.sleep(i) logging.debug("Connection successfull on " + str(mac)) DOTTIS[mac]['characteristic'] = btle.Characteristic( DOTTIS[mac]['connection'], btle.UUID('fff3'), 0x29, 8, 0x2A) return
async def main(servNotifying): logger.info("Connecting...") delg = bluepyDelegate(DEVADDRESS) #dev = btle.Peripheral(DEVADDRESS, btle.ADDR_TYPE_RANDOM) # btle.ADDR_TYPE_PUBLIC) if not delg or not delg.dev: logger.warning("unexpectedly leaving") return logger.info('dev %s iface:%s' % (delg.dev,delg.dev.iface) ) logger.info("Services...") for svc in delg.dev.services: stat = delg.dev.getStat() logger.info('stat:%s service:%s' % (stat,str(svc))) time.sleep(0.1) showChars(svc) time.sleep(5) descr = delg.dev.getDescriptors() for des in descr: try: logger.debug('descr:%d:%s: %s' % (des.handle, des, des.read())) except btle.BTLEGattError as e: logger.warning('%s:%s:' % (des,e )) if servNotifying: for srv in servNotifying: delg.startServiceNotifyers(delg.dev.getServiceByUUID(btle.UUID(srv))) #dev.withDelegate( delg ) try: await asyncio.gather( * delg.tasks() ) except KeyboardInterrupt: logger.warning('leaving') finally: delg.dev.disconnect()
class WaveMiniGen1(Device): """ Sensor values are updated every 5 minutes. """ KEY = WAVE_MINI_GEN_1_KEY MODEL_NUMBER = WAVE_MINI_GEN_1_MODEL_NUMBER LABEL = WAVE_MINI_GEN_1_LABEL RAW_DATA_FORMAT = WAVE_MINI_GEN_1_RAW_DATA_FORMAT DATA_UUID = btle.UUID(WAVE_MINI_GEN_1_UUID_DATA) SENSOR_CAPABILITIES = { SENSOR_HUMIDITY_KEY: True, SENSOR_RADON_SHORT_TERM_AVG_KEY: False, SENSOR_RADON_LONG_TERM_AVG_KEY: False, SENSOR_TEMPERATURE_KEY: True, SENSOR_ATMOSPHERIC_PRESSURE_KEY: False, SENSOR_CO2_KEY: False, SENSOR_VOC_KEY: True, } def _parse_data(self, data): self._measurements[SENSOR_TEMPERATURE_KEY] = TemperatureSensor( round(data[1] / 100.0 - 273.15, 2)) self._measurements[SENSOR_HUMIDITY_KEY] = HumiditySensor(data[3] / 100.0) self._measurements[SENSOR_VOC_KEY] = VOCSensor(data[4])
def read_device_metadata(self): p = btle.Peripheral(self.device.addr) readSensor = btle.UUID("0000a000-0000-1000-8000-00805f9b34fb") readService = p.getServiceByUUID(readSensor) for ch in readService.getCharacteristics(): if ch.uuid == btle.UUID("0000a001-0000-1000-8000-00805f9b34fb"): deviceMQTTName = self.strip_trailing_nulls(ch.read()) self.deviceMQTTName = deviceMQTTName elif ch.uuid == btle.UUID("0000a002-0000-1000-8000-00805f9b34fb"): deviceData = self.strip_trailing_nulls(ch.read()) self.interpret_device_data(deviceData) elif ch.uuid == btle.UUID("0000a003-0000-1000-8000-00805f9b34fb"): self.checksum = self.strip_trailing_nulls(ch.read()) elif ch.uuid == btle.UUID("0000a004-0000-1000-8000-00805f9b34fb"): ch.write(bytes.fromhex('01')) p.disconnect()
class WavePlusGen1(Device): """ Except for the radon measurements, the Wave Plus updates its current sensor values once every 5 minutes. Radon measurements are updated once every hour. """ KEY = WAVE_PLUS_GEN_1_KEY MODEL_NUMBER = WAVE_PLUS_GEN_1_MODEL_NUMBER LABEL = WAVE_PLUS_GEN_1_LABEL RAW_DATA_FORMAT = WAVE_PLUS_GEN_1_RAW_DATA_FORMAT DATA_UUID = btle.UUID(WAVE_PLUS_GEN_1_UUID_DATA) SENSOR_CAPABILITIES = { SENSOR_HUMIDITY_KEY: True, SENSOR_RADON_SHORT_TERM_AVG_KEY: True, SENSOR_RADON_LONG_TERM_AVG_KEY: True, SENSOR_TEMPERATURE_KEY: True, SENSOR_ATMOSPHERIC_PRESSURE_KEY: True, SENSOR_CO2_KEY: True, SENSOR_VOC_KEY: True, } def _parse_data(self, data): self._measurements[SENSOR_HUMIDITY_KEY] = HumiditySensor(data[1] / 2.0) self._measurements[ SENSOR_RADON_SHORT_TERM_AVG_KEY ] = RadonShortTermAverageSensor(parse_radon_data(data[4])) self._measurements[SENSOR_RADON_LONG_TERM_AVG_KEY] = RadonLongTermAverageSensor( parse_radon_data(data[5]) ) self._measurements[SENSOR_TEMPERATURE_KEY] = TemperatureSensor(data[6] / 100.0) self._measurements[SENSOR_ATMOSPHERIC_PRESSURE_KEY] = AtmosphericPressureSensor( data[7] / 50.0 ) self._measurements[SENSOR_CO2_KEY] = CO2Sensor(data[8] * 1.0) self._measurements[SENSOR_VOC_KEY] = VOCSensor(data[9] * 1.0)
def oxiThread(self): serviceUUID = "cdeacb80-5235-4c07-8846-93a37ee6b86d" serciceUUID = serviceUUID.upper() charUUID = "CDEACB81-5235-4C07-8846-93A37EE6B86D" oxi = "B4:52:A9:04:E6:E0" while self.oxon: try: oxiconn = btle.Peripheral(oxi) break except: print("connecting") oxiconn.setDelegate(self.myDelegate) setup_data = struct.pack('<bb', 0x01, 0x00) oxisensor = btle.UUID(serviceUUID) oxiserv = oxiconn.getServiceByUUID(oxisensor) oxiConf = oxiserv.getCharacteristics()[3] val = oxiConf.getHandle() + 1 print(val) oxiconn.writeCharacteristic(val, setup_data) while self.oxon: try: if oxiconn.waitForNotifications(1.0): continue except Exception as err: self.oxon = False
def getEnvInfoFromBLEDevices(): global m_temp global m_rh global btconnected gotdata = False error = False try: # devTH = btle.Peripheral(EnvMultiUV0980,btle.ADDR_TYPE_RANDOM) # devRH = btle.Peripheral(EvTH9640,btle.ADDR_TYPE_RANDOM) devRH = btle.Peripheral(EvTH7271, btle.ADDR_TYPE_RANDOM) except: error = True btconnected = False print("Cannot connect") if not error: btconnected = True # devTH.setMTU(31) devRH.setMTU(31) retry = 0 while (not gotdata) and (retry < 4): envSensor = btle.UUID("181a") envTHSvc = devRH.getServiceByUUID(envSensor) envRHSvc = devRH.getServiceByUUID(envSensor) tempUUIDVal = btle.UUID("2a6e") rhUUIDVal = btle.UUID("2a6f") tempVal = envRHSvc.getCharacteristics(tempUUIDVal)[0] rhVal = envRHSvc.getCharacteristics(rhUUIDVal)[0] _tempB = tempVal.read() tempB = reverse(_tempB) _rhB = rhVal.read() rhB = reverse(_rhB) x = binascii.b2a_hex(tempB) y = binascii.b2a_hex(rhB) if (x != 0) and (y != 0): gotdata = True m_temp = str(round(int(x, 16) / 100)) + "ºC" m_rh = str(round(int(y, 16) / 100)) + "%" else: retry += 1 devRH.disconnect() print( time.strftime('%F %H:%M') + "," + str(int(x, 16) / 100.0) + "," + str(int(y, 16) / 100.0))
def _getAnaMap0(self): descr = self.dev.getDescriptors() # also having the characteristics anamap = {} for des in descr: if des.uuid == btle.UUID( CHARS[chANA1ST]): # it is an analog channel charist hand = des.handle charist = self.dev.getCharacteristics(hand - 1, hand)[0] presform = charist.getDescriptors(btle.UUID( CHARS[dscPRESFORM])) # takes some time logger.debug('(%d) ana prfrm:%s with presfrm:%s ' % (hand, presform[0].handle, presform)) if presform: datPresForm = presform[0].read() chan == datPresForm[5] anamap[chan] = hand return anamap
def _sendDigBits(self): ''' send state of digital bits to aios device ''' nbits = len(self.digmods) if nbits <= 0: return bitsbuf = bytearray((nbits >> 2) + (1 if (nbits & 3) else 0)) for bt in range(nbits): bit2 = self.digmods[bt] if bit2 == mdOUT and self.bitvals[bt]: bit2 |= 1 bitsbuf[bt >> 2] |= bit2 << ((bt & 3) * 2) if self.dev: service = self.dev.getServiceByUUID(btle.UUID(AIOS_SVR)) chT = service.getCharacteristics(btle.UUID(CHARS[chDIGI])) self.write(chT[0], bytes(bitsbuf)) logger.debug('aios sending %d digdat:%s' % (nbits, tls.bytes_to_hex(bitsbuf, '.')))
class WaveGen1(Device): """ On 1st Gen Wave, temperature and humidity are updated every time we read the wave. Radon measurements are updated once every hour. """ KEY = WAVE_GEN_1_KEY MODEL_NUMBER = WAVE_GEN_1_MODEL_NUMBER LABEL = WAVE_GEN_1_LABEL RAW_DATA_FORMAT = WAVE_GEN_1_RAW_DATA_FORMAT UUID_DATETIME = btle.UUID(WAVE_GEN_1_UUID_DATETIME) UUID_HUMIDITY = btle.UUID(WAVE_GEN_1_UUID_HUMIDITY) UUID_TEMPERATURE = btle.UUID(WAVE_GEN_1_UUID_TEMPERATURE) UUID_RADON_STA = btle.UUID(WAVE_GEN_1_UUID_RADON_SHORT_TERM_AVERAGE) UUID_RADON_LTA = btle.UUID(WAVE_GEN_1_UUID_RADON_LONG_TERM_AVERAGE) SENSOR_CAPABILITIES = { SENSOR_HUMIDITY_KEY: True, SENSOR_RADON_SHORT_TERM_AVG_KEY: True, SENSOR_RADON_LONG_TERM_AVG_KEY: True, SENSOR_TEMPERATURE_KEY: True, SENSOR_ATMOSPHERIC_PRESSURE_KEY: False, SENSOR_CO2_KEY: False, SENSOR_VOC_KEY: False, } def _fetch_raw_data(self, connect_retries=3): self._connect(connect_retries) raw_data = self._fetch_characteristic(self.UUID_DATETIME) raw_data += self._fetch_characteristic(self.UUID_HUMIDITY) raw_data += self._fetch_characteristic(self.UUID_TEMPERATURE) raw_data += self._fetch_characteristic(self.UUID_RADON_STA) raw_data += self._fetch_characteristic(self.UUID_RADON_LTA) self._disconnect() return raw_data def _parse_data(self, data): self._measurements[SENSOR_HUMIDITY_KEY] = HumiditySensor(data[6] / 100.0) self._measurements[SENSOR_TEMPERATURE_KEY] = TemperatureSensor(data[7] / 100.0) self._measurements[ SENSOR_RADON_SHORT_TERM_AVG_KEY ] = RadonShortTermAverageSensor(parse_radon_data(data[8])) self._measurements[SENSOR_RADON_LONG_TERM_AVG_KEY] = RadonLongTermAverageSensor( parse_radon_data(data[9]) )
def btle_connect(): global p global tx_uuid global rx_uuid global tx global rx try: p = btle.Peripheral(server_settings.btle_address, "random") except btle.BTLEException as exc: print "Error connecting to BTLE device: " + exc.message return False tx_uuid = btle.UUID("6e400002-b5a3-f393-e0a9-e50e24dcca9e") rx_uuid = btle.UUID("6e400003-b5a3-f393-e0a9-e50e24dcca9e") tx = p.getCharacteristics(uuid=tx_uuid)[0] rx = p.getCharacteristics(uuid=rx_uuid)[0] p.setDelegate(MyDelegate({})) # Tell BTLE to accept notifications by sending 0x0100 to the CCCD p.writeCharacteristic(0x0023, '\x01\x00', False) return True
def GetRadonValue(): try: sensor = m.AirSensor.find_one({m.AirSensor.id: P.radoneye_id}) if sensor is not None: DevBT = btle.Peripheral(sensor.address, "random") RadonEye = btle.UUID("00001523-1212-efde-1523-785feabcd123") RadonEyeService = DevBT.getServiceByUUID(RadonEye) # Write 0x50 to 00001524-1212-efde-1523-785feabcd123 uuidWrite = btle.UUID("00001524-1212-efde-1523-785feabcd123") RadonEyeWrite = RadonEyeService.getCharacteristics(uuidWrite)[0] RadonEyeWrite.write(bytes("\x50", encoding='utf8')) # Read from 3rd to 6th byte of 00001525-1212-efde-1523-785feabcd123 uuidRead = btle.UUID("00001525-1212-efde-1523-785feabcd123") RadonEyeValue = RadonEyeService.getCharacteristics(uuidRead)[0] RadonValue = RadonEyeValue.read() RadonValue = struct.unpack('<f', RadonValue[2:6])[0] DevBT.disconnect() # Raise exception (will try get Radon value from RadonEye again) if received a very # high radoneye value or lower than 0. # Maybe a bug on RD200 or Python BLE Lib?! if (RadonValue > 1000) or (RadonValue < 0.1): L.l.error( "Very strange radoneye value={}. Debugging needed.".format( RadonValue)) else: #if args.becquerel: Unit = "Bq/m3" RadonValue = (RadonValue * 37) #else: # Unit = "pCi/L" sensor.radon = RadonValue sensor.save_changed_fields(broadcast=True, persist=True) L.l.info("Read radoneye {} value {} {}".format( sensor.address, RadonValue, Unit)) else: L.l.erro("Cannot find radoneye record with id={} in config".format( P.radoneye_id)) except Exception as ex: L.l.warning("Exception reading radoneye value {}".format(ex))
def _CharId(self, charist, CharDef=CHARS): ''' return unique id for a chracteristic ''' chId = None uuid = charist.uuid self._getAnaMap() for chi,uid in CharDef.items(): if btle.UUID(uid) == uuid: chId = chi break return chId
def connect_and_read(device_address): try: dev = btle.Peripheral(device_address) except btle.BTLEException as e: raise CouldNotConnectError() # Humidity: 00002a6f-0000-1000-8000-00805f9b34fb # Temperature: ... # Radon conc. average: b42e0a4c-ade7-11e4-89d3-123b93f75cba # Radon conc. 1 day: b42e01aa-ade7-11e4-89d3-123b93f75cba if False: print('Services') for service in dev.services: print(service) print('Characteristics') for ch in dev.getCharacteristics(): print(ch.getHandle(), ch.uuid, ch.propertiesToString()) service = dev.getServiceByUUID( btle.UUID('b42e1f6e-ade7-11e4-89d3-123b93f75cba')) temperature = humidity = radon_avg = radon_1day = accel = humidity2 = None for ch in service.getCharacteristics(): name = ch.uuid.getCommonName() if name == 'Temperature': value = unpack('h', ch.read())[0] temperature = value / 100 elif name == 'Humidity': value = unpack('h', ch.read())[0] humidity = value / 100 elif name == 'b42e0a4c-ade7-11e4-89d3-123b93f75cba': # Description: 'Radon conc. avg.' value = unpack('h', ch.read())[0] radon_avg = value elif name == 'b42e01aa-ade7-11e4-89d3-123b93f75cba': # Description: 'Radon conc. 1 day' value = unpack('h', ch.read())[0] radon_1day = value elif name == 'b42e1096-ade7-11e4-89d3-123b93f75cba': # Description: 'Accel. Light 5m' accel = unpack('H', ch.read())[0] elif name == 'b42e1348-ade7-11e4-89d3-123b93f75cba': # Description: 'Status info' # Seems to be identical to humidity humidity2 = unpack('h', ch.read())[0] / 100 dev.disconnect() return Measurement(humidity=humidity, temperature=temperature, radon_avg=radon_avg, radon_1day=radon_1day, accel=accel, humidity2=humidity2)
def ReadBLEData(): print("Connecting...") dev = btle.Peripheral(ConfigReader.g_config.bt_mac_addreses, 'random') print("Services...") for svc in dev.services: print(str(svc)) NRF_UART_SERVICE = btle.UUID( "6E400001-B5A3-F393-E0A9-E50E24DCCA9E") # nrfDataService print("charterstics...") nrfGattService = dev.getServiceByUUID(NRF_UART_SERVICE) for ch in nrfGattService.getCharacteristics(): print(str(ch)) NRF_UART_RX = btle.UUID("6E400002-B5A3-F393-E0A9-E50E24DCCA9E") NRF_UART_TX = btle.UUID("6E400003-B5A3-F393-E0A9-E50E24DCCA9E") CLIENT_CHARACTERISTIC_CONFIG = btle.UUID( "00002902-0000-1000-8000-00805f9b34fb") nrfGattCharacteristic = nrfGattService.getCharacteristics(NRF_UART_TX) print("nrfGattCharacteristic = ", nrfGattCharacteristic) #print nrfGattCharacteristic.supportsRead() print(nrfGattCharacteristic[0].propertiesToString()) #???nrfGattCharacteristic[0].write(struct.pack('<bb', 0x01, 0x00), False) bdescriptor = nrfGattCharacteristic[0].getDescriptors( CLIENT_CHARACTERISTIC_CONFIG) bdescriptor[0].write(struct.pack('<bb', 0x01, 0x00), False) CharacteristicSend = nrfGattService.getCharacteristics(NRF_UART_RX)[0] dev.setDelegate(MyDelegate(CharacteristicSend)) str1 = bytes([240]) print(str1) CharacteristicSend.write(str1) time.sleep(1.0) # Allow sensor to stabilize while True: dev.waitForNotifications(1.0)