Skip to content

Repository files navigation

Echo Remote

Turn a $10 Bluetooth camera-shutter remote into a programmable macro controller for your Mac — switch desktops, summon AI assistants, trigger any shortcut or script, all from a remote in your hand.

Echo Remote is a small Swift HID bridge for the VN11 BLE remote (a cheap camera shutter sold under many brand names). macOS normally treats these remotes as a half-broken keyboard that mashes the volume keys; Echo Remote seizes the raw HID stream instead and turns every button, ring, and gesture into an action you define in a plain-text config file.

ok = key:enter
left = key:cmd+w
up = oskey:ctrl+right          # next desktop
down_double = app:Terminal
shutter = run:~/bin/my_script.sh
zoom_out = url:https://claude.ai

Edit the file, press a button — the new mapping is live. No rebuild, no restart, no re-granting permissions.

Why not Karabiner?

The VN11 sends nonstandard consumer/digitizer reports that Karabiner cannot reliably distinguish (several buttons arrive as identical volume events, and the direction pad arrives as digitizer coordinates). Echo Remote reads the raw reports, reconstructs each physical button and gesture, and suppresses the system volume-HUD side effects by opening the device in seize mode.

What you get

  • 13 mappable inputs from one remote: OK, Left, Right, Up, Down (each with optional double-press), Shutter, Zoom In, Zoom Out, Function (single and double-press).
  • Five action types: synthetic keystrokes (key:), System Events keystrokes for Spaces switching (oskey:), app launch (app:), URLs (url:), and arbitrary shell commands (run:).
  • A menu-bar app with a live green/red health indicator; clicking it when red runs a full reconnect sequence (Bluetooth poke, bridge restart, and a notification telling you exactly what to fix if that wasn't enough).
  • Self-healing: a LaunchAgent starts the bridge at login, a supervisor restarts it if it dies, and reconnect handles the remote's sleep cycles.

Install

Requirements: macOS 13+, Xcode Command Line Tools (xcode-select --install), and a VN11-compatible remote — for example this one on Amazon (~$10; sold under many brand names, see Using a different remote).

git clone https://github.com/kkw-21/echo-remote.git
cd echo-remote
./install.sh

Then two one-time permission grants:

  1. Input Monitoring — System Settings → Privacy & Security → Input Monitoring → enable EchoRemoteRuntime. (macOS prompts the first time the bridge tries to seize the remote; until granted, the menu icon stays red with seize_open_failed.)
  2. Accessibility / Automation — only needed if you use oskey: or scripted actions; macOS prompts on first use.

Pair the remote in Bluetooth Settings, press a button, and watch the menu-bar dot turn green.

Configure your buttons

Everything lives in ~/.config/echo-remote/actions.conf (the menu-bar app has an Edit Button Actions shortcut). The config is re-read on every press, so edits apply instantly.

Button Config keys
OK (center) ok
Direction pad left, right, up, down + *_double variants
Shutter shutter
Zoom ring zoom_in, zoom_out
Function function, function_double

Action syntax:

Action Example Notes
key: key:cmd+shift+4 Modifiers: cmd, ctrl, opt, shift. Keys: letters, digits, enter, space, tab, esc, delete, arrows, f1f12, and more.
oskey: oskey:ctrl+right Same combos via System Events — required for Spaces switching and some system shortcuts.
app: app:Terminal Opens or activates an app.
url: url:https://claude.ai Opens in the default handler.
run: run:~/bin/toggle_mic.sh Any shell command, via zsh -c.
none Disable a button. Leaving *_double as none makes single presses fire with zero delay.

See examples/ai-workflow.conf for a complete "AI command deck" layout, and examples/scripts/focus_app_click_input.sh for focusing a chat app and clicking straight into its input box.

Using a different remote

Many BLE shutter remotes share the VN11's chipset. Point Echo Remote at yours in ~/.config/echo-remote/device.conf:

vendor_id = 1452
product_id = 544
product_name = VN11

Find your device's values with ioreg -r -c IOHIDDevice -l | grep -E 'Product|VendorID'. If the direction pad or OK button misbehave, your firmware's report frames may differ — launch the runtime with ECHO_REMOTE_LOG_RAW=1 to capture them and open an issue with the log.

Karabiner users

If Karabiner-Elements is installed, tell it to ignore the remote so the bridge is the only mapper. In ~/.config/karabiner/karabiner.json, add ignore: true device entries for vendor 1452 / product 544 (both the consumer and keyboard services).

Troubleshooting

  • Menu shows red — click it; the reconnect flow fixes the common cases and posts a notification when it needs you (usually Input Monitoring or a sleeping remote).
  • seize_open_failed in the log — Input Monitoring isn't granted for EchoRemoteRuntime. Toggle it in Privacy & Security, then click the menu icon.
  • Remote paired but silent — BLE shutters nap aggressively. Press any button to wake it; the bridge reattaches automatically.
  • Logs~/Library/Application Support/EchoRemote/echo_remote.log (or Open Log in the menu).
  • Statuscat "$HOME/Library/Application Support/EchoRemote/echo_remote.status"

Uninstall

./uninstall.sh          # keeps ~/.config/echo-remote
./uninstall.sh --purge  # removes config too

How it works

EchoRemoteRuntime opens the remote through IOHIDManager in seize mode (exclusive access — this is what silences the volume HUD), classifies each input report into a logical button or gesture (the direction pad is actually a digitizer surface; direction is recovered from coordinate deltas, and the zoom ring from a separate gesture mode), then dispatches the action mapped in actions.conf. Keeping mappings out of the binary matters on macOS: Input Monitoring authorization is tied to the signed binary, so a config-only change never costs you a re-grant.

License

MIT

About

Turn a $10 Bluetooth camera remote into a programmable macro controller for your Mac. Config-driven, no rebuilds to remap.

Topics

Resources

Stars

3 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages