question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Format Characteristics Value following Bluetooth SIG specification

See original GitHub issue

Hi, this is an enhancement proposal.

The feature I’m proposing is to automatically format a characteristic value following Bluetooth SIG specification. This would work the same way as nRF Connect android app, e.g. in service_explorer.py example instead of:

if "read" in char.properties:
                    try:
                        value = bytes(await client.read_gatt_char(char.uuid))
                    except Exception as e:
                        value = str(e).encode()

where value is a bytearray, implementing a function like get_char_value:

if "read" in char.properties:
                    try:
                        value = bytes(await client.read_gatt_char(char.uuid))
                        formatted_value = get_char_value(value)
                    except Exception as e:
                        value = str(e).encode()

This function will format the bytearray according to the characteristic. For example reading the Temperature characteristic, the value in this case could be b'\xc4\t', then formatted_value wil be: {'Temperature':{'Value':25.00, 'Symbol': 'ºC'}}

I’ve already got this working, although I haven’t test all the characteristic (there are around 283…) I think this looks promising, so If there is any interest in this feature I could make a PR this or the next week. 👍

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Comments:19 (18 by maintainers)

github_iconTop GitHub Comments

2reactions
Carglglzcommented, Aug 13, 2020

Well It took me longer than expected, but I think this is almost done, now I have to write the documentation #266. To sum up what will include this PR:

  • Format characteristics Value following Bluetooth SIG specification: (all OS) Carglglz/bleak#1 - get_xml_char, to parse a xml characteristic file. - get_char_value, + other functions to help with printing/unpacking the result (from bytes to readable output) - This is in bleak.utils module

  • Add descriptions to characteristics and descriptors (Linux, MacOS) Carglglz/bleak#4, Carglglz/bleak#5

  • Add missing uuids to uuid16_dict and uuid128_dict Carglglz/bleak#4, Carglglz/bleak#7

  • Fix for hbldh#102, with a timeout to event.wait() that prevents from blocking indefinitely. (MacOS) Carglglz/bleak#4

  • Fix for notify by handle, notify callback now accepts three inputs (handle, value, cUUID) (MacOS) Carglglz/bleak#8 #231

  • Add method to get/update the RSSI value of the connected Peripheral (MacOS) Carglglz/bleak#13

  • New module bleak.formatter with SuperStruct class which adds compatibility with Bluetooth SIG encoding formats that are not supported in Python (all OS) Carglglz/bleak#15: - FLOAT IEEE11073 - SFLOAT IEEE11073 - nibble - uint12 - uint40 - uint48 - uint24 - sint24 - uint128

This should add compatibility with any characteristic with a proper xml file and a compatible encoding format. There may be some exceptions like heart_rate_measurement mentioned above, but in any case it should be fixable. 👍

2reactions
Carglglzcommented, Aug 18, 2020

Hi @polskafan I’m still working on this. I think I fixed a) yesterday and improved characteristics references see Carglglz#9. It’s nice to see that this kind of works with other devices (I just have my phone and esp32 to check).

About b) The good news is that I think is doable. The bad news is I that I will need to introduce some changes to check for this specific characteristic and use its own method. I can’t do this right now but I will point you in the right direction:

Since this characteristic has a Flags field, it is unpacked to see which other fields are present: e.g. (hrm_value, is the result with just one RR interval field, to get the RR flag)

# Heart Rate Measurement
hrm = struct.pack('BBHHH', eval('0b00011000'), 60, 50, 1, 1)

# This should be implemented in _get_multiple_fields function 

_FIELDS_TO_READ = []
more_than_one = hrm_value[1]['RR-Interval bit'] # RR-Interval bit flag
if more_than_one == 'One or more RR-Interval values are present.':
    ctype_global = 'BBHH' # this is the global type that detects
    print("Global Unpack Format: {}".format(ctype_global))
    print("Global unpack format length: {}, Bytes: {}".format(struct.calcsize(ctype_global), len(hrm)))
    while len(hrm) > struct.calcsize(ctype_global):  # this is the correction
        ctype_global += 'H'
        _FIELDS_TO_READ.append('RR-Interval')
    print("Global unpack format length: {}, Bytes: {}".format(struct.calcsize(ctype_global), len(hrm)))
    print("Global Unpack Format: {}".format(ctype_global))

raw_values = struct.unpack(ctype_global, hrm)
print(raw_values)
Global Unpack Format: BBHH
Global unpack format length: 6, Bytes: 8
Global unpack format length: 8, Bytes: 8
Global Unpack Format: BBHHH
(24, 60, 50, 1, 1)

So that’s it, just check len(hrm) > struct.calcsize(ctype_global) and add ‘H’ while true. I will try to implement this next week I guess. 👍

Read more comments on GitHub >

github_iconTop Results From Across the Web

Coordinated Set Identification Service - Bluetooth SIG
A higher-layer specification defines when the Set Member Lock characteristic may be used and which resources are subject to exclusive access. The value...
Read more >
Chapter 4. GATT (Services and Characteristics) - O'Reilly
The Generic Attribute Profile (GATT) establishes in detail how to exchange all profile and user data over a BLE connection. In contrast with...
Read more >
Bluetooth GATT: How to Design Custom Services ... - Novel Bits
Utilize the Bluetooth SIG-adopted profiles, services, and characteristics in your design whenever possible. This has the following benefits:
Read more >
RN4870/71 Bluetooth Low Energy Module User's Guide
The format of the Set and Get commands are provided in Table 2-1. The Set command starts with character “S” and followed by...
Read more >
Generic Attribute Profile (GATT) — BLE-Stack User's Guide for ...
While characteristics and attributes are sometimes used interchangeably when referring to Bluetooth low energy, consider characteristics as groups of ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found