async def discover_descriptors( self, characteristic: CBCharacteristic) -> NSArray: future = self._event_loop.create_future() self._characteristic_descriptor_discover_futures[ characteristic.handle()] = future self.peripheral.discoverDescriptorsForCharacteristic_(characteristic) await future return characteristic.descriptors()
def __init__(self, service : CoreBluetoothService, cbcharacteristic : CoreBluetooth.CBCharacteristic, queue, *args, **kwargs): super(CoreBluetoothCharacteristic, self).__init__(service, *args, **kwargs) self._cbcharacteristic = cbcharacteristic self._cbperipheral = cbcharacteristic.service().peripheral() self._queue = queue self._identifier = cbcharacteristic.UUID().UUIDString() self.read_value_future = None
async def discover_descriptors(self, characteristic: CBCharacteristic, use_cached: bool = True) -> NSArray: if characteristic.descriptors() is not None and use_cached: return characteristic.descriptors() future = self._event_loop.create_future() self._characteristic_descriptor_discover_futures[ characteristic.handle()] = future self.peripheral.discoverDescriptorsForCharacteristic_(characteristic) await future return characteristic.descriptors()
async def read_characteristic(self, characteristic: CBCharacteristic, use_cached: bool = True) -> NSData: if characteristic.value() is not None and use_cached: return characteristic.value() future = self._event_loop.create_future() self._characteristic_read_futures[characteristic.handle()] = future self.peripheral.readValueForCharacteristic_(characteristic) await asyncio.wait_for(future, timeout=5) if characteristic.value(): return characteristic.value() else: return b""
async def _did_update_value_for_characteristic( self, cbcharacteristic: CoreBluetooth.CBCharacteristic, error: Foundation.NSError): cbservice = cbcharacteristic.service() service = self._services_by_identifier.get( cbservice.UUID().UUIDString()) if service is None: return char = await service.characteristic_with_identifier( cbcharacteristic.UUID().UUIDString()) if char is None: return char._did_update_value(error)
def did_update_value_for_characteristic( self, peripheral: CBPeripheral, characteristic: CBCharacteristic, value: NSData, error: Optional[NSError], ): c_handle = characteristic.handle() if error is None: notify_callback = self._characteristic_notify_callbacks.get( c_handle) if notify_callback: notify_callback(c_handle, bytearray(value)) future = self._characteristic_read_futures.get(c_handle) if not future: return # only expected on read if error is not None: exception = BleakError( f"Failed to read characteristic {c_handle}: {error}") future.set_exception(exception) else: logger.debug("Read characteristic value") future.set_result(None)
def peripheral_didUpdateValueForCharacteristic_error_( self, peripheral: CBPeripheral, characteristic: CBCharacteristic, error: Optional[NSError], ): logger.debug("peripheral_didUpdateValueForCharacteristic_error_") self._event_loop.call_soon_threadsafe( self.did_update_value_for_characteristic, peripheral, characteristic, characteristic.value(), error, )
async def start_notifications(self, characteristic: CBCharacteristic, callback: Callable[[str, Any], Any]) -> bool: c_handle = characteristic.handle() if c_handle in self._characteristic_notify_callbacks: raise ValueError("Characteristic notifications already started") self._characteristic_notify_callbacks[c_handle] = callback future = self._event_loop.create_future() self._characteristic_notify_change_futures[c_handle] = future self.peripheral.setNotifyValue_forCharacteristic_(True, characteristic) await future return True
async def stop_notifications(self, characteristic: CBCharacteristic) -> bool: c_handle = characteristic.handle() if c_handle not in self._characteristic_notify_callbacks: raise ValueError("Characteristic notification never started") future = self._event_loop.create_future() self._characteristic_notify_change_futures[c_handle] = future self.peripheral.setNotifyValue_forCharacteristic_( False, characteristic) await future self._characteristic_notify_callbacks.pop(c_handle) return True
async def write_characteristic( self, characteristic: CBCharacteristic, value: NSData, response: CBCharacteristicWriteType, ) -> bool: future = self._event_loop.create_future() self._characteristic_write_futures[characteristic.handle()] = future self.peripheral.writeValue_forCharacteristic_type_( value, characteristic, response) if response == CBCharacteristicWriteWithResponse: await future return True
def did_write_value_for_characteristic( self, peripheral: CBPeripheral, characteristic: CBCharacteristic, error: Optional[NSError], ): future = self._characteristic_write_futures.get( characteristic.handle()) if not future: return # event only expected on write with response if error is not None: exception = BleakError( f"Failed to write characteristic {characteristic.handle()}: {error}" ) future.set_exception(exception) else: logger.debug("Write Characteristic Value") future.set_result(None)
def did_update_notification_for_characteristic( self, peripheral: CBPeripheral, characteristic: CBCharacteristic, error: Optional[NSError], ): c_handle = characteristic.handle() future = self._characteristic_notify_change_futures.get(c_handle) if not future: logger.warning( "Unexpected event didUpdateNotificationStateForCharacteristic") return if error is not None: exception = BleakError( f"Failed to update the notification status for characteristic {c_handle}: {error}" ) future.set_exception(exception) else: logger.debug("Character Notify Update") future.set_result(None)
async def write_characteristic( self, characteristic: CBCharacteristic, value: NSData, response: CBCharacteristicWriteType, ) -> bool: # in CoreBluetooth there is no indication of success or failure of # CBCharacteristicWriteWithoutResponse if response == CBCharacteristicWriteWithResponse: future = self._event_loop.create_future() self._characteristic_write_futures[ characteristic.handle()] = future self.peripheral.writeValue_forCharacteristic_type_( value, characteristic, response) if response == CBCharacteristicWriteWithResponse: await future return True
def did_discover_descriptors_for_characteristic( self, peripheral: CBPeripheral, characteristic: CBCharacteristic, error: Optional[NSError], ): future = self._characteristic_descriptor_discover_futures.get( characteristic.handle()) if not future: logger.warning( f"Unexpected event didDiscoverDescriptorsForCharacteristic for {characteristic.handle()}" ) return if error is not None: exception = BleakError( f"Failed to discover descriptors for characteristic {characteristic.handle()}: {error}" ) future.set_exception(exception) else: logger.debug(f"Descriptor discovered {characteristic.handle()}") future.set_result(None)