Python and Bluetooth – Part 1: Scanning For Devices And Services (Python)

“Track and Trace” has got some attention in recent times here in the UK as the Covid-19 (Coronavirus) lockdown level looks to be relaxed. Part of the “Track and Trace” program is a mobile application that uses low energy bluetooth beaconing to see what other devices running the application have been close by. This has inspired me to look at Bluetooth connectivity in Python.

Note: I’ve written before, and I’ll probably write again, geektechstuff.com is not a political site. If you have come to this page/site to discuss political opinions around the NHS Track and Trace app, then please take them to a more appropriate site. Thank you. Also note, I am looking at Bluetooth and Python – I am not saying these functions are in the NHS app!

With this blog post I am going to take a look at using a Raspberry Pi (in this case a ZeroW) and some Python to get the Pi to detect active bluetooth devices.

Installing

I installed the required libraries for this project on my Raspberry Pi using the commands:

sudo apt install bluetooth libbluetooth-dev

pip3 install pybluez

Checking For Devices

geektechstuff_python_bluetooth
Using Python to scan for active Bluetooth devices

With the pybluez library installed and imported into Python, the Raspberry Pi can start to scan for active Bluetooth devices. This code can be tided up into a function, so that it can be expanded on later.

geektechstuff_python_bluetooth_2
Python Bluetooth scan function
#!/usr/bin/python3

# geektechstuff bluetooth

import bluetooth

def scan():

    print("Scanning for bluetooth devices:")

    devices = bluetooth.discover_devices(lookup_names = True, lookup_class = True)

    number_of_devices = len(devices)

    print(number_of_devices,"devices found")

    for addr, name, device_class in devices:

        print("\n")

        print("Device:")

        print("Device Name: %s" % (name))

        print("Device MAC Address: %s" % (addr))

        print("Device Class: %s" % (device_class))

        print("\n")

    return

Checking For Services Running On Devices

geektechstuff_python_bluetooth_services
Scanning for services on active Bluetooth devices

A function to scan for Bluetooth services on found devices can also be created.

def scan_services():

   print("Scanning for bluetooth devices: ")

   devices = bluetooth.discover_devices(lookup_names = True)

   number_of_devices = len(devices)

   print(number_of_devices, "devices found")

   for addr,name in devices:

      print("\n")

      print("Device Name: %s" % (name))

      print("Device MAC Address: %s" % (addr))

      print("Services Found:")

      services = bluetooth.find_service(address=addr)

      if len(services) <=0:

          print("zero services found on", addr)

      else:

          for serv in services:

              print(serv['name'])

      print("\n")

   return()

When run this function returns the device details and the name of the services it finds on those active devices.

Scan results (with names and MAC addresses removed)
Scan results (with names and MAC addresses removed)

Although I am only returning the service name (using serv[‘name’]) there are also options to return:

  • host
  • description
  • provider
  • protocol
  • port
  • service-classes
  • profiles
  • service-id

To use these, place them in the same format as serv[‘name’] e.g. serv[‘host’]

Links

The GitHub for pybluez (which contains examples of the library in action) can be found at:

https://github.com/pybluez/pybluez

The GitHub for NHSX Android Covid-19 app can be found at:

https://github.com/nhsx/COVID-19-app-Android-BETA

The GitHub for NHSX iOS Covid-19 app can be found at:

https://github.com/nhsx/COVID-19-app-iOS-BETA