def set_value(self, value, notify_client=False): """ Sets the value of the characteristic. :param value: The value to set to. Must be an iterable type such as a str, bytearray, or list of uint8 values. Length must be less than the characteristic's max length :param notify_client: Flag whether or not to notify the client. If indications and notifications are not set up for the characteristic, will raise an InvalidOperationException :raises: InvalidOperationException if value length is too long, or notify client set and characteristic is not notifiable """ if isinstance(value, BleDataStream): value = value.value if len(value) > self.max_length: raise InvalidOperationException("Attempted to set value of {} with length greater than max " "(got {}, max {})".format(self.uuid, len(value), self.max_length)) if notify_client and not self.notifiable: raise InvalidOperationException("Cannot notify client. " "{} not set up for notifications or indications".format(self.uuid)) v = nrf_types.BLEGattsValue(value) self.ble_device.ble_driver.ble_gatts_value_set(self.peer.conn_handle, self.value_handle, v) self._value = value if notify_client and self.client_subscribed and not self._read_in_process: self.notify(None)
def get_value(self) -> bytes: """ Fetches the attribute's value from hardware and updates the local copy. This isn't often necessary and should instead use the value property to avoid unnecessary reads from the hardware. """ v = nrf_types.BLEGattsValue(b"") self._ble_device.ble_driver.ble_gatts_value_get( self._peer.conn_handle, self._handle, v) self._value = bytes(bytearray(v.value)) return self._value
def _execute_queued_write(self, write_op): if not self._write_queued: return self._write_queued = False if write_op == nrf_events.BLEGattsWriteOperation.exec_write_req_cancel: logger.info("Cancelling write request, char: {}".format(self.uuid)) else: logger.info("Executing write request, char: {}".format(self.uuid)) # TODO Assume that it was assembled properly. Error handling should go here new_value = bytearray() for chunk in self._queued_write_chunks: new_value += bytearray(chunk.data) logger.debug("New value: 0x{}".format(str(new_value).encode("hex"))) self.ble_device.ble_driver.ble_gatts_value_set(self.peer.conn_handle, self.value_handle, nrf_types.BLEGattsValue(new_value)) self._value = new_value self._on_write.notify(self, WriteEventArgs(self.value)) self._queued_write_chunks = []
def set_value( self, value, notify_client=False ) -> Optional[EventWaitable[GattsCharacteristic, NotificationCompleteEventArgs]]: """ Sets the value of the characteristic. :param value: The value to set to. Must be an iterable type such as a str, bytearray, or list of uint8 values. Length must be less than the characteristic's max length. If a str is given, it will be encoded using the string_encoding property. :param notify_client: Flag whether or not to notify the client. If indications and notifications are not set up for the characteristic, will raise an InvalidOperationException :raises: InvalidOperationException if value length is too long, or notify client set and characteristic is not notifiable :return: If notify_client is true, this method will return the waitable for when the notification is sent to the client """ if isinstance(value, BleDataStream): value = value.value if isinstance(value, str): value = value.encode(self.string_encoding) if len(value) > self.max_length: raise InvalidOperationException( "Attempted to set value of {} with length greater than max " "(got {}, max {})".format(self.uuid, len(value), self.max_length)) if notify_client and not self.notifiable: raise InvalidOperationException( "Cannot notify client. " "{} not set up for notifications or indications".format( self.uuid)) v = nrf_types.BLEGattsValue(value) self.ble_device.ble_driver.ble_gatts_value_set(self.peer.conn_handle, self.value_handle, v) self._value = value if notify_client and self.client_subscribed and not self._read_in_process: return self.notify(None)
def set_value(self, value): """ Sets the value of the attribute. :param value: The value to set to. Must be an iterable type such as a str, bytes, or list of uint8 values, or a BleDataStream object. Length must be less than the attribute's max length. If a str is given, it will be encoded using the string_encoding property. :raises: InvalidOperationException if value length is too long """ if isinstance(value, BleDataStream): value = value.value if isinstance(value, str): value = value.encode(self.string_encoding) if len(value) > self.max_length: raise InvalidOperationException( "Attempted to set value of {} with length greater than max " "(got {}, max {})".format(self.uuid, len(value), self.max_length)) v = nrf_types.BLEGattsValue(value) self._ble_device.ble_driver.ble_gatts_value_set( self._peer.conn_handle, self._handle, v) self._value = value