Closed MaikuMori closed 3 years ago
Apologies for the slow response on this; it appears the email of this issue being opened got caught by the spam filter.
Anyway, the reason that the object is not returned is because it shouldn't be needed for the peripheral. The event-loop is running for the peripheral and so there is the read, write, notify callbacks.
The example I assume you are referencing is: https://github.com/ukBaz/python-bluezero/blob/master/examples/ble_uart.py This is a little unusual example because when a value is written on one characteristic it is forcing a notify on a different one.
Maybe if you stepped backed and explained what you are trying to do I could better understand what is missing from Bluezero.
Is your use case when the Central device writes to the peripheral device? What is not happening that should? That write will update the characteristic automatically. The write_callback is to allow some other action to happen based on the written value. For example, turn on an LED for example.
If you can give me some context I can help and maybe get a better example for the library.
I have a peripheral which doesn't use notify
on any of the characteristics. I have several read
and write
characteristics.
I need to write to a characteristic as a response to data received from another characteristic.
So far I'm doing something like this:
def __init__(self, adapter_address):
# ...
self.p = peripheral.Peripheral(adapter_address, local_name="...")
# ...
self.p.add_characteristic(
srv_id=1,
chr_id=2,
uuid=COMMAND_CHARACTERISTIC,
value=[],
notifying=False,
flags=["write"],
write_callback=self.on_write,
)
self.p.add_characteristic(
srv_id=1,
chr_id=3,
uuid=GET_CHARACTERISTIC,
value=[],
notifying=False,
flags=["read"],
)
# Workaround because it's not returned.
self.get_ch = self.p.characteristics[-1]
# ...
# ...
def on_write(self, value, options) -> None:
# ...
self.get_ch.set_value(value)
OK, I think I understand why you are having difficulty. Maybe my example was not helpful because the reads and writes should be accessing another object.
Is the following a more helpful example:
from gi.repository import GLib
# Bluezero modules
from bluezero import adapter
from bluezero import peripheral
# constants
THING_SRV = 'BBBB0001-B5A3-F393-E0A9-E50E24DCCA9E'
THING_W = 'BBBB0002-B5A3-F393-E0A9-E50E24DCCA9E'
THING_R = 'BBBB0003-B5A3-F393-E0A9-E50E24DCCA9E'
class MyThing:
value = [0]
@classmethod
def peri_read(cls):
print('Read:', cls.value)
return cls.value
@classmethod
def peri_write(cls, value, options):
print('Write:', value)
cls.value = value
print(cls.value)
def main(adapter_address):
ble_thing = peripheral.Peripheral(adapter_address, local_name='BLE Thing')
ble_thing.add_service(srv_id=1, uuid=THING_SRV, primary=True)
ble_thing.add_characteristic(srv_id=1, chr_id=1, uuid=THING_W,
value=[], notifying=False,
flags=['write', 'write-without-response'],
write_callback=MyThing.peri_write,
read_callback=None,
notify_callback=None)
ble_thing.add_characteristic(srv_id=1, chr_id=2, uuid=THING_R,
value=[], notifying=False,
flags=['read'],
notify_callback=None,
read_callback=MyThing.peri_read,
write_callback=None)
ble_thing.publish()
if __name__ == '__main__':
main(list(adapter.Adapter.available())[0].address)
I see, so that's the intended usage.
I can re-write to something similar. I'd probably still embed the Peripheral in my class and then not use static methods. The key takeaway is to use the read_callback
.
Peripheral.add_characteristic(...)
doesn't return the created characteristic which makes it hard to later set the value. In the examples the characteristic is obtained innotify_callback
, but ifnotify
is not used there is no easy way to obtain it.Meanwhile,
Central.add_characteristic(...)
does return the remote Characteristic object.