def discovered_devices(self) -> List[BLEDevice]: found = [] peripherals = self._manager.central_manager.retrievePeripheralsWithIdentifiers_( NSArray(self._identifiers.keys()), ) for peripheral in peripherals: address = peripheral.identifier().UUIDString() name = peripheral.name() or "Unknown" details = peripheral rssi = self._manager.devices[address].rssi advertisementData = self._identifiers[peripheral.identifier()] manufacturer_binary_data = advertisementData.get( "kCBAdvDataManufacturerData" ) manufacturer_data = {} if manufacturer_binary_data: manufacturer_id = int.from_bytes( manufacturer_binary_data[0:2], byteorder="little" ) manufacturer_value = bytes(manufacturer_binary_data[2:]) manufacturer_data = {manufacturer_id: manufacturer_value} uuids = [ cb_uuid_to_str(u) for u in advertisementData.get("kCBAdvDataServiceUUIDs", []) ] service_data = {} adv_service_data = advertisementData.get("kCBAdvDataServiceData", []) for u in adv_service_data: service_data[cb_uuid_to_str(u)] = bytes(adv_service_data[u]) found.append( BLEDevice( address, name, details, rssi=rssi, uuids=uuids, manufacturer_data=manufacturer_data, service_data=service_data, delegate=self._manager.central_manager.delegate(), ) ) return found
def callback(p: CBPeripheral, a: Dict[str, Any], r: int) -> None: # update identifiers for scanned device self._identifiers.setdefault(p.identifier(), {}).update(a) if not self._callback: return # Process service data service_data_dict_raw = a.get("kCBAdvDataServiceData", {}) service_data = { cb_uuid_to_str(k): bytes(v) for k, v in service_data_dict_raw.items() } # Process manufacturer data into a more friendly format manufacturer_binary_data = a.get("kCBAdvDataManufacturerData") manufacturer_data = {} if manufacturer_binary_data: manufacturer_id = int.from_bytes( manufacturer_binary_data[0:2], byteorder="little" ) manufacturer_value = bytes(manufacturer_binary_data[2:]) manufacturer_data[manufacturer_id] = manufacturer_value service_uuids = [ cb_uuid_to_str(u) for u in a.get("kCBAdvDataServiceUUIDs", []) ] advertisement_data = AdvertisementData( local_name=p.name(), manufacturer_data=manufacturer_data, service_data=service_data, service_uuids=service_uuids, platform_data=(p, a, r), ) device = BLEDevice( p.identifier().UUIDString(), p.name(), p, r, uuids=service_uuids, manufacturer_data=manufacturer_data, service_data=service_data, delegate=self._manager.central_manager.delegate(), ) self._callback(device, advertisement_data)
def __init__(self, obj: CBCharacteristic): super().__init__(obj) self.__descriptors: List[BleakGATTDescriptorCoreBluetooth] = [] # self.__props = obj.properties() self.__props: List[str] = [ _GattCharacteristicsPropertiesEnum[v][0] for v in [2**n for n in range(10)] if (self.obj.properties() & v) ] self._uuid: str = cb_uuid_to_str(self.obj.UUID())
def __init__(self, obj: CBCharacteristic): super().__init__(obj) self.__descriptors = [] # self.__props = obj.properties() self.__props = [ _GattCharacteristicsPropertiesEnum[v][0] for v in [2**n for n in range(10)] if (self.obj.properties() & v) ] self._uuid = cb_uuid_to_str(self.obj.UUID())
def _update_uuids(self, advertisementData: NSDictionary): cbuuids = advertisementData.get("kCBAdvDataServiceUUIDs", []) if not cbuuids: return chuuids = [cb_uuid_to_str(u) for u in cbuuids] if "uuids" in self.metadata: for uuid in chuuids: if not uuid in self.metadata["uuids"]: self.metadata["uuids"].append(uuid) else: self.metadata["uuids"] = chuuids
async def get_services(self) -> BleakGATTServiceCollection: """Get all services registered for this GATT server. Returns: A :py:class:`bleak.backends.service.BleakGATTServiceCollection` with this device's services tree. """ if self._services is not None: return self.services logger.debug("Retrieving services...") manager = self._central_manager_delegate services = await manager.connected_peripheral_delegate.discoverServices() for service in services: serviceUUID = service.UUID().UUIDString() logger.debug( "Retrieving characteristics for service {}".format(serviceUUID) ) characteristics = ( await manager.connected_peripheral_delegate.discoverCharacteristics_( service ) ) self.services.add_service(BleakGATTServiceCoreBluetooth(service)) for characteristic in characteristics: cUUID = characteristic.UUID().UUIDString() logger.debug( "Retrieving descriptors for characteristic {}".format(cUUID) ) descriptors = ( await manager.connected_peripheral_delegate.discoverDescriptors_( characteristic ) ) self.services.add_characteristic( BleakGATTCharacteristicCoreBluetooth(characteristic) ) for descriptor in descriptors: self.services.add_descriptor( BleakGATTDescriptorCoreBluetooth( descriptor, cb_uuid_to_str(characteristic.UUID()), int(characteristic.handle()), ) ) logger.debug("Services resolved for %s", str(self)) self._services_resolved = True self._services = services return self.services
def uuid(self) -> str: """UUID for this service.""" return cb_uuid_to_str(self.obj.UUID())
def service_uuid(self) -> str: """The uuid of the Service containing this characteristic""" return cb_uuid_to_str(self.obj.service().UUID())
def uuid(self) -> str: """UUID for this descriptor""" return cb_uuid_to_str(self.obj.UUID())
'Mesh Proxy Data In', 'Mesh Proxy Data Out', 'Perceived Lightness', 'Percentage 8', 'Power', 'Power Specification', 'Relative Runtime In A Current Range', 'Relative Runtime In A Generic Level Range', 'Relative Value In A Period of Day', 'Relative Value In A Temperature Range', 'Relative Value In A Voltage Range', 'Relative Value In An Illuminance Range', 'Temperature 8', 'Temperature 8 In A Period Of Day', 'Temperature 8 Statistics', 'Temperature Range', 'Temperature Statistics', 'Time Decihour 8', 'Time Exponential 8', 'Time Hour 24', 'Time Millisecond 24', 'Time Second 16', 'Time Second 8', 'Voltage', 'Voltage Specification', 'Voltage Statistics', 'Volume Flow' ] CK_codes = [cb_uuid_to_str(ck.replace('0x', '')) for ck in CK] ble_char_dict = dict(zip(CK_codes, TK)) ble_char_dict_rev = dict(zip(TK, CK_codes)) # XML PARSER --> get char tag and return char_xml class class CHAR_XML: def __init__(self, xml_file): self._tree = ET.parse("{}/{}".format(CHARS_XML_DIR, xml_file)) with open("{}/{}".format(CHARS_XML_DIR, xml_file), 'rb') as xmlfileraw: self._raw = xmlfileraw.read().decode() self._root = self._tree.getroot() self.char_metadata = None self.name = None self.char_type = None self.uuid = None