Introduction to Bluetooth
Connecting to, and Reading Data from Bluetooth Devices using Python and Bleak
Updated: 03 September 2023
Overview
Bluetooth Low Energy (BLE) devices make use of a few different concepts for reading and writing data. At a high level, bluetooth data is organized as follows:
Each characteristic contains the following attributes:
- Properties - specify the operations allowed on a characteristic, e.g.
read
,write
- UUID - A unique ID for this characteristic, this can be a 16-bit, approved UUID from this list or a custom 128 bit as specified by the device manufacturer
- Value - The actual value contained in a characteristic. How this value is interpreted is based on the UUID and is either a standard value or a custom manufacturer-specific value
Reading Bluetooth Data
I’m going to be using Bleak with Python to read Bluetooth data and characteristics. Although it’s also possible to use the nrf Connect app or another bluetooth debugging tool to do much of the same kind of stuff I’m doing here
Install Bleak
In order to connect to bluetooth devices I’m using a library called Bleak. To install Bleak you can use the following command:
Scan for Devices
To scan for devices we can use the BleakScanner.discover
method:
discover.py
This will print all devices that were found during the discover call in the form of:
An example can be seen below:
List Services and Characteristics
To list the services of a device we can make use of the BleakClient
class. To do this we need a client address as we saw above:
get_device_info.py
We can expand on the above to list the characteristics and descriptors of each service as well:
get_device_info.py
Below you can see the results of reading from a sample server that I’ve configured which has a few characteristics with different permissions
Using the above, I can read some characteristics using their UUID like so:
Depending on the data structure and type the requirements for decoding the data may be different.
Using the above idea, Bleak also gives us a way to listen to data that’s being sent from a client by way of the BleakClient.start_notify
method which takes a characteristic to listen to and a callback which will receive a handle for the characteristic as well as the value
References
Overview
A good overview of how Bluetooth and how GATT (The Generic Attribute Profile) for a bluetooth device structures data can be found in Getting Started with Bluetooth Low Energy by Kevin Townsend, Carles Cufí, Akiba, Robert Davidson. A good overview of what we’ll be using can be found on Chapter 1 - Introduction and Chapter 4 - GATT (Services and Characteristics)
Library
A library I’ve found to be fairly simple for using to play around with Bluetooth is Bleak which is a multi-platform library for Python
I’ve had some issues using Bleak with Windows so I would recommend a Linux-based OS instead
Debugging Tool
A useful and easy to use tool for snooping around for bluetooth activity and exploring bluetooth data is the nrf Connect Android App
Reverse Engineering
An approach for reverse engineering the data structure for a simple bluetooth device can be found on BLE Reverse engineering — Mi Band 5
List of Bluetooth IDs
A database of bluetooth numbers can be found in the Bluetooth numbers database as well as the previously mentioned {Bluetooth specifications document}(https://btprodspecificationrefs.blob.core.windows.net/assigned-values/16-bit%20UUID%20Numbers%20Document.pdf)
Next Ideas
It may be worth looking into creating a Bluetooth Server. The library installed on Raspberry Pi is Bluez and it looks it supports creating a Bluetooth Server. The documentation for Bluez can be found here. Additionally, there’s also the Bluetooth for Linux developers which goes through creating a device that acts as a Bluetooth LE peripheral which could be useful in simulating a BLE device