Created
March 20, 2026 03:48
-
-
Save kieranklaassen/b67bc552dfc0ce6f260f12534587331f to your computer and use it in GitHub Desktop.
Antic/OneWheel BLE scanner - discover and dump all characteristics
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/env python3 | |
| """Scan for Antic/OneWheel BLE devices and dump all characteristics.""" | |
| import asyncio | |
| from bleak import BleakScanner, BleakClient | |
| OW_SERVICE = "e659f300-ea98-11e3-ac10-0800200c9a66" | |
| async def scan(): | |
| print("Scanning for Antic/OneWheel devices (10 seconds)...") | |
| print("Make sure your Antic is powered on and nearby.\n") | |
| devices = await BleakScanner.discover(timeout=10.0) | |
| ow_devices = [] | |
| for d in devices: | |
| uuids = [str(u).lower() for u in (d.metadata.get("uuids") or [])] | |
| name = d.name or "" | |
| if OW_SERVICE in uuids or "onewheel" in name.lower() or "antic" in name.lower() or "ow" in name.lower(): | |
| ow_devices.append(d) | |
| print(f" FOUND: {d.name!r} @ {d.address}") | |
| else: | |
| print(f" skip: {d.name!r}") | |
| if not ow_devices: | |
| print("\nNo Antic/OneWheel found. Try:") | |
| print(" - Power on the Antic (hold power button)") | |
| print(" - Close the OneWheel app on your phone first") | |
| print(" - Run again — BLE can be flaky on first scan") | |
| return | |
| target = ow_devices[0] | |
| print(f"\nConnecting to {target.name!r}...") | |
| async with BleakClient(target.address, timeout=20.0) as client: | |
| print(f"Connected! MTU={client.mtu_size}\n") | |
| print("=== All GATT Services & Characteristics ===\n") | |
| for service in client.services: | |
| print(f"Service: {service.uuid}") | |
| if service.description: | |
| print(f" ({service.description})") | |
| for char in service.characteristics: | |
| props = ", ".join(char.properties) | |
| print(f" Char: {char.uuid} [{props}]") | |
| if char.description: | |
| print(f" ({char.description})") | |
| if "read" in char.properties: | |
| try: | |
| val = await client.read_gatt_char(char.uuid) | |
| print(f" value: {val.hex()} ({bytes(val)})") | |
| except Exception as e: | |
| print(f" read error: {e}") | |
| print() | |
| asyncio.run(scan()) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment