Search code examples
bluetooth-lowenergypython-3.7ibeacon

Python Bleak BLE not getting UUID


I have a respberry server and a windows client, both implemented in Python. The server transmits a BLE signal like a iBeacon signal.

Here is the code of the server:

import time

from bluetooth.ble import BeaconService

service = BeaconService()

uuid = "11111111-2222-3333-4444-555555555555"
major = 2   # 1 - 65535
minor = 1   # 1 - 65535
txpower = 1
interval = 200

service.start_advertising(uuid, major, minor, txpower, interval)

try:
    time.sleep(300)
    service.stop_advertising()

except KeyboardInterrupt:
    print("cancelled")

finally:
    service.stop_advertising()

print("Done.")

This code is working fine. I checked by installing an android app and I could find the device with that information.

Now I need to get that information in the windows client. In the windows client I'm using bleak library.

I have the following code to scan for beacon devices:

import asyncio
from bleak import discover

async def run():
    devices = await discover()
    for d in devices:
        #if d.address == "B8:27:EB:03:5A:D6":
        print(d.address, d.name, d.metadata, d.rssi)            

loop = asyncio.get_event_loop()
loop.run_until_complete(run())

The problem is when I check the console, I dont see the major, minor and UUID information:

There are showed other devices and I can see in one of them that the UUID is readable. What I'm doing wrong here? Is bleak impossible to get the information I want? (minor, major) or am I transmitting in the wrong way? I dont think so because the mobile app is reading fine. Is there another library available to windows to get this information? Thanks for the help. Have a good day.


Solution

  • Do not confuse the GATT Service UUID list returned by bleak with the iBeacon ProximityUUID you want. They are two totally different identifiers. The iBeacon ProximityUUID is encoded inside the manufacturer data returned by bleak. It will not parse it for you, but you could write a parser yourself. If you print out the manufacturer data bytes as hex you will see the pattern.

    I wrote a Windows Beacon Library that does what you want. It is a port of the Android Beacon Library for Windows 10. But the documentation is sorely lacking. If you are stuck, I can help you use it, but it is designed to be used with Visual Studio languages not Python.

    Using that library you can parse an iBeacon frame from BluetoothLEAdvertisementReceivedEventArgs in C# like this:

    var beaconParser = new BeaconParser();
    beaconParser.SetBeaconLayout("m:2-3=0215,i:4-19,i:20-21,i:22-23,p:24-24");
    Beacon beacon = beaconParser.FromAdvertisement(args.Advertisement, args.RawSignalStrengthInDBm, args.BluetoothAddress);
    if (beacon != null)
    {
        OLogger.Debug("Found iBeacon: UUID=" + beacon.Id1 + " major=" + beacon.Id2 + " minor=" + beacon.Id3 + " rssi: " + beacon.Rssi);
    }