# Async Nxbt Migration Notes ## Overview NXBT now exposes an async-friendly facade so that applications can await controller lifecycle events directly instead of relying on background threads. The new `nxbt.AsyncNxbtClient` wraps the legacy `Nxbt` API but offloads each blocking call to a worker thread, allowing you to coordinate controllers from within an `asyncio` event loop. ```python import asyncio from nxbt import AsyncNxbtClient, PRO_CONTROLLER async def main(): async with AsyncNxbtClient(debug=False) as nx: adapters = await nx.get_available_adapters() index = await nx.create_controller(PRO_CONTROLLER, adapters[0]) await nx.wait_for_connection(index) await nx.macro(index, "A 0.1s\n0.1s") asyncio.run(main()) ``` Key points: 1. Use `async with AsyncNxbtClient(...)` to ensure cleanup mirrors the previous `atexit` behaviour (BlueZ toggles, runtime shutdown). 2. All high-level helpers (`macro`, `press_buttons`, `tilt_stick`, `set_controller_input`, `wait_for_connection`, etc.) are now `await`-able. The `state` dict remains synchronous for quick inspection without additional locking. 3. CLI utilities (`nxbt.cli` commands and `scripts/demo_loop.py`) already route through `asyncio.run`, so they can be embedded inside larger event loops or scripted via `asyncio.create_task`. ### Compatibility The legacy `Nxbt` class still works for synchronous consumers and continues to wrap the async controller manager internally. Downstream callers can migrate at their own pace: - **Synchronous projects** – keep using `Nxbt` as before. - **Async-aware projects** – switch to `AsyncNxbtClient` and await controller operations directly. Future releases will update the TUI and web entry points to the async client as well, completing Phase 4 of the refactor plan.