Direct Bluetooth Mesh control of your amaran lights — no amaran Desktop app required.
Reverse-engineered protocol: the lights run a Telink BLE SIG Mesh. All physical
controls (wake/sleep, brightness, CCT, HSI) use Telink proprietary opcode 0x26
with 10-byte payloads, sent as app-key-encrypted mesh messages through any
light's Mesh Proxy GATT service (0x1828 / 0x2ADD / 0x2ADE).
Protocol + crypto verified against live lights (Halo 60x ×2, T2c ×1) and
cross-checked with the independently derived reference implementation
wesbos/amaran-BLE-control
(cloned in reference/).
npx skills add R44VC0RP/amcliUses the skills.sh ecosystem — installs SKILL.md into
whatever agents you use (Claude Code, Codex, opencode, Cursor, …) so they know
how to drive the CLI. Add -g for a global (all-projects) install.
The skill teaches agents the commands; the CLI itself is a Python package:
git clone https://github.com/R44VC0RP/amcli.git && cd amcli
./install.sh # venv + pip install + `amaran` into ~/.local/bin + key importor manually:
python3 -m venv .venv && .venv/bin/pip install -e .
ln -sf "$PWD/.venv/bin/amaran" ~/.local/bin/amaran
amaran setup # one-time: import mesh keys from the amaran Desktop DBRequires macOS, python3, and git. The amaran Desktop app must have paired the lights at least once (its local DB holds the mesh keys) and must be quit while using the CLI.
amaran on [target] # turn on
amaran off [target] # turn off
amaran bright <0-100> [target] # brightness %
amaran cct <0-100> <kelvin> [target] # brightness + color temp (add --gm -10..10 for T2c)
amaran hsi <0-100> <hue> <sat> [target] # color (T2c only)
amaran status [target] # query current state
amaran repl # stay connected, run commands interactively (fast)
amaran scan # list nearby mesh lights
amaran lights # list configured lights
amaran setup # re-import mesh keys from amaran.dbTarget defaults to all (mesh group 0xC000). Substrings match configured
light keys/names: halo hits both Halos, t2c the tube, halo-60x-3 one light.
Examples:
amaran bright 50 # everything to 50%
amaran cct 80 4300 # all lights 80% @ 4300K
amaran hsi 40 220 90 t2c # tube: 40%, blue
amaran off halo # both Halos offNotes:
- Quit the amaran Desktop app first — it holds the BLE connections.
- First run may trigger a macOS Bluetooth permission prompt for your terminal.
amaran statusreplies can occasionally get lost in the mesh — just retry.
SKILL.md— agent skill file (generic; symlink into your agent's skills dir)src/amaran_cli/mesh.py— mesh crypto (network/transport), proxy handshake, bleak clientsrc/amaran_cli/telink.py— opcode0x26payload builders + status decodersrc/amaran_cli/cli.py— argparse CLI + REPLtests/test_vectors.py— crypto vectors + PDU round-trip testsconfig—~/.config/amaran/lights.json(mesh keys + lights, fromamaran setup)debug_ble.py— raw traffic debugging script used during bring-upappcopy/— copy of the desktop app used for analysis (safe to delete, ~800 MB)reference/— wesbos/amaran-BLE-control clone (reference only, safe to delete)
- amaran fixtures never send the proxy Filter Status reply; the filter is set anyway — the CLI proceeds after a short wait (verified).
- Nearby foreign Telink mesh devices are rejected by matching the beacon's Network ID against k3(netKey).
- Halo 60x #2 currently caps brightness at 15% regardless of commands (CCT/on/off
all work). Likely fixture-side (power input / thermal). Investigate if it
surprises you —
amaran cct 100 5600 halo-60x-2reproduces the cap.