def did_update_value_for_characteristic( self, peripheral: CBPeripheral, characteristic: CBCharacteristic, value: bytes, error: NSError, ): cUUID = characteristic.UUID().UUIDString() c_handle = characteristic.handle() if error is not None: raise BleakError( "Failed to read characteristic {}: {}".format(cUUID, error) ) notify_callback = self._characteristic_notify_callbacks.get(c_handle) if notify_callback: notify_callback(c_handle, value) logger.debug("Read characteristic value") event = self._characteristic_read_events.get(cUUID) if event: event.set() else: # only expected on read pass
def peripheral_didWriteValueForCharacteristic_error_( self, peripheral: CBPeripheral, characteristic: CBCharacteristic, error: NSError): cUUID = characteristic.UUID().UUIDString() if error is not None: raise BleakError("Failed to write characteristic {}: {}".format( cUUID, error)) logger.debug("Write Characteristic Value") self._characteristic_write_log[cUUID] = True
def peripheralManager_central_didUnsubscribeFromCharacteristic_( # noqa: N802 E501 self, peripheral_manager: CBPeripheralManager, central: CBCentral, characteristic: CBCharacteristic): central_uuid: str = central.identifier().UUIDString() char_uuid: str = characteristic.UUID().UUIDString() logger.debug( "Central device {} is unsubscribing from characteristic {}".format( central_uuid, char_uuid)) self._central_subscriptions[central_uuid].remove(char_uuid) if len(self._central_subscriptions[central_uuid]) < 1: del self._central_subscriptions[central_uuid]
def peripheral_didUpdateNotificationStateForCharacteristic_error_( self, peripheral: CBPeripheral, characteristic: CBCharacteristic, error: NSError): cUUID = characteristic.UUID().UUIDString() if error is not None: raise BleakError( "Failed to update the notification status for characteristic {}: {}" .format(cUUID, error)) logger.debug("Character Notify Update") self._characteristic_notify_log[cUUID] = True
def peripheral_didDiscoverDescriptorsForCharacteristic_error_( self, peripheral: CBPeripheral, characteristic: CBCharacteristic, error: NSError): cUUID = characteristic.UUID().UUIDString() if error is not None: raise BleakError( "Failed to discover descriptors for characteristic {}: {}". format(cUUID, error)) logger.debug("Descriptor discovered {}".format(cUUID)) self._characteristic_descriptor_log[cUUID] = True
async def discoverDescriptors_( self, characteristic: CBCharacteristic, use_cached=True ) -> [CBDescriptor]: if characteristic.descriptors() is not None and use_cached is True: return characteristic.descriptors() cUUID = characteristic.UUID().UUIDString() event = self._characteristic_descriptor_discover_events.get_cleared(cUUID) self.peripheral.discoverDescriptorsForCharacteristic_(characteristic) await event.wait() return characteristic.descriptors()
async def stopNotify_(self, characteristic: CBCharacteristic) -> bool: cUUID = characteristic.UUID().UUIDString() self._characteristic_notify_log[cUUID] = False self.peripheral.setNotifyValue_forCharacteristic_( False, characteristic) while not self._characteristic_notify_log[cUUID]: await asyncio.sleep(0.01) self._characteristic_notify_status = False return True
async def readCharacteristic_(self, characteristic: CBCharacteristic, use_cached=True) -> NSData: if characteristic.value() is not None and use_cached is True: return characteristic.value() cUUID = characteristic.UUID().UUIDString() event = self._characteristic_read_events.get_cleared(cUUID) self.peripheral.readValueForCharacteristic_(characteristic) await event.wait() return characteristic.value()
async def stopNotify_(self, characteristic: CBCharacteristic) -> bool: cUUID = characteristic.UUID().UUIDString() if cUUID not in self._characteristic_notify_callbacks: raise ValueError("Characteristic notification never started") event = self._characteristic_notify_change_events.get_cleared(cUUID) self.peripheral.setNotifyValue_forCharacteristic_(False, characteristic) # wait for peripheral_didUpdateNotificationStateForCharacteristic_error_ to set event await event.wait() self._characteristic_notify_callbacks.pop(cUUID) return True
async def startNotify_cb_(self, characteristic: CBCharacteristic, callback: Callable[[str, Any], Any]) -> bool: cUUID = characteristic.UUID().UUIDString() self._characteristic_notify_log[cUUID] = False self._characteristic_notify_callbacks[cUUID] = callback self.peripheral.setNotifyValue_forCharacteristic_(True, characteristic) while not self._characteristic_notify_log[cUUID]: await asyncio.sleep(0.01) self._characteristic_notify_status[cUUID] = True return True
async def startNotify_cb_(self, characteristic: CBCharacteristic, callback: Callable[[str, Any], Any]) -> bool: cUUID = characteristic.UUID().UUIDString() if cUUID in self._characteristic_notify_callbacks: raise ValueError("Characteristic notifications already started") self._characteristic_notify_callbacks[cUUID] = callback event = self._characteristic_notify_change_events.get_cleared(cUUID) self.peripheral.setNotifyValue_forCharacteristic_(True, characteristic) # wait for peripheral_didUpdateNotificationStateForCharacteristic_error_ to set event await event.wait() return True
async def writeCharacteristic_value_(self, characteristic: CBCharacteristic, value: NSData) -> bool: cUUID = characteristic.UUID().UUIDString() self._characteristic_write_log[cUUID] = False self.peripheral.writeValue_forCharacteristic_type_( value, characteristic, 0) while not self._characteristic_write_log[cUUID]: await asyncio.sleep(0.01) return True
def peripheral_didUpdateValueForCharacteristic_error_( self, peripheral: CBPeripheral, characteristic: CBCharacteristic, error: NSError): cUUID = characteristic.UUID().UUIDString() if error is not None: raise BleakError("Failed to read characteristic {}: {}".format( cUUID, error)) if (cUUID in self._characteristic_notify_status and self._characteristic_notify_status[cUUID]): self._characteristic_notify_callbacks[cUUID]( cUUID, characteristic.value()) logger.debug("Read characteristic value") self._characteristic_value_log[cUUID] = True
async def readCharacteristic_(self, characteristic: CBCharacteristic, use_cached=True) -> NSData: if characteristic.value() is not None and use_cached is True: return characteristic.value() cUUID = characteristic.UUID().UUIDString() self._characteristic_value_log[cUUID] = False self.peripheral.readValueForCharacteristic_(characteristic) while not self._characteristic_value_log[cUUID]: await asyncio.sleep(0.01) return characteristic.value()
def did_write_value_for_characteristic(self, peripheral: CBPeripheral, characteristic: CBCharacteristic, error: NSError): cUUID = characteristic.UUID().UUIDString() if error is not None: raise BleakError("Failed to write characteristic {}: {}".format( cUUID, error)) logger.debug("Write Characteristic Value") event = self._characteristic_write_events.get(cUUID) if event: event.set() else: # event only expected on write with response pass
async def discoverDescriptors_(self, characteristic: CBCharacteristic, use_cached=True) -> [CBDescriptor]: if characteristic.descriptors() is not None and use_cached is True: return characteristic.descriptors() cUUID = characteristic.UUID().UUIDString() self._characteristic_descriptor_log[cUUID] = False self.peripheral.discoverDescriptorsForCharacteristic_(characteristic) while not self._characteristic_descriptor_log[cUUID]: await asyncio.sleep(0.01) return characteristic.descriptors()
async def writeCharacteristic_value_type_(self, characteristic: CBCharacteristic, value: NSData, response: int) -> bool: # TODO: Is the type hint for response correct? Should it be a NSInteger instead? cUUID = characteristic.UUID().UUIDString() event = self._characteristic_write_events.get_cleared(cUUID) self.peripheral.writeValue_forCharacteristic_type_( value, characteristic, response) if response == CBCharacteristicWriteWithResponse: await event.wait() return True
def did_discover_descriptors_for_characteristic( self, peripheral: CBPeripheral, characteristic: CBCharacteristic, error: NSError): cUUID = characteristic.UUID().UUIDString() if error is not None: raise BleakError( "Failed to discover descriptors for characteristic {}: {}". format(cUUID, error)) logger.debug("Descriptor discovered {}".format(cUUID)) event = self._characteristic_descriptor_discover_events.get(cUUID) if event: event.set() else: logger.warning( "Unexpected event didDiscoverDescriptorsForCharacteristic")
def did_update_notification_for_characteristic( self, peripheral: CBPeripheral, characteristic: CBCharacteristic, error: NSError): cUUID = characteristic.UUID().UUIDString() if error is not None: raise BleakError( "Failed to update the notification status for characteristic {}: {}" .format(cUUID, error)) logger.debug("Character Notify Update") event = self._characteristic_notify_change_events.get(cUUID) if event: event.set() else: logger.warning( "Unexpected event didUpdateNotificationStateForCharacteristic")
def peripheralManager_central_didSubscribeToCharacteristic_( # noqa: N802 self, peripheral_manager: CBPeripheralManager, central: CBCentral, characteristic: CBCharacteristic): central_uuid: str = central.identifier().UUIDString() char_uuid: str = characteristic.UUID().UUIDString() logger.debug( "Central Device: {} is subscribing to characteristic {}".format( central_uuid, char_uuid)) if central_uuid in self._central_subscriptions: subscriptions = self._central_subscriptions[central_uuid] if char_uuid not in subscriptions: self._central_subscriptions[central_uuid].append(char_uuid) else: logger.debug(("Central Device {} is already " + "subscribed to characteristic {}").format( central_uuid, char_uuid)) else: self._central_subscriptions[central_uuid] = [char_uuid]
def peripheral_didUpdateValueForCharacteristic_error_( self, peripheral: CBPeripheral, characteristic: CBCharacteristic, error: NSError): cUUID = characteristic.UUID().UUIDString() if error is not None: raise BleakError("Failed to read characteristic {}: {}".format( cUUID, error)) notify_callback = self._characteristic_notify_callbacks.get(cUUID) if notify_callback: notify_callback(cUUID, characteristic.value()) logger.debug("Read characteristic value") event = self._characteristic_read_events.get(cUUID) if event: event.set() else: # only expected on read pass