diff --git a/slab/bin/ac-dmx-cli b/slab/bin/ac-dmx-cli new file mode 100755 index 0000000000..eaa38c5d5d --- /dev/null +++ b/slab/bin/ac-dmx-cli @@ -0,0 +1,35 @@ +#!/bin/bash +# ac-dmx-cli — node-resolving wrapper around ac-dmx-cli.mjs. +# +# Same shape as the other slab bins: symlinked into ~/.local/bin, resolves +# through the link back to the .mjs next to it, and finds a usable `node` +# even under launchd's minimal PATH (no fnm shim there). +set -u +SRC="${BASH_SOURCE[0]}" +while [ -L "$SRC" ]; do + DIR="$(cd -P "$(dirname "$SRC")" && pwd)" + SRC="$(readlink "$SRC")" + [[ "$SRC" != /* ]] && SRC="$DIR/$SRC" +done +HERE="$(cd -P "$(dirname "$SRC")" && pwd)" +SCRIPT="$HERE/ac-dmx-cli.mjs" + +find_node() { + if command -v node >/dev/null 2>&1; then command -v node; return; fi + local c + for c in \ + "$HOME/.local/share/fnm/aliases/default/bin/node" \ + "$HOME/.fnm/aliases/default/bin/node" \ + /opt/homebrew/bin/node \ + /usr/local/bin/node \ + "$HOME/.volta/bin/node"; do + [ -x "$c" ] && { echo "$c"; return; } + done + c=$(ls -td "$HOME"/.local/share/fnm/node-versions/*/installation/bin/node \ + 2>/dev/null | head -1) + [ -n "$c" ] && [ -x "$c" ] && { echo "$c"; return; } + return 1 +} + +NODE="$(find_node)" || { echo "ac-dmx-cli: no node found" >&2; exit 1; } +exec "$NODE" "$SCRIPT" "$@" diff --git a/slab/bin/ac-dmx-cli.mjs b/slab/bin/ac-dmx-cli.mjs new file mode 100755 index 0000000000..975de5c70e --- /dev/null +++ b/slab/bin/ac-dmx-cli.mjs @@ -0,0 +1,625 @@ +#!/usr/bin/env node +// ac-dmx-cli — poke a USB DMX widget from the shell. +// +// Talks Enttec DMX USB Pro framing (the house DMXking DMX USB PRO, FTDI +// serial) — the same wire that Menu Band's DMXOut.swift and AC OS's +// system.dmxSend push, so whatever this proves on the bench is what the +// synth lane and the native piece will do. Node + stty only; no deps. +// +// ac-dmx-cli list widgets, USB identity, who holds them +// ac-dmx-cli info serial number + firmware + DMX timing +// ac-dmx-cli set 510=255 511=0 512=0 channels (1-based; ranges 1-3=255) +// ac-dmx-cli rgb 255 0 0 [--at 1] 3-channel fixture at an address +// ac-dmx-cli fill 255 every slot +// ac-dmx-cli blackout every slot to 0 +// ac-dmx-cli sweep [--from 1 --to 512 --ms 300 --width 1] +// walk one lit channel — find the +// fixture's address by watching it +// ac-dmx-cli cycle [--at 1 --ms 600] red/green/blue/white/off — proves +// channel order +// ac-dmx-cli strobe [r g b] [--at 1 --hz 10 --duty 0.5] +// hard on/off — how sharp can the +// fixture flash? +// ac-dmx-cli desk [--at 1,7,13 --names R,G,B,A,W,UV --slew 1 --link] +// terminal fader desk: arrows move +// sliders, moves glide, all live; +// several fixtures on one screen +// ac-dmx-cli stdin lines of `510=255 …` / `rgb r g b` +// / `fill v` / `off`, held live +// ac-dmx-cli raw