AudioControl Multi-Zone Amplifier
The audiocontrol driver controls AudioControl networked multi-zone matrix amplifiers (Director M-series, D2800, D4600). Telnet ASCII commands on port 23 drive the amp and poll zone status via SYSTEMstat?.
Prerequisites
- Amplifier on the same LAN as GEM, with a static IP or DHCP reservation.
note
The /json/signalprocessing.json endpoint is only used once at connect for model detection — its body is too large for the device HTTP server to serve reliably on multi-zone amps (truncates around 24 KB), so all live zone state comes over telnet.
Setup
- System → Devices: add a device with driver
audiocontrol. Setip. Defaultportis 23. - Save and enable. On connect the driver:
- probes
/json/signalprocessing.jsonforampModel/ampNameand writes them tomodel/amp_name. If the JSON endpoint is unreachable it falls back toSYSTEMstat?over telnet, parsing theAMPLIFIER NAME:line. - starts polling the amp every
sync_intervalms (default 5000) viaSYSTEMstat?. Each zone row in the response auto-creates a GEM zone the first time it is seen, under theavsubsystem. Wired zones get numeric addresses (1..N); Digital Out zones get letter addresses (a,b).
- probes
- You don't have to wait for the first poll — run the
sync_zonescommand to force an immediateSYSTEMstat?sweep and create any missing zones now. It reports how many zones itcreatedversus how many alreadyexisting. - Run
sync_av_zonesto create matching AV Zone rows for the main (numeric) zone outputs (so each shows up in the AV routing graph). Existing AV Zone rows are left alone. Digital Out zones are skipped — they're driven by theDXOcommands rather thanZ[address]templates, and their always-on power state would otherwise trip AV power divergence detection. If a Digital Out already has an AV Zone row from an earlier sync, delete it (or setpower_reconcile=falseon the zone) to stop divergence alerts.
Attributes
Device — required
| Attribute | Type | Description |
|---|---|---|
ip | string | LAN IP of the amplifier. |
Device — optional
| Attribute | Type | Default | Description |
|---|---|---|---|
port | int | 23 | Telnet port. |
zone_count | int | 8 | Number of output zones. |
sync_interval | int (ms) | 5000 | Zone status poll cadence. |
Reflected device attributes
| Attribute | Source |
|---|---|
model | ampModel from one-shot JSON probe, or AMPLIFIER NAME: from SYSTEMstat?. |
amp_name | ampName from the one-shot JSON probe (user-renamable). |
global_temp, global_voltage, global_protection, thermal_protection | Parsed from SYSTEMstat? lines. |
active_zones | JSON list of the names of zones currently powered on, recomputed after each SYSTEMstat? poll settles (read-only at-a-glance summary of what the amp is driving). |
last_error | Last poll error message. |
Zone
- Address required: yes.
- Address format: numeric
1..Nfor wired zones,a/bfor Digital Out zones.
The driver writes the following onto each polled zone:
| Attribute | Type | Source |
|---|---|---|
power_state | string | on / off |
mute_state | string | on / off. The regular status poll does not report mute, and there is no dedicated mute-query command, so this only populates if you issue a raw mute query through passthrough (e.g. Z1mute?). |
volume | int | Current zone volume (0–100 scale). |
input | string | Raw source label the zone is currently on, exactly as the amp reports it — e.g. MX13 & 13 (matrix channel pair), DXa (Digital In A), Local. This is the source label, not a numeric id. |
signal_sense | string | on / off |
Commands
Power & status
| Command | Args | Notes |
|---|---|---|
power_on / power_off | — | Whole-amp power. |
query_status | — | Issues SYSTEMstat?; populates global telemetry attributes. |
query_voltage / query_temp / query_protect / query_short | — | Single-value queries. |
query_groups / query_amp_name | — | |
query_zone_on / query_zone_off / query_input / query_group_input | — | |
sync_zones | — | Force a zone status poll now and auto-create any missing GEM zones. |
sync_av_zones | — | Walk the main (numeric) zone outputs and ensure a matching AV Zone row exists. Digital Out zones are skipped. |
all_zones_on / all_zones_off | — | |
mute_all / unmute_all | — | Mute or unmute every zone at once. |
Zone control
| Command | Args | Notes |
|---|---|---|
zone_on / zone_off | address | Per-zone power. |
volume | address, volume | Set absolute zone volume. The amp reports volume on a 0–100 scale. |
volume_up / volume_down | address | Step the zone volume up/down by one increment. |
mute_on / mute_off | address | |
set_bass / set_treble | address, level | |
bass_up / bass_down / treble_up / treble_down | address | |
loudness_on / loudness_off | address | |
zone_signalsense_on / zone_signalsense_off | address | Per-zone signal sense. |
all_signalsense_on / all_signalsense_off | — | Global. |
get_volume | address | |
recall_eq | address, preset (1-6) | |
query_zone_stat / query_zone_eq / query_zone_bass / query_zone_treble / query_zone_loudness / query_zone_input / query_zone_signalsense / query_zone_power | address | |
get_zone_input | address | Alias of query_zone_input. |
Source routing
| Command | Args | Notes |
|---|---|---|
set_source | address, source_id | M-series numbered local source (legacy). |
set_source_local | address | D2800 / D4600: switch zone to its Local input. |
set_source_bus_a | address | D2800 / D4600: switch zone to Bus A. |
set_source_bus_b | address | D2800 / D4600: switch zone to Bus B. |
set_input | address, input (1-8) | Route a matrix (analog) source channel pair (1-2 … 15-16) to a zone. |
set_digital_input | address, input (a/b) | Route Digital Input A or B to a zone. |
set_dante_input | address, input (raw suffix) | Route a Dante source by raw source suffix — e.g. V0CS3 (Dante input 3 via Dante Controller), V1CS2 (AudioControl Dante amp source), MX5 (matrix), DXa (digital). Appended after Z[n]source. |
set_digital_output | address (a/b), input (MX1–MX8, DXa, DXb, V0CSx, …) | Route a source to Digital Output A or B by raw source suffix. |
set_source_matrix | address, source_id (1-8) | M6800D / Director: route a matrix (analog) source channel pair (1-2 … 15-16) to a zone. |
set_source_digital | address, digital_input (a/b) | M6800D / Director: route Digital Input A or B to a zone. |
set_source_dante | address, dante_id, input_index | M6800D / Director: route a Dante source to a zone. dante_id 1-8 = AudioControl Dante amps (0 for non-AudioControl sources via Dante Controller); input_index 1-8 stereo pair from amp web UI. Digital inputs cannot be Dante-routed. |
set_dxo_source_matrix | output (a/b), source_id (1-8) | M6800D / Director: route a matrix channel pair to Digital Output A or B. |
set_dxo_source_dante | output (a/b), dante_id, input_index | M6800D / Director: route a Dante source to Digital Output A or B. |
query_dxo_input | output (a/b) | Query the source currently routed to Digital Output A or B. |
Lipsync (D4600 zones 5-8)
| Command | Args | Notes |
|---|---|---|
lipsync_up / lipsync_down | address | Step delay by 5 ms. |
set_lipsync | address, steps (0-19) | 5 ms per step. |
Groups
| Command | Args | Notes |
|---|---|---|
group_zone | address, group_id | Add zone to a group. |
ungroup_zone | address, group_id | Remove a zone from a group. |
group_volume | group_id, volume | Set every zone in a group to a volume. |
group_mute / group_unmute / group_on / group_off | group_id |
Escape hatch
| Command | Args | Notes |
|---|---|---|
passthrough | input | Send a raw telnet command to the amp. The string is transmitted verbatim. Useful for one-off diagnostics or commands not yet wrapped by the driver. |
Known quirks
- The amp does not push state changes — front-panel volume / source changes only appear after the next poll.
- Digital Out zones use letter addresses (
a,b); wired zones use numeric ids. - AV zones aren't auto-created on connect — run
sync_av_zonesonce to populate them (main zone outputs only; Digital Out zones are excluded). - M-series uses numbered
set_source; D2800 / D4600 use the Local / Bus A / Bus B variants. - Garbage commands echo back as
xx<cmd>xxand are logged as warnings — useful for catching typos in custom macros.
Troubleshooting
| Symptom | Check |
|---|---|
| Zone state diverges from front panel | Lower sync_interval or run sync_zones manually; the amp does not push events. |
| Zone physically on but GEM shows it off (e.g. an off command lost to a network blip) | Self-heals: the driver's power_state poll feeds GEM's physical power reconciliation, which restores the zone's source (macros suppressed) so the off controls return. Opt out per zone with power_reconcile = false. |
| Model never populated | One-shot JSON probe failed; check http://<ip>/json/signalprocessing.json in a browser, or watch logs for the telnet fallback. |
sync_zones reports errors | Confirm the av subsystem exists in GEM — auto-created zones live under it. Also confirm telnet on port 23 is reachable. |