Skip to content

dallanwagz/untether

Repository files navigation

untether — free your devices from their apps

Local control. No cloud. No leash.

untether — reverse-engineer a Bluetooth/BLE gadget that's locked to its vendor app, and free it: decode its radio protocol and rebuild it as a local, cloud-free Home Assistant integration.


A Claude Code skill with a structured, phase-gated methodology for reverse-engineering a Bluetooth / BLE consumer device (controlled by a vendor Android or iOS app) into a local Home Assistant integration — no cloud, no vendor app. (Formerly android-ble-to-ha.)

The objective: an integration that installs out-of-the-box via HACS and is structured to be submitted as a PR into Home Assistant Core, so others can use it — a properly built, tested, documented integration, not a one-off script. New here? Start with docs/WORKFLOWS.md — workflows, prerequisites, the cost/involvement tradeoffs, and what's required of you.

It covers the whole pipeline, and insists on doing both halves of the work:

  • Static — decompile the APK (jadx): the write path, frame format (framing + checksum), the full command catalog, the command-gating logic, and the status-struct field list. The spec.
  • Dynamic — drive the app over ADB + UIAutomator (accessibility-hierarchy taps, not pixels) and capture what each press emits (HCI snoop / logcat / live status diffing); enumerate GATT; match commands to features. The truth on your actual hardware.

…then decode the status frame byte-by-byte, and ship a HACS integration (pure unit-tested protocol.py, a reconnecting coordinator with a staleness watchdog, config flow, entities, and a generic send_command service).

See SKILL.md for the full methodology, and examples/ for real artifacts from a worked project (a massage chair) — each shows an RE finding and the exact Home Assistant code it became, from a decompiled Java frame builder all the way to live sensors.

For Bluetooth Classic / RFCOMM / SPP specifically — the transport the BLE-only toolchain can't reach — read docs/CLASSIC-BT-RE-HANDBOOK.md: a spec-grounded map of the stack (L2CAP PSM, RFCOMM/TS 07.10 framing and DLCI math, SDP channel discovery, Class of Device), each layer tied to the untether-bt primitive that decodes it.

For Bluetooth Classic SPP devices (which HA's BLE-only stack can't reach), the repo also ships a hardware-verified bridge: components/untether_spp, an ESPHome external component for a classic ESP32 that RFCOMM-connects to up to 4 SPP devices at once (each on its own TCP port, over one shared radio) and re-exposes their byte streams as TCP servers — nc <esp32-ip> 8888 and you're talking to a device. Verified driving 4 devices simultaneously across two wire dialects (Pixoo NewMode + TimeBox byte-stuffed).

And the host-side toolkit is a pip-installable Python library, python/ (untether-bt): the framing/codec engine, the SPP-bridge client (sync + async) plus a self-healing SppConnection that the example HA integration is built on, a BLE advertisement decoder, and the full reverse-engineering pipeline — live ADB/UIAutomator driver → btsnoop parse → HCI/ATT extraction → UI-action↔wire-byte correlation, static (jadx) + dynamic (Frida) analysis, and the protocol primitives (SDP record parser, GATT client over bleak, a full Assigned-Numbers resolver — every company ID, UUID, SDP service class, protocol ID, AD type, and Class of Device), plus Android btsnooz decompression and live SDP browsing on BlueZ — first-class Bluetooth Classic support the BLE-only ecosystem (bleak/HA/ESPHome) lacks.

Install (as a Claude Code skill)

mkdir -p ~/.claude/skills/untether
cp SKILL.md ~/.claude/skills/untether/SKILL.md

Then invoke it in Claude Code with /untether.

Contributing — a library that grows with every use

This is meant to get better each time someone uses it. After you take a device from app → HA, contribute a device profile (copy examples/_TEMPLATE.mdexamples/devices/) so the next person starts further ahead — and improve SKILL.md if you found a technique it's missing.

  • AI agents: read AGENTS.md — the contract for contributing back (what to contribute, branch conventions, the quality bar).
  • Humans: see CONTRIBUTING.md. Both flow through the PR template.
  • CLAUDE.md drives the contribute-back loop when Claude uses the skill.

Key principle

Static = the spec; dynamic = the truth. The app you can decompile may not even be the working transport (e.g. an Android app speaks Classic SPP while the device is really driven over BLE by the iOS app) — so verify the transport with dynamic evidence before building anything.

About

Free your devices from their apps. Reverse-engineer a Bluetooth/BLE gadget locked to its vendor app and rebuild it as a local, cloud-free Home Assistant integration — a Claude Code skill + growing device library.

Resources

License

Contributing

Stars

3 stars

Watchers

1 watching

Forks

Packages

 
 
 

Contributors