-
Notifications
You must be signed in to change notification settings - Fork 310
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Scan peripherals and filter by service UUID #230
Comments
By OS:
The BlueZ documentation includes a section on Here's an example of scanning in the CoreBluetooth version:
|
Is there a compelling reason (like performance) that the filtering should be done at the OS level? I've been thinking it would be nice to have an async iterator in the scanner. This could be used to implement filters in Python and it would not be restricted to the lowest common denominator of OS capabilities. (Off topic: this feature would also nicely replace For example, get the first device with matching service UUID (ignore that it doesn't match the current API - this is more like pseudo-code): MY_UUID = 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'
async with BleakScanner() as scanner:
# this has an iteration every time a new advertisement is seen
async for advertisement in scanner.scan(timeout=5.0):
if advertisement.service_uuids and MY_UUID in advertisement.service_uuids:
my_device_id = advertisement.device_id
# Breaking out of the for loop stops scanning. If there were any advertisements
# already received after this one, they are ignored.
break
else:
# The for loop completed without `break` so we must have reached timeout.
print('device not found!')
exit(1)
my_device = await scanner.connect(my_device_id)
... Or for all matching devices: MY_UUID = 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'
device_ids = []
async with BleakScanner() as scanner:
async for advertisement in scanner.scan(timeout=5.0):
if not advertisement.service_uuids:
continue
if MY_UUID not in advertisement.service_uuids:
continue
device_ids.append(advertisement.device_id)
if not device_ids:
print('no devices found!')
exit(1)
devices = await asyncio.gather(*(scanner.connect(x) for x in device_ids))
... |
As @bsiever says, there is OS level scan filtering available:
@dlech My sole reason for leaving the scan filtering on the OS level is so that I would not have to support more code. Since it is already available there, I thought that it would be sufficient with providing access to those methods and leave it at that. The Interesting that you put the |
@hbldh I thought that scanning may merit merging into the client too, but I haven't looked at all three clients. On the CoreBluetooth end this may make it easier to remove the singleton/cbapp. It may also be worth considering people who are using bleak for observers that purely scan and process advertisements --- I don't know if there's a downside to folding scanning into clients for that use-case. |
One issue with bluez scanning is that the kernel support always turns on de-duplication of advertisements. This makes it difficult or impossible to use multiple advertisements to transmit changing data in a connectionless way. See https://marc.info/?l=linux-bluetooth&m=158225950522806&w=2. We are lobbying to allow control over this. For now, we have gotten around this problem by using I do not expect |
Don't put any importance on that. I was just being lazy and didn't look up the existing API. 😄 |
@dhalbert Even if bleak provided the Please open a issue where this BlueZ scanning discussion can be had! |
Right, I agree about that. We only did what we had to, after this unpleasant discovery. The |
Thank you for your numerous responses I think on Windows the filters "UUIDs" when calling BleakScanner has no effect.
|
@joelviel No, the UUIDs filter option does not exist in Windows. Look at the docstring for the Windows backend Scanner: https://github.com/hbldh/bleak/blob/master/bleak/backends/dotnet/scanner.py#L51-L58 You have to do something like from System import Guid
from Windows.Devices.Bluetooth.Advertisement import BluetoothLEAdvertisementFilter, BluetoothLEAdvertisement
adv_filter = BluetoothLEAdvertisementFilter()
adv_filter.Advertisement = BluetoothLEAdvertisement()
adv_filter.Advertisement.ServiceUuids = [Guid.Parse("0000fff0-0000-1000-8000-00805f9b34fb")]
bleak.BleakScanner(AdvertisementFilter=adv_filter) first. I haven't tried the code above, merely writing it from documentation. Try it out. Evidently, scanning filters need better documentation and some examples... |
This provides an implementation for the BleakScanner service_uuids kwarg in the WinRT backend. As explained in the code comment, it is not possible to use the OS-provided filter mechanism for technical reasons. Fixes #230
This provides an implementation for the BleakScanner service_uuids kwarg in the WinRT backend. As explained in the code comment, it is not possible to use the OS-provided filter mechanism for technical reasons. Fixes #230
This provides an implementation for the BleakScanner service_uuids kwarg in the WinRT backend. As explained in the code comment, it is not possible to use the OS-provided filter mechanism for technical reasons. Fixes #230
Added ----- * Added ``service_uuids`` kwarg to ``BleakScanner``. This can be used to work around issue of scanning not working on macOS 12. Fixes #230. Works around #635. * Added UUIDs for LEGO Powered Up Smart Hubs. Changed ------- * Changed WinRT backend to use GATT session status instead of actual device connection status. * Changed handling of scan response data on WinRT backend. Advertising data and scan response data is now combined in callbacks like other platforms. * Updated ``bleak-winrt`` dependency to v1.1.0. Fixes #698. Fixed ----- * Fixed ``InvalidStateError`` in CoreBluetooth backend when read and notification of the same characteristic are used. Fixes #675. * Fixed reading a characteristic on CoreBluetooth backend also triggers notification callback. * Fixed in Linux, scanner callback not setting metadata parameters. Merged #715.
Added ----- * Added ``service_uuids`` kwarg to ``BleakScanner``. This can be used to work around issue of scanning not working on macOS 12. Fixes #230. Works around #635. * Added UUIDs for LEGO Powered Up Smart Hubs. Changed ------- * Changed WinRT backend to use GATT session status instead of actual device connection status. * Changed handling of scan response data on WinRT backend. Advertising data and scan response data is now combined in callbacks like other platforms. * Updated ``bleak-winrt`` dependency to v1.1.0. Fixes #698. Fixed ----- * Fixed ``InvalidStateError`` in CoreBluetooth backend when read and notification of the same characteristic are used. Fixes #675. * Fixed reading a characteristic on CoreBluetooth backend also triggers notification callback. * Fixed in Linux, scanner callback not setting metadata parameters. Merged #715.
Hi,
Is it possible to scan peripherals and only consider those with a specific service UUID?
BLE addresses change often if using Android peripheral, what is your solution to detect compliant peripherals with your central in that case?
I am currenty using NodeJS noble ( noble.startScanning(uuid) ) but I am looking for alternative
Thanks
The text was updated successfully, but these errors were encountered: