The Android reference app.
Connect Colmi rings over BLE, filter the sensor stream, recognize gestures and map them to keys, scroll actions, macros or musical controls. Live signal inspection and mapping tools help separate a noisy input from a bad mapping.
- Configurable spin, shake and menu gestures.
- Per-ring mappings, timing and thresholds.
- Input injection through the available IME, accessibility or shell route.
- Music controls and optional event emission to a desktop or keyboard receiver.
Build from the repository’s Android Nix development shell:
cd android-app
nix develop path:"$PWD" --command \
gradle --no-daemon :app:assembleDebugThe project’s Play distribution is an internal testing track, not an unrestricted public store release. Bluetooth and input permissions must be granted through Android’s normal flows.
Android source and build files ↗Rust CLI, daemon and MCP.
The ring command scans and registers devices, reads identity, runs streaming workers, reports connection and subtype-rate snapshots, and exposes events through the command line and MCP.
Release downloads ↗ cover Linux x86_64, macOS aarch64 and Windows x86_64. With Nix, you can start by inspecting nearby devices:
nix run github:harryaskham/ring-mods#ring -- scan --jsonFor an already configured ring, inspect before changing anything:
ring list --json
ring info --name desk-ring --json
ring connections --json
ring rates --name desk-ring --jsonThen follow semantic events or expose the same tool surface to an agent:
ring get --events scroll-up,scroll-down -n 1
ring tail --format json
ring mcp stdioReplace desk-ring with your configured name. get waits for new events by default. Cached connection and rate output is not proof of a currently connected ring; inspect timestamps.
Host filtering does not speed up the ring. A processing cap can drop or coalesce packets at the host. A higher physical sensor or notification rate requires separate device-side evidence.
A phone can be the source.
The Android app’s opt-in Event Emission Server streams newline-delimited JSON over TCP. The desktop daemon connects to it and treats it as a ring source, without taking over the phone’s app lifecycle.
ring pair --android PHONE_IP:9779 --name phone
ring get --events scroll-up,scroll-down -n 1Enable the server in the app first and replace PHONE_IP with the reachable phone address. Configure shared-token authentication when exposing it on a network. Without a token, a reachable client can read the stream; the server is off by default.
The app can also send mapped events to an omni keyboard receiver. Keep this transport separate from gesture detection: changing where an event goes should not change how it was recognized.
Hear it, inspect it, route it.
ring midi converts the Android emission stream into standard MIDI. It can monitor messages, play notes with a built-in diagnostic synth, and forward the original MIDI to a DAW.
ring midi --android PHONE_IP:9779 --play --monitor
# macOS / Linux: expose a virtual MIDI source
ring midi --android PHONE_IP:9779 --port-name "Ring MIDI"
# Windows: connect to an existing destination, such as loopMIDI
ring midi --android PHONE_IP:9779 --output-port "Ring MIDI"The built-in synth is a bounded diagnostic instrument, not the complete MIDI receiver: it follows notes and velocity, while the MIDI output also carries control changes, bend, clock and transport. A visible port name alone does not prove a DAW is receiving bytes.
MIDI behaviour, reconnect safety and receiver checks ↗Firmware tools stay on the workbench.
The repository includes disassembly helpers, candidate builders, strict execution probes, an image catalogue and a Web Bluetooth flasher. The public Probes page provides a narrow read-only test. Firmware flashing remains a separate local tool; this site does not host live flash buttons or raw .bin payloads.
That is a publishing choice, not a claim that every modified image is cryptographically blocked. The container research explains the corrected activation model, and the family table separates physical results from review-only candidates.
- Local Web Bluetooth flasher source ↗Use from a checkout with the matching catalogue. Device-specific flash/readiness gates remain in force.
- R12 read-only canary helper ↗Offline preview by default. Exact stock identity is required before one C0 read; no RAM-write command is exposed.
- R12 audit and experiment limits →
Legacy Python tooling
The original BLE client and web dashboard remain in the repository. They are historical desktop tools, not the Android gesture reference or the current Rust command surface. Legacy source and notes ↗