With BLE data in a characteristic, there are typically multiple fields within the one characteristic. For example, the official Heart Rate measurement characteristic can be 8 octets long and have fields for the flags, HRM Value, Energy Expended and RR-interval all in the one characteristic.
If it is using the Bluetooth standard for Heart Rate measurement then the characteristic UUID will be 00002A37-0000-1000-8000-00805F9B34FB. Official UUID's are often written as shortened to 16-bit values, so for this it would be 0x2A37.
You can read about the values in 16-bit UUID Numbers Document . Another useful document is the GATT Specification Supplement that specifies how values are represented in official Characteristics.
These documents are of little/no help if the manufacturer has used a custom characteristic. A custom characteristic is represented by a UUID value not in the range of 0000xxxx-0000-1000-8000-00805F9B34FB
To explore the data, using a generic Bluetooth Low Energy scanning and exploration tool such as nRF Connect is often helpful
The binary values are often easier to understand in Python if split into a list where each item represents an octet. For example:
>>> data = b'\r\xb1\x1aQ\xb4x\xa3C\x83\xdcv\xd3Q\x12\xbdJ\x7f\x82\xbf\x06\x91s\x07\xb7'
>>> list(data)
[13, 177, 26, 81, 180, 120, 163, 67, 131, 220, 118, 211, 81, 18, 189, 74, 127, 130, 191, 6, 145, 115, 7, 183]
>>> [f'{i:02x}' for i in data]
['0d', 'b1', '1a', '51', 'b4', '78', 'a3', '43', '83', 'dc', '76', 'd3', '51', '12', 'bd', '4a', '7f', '82', 'bf', '06', '91', '73', '07', 'b7']
The other thing to be aware of is that when converting between octets and integers the int
type has the methods from_bytes
and to_bytes
. For example, if we know a value is of type sint16
, it is signed and take 2 octets. The other thing to note is that BLE data is typically in little endian format.
>>> int.from_bytes([0x82, 0xbf], byteorder='little', signed=True)
-16510
>>> int(-16510).to_bytes(2, byteorder='little', signed=True)
b'\x82\xbf'
>>> int.from_bytes(b'\x82\xbf', byteorder='little', signed=True)
-16510