scenelight
CLI for direct BLE-Mesh control of studio lights (amaran Ray series today, more brands later). Sub-100 ms latency once the background daemon is running.
Install (per machine, ~5 seconds)
curl -fsSL https://releases.daslab.dev/scenelight/install.sh | sh
Drops the binary at ~/.local/bin/scenelight. Apple Silicon Macs only for now.
Setup (per user, once)
Requires the amaran iOS-on-Mac app installed and signed into the user's Aputure account, with at least one light paired. Then:
scenelight setup # extracts mesh keys from amaran's local SQLite
scenelight start # background daemon for fast subsequent calls
Commands
scenelight color <spec> [-b <0-100>] [<light>]
scenelight on [<light>]
scenelight off [<light>]
scenelight brightness <0-100> [<light>]
scenelight lights # list configured lights
scenelight status [<light>] # current state
scenelight raw <dst> <opcode> <hex-payload> # lowest-level mesh PDU
scenelight stream [--retries N] [--rate FPS] # animation pipe
<spec> accepts
| form | examples |
|---|---|
| Hex | #ff8800, ff8800, f80 |
| Named chromatic | red, orange, amber, yellow, lime, green, spring, teal, cyan, sky, blue, indigo, purple, violet, magenta, pink, rose, white |
| Named white CCT | candle, tungsten (= warm), bulb, halogen, fluorescent, daylight, cool |
<light> accepts
- A key like
ray3— seescenelight lights - A mesh address like
0x0004 - Omit (or
all) — broadcasts to every configured light
Examples
scenelight color warm -b 70 # warm tungsten at 70%
scenelight color "#003355" -b 50 # deep navy at 50%
scenelight color daylight ray3 # only ray3 to daylight white
scenelight off # all lights off
stream — animation pipe
scenelight stream reads commands from stdin, one per line, and dispatches them against the running daemon over a single persistent socket (no per-frame reconnect). Each line is a bare CLI subcommand with the scenelight prefix dropped.
Special directives:
sleep <seconds>— pause without dropping the socket- lines starting with
#are comments
Defaults --retries 1 (vs 3 for one-shot commands) — animation streams tolerate per-frame packet loss because the next frame corrects it visually, and lower retries means 3× higher effective frame rate.
# Hand-written
printf 'color warm -b 70\nsleep 0.2\ncolor blue\nsleep 0.2\noff\n' | scenelight stream
# Generated — sea waves (cyan ↔ deep blue, breathing brightness)
awk 'BEGIN {
for (t = 0; t < 150; t++) {
sec = t / 10.0
h = 220 + int(45 * sin(sec * 0.6))
b = 60 + int(35 * sin(sec * 0.4))
print "hsi " b " " h " 100"
print "sleep 0.1"
}
}' | scenelight stream --retries 1
# Optional rate cap so a runaway generator doesn't oversaturate
scenelight stream --rate 20 < animation.lights
The grammar is the existing CLI minus the binary name. Any shell tool that can emit lines into a pipe — awk, python3, tail -f, a Daslab agent emitting via shell asset — can drive lights.
Notes
- Latency: first call after
scenelight startis ~5 s (BLE connect + filter). Subsequent calls are <100 ms. - Exclusivity: the BLE mesh proxy accepts one client at a time. Close the amaran app before scenelight takes over; reopen amaran whenever you want — scenelight releases the connection on exit.
- Available lights: run
scenelight lightsto see what's configured on this machine. rawis the protocol escape hatch: opcode0x26with a 10-byte Telink vendor payload covers HSI/CCT/RGB/effects. Use this when the convenience commands don't expose what you need.- Stream mode default retries = 1: for one-shot commands the daemon defaults to 3 retries (reliability over speed); stream flips that trade.