Closed andyboeh closed 5 years ago
@andyboeh did you try writing to the descriptor handle? You can get the handle from UUID and can use pygatt's char_write_handle to start getting notifications from the sensor.
Unfortunately, I get the same error message when doing device.get_handle(UUID):
pygatt.exceptions.BLEError: No characteristic found matching 00002902-0000-1000-8000-00805f9b34fb
It checks internally if the UUID is available as a characteristic (which it isn't!) and thus fails.
I was investigating similar thing - write to CCCD to enable notifications. But when I enabled DEBUG log level I found that library automatically enables notifications for all properties that support it. So, I'm good with it now. But, hopefully, my little investigation will give you some clues of how to access CCCDs manually (I did not tested it on a pygatt myself).
So, first of all I used gatttool to investigate how to enable notifications there. (Also inserted my comments between calls, I have doubts about 100% correctness, so if you spot any misleading info, please let me know):
$ gatttool -I
# connect
0x180f is a Battery Service
# characteristics 0x002e 0x0032 handle: 0x002f, char properties: 0x12, char value handle: 0x0030, uuid: 00002a19-0000-1000-8000-00805f9b34fb
0x2a19 is a Battery Level Characteristic
# char-desc 0x0031 0x0032 handle: 0x0031, uuid: 00002902-0000-1000-8000-00805f9b34fb handle: 0x0032, uuid: 00002908-0000-1000-8000-00805f9b34fb
0x2902 is a Client Characteristic Configuration Descriptor for service 0x180f
# char-write-req 0x0031 0100 Characteristic value was written successfully
0x0100 enables notification, it will be written to handle 0x0031 of CCCD 0x2902 of service 0x180f
.............. Notification handle = 0x0030 value: 5e
and after battery level changed you receive notification for "char value handle" 0x0030
So, basically, to do the same with pygatt you could try to get handle number with gatttool first as pygatt does not support char-desc command now, then use char_write_handle as suggested by @BhargavaRamM . Something like (not tested):
adapter.char_write_handle(0x0031, bytearray([01 00]))
@e27182 The issue here is that pygatt is not discovering CCCD as a characteristic. If you want to get the handle for CCCD, you have to check the handle value through gatttool using the above commands you used. I tried to find the handle value for CCCD of my BLE device using pygatt and it always returned characteristic not found error. Hence, pygatt was unable to write to the handle. I am not sure why this is happening with pygatt. Maybe @peplin can give us an answer.
@BhargavaRamM , yep and the reason is here:
self.sendline('characteristics')
this command returns only characteristics for specified service. To retrieve descriptor for specified characteristic 'char-desc' command should be used with handler or range of handlers for the characteristic you are interested in. Sadly, it is not supported by pygatt now. And this branch "gattool-fix" actually adding support of it, but now it seems too old..
A pull request off of the latest master
branch to add this feature would be welcome! That gattoool-fix
branch was a giant refactoring that ultimately didn't do what we needed, so it's considered abandoned.
Yeah, there are actually two possibilities on how to implement this and I'm not yet sure which way to go:
char-desc
in addition to characteristics
and let the user write to the now-known handle. However, the user wouldn't have the chance to retrieve the handle directly and would have to call gatttool to find the handle.char-desc
command to pygattI suppose option 2 is the cleaner approach..
Did this not go anywhere? I'm experiencing the exact same problem and I guess will have to use another library or gatttool directly?
In pygatt/backends/bgapi/bgapi.py: I modified def _get_uuid_type(uuid), instead of returning None, have it return UUIDType.characteristic In pygatt/backends/bgapi/device.py: I commented out line 106 in def char_write_handle
Many improvements to characteristics writes (including long write support) landed in v4.0, now on PyPi. Please give that a try and open a new issue if you are still having problems. Thanks!
I just came over pygatt while trying to connect to a cheap Pulse Oximeter (BerryMed). This one requires to write to the Client Character Config Descriptor to enable the streaming of data packets.
Since the CCCD is not included during characteristics discovery, pygatt doesn't let me write to it using its UUID. Any suggestions how I can write to this descriptor using pygatt?
EDIT: It looks like some work on this has been done on the branch "gattool-fix"!?