Coastal Source CRS / Powersoft Mezzo
Control a Powersoft Mezzo DSP amplifier — Mezzo 322 / 324 / 602 / 604 in both the A (amplifier) and AD (amplifier + DSP) variants — and the Coastal Source CRS-series outdoor amplifiers that use the same engine (the CRS600/4 is a Mezzo 604). The driver exposes per-channel volume and mute across the four amplifier channels, stereo channel pairing, a global standby, front-panel identify, and live metering (per-channel output voltage and mains voltage).
Control is the amplifier's native binary protocol over UDP port 8002. The unit also runs an HTTP service on port 80, but that is only an opaque ArmoníaPlus configuration-staging buffer with no readable control API — it is not used by this driver, and its presence does not indicate that control is reachable. Verify UDP 8002 specifically.
Prerequisites
- A Powersoft Mezzo or Coastal Source CRS amplifier reachable from the GEM server on UDP port 8002 — same LAN, or a routed / VPN path that forwards UDP (not just TCP).
- A static or DHCP-reserved IP for the amplifier. The factory network setting is DHCP/AutoIP; find the address in ArmoníaPlus or with a network scan.
Setup steps
- Note the amplifier IP.
- In /admin/devices, add a device with driver Coastal Source CRS / Powersoft Mezzo.
Enter the IP; the port defaults to
8002. Enable the device. - On connect the driver reads model, serial, firmware and full channel state, then polls state and metering every 15 seconds.
- Zones are created automatically — under the av subsystem — as soon as the model is
read (the channel count comes from the model). With Stereo Pairs on (the default) that
is one zone per pair; turn it off first if you want four independent mono channels. To
force it, run the
sync_zonescommand.on/off,set_volumeand the mute commands then act on each zone (zone.address=1–4).
Zones
The driver auto-creates GEM zones the first time it reads the model on connect — the channel count is derived from the model (Mezzo 604 / 324 = 4 channels, 602 / 322 = 2).
With Stereo Pairs on (the default) it creates one zone per pair, addressed by the pair's
first channel: 1 labelled Channels 1-2 and 3 labelled Channels 3-4. With Stereo Pairs
off it creates one zone per channel: 1, 2, 3, 4.
Creation is idempotent and honors disabled zones: a channel you delete or disable is not
recreated, so trim the channels you do not use. Set the Channel Count device attribute
(0 = auto) to override detection. Re-run sync_zones any time to (re)create missing zones.
Stereo pairs
Stereo Pairs is a device attribute, on by default. With it on, a command addressed to
a channel also applies to the next channel up — address 1 drives channels 1 and 2,
address 3 drives channels 3 and 4. Both sides of a pair therefore always carry the same
volume and mute, and they cannot drift apart: volume_up and volume_down move both to the
same absolute level rather than adding a delta to each channel's own value.
The topmost channel has nothing above it, so on a four-channel amp address 4 stays mono
whether or not pairing is on.
Turn Stereo Pairs off to drive four independent mono channels. If you turn it off after
the paired zones were created, run sync_zones again to add the missing per-channel zones —
existing zones are never deleted, so check the zone list afterwards and remove any that no
longer match your wiring.
Addressing
Per-channel commands resolve their channel in this order:
av_zone.address— when the AV zone's address names an amplifier channel (1–4), it wins. An address that is not a channel number (a matrix-style output address, say) is skipped rather than treated as an error.- The address passed with the command — for a plain zone command the server fills this
from
zone.address. zone.addressread directly.
Commands
Per-channel commands take the zone address (channel 1–4; with Stereo Pairs on, the first
channel of the pair):
| Command | Effect |
|---|---|
on / off | Emulated power — unmute / mute the channel (the amp has no per-channel power). |
set_volume (level 0–100) | Set the channel's DSP user gain, mapped onto the dB window. |
volume_up / volume_down | Step the channel volume by 5. |
mute_on / mute_off / mute_toggle | Mute control (mute_toggle uses the last polled state — there is no native toggle). |
Device-level commands take no address:
| Command | Effect |
|---|---|
standby_on / standby_off | Standby the whole amplifier / wake it. |
identify | Blink the front-panel LED. |
get_status | Force a full state + metering read. |
sync_zones | Create the amplifier's GEM zones under the av subsystem — one per stereo pair, or one per channel with Stereo Pairs off (runs automatically on connect; idempotent and honors disabled zones). |
get_zones | Enumerate the amplifier zones and the channels each one drives. |
Volume mapping
The per-channel "volume" is the DSP user gain trim, not an input-source level. It is a
float32 linear multiplier on the wire where linear = 10^(dB/20) (unity 0 dB = 1.0). GEM
0–100 maps onto a dB window set by the device attributes Volume Min (dB) and Volume Max
(dB) — default −60 dB … 0 dB, so 100 = unity. Raise Volume Max (dB) above 0 if
you need boost above unity, or narrow the window to match the useful range for your speakers.
Behaviour notes
- One global standby, not per-channel power.
on/offon a zone unmute/mute that channel (unmuted = audible = on);standby_on/standby_offcontrol the whole unit. - Writes are confirmed. The amplifier echoes the address of every write it accepts. The driver waits ~500 ms for that echo, retransmits once if it does not arrive, and logs an unconfirmed write. A command that could not be put on the wire at all returns an error, not a success, and no optimistic attribute is written for it — so a value shown in GEM is one the amplifier was actually told about. The 15-second poll still reconciles against hardware truth, which is how ArmoníaPlus or front-panel changes are picked up.
- Standby and identify are write-only. The amplifier declines reads of both, so GEM cannot
see a standby entered from the front panel or ArmoníaPlus; the
standbyattribute reflects what GEM last commanded. The driver still asks for standby on every poll, so a firmware that starts answering will reconcile automatically with no configuration change. - Heatsink temperature is not published. The register available to the driver returns a constant 0 on a warm running amplifier, so it is not the real one — publishing it would make a thermal trigger look armed while being unable to fire. Mains voltage and per-channel output voltage read correctly.
- Metering is read-only telemetry. Per-channel output voltage lands on each zone
(
output_voltage) and mains voltage on the device (mains_voltage). These read idle / near-zero when the amplifier is passing no signal. A paired zone carries the output voltage of its first channel — the second half of the pair has no zone of its own to land on. - Model string identifies the unit (e.g.
DMZO604_ND). A and AD variants speak the same protocol; AD carries the DSP. - Only the amplifier's own address is believed. The control protocol is unauthenticated UDP, so
a datagram whose source is not the device's configured
ipis dropped without being parsed — nothing else on the network can write zone volume, mute state, or output voltage into GEM. The first datagram from an unexpected source is logged once (ignoring datagram from unexpected source) and the rest are silent, so a chatty neighbour cannot fill the log. If the amplifier's address changes, update the deviceip— state stops updating until you do.
Troubleshooting
| Symptom | Check |
|---|---|
| Device never connects / no state | Confirm UDP 8002 reachability specifically — the HTTP :80 service being up does not mean control works. A firewall or a TCP-only tunnel will silently drop UDP control. |
| Volume feels coarse or off-scale | The wire value is dB, not linear 0–100. Adjust Volume Min/Max (dB) so the mapped window matches your speakers. |
| Front-panel / ArmoníaPlus changes not reflected | State comes from the 15-second poll (the amp sends no unsolicited updates). Lower Status Poll Interval for faster convergence. |
| Commands appear to send but no state ever returns | Check the log for ignoring datagram from unexpected source. The amplifier is replying from an address other than the device's ip — usually a changed DHCP lease or the wrong address on the device row. |