Testing BLE? Ditch your phone!

If you've ever developed BLE firmware, odds are you've used Lightblue to test it. It's a great app for ad-hoc testing, but when you're ready to start doing continuous integration and automated testing, needing to have a phone in your test loop becomes a hassle. Furthermore, a touch screen interface is probably not the fastest or most accurate way to make changes to your test setup, nor can changes to the tests be easily version controlled

Wouldn't it be nicer if a BLE test looked like this:

{% c-block language="python" %}
import asyncio
import sys
from bleak import BleakScanner, BleakClient
from bleak.exc import BleakError
FIRMWARE_REV_UUID = "00002a26-0000-1000-8000-00805f9b34fb"
EXPECTED_FIRMWARE_REV = b'3.1'
async def run(address):
   device = await BleakScanner.find_device_by_address(address, timeout=20.0)
   if not device:
       raise BleakError('Device not found')
   try:
       async with BleakClient(device, timeout=5) as client:
           try:
               model_number = await client.read_gatt_char(FIRMWARE_REV_UUID)
           except (EOFError, BleakError):
               raise SystemExit(f'Could not read firmware revision of {device}')
           else:
               if model_number != EXPECTED_FIRMWARE_REV:
                   raise SystemExit(f"{device.name} Firmware Revision: {''.join(map(chr, model_number))}")
               else:
                   print("Firmware revision is correct!")
   except (BleakError, asyncio.TimeoutError):
       raise SystemExit(f'Could not connect to {device}')
def main():
   loop = asyncio.get_event_loop()
   address = sys.argv[1]
   loop.run_until_complete(run(address))
if __name__ == '__main__':
   main()
{% c-block-end %}

But enough code, let's see it in action:

Want to stay up to date on the future of firmware? Join our mailing list.

Section
Chapter
Published