minidsp-dash
A phone-friendly web remote for miniDSP devices — presets, master gain, mute, source switching, and live input/output meters — in a single dependency-free Python file on top of the minidsp CLI (minidsp-rs).
miniDSP's own config tools are desktop apps; this gives you the day-to-day controls on your phone. Add it to your home screen and it behaves like an app (dark UI, safe-area aware, auto-reloads itself when you bump APP_VERSION).
- Presets — 4 buttons, labels you choose
- Master gain — big slider with live dB readout (cut-only, floor configurable)
- Mute — one thumb-sized toggle
- Source — analog / toslink / usb (configurable)
- Meters — live input/output levels at 8 Hz with proper ballistics (instant attack, ~1.5 s decay, peak-hold markers) when
minidspdis running; graceful ~1.5 s fallback via the CLI when it isn't - Zero dependencies — Python 3.8+ stdlib; the only requirement is a working
minidspCLI
Setup
- Install minidsp-rs and check
minidspprints your device's status. - Run the dashboard, either from a checkout:
python3 minidsp_dash.py
# open http://<host>:5390 from your phone
or from PyPI, which puts a minidsp-dash command on your PATH:
pip install minidsp-dash
minidsp-dash
Both run the same single file and pull in nothing else — the package has no
Python dependencies. The minidsp CLI is the only requirement, and it is not a
Python package, so it has to be installed separately either way.
Configuration is all environment variables:
PRESET_NAMES="Flat,EDM,Movies,Late Night" \
SOURCES="analog,toslink,usb" \
GAIN_MIN=-60 \
DASH_TOKEN=some-secret \
DASH_PORT=5380 \
python3 minidsp_dash.py
| Variable | Default | Meaning |
|---|---|---|
MINIDSP_BIN |
minidsp (PATH) |
Path to the CLI; point it at a wrapper script to use minidsp --url against a remote minidspd |
DSPD_URL |
http://127.0.0.1:5380/devices/0 |
minidspd's HTTP API — the fast meter path (~7 ms/poll vs a CLI spawn). Meters run at 8 Hz through it and fall back to CLI status automatically when unreachable |
DASH_PORT |
5390 (5380 is minidspd's own HTTP API — avoid it) |
Listen port |
DASH_TOKEN |
(off) | If set, requests need ?t=<token> (open the page as http://host:5390/?t=<token>) |
PRESET_NAMES |
Preset 1..4 |
Comma-separated labels for the preset buttons |
SOURCES |
analog,toslink,usb |
Which sources to offer |
GAIN_MIN |
-60 |
Bottom of the gain slider (dB) |
Auth note: the token gates control of your DSP but travels in plain HTTP on your LAN. Fine for a home network; don't port-forward it to the internet.
Run at login (macOS)
Save as ~/Library/LaunchAgents/com.minidsp.dash.plist, then launchctl load it:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0"><dict>
<key>Label</key><string>com.minidsp.dash</string>
<key>ProgramArguments</key><array>
<string>/usr/bin/python3</string>
<string>/PATH/TO/minidsp-dash/minidsp_dash.py</string>
</array>
<key>EnvironmentVariables</key><dict>
<key>PRESET_NAMES</key><string>Flat,EDM,Movies,Late Night</string>
</dict>
<key>RunAtLoad</key><true/>
<key>KeepAlive</key><true/>
</dict></plist>
KeepAlive restarts the agent if it crashes, but not when you edit
minidsp_dash.py — the process keeps serving whatever it loaded at launch. After
editing, restart it explicitly:
launchctl kickstart -k gui/$(id -u)/com.minidsp.dash
Skipping that is a genuinely confusing bug to chase: the source on disk shows
a fix the running server has never loaded. If a symptom contradicts the code,
compare the process start time (ps -Ao pid,lstart | grep minidsp_dash.py) against
the file's mtime before debugging anything else.
On Linux, an equivalent systemd user unit works the same way.
How it works
The server shells out to the minidsp CLI for everything — status is parsed from the CLI's MasterStatus { ... } line plus the input/output level lines, writes are minidsp config N, minidsp gain -- -X.X, minidsp mute on|off, minidsp source <name>. No USB/HID code here, so anything minidsp-rs supports (2x4HD, Flex, SHD, DDRC-24, remote minidspd, ...) should work; presets/gain/mute/source are the common denominator.
The page polls /api/status every ~1.5 s; controls are optimistic (they render instantly and reconcile against device truth). Meters have their own fast path: /api/meters proxies minidspd's HTTP API (DSPD_URL) at 8 Hz, and the client applies meter ballistics — instant attack, ~1.5 s full-scale decay, a peak-hold marker that holds 1.5 s then falls. When minidspd isn't reachable the bars quietly revert to the ~1.5 s CLI numbers. APP_VERSION is stamped into the page and the status JSON — a stale cached client notices the mismatch and reloads itself once, which matters for iOS home-screen apps that cache aggressively.
Troubleshooting
- Meters sluggish? You're on the CLI fallback — check
minidspdis running andDSPD_URLpoints at it. - Device healthy but silent, inputs stuck at noise floor (~−86 dB)? A USB DAC feeding your analog inputs can wedge in a way that's invisible to the OS (streaming happily, nothing coming out). Two resets that fix it in practice: toggle the DSP's source away and back (
minidsp source usb && sleep 1 && minidsp source analog), and/or switch your computer's output device away and back to rebuild the USB stream. Check the DAC's front panel before blaming cables. - Meters legitimately read the noise floor when nothing is playing — silence at the inputs is not a fault. Verify against a playing source before concluding anything is broken.
Related projects
- minidsp-rs — the CLI/daemon this sits on
- minidsp-rs-hass — Home Assistant integration
- Sibling project: biamp-ntp — control Biamp Nexia/Audia DSPs from Python
Development
python3 -m unittest discover -s tests -v
The tests cover status parsing against canned CLI output; no hardware needed.
License
MIT.
Metadata
Release files for minidsp-dash 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| minidsp_dash-0.1.0.tar.gz | 13.2 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| minidsp_dash-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 26.0 kB
Release files / minidsp_dash-0.1.0.tar.gz
| Download URL | minidsp_dash-0.1.0.tar.gz |
|---|---|
| Size | 13.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
ae0fb0484e5e81cb12772f3d2e61215f80eeccf09e58f1bc9f435fb0bcd95436
|
|
BLAKE2b-256 checksum How to use checksums |
d93f4fedbcdc0799e880ec2844377f1d9f65ad22b6a2a2dc7823f98557b76dc0
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 22, 2026.
Transparency logRelease files / minidsp_dash-0.1.0-py3-none-any.whl
| Download URL | minidsp_dash-0.1.0-py3-none-any.whl |
|---|---|
| Size | 12.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
d44facc601895225bb8406a065a9c1ffcdec65ff2d68a4bda0b2707b3de36521
|
|
BLAKE2b-256 checksum How to use checksums |
e666d6563c0c4f305f939e5fe4ff69834b0a876bf366299bef9959e27a59ab12
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 22, 2026.
Transparency log