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 connectToDevice(MAC): p = Peripheral(MAC) #p = Peripheral("98:4f:ee:0f:84:1f") for x in range(0, uuidCount): uuidVal = validUUIDs[x][0] try: ch = p.getCharacteristics(uuid=uuidVal)[0] if (ch.supportsRead()): val = binascii.b2a_hex(ch.read()) val = binascii.unhexlify(val) val = str(val).strip() val = int(val) print validUUIDs[x][1] + ": " + str(val) if validUUIDs[x][1] == "compostTempF": tempF = val tempC = (tempF - 32) * 5 / 9 elif validUUIDs[x][1] == "ambientTempF": ambientTempF = val ambientTempC = (ambientTempF - 32) * 5 / 9 if ambientTempF <= ambientTempCold: ambientTemp = "low" else: ambientTemp = "high" elif validUUIDs[x][1] == "compostMoisture": moisture = val elif validUUIDs[x][1] == "methanePPM": methane = val elif validUUIDs[x][1] == "waterLevel": waterLevel = val finally: print "Done" persistSensorData(tempF, tempC, ambientTempF, ambientTempC, moisture, methane, waterLevel) overallMsg, ventAngle, needWater = analyzeData(tempF, tempC, ambientTemp, moisture, methane, waterLevel) print str(needWater) + " : Need Water?" print str(ventAngle) + " : Vent Angle" if needWater == 1: ch = p.getCharacteristics( uuid="0411dc98-895b-4639-b627-c663f6726c3c")[0] ch.write("1") if ventAngle == 1: ch = p.getCharacteristics( uuid="0411dc97-895b-4639-b627-c663f6726c3c")[0] ch.write("1") else: ch = p.getCharacteristics( uuid="0411dc97-895b-4639-b627-c663f6726c3c")[0] ch.write("0") p.disconnect() return overallMsg
def configure_device(scanEntry): logging.info("Connecting to: %s", scanEntry.addr) try: peripheral_device = Peripheral(scanEntry) except: logging.warning("_-_-_ Failed to connect to: %s", scanEntry.addr) else: peripheral_device.setDelegate(ConfigDelegate()) # serviceList = peripheral_device.getServices() # logging.debug(serviceList) # logging.debug(list(serviceList)) # for service in peripheral_device.getServices(): # logging.debug("S: %s", service.uuid) # for characteristic in service.getCharacteristics(): # logging.debug("C: %s", characteristic.uuid) # Read HW ID and apply corresponding configuration hw_id_char = peripheral_device.getCharacteristics(uuid="00001101-0f58-2ba7-72c3-4d8d58fa16de")[0] hw_id = unpack("H", hw_id_char.read())[0] logging.info("HWID:%s", hw_id) if hw_id == HW_ID_CLIMATE: config = climate_configuration elif hw_id == 5: config = conference_configuration else: peripheral_device.disconnect() return uartRxChar = peripheral_device.getCharacteristics(uuid="6e400003-b5a3-f393-e0a9-e50e24dcca9e")[0] uartTxChar = peripheral_device.getCharacteristics(uuid="6e400002-b5a3-f393-e0a9-e50e24dcca9e")[0] # logging.debug(uartRxChar) # logging.debug(uartTxChar) # logging.debug("RX char properties: %s", uartRxChar.propertiesToString()) # logging.debug("TX char properties: %s", uartTxChar.propertiesToString()) logging.debug("Enable notification") uartRxCharDescriptorHandle = uartRxChar.getHandle() + 1 peripheral_device.writeCharacteristic(uartRxCharDescriptorHandle , (1).to_bytes(2, byteorder='little')) # logging.debug(uartRxChar.getHandle()) # logging.debug(uartTxChar.getHandle()) for x in range(0, len(config)): # logging.debug(x) uartTxChar.write(config[x]) if peripheral_device.waitForNotifications(1): pass # logging.debug("Notification received") else: logging.debug("No notification received") peripheral_device.waitForNotifications(1) logging.info("Configuration complete") peripheral_device.disconnect()
def putimage(addr, image): # line below needs to be changed to use your mugs MAC address try: peripheral = Peripheral(addr, addrType=ADDR_TYPE_RANDOM) print("connected to muki") # line below uses characteristics directly. you can also request it characteristic = peripheral.getCharacteristics( uuid='06640002-9087-04a8-658f-ce44cb96b4a1')[0] print("writing image to device") characteristic.write(bytes.fromhex('74'), withResponse=True) # Write image in 291 chunks, 20 bytes at time index = 0 for i in range(0, 291): data = image[index:index + 20] # last one may be too short while len(data) < 20: data.append(0xFF) characteristic.write(data, withResponse=False) index = index + 20 # this one is write without response because it fails if response # is required. Image is written anyway characteristic.write(bytes.fromhex('64'), withResponse=True) peripheral.disconnect() except (BTLEException): print("Write failed") return False print("write successful") return True
def run(self): uuid = "36d25039-5cbc-5ee5-b688-b90fda300d6" bmac = self.args["bmac"] try: iface = int(self.args["iface"]) except: iface = 0 print_info(f"Trying to connect {bmac}") try: p = Peripheral(bmac, "random", iface) print_ok("connected") except KeyboardInterrupt: print_info("Interrupted... exit run") return except: print_error("Failed to connect") return try: ch = p.getCharacteristics(uuid=uuid)[0] if "WRITE" in ch.propertiesToString(): print_ok("Good! It's writable!") else: print_error("It is not writable") return hex_password = bytes.fromhex(self.args['password'].replace( "0x", "")) print_info(f"Updating Password in {bmac}") ch.write(hex_password) print_ok("Done!") except: print_error("It was not possible to write")
def get_service_value(addr: str, addr_type: str, offset: str): """ Gets the value from a Blue Tooth Low Energy device. Arguments: addr {string} -- The address to get the value from add_type {string} -- The type of address we are using. offset {string} -- The offset from the device's address to get the value from Returns: {int} -- The result of the fetch """ # Generate fake values for debugging # and for the development of the visuals. if not IS_LINUX: return 0 try: p = Peripheral(addr, addr_type) ch_all = p.getCharacteristics(uuid=offset) if ch_all[0].supportsRead(): res = ch_all[0].read() p.disconnect() return ord(res) except Exception as ex: print(" ex in get_name={}".format(ex)) return None
def get_service_value(addr, addr_type, offset): """ Gets the value from a Blue Tooth Low Energy device. Arguments: addr {string} -- The address to get the value from add_type {string} -- The type of address we are using. offset {string} -- The offset from the device's address to get the value from Returns: {int} -- The result of the fetch """ # Generate fake values for debugging # and for the development of the visuals. if not IS_LINUX: if offset in CO_OFFSET: return int(aithre_co_simulator.get_value()) else: return int(aithre_bat_simulator.get_value()) try: p = Peripheral(addr, addr_type) # bluepy.btle.ADDR_TYPE_PUBLIC) ch_all = p.getCharacteristics(uuid=offset) if ch_all[0].supportsRead(): res = ch_all[0].read() p.disconnect() return ord(res) except Exception as ex: print(" ex in get_name={}".format(ex)) return None
def read(self, p: Peripheral): ch = p.getCharacteristics(uuid=self.uuid)[0] if not ch.supportsRead(): return None val = struct.unpack(self.format_type, ch.read()) return str(val[0] * self.scale)
class RadonSensor: def __init__(self, MAC_address): self.peripheral = Peripheral(MAC_address) self.sensors = [] self.sensors.append(Sensor("timestamp", UUID(0x2A08), 'HBBBBB', "", 0)) self.sensors.append( Sensor("temperature", UUID(0x2A6E), 'h', "C", 1.0 / 100.0)) self.sensors.append( Sensor("humidity", UUID(0x2A6F), 'H', "%RH", 1.0 / 100.0)) self.sensors.append( Sensor("Radon_24h_avg", "b42e01aa-ade7-11e4-89d3-123b93f75cba", 'H', "Bq/m3", 1.0)) self.sensors.append( Sensor("Radon_long_term", "b42e0a4c-ade7-11e4-89d3-123b93f75cba", 'H', "Bq/m3", 1.0)) def get_data(self): data = {} timestamp = None for s in self.sensors: ch = self.peripheral.getCharacteristics(uuid=s.uuid)[0] if ch.supportsRead(): val = ch.read() if s.name == "timestamp": unpacked = struct.unpack(s.format_type, val) dt = datetime(*unpacked) timestamp = time.mktime(dt.timetuple()) else: data[s.name] = {} data[s.name]['value'] = struct.unpack(s.format_type, val)[0] * s.scale data[s.name]['unit'] = s.unit return data, timestamp
class WavePlus(): def __init__(self, MAC_ADDR): self.periph = None self.curr_val_char = None self.MacAddr = MAC_ADDR self.uuid = UUID("b42e4dcc-ade7-11e4-89d3-123b93f75cba") def connect(self): # 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] def read(self): if (self.curr_val_char is None): print("ERROR: Devices are not connected.") sys.exit(1) rawdata = self.curr_val_char.read() rawdata = struct.unpack('BBBBHHHHHHHH', rawdata) sensors = Sensors() sensors.set(rawdata) return sensors def disconnect(self): if self.periph is not None: self.periph.disconnect() self.periph = None self.curr_val_char = None
def update(self, force_update=False): if force_update or (self._last_update is None) or (datetime.now() - self._min_update_inteval > self._last_update): self._lock.acquire() try: p = Peripheral(self._mac, "public") chList = p.getCharacteristics() for ch in chList: if str(ch.uuid) == SERVICE_UUID: if p.writeCharacteristic(ch.getHandle(), b'\x55\x03' + bytes([self.get_sequence()]) + b'\x11', True): data = ch.read() humihex = data[6:8] temphex = data[4:6] temp10 = int.from_bytes(temphex, byteorder='little') humi10 = int.from_bytes(humihex, byteorder='little') self._temperature = float(temp10) / 100.0 self._humidity = float(humi10) / 100.0 if p.writeCharacteristic(ch.getHandle(), b'\x55\x03' + bytes([self.get_sequence()]) + b'\x10', True): data = ch.read() battery10 = data[4] self._battery = float(battery10) / 10.0 break p.disconnect() except Exception as ex: print("Unexpected error: {}".format(ex)) p.disconnect() finally: self._lock.release()
class Zuma(): def __init__(self, addr): try: self.device = Peripheral(addr) except BTLEException: print('Non trovo Zuma!') self.device = False if(self.device is not False): self.comm = self.device.getCharacteristics(uuid='0000ffe1-0000-1000-8000-00805f9b34fb')[0]
class PiBuddy(): def __init__(self, address): self.device = Peripheral(address) self.read = self.device.getCharacteristics( uuid="6E400003-B5A3-F393-E0A9-E50E24DCCA9E")[0] self.readHandle = self.read.getHandle() def getCurrentStatus(self): return self.device.readCharacteristic(self.readHandle)
class WavePlus(): def __init__(self, SerialNumber): self.periph = None self.curr_val_char = None self.MacAddr = None self.SN = SerialNumber self.uuid = UUID("b42e2a68-ade7-11e4-89d3-123b93f75cba") 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) if (ManuData is None): continue 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." print "GUIDE: (1) Please verify the serial number." print " (2) Ensure that the device is advertising." print " (3) Retry connection." sys.exit(1) # 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] def read(self): if (self.curr_val_char is None): print "ERROR: Devices are not connected." sys.exit(1) rawdata = self.curr_val_char.read() rawdata = struct.unpack('BBBBHHHHHHHH', rawdata) sensors = Sensors() sensors.set(rawdata) return sensors def disconnect(self): if self.periph is not None: self.periph.disconnect() self.periph = None self.curr_val_char = None
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) -> Optional[Packet]: logger.debug(f"Send {packet}") self.ch_api_v2.write(packet.build(), withResponse=True) return self.packet_collector.get_response(packet, raise_api_error, timeout=timeout) 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]
class WavePlus: def __init__(self, serial_number, mac_addr): self.periph = None self.curr_val_char = None self.mac_addr = mac_addr self.sn = serial_number self.uuid = UUID(WAVEPLUS_UUID) def search(self): # Auto-discover device on first connection scanner = Scanner().withDelegate(DefaultDelegate()) search_count = 0 while search_count < MAX_SEARCH_COUNT: devices = scanner.scan(SCAN_TIMEOUT) search_count += 1 for dev in devices: manu_data = dev.getValueText(255) sn = parse_serial_number(manu_data) if sn == self.sn: return dev.addr # Device not found after MAX_SEARCH_COUNT print( "ERROR: Could not find device.", "GUIDE: (1) Please verify the serial number.", " (2) Ensure that the device is advertising.", " (3) Retry connection.", sep="\n", ) sys.exit(1) def connect(self): if self.mac_addr is None: self.mac_addr = self.search() if self.periph is None: self.periph = Peripheral(self.mac_addr) if self.curr_val_char is None: self.curr_val_char = self.periph.getCharacteristics( uuid=self.uuid)[0] def read(self): if self.curr_val_char is None: print("ERROR: Devices are not connected.") sys.exit(1) raw_data = self.curr_val_char.read() raw_data = struct.unpack("<BBBBHHHHHHHH", raw_data) sensors = Sensors() sensors.set(raw_data) return sensors def disconnect(self): if self.periph is not None: self.periph.disconnect() self.periph = None self.curr_val_char = None
class T1D: _previous_state = "" rstick = '' def __init__(self, mac_address): self._controller = Peripheral(mac_address, 'random') self._state_characteristic = self._controller.getCharacteristics( uuid="00008651-0000-1000-8000-00805f9b34fb")[0] self.get_state() print("Connected") def get_state(self) -> bool: # Returns True is state did change self._state_vec = self._state_characteristic.read() if self._state_vec[0] == 0xc9: # Creates garbage values return False if self._previous_state != self._state_vec: self._previous_state = self._state_vec self.parse_state() return True return False def parse_state(self): # Notes: Last byte (data[19] is updated on every controller change - can be used as trigger instead of polling) data = self._state_vec self.L1 = int(bool(data[9] & 0x40)) self.L2 = int(data[7]) # int 0-255 self.R1 = int(bool(data[9] & 0x80)) self.R2 = int(data[8]) self.X = int(bool(data[9] & 0x08)) self.Y = int(bool(data[9] & 0x10)) self.A = int(bool(data[9] & 0x01)) self.B = int(bool(data[9] & 0x02)) self.C1 = int(bool(data[10] & 0x04)) self.C2 = int(bool(data[10] & 0x08)) self.MENU = int(bool(data[9] & 0x04)) self.Down = int(bool(data[11] == 0x05)) self.Up = int(bool(data[11] == 0x01)) self.Left = int(bool(data[11] == 0x07)) self.Right = int(bool(data[11] == 0x03)) self.LX = int(((data[2]) << 2) | (data[3] >> 6)) self.LY = int(((data[3] & 0x3f) << 4) + (data[4] >> 4)) self.RX = int(((data[4] & 0xf) << 6) | (data[5] >> 2)) self.RY = int(((data[5] & 0x3) << 8) + ((data[6]))) def __str__(self): return "L1: {}\nL2: {}\nR1: {}\nR2: {}\nX : {}\nY : {}\nA : {}\nB : {}\nC1: {}\nC2: {}\nMENU: {}\nDown: {}\nUp: {}\nLeft: {}\nRight: {}\nLX : {}\nLY : {}\nRX : {}\nRY : {}".format( self.L1, self.L2, self.R1, self.R2, self.X, self.Y, self.A, self.B, self.C1, self.C2, self.MENU, self.Down, self.Up, self.Left, self.Right, self.LX, self.LY, self.RX, self.RY)
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 send_ble(addr="CA:34:A7:E4:DF:50", uuid=0x0001, message='2'): try: print("ble sending ", message) p = Peripheral(addr, "random") # Connect to Peripheral with addr ch = p.getCharacteristics( uuid=uuid)[0] # Get first Characteristic of Peripheral print("Sending {}".format(message)) ch.write( str.encode(message), withResponse=True ) # Send message as bytes, withResponse checks if message sent finally: p.disconnect() # Disconnect from Peripheral
def run(self): #Creation d'un objet Peripheral p = Peripheral() try: #Connection au peripherique en passant son adresse en parametre p.connect(self.adresse) except: #Si erreur (MARCHE MAL) print "Erreur co" subprocess.Popen(['sudo', 'hcitool', 'ledc','64']) subprocess.Popen(['sudo', 'hcitool', 'ledc','65']) time.sleep(2) p.connect(self.adresse) print("Connect devices : " + str(self.adresse)) #Retourne la liste des characteristiques du peripherique chrs = p.getCharacteristics() #Parcours de la liste for chr in chrs: #print chr.getHandle() #Si le handle correspond a 18 on envoie les données au peripherique #18 Correspond au handle permettantde dialoguer avec le HM10 (WRITE,READ,NOTIF) if chr.getHandle() == 18: while True: #Recuperation des données via une Base de données sqlite3 """Toutes les secondes (time.sleep(1)) On recupere la DERNIERE ligne de la table MONTRE qui correspond a la derniere valeur que la montre a envoyée et que l'on a inseré dans la bases de données time.sleep permet ici de regler la frequence d'envoi des données aux devices de visualisation """ conn = sqlite3.connect('DatabaseIOT.db') cursor = conn.cursor() cursor.execute(""" SELECT BPM, RRINTERVAL FROM MONTREWITHTIME WHERE ID = (SELECT MAX(ID) FROM MONTREWITHTIME);""") conn.commit() watchDataSQLite = cursor.fetchone() print(str(watchDataSQLite)) conn.close() #Boucle infinie ou l'on envoie en boucle les données chr.write(str(watchDataSQLite)) print "Data Send on " + str(self.adresse) time.sleep(1) """On peut raccourcir le code en utilisant la methode writeCharacteristic()
class BLEDevice(Thread): def __init__(self, room_batch_queue, room_sub_update_queue, addr, addrType, ble_activity_lock): Thread.__init__(self) print("Created BLE Device: {}".format(addr)) self.room_batch_queue = room_batch_queue self.room_sub_update_queue = room_sub_update_queue self.addr = addr self.addrType = addrType self.ble_activity_lock = ble_activity_lock def ble_listen_loop(self, write_cs, notify_cs): print("writing something so connection stays alive") write_cs.write(b"hey") print("listening to read...") while True: if self.conn.waitForNotifications(1.0): continue print("waiting...") # TODO: Listen for self.room_sub_update_queue updates time.sleep(0.05) def run(self): print("attempting connect to {}".format(self.addr)) self.ble_activity_lock.acquire() self.conn = Peripheral(self.addr, self.addrType) self.ble_activity_lock.release() print("Connected! {}".format(self.addr)) css = self.conn.getCharacteristics() notify_cs = None write_cs = None for cs in css: print(cs.uuid, cs.propertiesToString()) # per.getCharacteristics(uuid='6e400003-b5a3-f393-e0a9-e50e24dcca9e')[0] if cs.propertiesToString() == "NOTIFY ": notify_cs = cs if "WRITE" in cs.propertiesToString(): write_cs = cs if write_cs and notify_cs: self.conn.setDelegate(MyDelegate(self.addr, self.room_batch_queue)) # enable notification setup_data = b"\x01\x00" notify_handle = notify_cs.getHandle() + 1 self.conn.writeCharacteristic(notify_handle, setup_data, withResponse=True) self.ble_listen_loop(write_cs, notify_cs) else: print( "Device {} did not have a write and notify BLE characteristic." .format(self.addr))
class WavePlus(): def __init__(self, serialNumber): self.periph = None self.curr_val_char = None self.SN = serialNumber self.MacAddr = None self.uuid = UUID("b42e2a68-ade7-11e4-89d3-123b93f75cba") def connect(self): # Auto-discover device on first connection if (self.MacAddr is None): scanner = Scanner().withDelegate(DefaultDelegate()) searchCount = 0 #I have my wave plus and the pi zero W this runs on mounted directly across from each other in a standard hallway #It still fails at 0.1 and 50 more than once a day. while self.MacAddr is None and searchCount < 100: devices = scanner.scan(0.2) # 0.1 seconds scan period searchCount += 1 for dev in devices: ManuData = dev.getValueText(255) SN = parseSerialNumber(ManuData) if (str(SN) == str(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 wave plus") sys.exit(1) # 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] def read(self): if (self.curr_val_char is None): print("ERROR - Device not connected") sys.exit(1) rawdata = self.curr_val_char.read() rawdata = struct.unpack('BBBBHHHHHHHH', rawdata) sensors = Sensors() sensors.set(rawdata) return sensors def disconnect(self): if self.periph is not None: self.periph.disconnect() self.periph = None self.curr_val_char = None
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 read_student_number(self, mac_address): start = time.time() device = Peripheral(mac_address, addrType="random") service = device.getServiceByUUID(student_number_service) chars = device.getCharacteristics(uuid=student_number_characteristic) print(service) print(chars) for char in chars: print(char, char.getHandle(), char.propertiesToString(), char.supportsRead()) student_number = chars[-1].read() end = time.time() print("{0} seconds".format(end - start)) return student_number.decode('utf-8')
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 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
def on_message(client, userdata, msg): try: #connecting to device mac = msg.topic[4:21] print('connecting to ' + mac + '...') p = Peripheral(mac, 'random') print('connected') #sending message to device w = p.getCharacteristics(uuid=write_uuid)[0] data = json.loads(msg.payload) print('writing message to device: ', base64.b64decode(data['payload'])) w.write(base64.b64decode(data['payload'])) # disconnect device p.disconnect() except Exception as e: print(e)
class BLE_interface(): def __init__(self, addr_str, write_uuid): self.dev = Peripheral(deviceAddr=addr_str) logging.info(f'Connected device {self.dev.addr}') if write_uuid: self.write_uuid = [UUID(write_uuid)] else: self.write_uuid = [UUID(x) for x in ble_chars] logging.debug(f'No write uuid specified, trying {ble_chars}') for c in self.dev.getCharacteristics(): if c.uuid in self.write_uuid: self._write_charac = c self.write_uuid = self._write_charac.uuid logging.debug(f'Found write characteristic {self.write_uuid}') break assert hasattr(self, '_write_charac'), \ "No characteristic with specified UUID found!" assert (self._write_charac.properties & Characteristic.props["WRITE_NO_RESP"]), \ "Specified characteristic is not writable!" ### Status does not work with patches for wr response with threads... # status = self.dev.status() # logging.debug(status) # logging.info(f'Device {addr_str} state change to {status["state"][0]}') def send(self, data: bytes): logging.debug(f'Sending {data}') self._write_charac.write(data, withResponse=False) def set_receiver(self, callback): logging.info('Receiver set up') self.dev.setDelegate(ReceiverDelegate(callback)) def receive_loop(self): assert isinstance( self.dev.delegate, ReceiverDelegate), 'Callback must be set before receive loop!' self.dev.waitForNotifications(3.0) def shutdown(self): self.dev.disconnect() logging.info('BT disconnected')
def SignDevice(dev): if dev.valid is True: read = "81353fc9-33e0-4c51-994b-b52235b4d585" write = "2de200df-7fe6-49e3-a768-5ff79e767fa6" print("trying to connect to device: %s" % dev.addr) connection = Peripheral(dev.addr, "random") for c in connection.getCharacteristics(): if c.uuid == read: data = c.read() print("".join(map(chr, data))) elif c.uuid == write: sig = "node-1_%s" % dev.rssi signature = '%s|%s' % (sig, getTime()) res = c.write(str.encode(signature), True) if res['rsp'] is not None: print("SUCCESFUL RESPONSE: ", res) return else: print("Device is not connectable") return
def initRead(addrs, chars): logs = [] devs = [] for (btAddr, btRead) in zip(addrs, chars): # Creacion de archivos log start, logThis = start_log(btAddr[-2:]) logs.append(logThis) # Conexion a los sensores btDev = Peripheral(btAddr) devs.append(btDev) # Seleccion de las caracteristicas de lectura btCh = btDev.getCharacteristics(uuid=btRead)[0] # Asignacion del "delegate" (tambien se activan las notificaciones) btDev.setDelegate(BtDelegate(btDev, btCh.valHandle, logThis, start)) return logs, devs
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) print "Info, reading values!" ch = p.getCharacteristics(uuid=data_uuid)[0] rawVals = ch.read() rawVal = (ord(rawVals[1])<<8)+ord(rawVals[0]) #object temp and ambient temp are calculated as shown below mantissa = rawVal & 0x0FFF; exponent = (rawVal >> 12) & 0xFF; magnitude = pow(2.0, exponent); output = (mantissa * magnitude);
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()
class BtlePeripheral(): def __init__(self, addr, producer, loop, receive_uuid = 0x2221, send_uuid = 0x2222, security = False): self._addr = addr self._producer = producer self._receive_uuid = receive_uuid self._send_uuid = send_uuid self._loop = loop self._security = security self._p = None 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) @asyncio.coroutine def btleNotificationListen(self): try: while True: if self._p.waitForNotifications(0.2): pass time.sleep(0.01) yield None except BTLEException as e: print("Btle exception: " + str(e) + "; try to restart") self._p = None self.start()
class TempSensor(object): _scanning_lock = threading.Lock() 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 connect(self): self.tag.connect() def disconnect(self): self.tag.disconnect() def get_ambient_temp(self): pass def _write_uuid(self, uuid, data): try: if not uuid in self.characteristics: self.characteristics[uuid] = self.peripheral.getCharacteristics(uuid=uuid)[0] #If there's still no characteristic, error if not uuid in self.characteristics: raise Exception('UUID ' + str(uuid) + ' not found on device ' + self.mac) self.characteristics[uuid].write(data) except BTLEException as e: logger.warn(self.mac + ' disconnected. Try to reconnect.') raise DisconnectedException(e.message) def _read_uuid(self, uuid): try: if not uuid in self.characteristics: self.characteristics[uuid] = self.peripheral.getCharacteristics(uuid=uuid)[0] #If there's still no characteristic, error if not uuid in self.characteristics: raise Exception('UUID ' + str(uuid) + ' not found on device ' + self.mac) return self.characteristics[uuid].read() except BTLEException as e: logger.warn(self.mac + ' disconnected. Try to reconnect.') raise DisconnectedException(e.message) @staticmethod def find_temp_sensors(sensors): TempSensor._scanning_lock.acquire() logger.debug('Scanning for devices') scanner = Scanner().withDelegate(ScanDelegate()) try: devices = scanner.scan(10.0) if sensors is None: sensors = {} for device in devices: if device.addr in sensors: continue name = '' if device.getValueText(9): name = device.getValueText(9) elif device.getValueText(8): name = device.getValueText(8) logger.debug('Device name: ' + name) if 'SensorTag' in name: logger.info('Found SensorTag with address: ' + device.addr) sensors[device.addr] = SensorTag(device) elif 'MetaWear' in name: logger.info('Found MetaWear with address: ' + device.addr) sensors[device.addr] = MetaWear(device) logger.debug('Finished scanning for devices') TempSensor._scanning_lock.release() if len(sensors) == 0: raise NoTagsFoundException('No sensors found!') except BTLEException as e: scanner.stop() logger.warn('Got exception ' + e.message) TempSensor._scanning_lock.release() return sensors
def onBtleData(data): print "got data: " + data.getName().toUri() el = BtleNode(onBtleData, None, None) em = ElementReader(el) class MyDelegate(DefaultDelegate): def __init__(self): DefaultDelegate.__init__(self) def handleNotification(self, cHandle, data): em.onReceivedData(data[2:]) p.setDelegate(MyDelegate()) p.writeCharacteristic(p.getCharacteristics(uuid=my_uuid)[0].valHandle + 1, "\x01\x00") while True: if p.waitForNotifications(1.0): continue """ try: #p.writeCharacteristic(0x2221, bytes(0x01), True) #print p.getCharacteristics() ch = p.getCharacteristics(uuid=my_uuid)[0] if (ch.supportsRead()): while True: val = ch.read() print binascii.hexlify(bytearray(val)) if len(val) > 5:
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()
service = p.getServiceByUUID(Service_UUID) for Character in service.getCharacteristics(): print(Character.uuid) for x in range(len(MainCharacteristics_head)): if Character.uuid.getCommonName().startswith(MainCharacteristics_head[Characteristics[x]]): print(Characteristics[x]," Get!") MainCharacteristics[Characteristics[x]] = Character.uuid pass Balance_GATT = p.getCharacteristics(uuid=MainCharacteristics['Balance_UUID'])[0] print(AES_Key) print(len(AES_Key)) AES_Key = bytes(bytearray.fromhex(AES_Key) ) print(AES_Key) print(len(AES_Key)) print("IV:",_IV.hex()) print("Writing Balance msg...") addr = bytearray.fromhex(Address)
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()
class BleCam(object): locked = True 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 _ipcamservice(self): try: print("Verifying IPCam service") self.service = self.periph.getServiceByUUID(0xd001) self.handles = self.service.getCharacteristics() except BTLEEException: print("no IPCam service found for %s" % periph.address) def dumpchars(self): print("%s supports these characteristics:" % self.name) for h in self.handles: print("%s - Handle=%#06x (%s)" % (h.uuid, h.getHandle(), h.propertiesToString())) def unlock(self): if not self.locked: return True auth = self.service.getCharacteristics(0xa001)[0] state = kv2dict(auth.read().decode()) # already unlocked? if state["M"] == 0: self.locked = False return True self.challenge = state["C"] hashit = self.name + self.pincode + self.challenge self.key = base64.b64encode(hashlib.md5(hashit.encode()).digest())[:16] try: auth.write("M=0;K=".encode() + self.key, True) self.locked = False except: print("ERROR: failed to unlock %s - wrong pincode?" % self.name) return not self.locked def get_ipconfig(self): if not self.unlock(): return return kv2dict(self.service.getCharacteristics(0xa104)[0].read().decode()) def get_wificonfig(self): if not self.unlock(): return return kv2dict(self.service.getCharacteristics(0xa101)[0].read().decode()) def wifilink(self): if not self.unlock(): return r = kv2dict(self.service.getCharacteristics(0xa103)[0].read().decode()) return r["S"] == "1" def sysinfo(self): if not self.unlock(): return return kv2dict(self.service.getCharacteristics(0xa200)[0].read().decode()) def setup_wifi(self, essid, passwd): for net in self.wifi_scan(): if net["I"] == essid: cfg = "M=" + net["M"] + ";I=" + essid + ";S=" + net["S"] + ";E=" + net["E"] + ";K=" + passwd print("Will configure: %s" % cfg) self.service.getCharacteristics(0xa101)[0].write(cfg.encode(), True) self.service.getCharacteristics(0xa102)[0].write("C=1".encode(), True) return True print("%s cannot see the '%s' network" % (self.name, essid)) return False def wifi_scan(self): def _wifi2dict(wifistr): return kv2dict(wifistr[2:], ",") if not self.unlock(): return print("%s is scanning for WiFi networks..." % self.name) scan = self.service.getCharacteristics(0xa100)[0] p = -1 n = 0 result = "" while p < n: t = scan.read().decode().split(";", 3) result = result + t[2] if not t[0].startswith("N=") or not t[1].startswith("P="): return n = int(t[0].split("=",2)[1]) p = int(t[1].split("=",2)[1]) # print("read page %d of %d" % (p, n)) return map(_wifi2dict, result.split("&", 50)) def run_command(self, command): if not self.unlock(): return run = "P=" + self.pincode + ";N=" + self.pincode + "&&(" + command + ")&" if len(run) > 128: print("ERROR: command is too long") return print("Attempting to run '%s' on %s by abusing the 'set admin password' request" % (command, self.name)) try: self.service.getCharacteristics(0xa201)[0].write(run.encode(), True) except: # try repeating with an empty password, which seems to be te initial state after factory reset run = "P=;N=" + self.pincode + "&&(" + command + ")&" try: self.service.getCharacteristics(0xa201)[0].write(run.encode(), True) except: print("ERROR: Failed - is the admin password different from the pincode?")
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()
# 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) if ch.supportsRead(): while 1: p.waitForNotifications(604800) # 1 semaine d'attente # handleNotification() was called continue finally: Analyser.ls.close() p.disconnect()
service = p.getServiceByUUID(Service_UUID) for Character in service.getCharacteristics(): print(Character.uuid) for x in range(len(MainCharacteristics_head)): if Character.uuid.getCommonName().startswith(MainCharacteristics_head[Characteristics[x]]): print(Characteristics[x]," Get!") MainCharacteristics[Characteristics[x]] = Character.uuid pass Transaction_GATT = p.getCharacteristics(uuid=MainCharacteristics['Transaction_UUID'])[0] print("Writing Tx msg...") addr = bytearray.fromhex(sys.argv[1]) Value_eth = float(sys.argv[2]) GasPrice_int = int(sys.argv[3]) GasLimit_int = int(sys.argv[4]) Noice_int = int(sys.argv[5]) data_byte = bytearray.fromhex(sys.argv[6]) Value_int = int(Value_eth*1000000000*1000000000)
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)
def main(): # uuid definition targetDevice = "" targetUUID = UUID("08590f7e-db05-467e-8757-72f6f66666d4") # targetUUID = UUID(0x2a2b) serviceUUID = UUID("e20a39f4-73f5-4bc4-a12f-17d1ad666661") # scanning for Bluetooth LE device # P.S. root permission is needed print "scanning started..." scanner = Scanner().withDelegate(ScanDelegate()) devices = scanner.scan(5) print "\n\nscanning completed...\n found %d device(s)\n" % len(devices) for dev in devices: print "Device %s (%s), RSSI=%d dB" % (dev.addr, dev.addrType, dev.rssi) for (adtype, desc, value) in dev.getScanData(): print " %s = %s" % (desc, value) try: p = Peripheral(dev.addr, "random") ch = p.getCharacteristics(uuid=targetUUID) if len(ch) > 0: print "the desired target found. the address is", dev.addr targetDevice = dev.addr except: # print "Unexpected error:", sys.exc_info()[0] print "Unable to connect" print " " finally: p.disconnect() # scanning completed, now continue to connect to device if targetDevice == "": # the target is not found. end. print "no target was found." else: # the target found, continue to subscribe. print "\n\nthe target device is ", targetDevice print "now try to subscribe..." try: # try to get the handle first p = Peripheral(targetDevice, "random") p.setDelegate(NotificationDelegate()) # svc = p.getServiceByUUID(serviceUUID) ch = p.getCharacteristics(uuid=targetUUID)[0] # svc.getCharacteristics(targetUUID)[0] handle = ch.getHandle() print handle ch.write(struct.pack('<bb', 0x01, 0x00)) # ch.write(bytes('aa', 'utf-8')) # p.writeCharacteristic(handle, struct.pack('<bb', 0x01, 0x00), True) print # Main loop while True: if p.waitForNotifications(5): # handleNotification() was called continue print "Waiting..." # Perhaps do something else here # except: # print "Unexpected error:", sys.exc_info()[0] finally: p.disconnect()