Dependency-free Python client + CLI for the Biamp Nexia/Audia Text Protocol (telnet control)
Project description
biamp-ntp
A tiny, dependency-free Python client and CLI for the Biamp Nexia / Audia Text Protocol — the line-based control protocol those DSPs expose over telnet (TCP port 23, no authentication).
Works with the Nexia family (CS / PM / SP / VC / TC) and Audia (FLOW, …). Pure standard library, so it runs anywhere Python does — macOS, Linux, a Raspberry Pi, inside Home Assistant, wherever. No vendor software or Windows box needed for day-to-day control.
Scope: telnet transport only (TCP port 23). The same NTP/ATP grammar also runs over RS-232, but this library doesn't drive serial ports — put the device on the network or use a serial-to-TCP bridge.
Extracted and generalized from a working Nexia PM sub-controller. The fiddly parts — telnet IAC stripping, reply framing, and the instance-ID drift problem — are already solved here.
Install
pip install biamp-ntp
# or straight from GitHub / a local checkout:
pip install git+https://github.com/biamp-ntp/biamp-ntp
pip install -e .
CLI
# read the device number (needed as <dev> in every command; usually 1)
biamp-ntp --host 192.168.1.199 devid
# discover instance IDs — the #1 thing you need (see "Instance IDs" below)
biamp-ntp --host 192.168.1.199 scan OUTLVLPM # sweep output-level blocks
biamp-ntp --host 192.168.1.199 scan MMLVLOUT # sweep matrix outputs
# read / write an attribute: <attr> <instance> <idx...> [value]
biamp-ntp --host 192.168.1.199 get OUTLVLPM 8 5 # output block inst 8, ch 5
biamp-ntp --host 192.168.1.199 set OUTLVLPM 8 5 -6.0 # set ch 5 to -6 dB
biamp-ntp --host 192.168.1.199 set OUTMUTEPM 8 5 1 # mute ch 5
# recall a preset (system-wide) and nudge levels
biamp-ntp --host 192.168.1.199 recall 1001
biamp-ntp --host 192.168.1.199 inc OUTLVLPM 8 5 2 # +2 dB
biamp-ntp --host 192.168.1.199 dec OUTLVLPM 8 5 2 # -2 dB
# escape hatch: send any raw command line
biamp-ntp --host 192.168.1.199 raw GET 0 DEVID
Library
from biamp_ntp import BiampNTP, scan, protocol as p
with BiampNTP("192.168.1.199") as dsp:
print(dsp.device_id()) # -> 1
# find the output block's instance ID (don't hardcode it)
for inst, val in scan(dsp, p.OUTPUT_LEVEL_PM):
print("output block at instance", inst)
level = dsp.get_float(p.OUTPUT_LEVEL_PM, 8, 5) # ch 5 level, dB
dsp.set(p.OUTPUT_LEVEL_PM, 8, 5, -6.0) # set ch 5 to -6 dB
dsp.set(p.OUTPUT_MUTE_PM, 8, 5, True) # mute (bool -> 1)
dsp.inc(p.OUTPUT_LEVEL_PM, 8, 5, 2) # nudge ch 5 up 2 dB
dsp.recall_preset(1001) # system-wide preset
command() is thread-safe and reconnects automatically if the socket drops.
Instance IDs — read this
Every block in a Biamp design has an instance ID, used in every GET/SET. The catch: instance IDs are assigned at compile time and renumber whenever the design is recompiled and re-pushed from the Windows software. So the numbers in your .nex file go stale, and hardcoding them will silently break after an edit.
Always discover them live:
biamp-ntp --host <ip> scan <ATTR>
Only a real block of that type answers; everything else returns -ERR:XACTION ERROR. Use --range 1-400 for large designs.
Common attributes
| Block | Level | Mute | Other | Index |
|---|---|---|---|---|
| PM input | INPLVLPML |
INPMUTEPML |
INPGAINPML |
input |
| PM output | OUTLVLPM |
OUTMUTEPM |
OUTINVRTPM (polarity) |
output ch |
| Generic output | OUTLVL |
OUTMUTE |
output ch | |
| Matrix mixer | MMLVLOUT / MMLVLIN |
MMMUTEOUT |
MMLVLXP (crosspoint) |
out / in |
| Level (fader) | FDRLVL |
FDRMUTE |
channel | |
| Device | DEVID (GET 0 DEVID) |
— |
Levels are dB; mute/invert are 0/1. Crosspoints (MMLVLXP/MMMUTEXP) take two indices: input row, output column. Any attribute string works with get/set — the table is just the common ones. See biamp_ntp/protocol.py.
Protocol notes (the gotchas)
- Grammar:
GET <dev> <ATTR> <inst> <idx...>→ value;SET <dev> <ATTR> <inst> <idx...> <value>→+OK. Errors:-ERR:SYNTAX,-ERR:XACTION ERROR. - Telnet IAC: the server sends IAC negotiation bytes on connect and can interleave them with replies — this library strips them.
- Reply timing: replies dribble out just after the command echo, so a single immediate
recv()catches a partial frame. The client reads until a complete reply line (+OK,-ERR:..., or a value) arrives, then paces the next command bypace=(default 50 ms). Don't setpace=0blindly: at full rate a real Nexia prepends an undocumented-ERR:# 0x16complaint to each reply and falls behind. The client treats-ERR:#lines as timing complaints (prefers the line that follows, returns the complaint only if nothing else arrives).settle=only paces the one-off banner drain at connect. - One client at a time: the telnet server is happiest single-threaded;
command()serializes on a lock.
Development
pip install -e .
python -m unittest discover -s tests -v
The unit tests need no hardware (they cover parsing / IAC / formatting).
License
MIT.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file biamp_ntp-0.2.0.tar.gz.
File metadata
- Download URL: biamp_ntp-0.2.0.tar.gz
- Upload date:
- Size: 16.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.9.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b170aded72ac017b57d73452a438a7600a5e83b1c9a27c865e118c3680553f5f
|
|
| MD5 |
1cccd5115a0881c188b56809a6ba558e
|
|
| BLAKE2b-256 |
10ff1af5b1f6b96159f7f56cce2b76bcb04928ced480cecaf5d3096d0360bff2
|
File details
Details for the file biamp_ntp-0.2.0-py3-none-any.whl.
File metadata
- Download URL: biamp_ntp-0.2.0-py3-none-any.whl
- Upload date:
- Size: 12.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.9.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9a9c86a8089a8e1418cf8c981a3f0badbc5c4faa5d3b2cc84b55f86ee6932f96
|
|
| MD5 |
db988c24215fa794c2e35bb5c902619c
|
|
| BLAKE2b-256 |
3c6f0019e3a618a3a8afb2b40b248311ac51c43ef1b621ec92629cd783f241e5
|