Skip to content

Instantly share code, notes, and snippets.

@kieranklaassen
Created March 20, 2026 03:48
Show Gist options
  • Select an option

  • Save kieranklaassen/b67bc552dfc0ce6f260f12534587331f to your computer and use it in GitHub Desktop.

Select an option

Save kieranklaassen/b67bc552dfc0ce6f260f12534587331f to your computer and use it in GitHub Desktop.
Antic/OneWheel BLE scanner - discover and dump all characteristics
#!/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