{"id":7050,"library":"bluetooth-auto-recovery","title":"Bluetooth Auto Recovery","description":"bluetooth-auto-recovery is a Python library designed to detect and recover Bluetooth adapters that enter an unresponsive or 'stuck' state. It actively monitors Bluetooth management sockets and initiates recovery procedures, such as resetting the adapter, when issues are detected. The current version is 1.5.3, with minor releases focusing on bug fixes and dependency updates, typically every few months.","status":"active","version":"1.5.3","language":"en","source_language":"en","source_url":"https://github.com/bluetooth-devices/bluetooth-auto-recovery","tags":["bluetooth","recovery","hardware","linux","asyncio"],"install":[{"cmd":"pip install bluetooth-auto-recovery","lang":"bash","label":"Install latest version"}],"dependencies":[{"reason":"Required for D-Bus communication with the system's Bluetooth daemon (BlueZ).","package":"dbus-next"}],"imports":[{"symbol":"BluetoothAutoRecovery","correct":"from bluetooth_auto_recovery import BluetoothAutoRecovery"}],"quickstart":{"code":"import asyncio\nfrom bluetooth_auto_recovery import BluetoothAutoRecovery\n\nasync def main():\n    print(\"Starting Bluetooth Auto Recovery...\")\n    async with BluetoothAutoRecovery(\n        recovery_timeout=60, # Max time to wait for recovery in seconds\n        unresponsive_timeout=300 # Time to wait for unresponsiveness before recovering\n    ) as recovery:\n        print(\"Monitoring Bluetooth adapters. Press Ctrl+C to stop.\")\n        try:\n            # Start monitoring in the background\n            await recovery.start()\n            # Keep the main task running indefinitely to monitor\n            await asyncio.Future() # Await an eternal future\n        except asyncio.CancelledError:\n            print(\"Monitoring stopped.\")\n        finally:\n            await recovery.stop() # Explicitly stop the recovery\n            print(\"Bluetooth Auto Recovery stopped.\")\n\nif __name__ == \"__main__\":\n    try:\n        asyncio.run(main())\n    except KeyboardInterrupt:\n        print(\"Program interrupted by user.\")\n","lang":"python","description":"Initializes `BluetoothAutoRecovery` and starts monitoring Bluetooth adapters in an asynchronous context. The recovery process runs in the background, attempting to fix unresponsive adapters. This example includes a robust shutdown on `KeyboardInterrupt`."},"warnings":[{"fix":"Run your Python script with `sudo python your_script.py` or ensure the user running the script has appropriate permissions to access `/var/run/bluetooth/mgmt` and interact with `rfkill`.","message":"This library relies on Linux-specific Bluetooth management sockets (BlueZ) and typically requires root or `sudo` privileges to operate correctly. Running without elevated permissions will likely result in permission errors or inability to access Bluetooth hardware.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Ensure `pip` is able to fetch and install git dependencies. If issues arise, consider creating a clean virtual environment or checking the GitHub repository for the exact `pybluez` fork used.","message":"The library depends on a specific, potentially patched version of `pybluez` fetched directly from GitHub via its `pyproject.toml`. While `pip` generally handles this, custom `pybluez` installations or conflicts with system-installed `pybluez` might occur, especially in isolated environments.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Always use `async with BluetoothAutoRecovery(...)` and ensure your application's entry point uses `asyncio.run(main_async_function())` to correctly manage the event loop.","message":"The `BluetoothAutoRecovery` class is designed for asynchronous operations and must be run within an `asyncio` event loop. Improper use outside an async context or incorrect handling of the event loop can lead to `RuntimeError` or unexpected behavior.","severity":"gotcha","affected_versions":"All versions"},{"fix":"If running in a container, verify the correct path to the Bluetooth management socket within the container and pass it to the `bluetooth_management_socket` parameter of `BluetoothAutoRecovery`.","message":"For containerized environments (e.g., Docker), the Bluetooth management socket path might be different or require specific volume mounts. The default path is `/var/run/bluetooth/mgmt`.","severity":"gotcha","affected_versions":"All versions"}],"env_vars":null,"last_verified":"2026-04-16T00:00:00.000Z","next_check":"2026-07-15T00:00:00.000Z","problems":[{"fix":"Run the Python script with `sudo` (e.g., `sudo python your_script.py`) or adjust user permissions to allow access to the Bluetooth management socket and `rfkill`.","cause":"The Python script does not have sufficient permissions to access the Bluetooth management socket (e.g., `/var/run/bluetooth/mgmt`).","error":"Failed to connect to Bluetooth management socket: [Errno 13] Permission denied"},{"fix":"Install the required dependency: `pip install bluetooth-auto-recovery` (which should pull `dbus-next`) or explicitly `pip install dbus-next`.","cause":"The `dbus-next` dependency, which is crucial for D-Bus communication, is not installed.","error":"ModuleNotFoundError: No module named 'dbus_next'"},{"fix":"Ensure `asyncio.run()` is called only once as the top-level entry point for your asynchronous code, typically within `if __name__ == '__main__':`. If integrating into an existing async application, use `asyncio.create_task()` or `await` directly within the existing event loop.","cause":"Attempting to run `asyncio.run()` when an `asyncio` event loop is already active in the current thread, or calling async functions outside of an awaitable context.","error":"RuntimeError: Event loop is already running"}]}