ukBaz / python-bluezero

A simple Python interface to Bluez
MIT License
395 stars 112 forks source link

How best to get extra information like RSSI and tx_power during scan #388

Closed chadrockey closed 1 year ago

chadrockey commented 1 year ago

So I've observed an interesting quirk of bluez that only populates certain extra information while a scan is in progress. In this case, I checked RSSI and tx_power as I'm interesting in scanning for passive beacons for proximity estimation (closest beacon assumed via signal strength).

There appears to be difficult to use timing in bluez which can be demonstrated via bluetoothctl:

bluetoothctl

scan on

# You'll see various updates including RSSI and TxPower values and found devices

scan off

# You'll see that bluetoothctl now prints updates for every device to show RSSI as nil

I originally tried to use the convenience function to scan for devices like this:

dongle.nearby_discovery(timeout=timeout)
for dev in central.Central.available(dongle.address):
     # Look for UUIDs, Name, and RSSI

However, just like when using bluetoothctl, because we go through the available devices after we stop scanning, RSSI and tx_power are always None.

So I have to work around this like the following:

            dongle.start_discovery()
            time.sleep(timeout)
            for dev in central.Central.available(dongle.address):
                # Filter my devices
                # dev.RSSI etc

            dongle.stop_discovery()

This works well, but I feel like this is confusing to users and not clear why some of the device values are None after the convenience function nearby_discovery is done. I at least wanted to create an issue so others can find this and see a workaround. I really don't think it's appropriate to cache results for values like these, but they're clearly only valid when scanning.

Are there any other bluez ways to cache RSSI or enable their last known values even after scanning?

Is this severe enough that we should recommend removing and no longer using the nearby_discovery function?

ukBaz commented 1 year ago

Thanks for posting this here.

The dongle.nearby_discovery functionality was added to allow the discovery of nearby devices without the user having to create an eventloop and handle events asynchronously.

The scanner/observer functionality within Bluezero better demonstrates how to scan and get the RSSI values as the devices are discovered: https://github.com/ukBaz/python-bluezero/blob/7cb8e8f019a3a045f074322a08deb1aa9af6ee67/bluezero/observer.py#L232

This uses the signals within the API PropertiesChanged, InterfacesAdded, and InterfacesRemoved

https://github.com/ukBaz/python-bluezero/blob/7cb8e8f019a3a045f074322a08deb1aa9af6ee67/bluezero/adapter.py#L270-L328

chadrockey commented 1 year ago

Thanks! Hopefully this is searchable in the future for those having issues.