BleakDBusError 'Operation already in progress' - is it possible to stop the BleakScanner after a timeout #1629
-
DescriptionI have a gateway continually connecting to 4 of the same type of device in a round-robin fashion. I have a BleakScanner with a timeout. The timeout still occured after returning from the
My question is - is it possible to cancel the scanning without having to restart the entire process? What I DidI ran the following code and get the log from the async def scan(
device_id, timeout=SCAN_TIMEOUT_S
) -> Optional[Tuple[BLEDevice, Set[str]]]:
try:
filter = get_device_filter(device_id)
return await asyncio.wait_for(_scan_with_timeout(filter, device_id), timeout)
except asyncio.TimeoutError:
logger.info(
f"Timeout reached. Device {device_id} not found after {timeout} seconds"
)
return None
async def _scan_with_timeout(filter, device_id):
seen = set()
async with BleakScanner() as scanner:
async for device, advertisement in scanner.advertisement_data():
found_device_id = get_device_id(device)
if found_device_id and found_device_id.startswith(filter):
logger.info(f"Found {device!r}")
logger.debug(f"{advertisement!r}")
logger.debug(f"platform_data: {advertisement.platform_data}")
logger.debug(f"service_data: {advertisement.service_data}")
seen.add(found_device_id)
if found_device_id == device_id:
logger.info(f"Connecting")
return (device, seen) LogsThese are the logs I have, I don't have any further in depth logs yet.
These two lines are the ones that are the problem:
The "Connecting" log occurs just before the return of the function. |
Beta Was this translation helpful? Give feedback.
Replies: 3 comments 3 replies
-
This sounds relevant: #691 (comment) |
Beta Was this translation helpful? Give feedback.
-
|
Beta Was this translation helpful? Give feedback.
-
As a final follow up to this, the Lines 444 to 451 in e01e264 This was my final source code and I haven't had a problem since. Note the extra attempts to stop the scanning on a async def scan(
device_id, timeout=SCAN_TIMEOUT_S
) -> Optional[Tuple[BLEDevice, AdvertisementData, Set[str]]]:
try:
# structure copied from Bleak source
# {@link https://github.com/hbldh/bleak/blob/e01e2640994b99066552b6161f84799712c396fa/bleak/__init__.py#L446}
async with BleakScanner(service_uuids=SERVICE_UUIDS) as scanner:
try:
filter = get_device_filter(device_id)
if not filter:
logger.error(
f"Stopping scan, couldn't filter devices, unrecognised device ID '{device_id}'"
)
return None
# Enforce a scanning timeout - requires Python 3.11
async with asyncio.timeout(timeout):
seen = set()
async for device, advertisement in scanner.advertisement_data():
found_device_id = get_device_id(device)
if found_device_id and found_device_id.startswith(filter):
logger.info(f"Found {device!r}, RSSI: {advertisement.rssi}")
logger.debug(f"{advertisement!r}")
logger.debug(
f"platform_data: {advertisement.platform_data}"
)
logger.debug(
f"service_uuids: {advertisement.service_uuids}"
)
logger.debug(f"service_data: {advertisement.service_data}")
seen.add(found_device_id)
if found_device_id == device_id:
logger.info(f"Found desired {device!r}")
return (device, advertisement, seen)
except asyncio.TimeoutError:
logger.info(
f"Timeout reached. Device {device_id} not found after {timeout}s"
)
return None
except BleakDBusError as e:
if "org.bluez.Error.InProgress" in str(e):
logger.warning("Operation already in progress. Attempting to stop scanner.")
scanner = BleakScanner(service_uuids=SERVICE_UUIDS)
try:
await scanner.stop()
except Exception as stop_error:
logger.error(f"Failed to stop scanner: {stop_error}")
else:
logger.error(f"Unexpected BleakDBusError: {e}")
return None |
Beta Was this translation helpful? Give feedback.
As a final follow up to this, the
async.timeout
didn't solve the problem. What did, and I took inspiration from the Bleak source code is to switch the order of the context blocks. So that theasync with asyncio.timeout
is performed inside theasync with BleakScanner
context block.bleak/bleak/__init__.py
Lines 444 to 451 in e01e264
This was my final source code and I haven't had a problem since. Note the extra attempts to stop the scanning…