Monoprice/McLELLAND whole-home audio amplifier serial to MQTT bridge controller.
The main component of this project is mwha2mqttd
, a background daemon that communicates with various models of multi-zone whole-home audio amplifiers via RS232,
enabling status enquiry and remote control of these amplifiers via MQTT.
mwha2mqttd
periodically polls the connected amp(s) for zone status.
When zone attributes (e.g., volume) change the new values are published to MQTT topics.
Clients can adjust zone attributes by publishing values to MQTT topics.
mwha2mqttd
subscribes to these topics and will communicate with the amp to adjust the zone(s).
See Topics below for details.
The project has been rewritten in Rust!
The old Python version can be found on the python
branch.
- Zone attribute published and adjustable over MQTT.
- Communication via physical TTY or COM port (such as a USB<->RS232 adapter) or raw serial-over-TCP (RFC2217 not supported).
- Shairport Sync (AirPlay) volume control integration.
- A basic cli client tool (
mwha-cli
). - A GUI mixer client.
- Automatic HomeKit and HomeAssistant integration.
- Automatic serial baud-rate detection and negotiation (for physical ports) (code is there, but doesn't work).
- MQTT SRV support.
- Example systemd service files.
- Packaging/install scripts for various distros.
Manufacturer | Model | Compatibility | Notes |
---|---|---|---|
Monoprice | MPR-6ZHMAUT (10761) | Compatible | Equivalent to MAP-1200HD. Product Page, Manual |
McLELLAND | MAP-1200HD | Unconfirmed | OEM. Product Page |
McLELLAND | MAP-1200WE/MAP1200EW | Unconfirmed | OEM. Product Page |
DaytonAudio | DAX66 | Unconfirmed | Product Page, RS232 Commands |
OSDAudio | NERO MAX12 | Unconfirmed | Product Page |
Texonic | A-M600 | Unconfirmed | Product Page |
Rave Technology | RMC-66A | Unconfirmed | Product Page, Manual |
Soundavo | WS66i | Unconfirmed | Product Page, Manual |
Amps listed as "unconfirmed" are those that haven't yet been validated as fully compatible with mwha2mqtt
.
These amps list RS232 control codes in their instruction manuals that match the MAP-1200HD
and/or have a similar appearance (same chassis, ports and zone keypads).
Pull requests to update this table would be appreciated once mwha2mqtt
is confirmed working with these amps.
mwha2mqttd
has various settings that are set by a TOML configuration file.
The default config file shows all the available settings and documentation is provided as comments.
The location and name of this config file varies depending on how mwha2mqtt is installed.
On most Linux-based systems, packaged versions of mwha2mqttd
reads its configuration from /etc/mwha2mqttd.conf
.
The topic names below are shown with the prefix mwha/
.
This prefix can be changed in the mwha2mqttd
configuration file (see the mqtt.url
option)
In the topic names below <a>
represents a placeholder for value a
(the <
and >
characters are not present in the topic name).
For example source/<i>
where i
= 1 results in a topic name source/1
.
Messages sent on topics are JSON encoded.
The JSON data type of the message clients should expect to send/receive on a particular topic is noted in the Data Type column.
Integer
is a JSON Number
that only has an integer component.
The following topics are for clients to receive metadata and updates about the configured amps, zones and sources.
Publishing messages to these topics is handled by mwha2mqttd
.
Any messages published by other clients will be ignored by mwha2mqttd
Messages published to these topics by mwha2mqttd
will have their retain flag set.
A message to each topic will be published once when mwha2mqttd
starts, then whenever a zone attribute changes (after a successful
status query to the amp).
Topic | Data Type | Description |
---|---|---|
mwha/connected |
Integer | mwha2mqttd connected status.0 = not connected/not running.2 = connected to MQTT & serial. |
mwha/status/amp/model |
String | Amplifier model, as defined in the config. |
mwha/status/amp/manufacturer |
String | Amplifier manufacturer, as defined in the config. |
mwha/status/amp/serial |
String | Amplifier serial number, as defined in the config. |
mwha/status/source/<source-id>/<attribute> |
Various | Source status and metadata. See Source Attribute Topics below for details. |
mwha/status/zones |
String array | An array of configured zone IDs. Clients can use this to determine which zone topics are valid. |
mwha/status/zone/<zone-id>/<attribute> |
Various | Zone status and metadata. See Zone Attribute Topicsbelow for details. |
The following topics are for clients to alter the attributes of configured zones.
Publishing a message to topic for an unconfigured zone is a no-op. Invalid values will be logged but are otherwise a no-op.
Topic | Data Type | Description |
---|---|---|
mwha/set/zone/<zone-id>/<attribute> |
Various | Zone adjustment. See Zone Attribute Topics below for details. |
Source metadata and attribute updates are published by mwha2mqttd
to the mwha/status/source/<source-id>/<attribute>
topics.
source-id
in the topic is the source ID. Valid source IDs are 1
through 6
(inclusive).
attribute
in the topic is a source attribute name from the table below.
Attribute | Data Type | Description |
---|---|---|
name |
String | Source name, as defined in the config. |
enabled |
Boolean | Source enabled state. Sources can be marked as disabled in the config. This is used as a hint to clients that the source isn't available. How clients reflect this is up to the client. All sources can always be selected from zone keypads. |
Zone metadata and attribute updates are published by mwha2mqttd
to the mwha/status/zone/<zone-id>/<attribute>
topics.
Clients can adjust certain zone attributes by publishing messages to the mwha/set/zone/<zone-id>/<attribute>
topics.
For the meaning of <zone-id>
and <attribute>
, see Zone IDs and Zone Attributes.
Note: Zones must be first configured in the config file before mwha2mqttd
will publish status and handle adjustments for them.
Sending adjustments to an unconfigured zone is a no-op.
The mwha/status/zones
topic will contain a list of configured zone IDs.
It is recommended that clients subscribe to this topic to discover the list of configured/active zones.
<zone-id>
in the topic is a 2-digit zone identifier in the format AZ.
The first digit A is the amplifier number, and valid values are 1
through 3
(inclusive), or 0
(see below).
The second digit Z is the zone number on amplifier A, and valid values are 1
through 6
(inclusive), or 0
(see below).
See the table below for a full list of valid zone IDs.
Zone IDs refer to physical zones unless their ID contains a 0
which instead refers to a virtual zone.
ID 00
is a virtual zone representing all zones (aka "the system").
No attribute status execpt name
will be reported for this zone. However, adjustments sent to this zone will adjust all zones on every amp simultaniously.
IDs 10
, 20
, and 30
are virtual zones representing all zones on amp 1
, 2
and 3
(respectively).
No attribute status execpt name
will be reported for these zones. However, adjustments sent to these zones will adjust all zones on amp A simultaniously.
ID | Zone Type | Attr. Status Updates | Description |
---|---|---|---|
11 .. 16 |
Physical | All attributes | Zones on amp 1 (Master position on the selector switch on the rear of the amp). |
21 .. 26 |
Physical | All attributes | Zones on amp 2 (Slave 1 position on the selector switch on the rear of the amp). |
31 .. 36 |
Physical | All attribute | Zones on amp 3 (Slave 2 position on the selector switch on the rear of the amp). |
00 |
Virtual | name only |
"System" zone. Adjusts all zones on all amps. |
10 |
Virtual | name only |
Amp 1 zone, adjusts all zones on amp 1. |
20 |
Virtual | name only |
Amp 2 zone, adjusts all zones on amp 2. |
30 |
Virtual | name only |
Amp 3 zone, adjusts all zones on amp 3. |
<attribute>
in the topic is a zone attribute name from the table below.
In the table below, attributes marked as RO cannot be adjusted.
Updates for these attributes will be published on the status/
topic. However, trying to adjust them via the set/
topic is a no-op.
Attributed marked R/W can be adjusted via the set/
topic.
Attribute | Data Type | Details | |
---|---|---|---|
name |
String | RO | Zone name, as defined in the config. |
public-announcement |
Boolean | RO | Zone public announcement status. When a zone is in PA mode it will play audio from source 1. true = zone is in PA mode (the PA 12V trigger is pulled high).false = zone is normal. |
power |
Boolean | R/W | Zone power status.true = zone powered on.false = zone powered off. |
mute |
Boolean | R/W | Zone mute status.true = zone is muted.false = zone is un-muted. |
do-not-disturb |
Boolean | R/W | Zone do not disturb status.true = DND enabled.false = zone is un-muted. |
volume |
Integer | R/W | Zone volume. Value ranges from 0 to 38 , inclusive. |
treble |
Integer | R/W | Zone treble adjustment. Value ranges from 0 to 14 , inclusive.0 = maximum treble reduction.7 = flat (no adjustment).14 = maximum treble boost. |
bass |
Integer | R/W | Zone bass adjustment. Value ranges from 0 to 14 , inclusive.0 = maximum bass reduction.7 = flat (no adjustment).14 = maximum bass boost. |
balance |
Integer | R/W | Zone balance adjustment. Value ranges from 0 to 20 , inclusive0 = 100% left.7 = centre (no adjustment).14 = 100% right. |
source |
Integer | R/W | Zone active source. Value ranges from 1 to 6 , inclusive.This value can be mapped to the source metadata topics ( source/<i> ) for source info. |
keypad-connected |
Boolean | RO | Zone keypad connected status.true = zone keypad connected.false = zone keypad disconnected. |
mwha2mqttd
can integrate with Shairport Sync via MQTT, which allows for volume control of zone(s) from AirPlay clients (such as iOS or macOS). When one or more zones are listening to a designated Shairport Sync source, volume control commands from AirPlay client(s) of that source change the volume of the zones listening to that source.
For example: a PC running Shairport Sync has its S/PDIF optical out connected to the Source 6 input on the back of the master amp, and this source is configured in the mwha2mqttd
configuration as a Shairport Sync source (shairport.volume_topic
is specified). Zones 1 and 4 are listening to Source 6 and an iOS client plays music over AirPlay to the Shairport Sync speaker, hence Zones 1 and 4 hear the music playing from the iOS device. The user adjusts the speaker volume on the iOS device and Shairport Sync publishes volume change metadata MQTT messages. mwha2mqttd
receives these messages and adjusts the volume of Zones 1 and 4 to match the iOS clients' specified volume.
To use this feature, Shairport Sync must be compiled with MQTT support, and MQTT metadata must be enabled in the shairport-sync.conf
configuration file. When enabled, Shairport Sync will publish metadata about the current AirPlay stream, including volume level, onto MQTT topics.
-
Connect the hardware, so that the audio output of a device running Shairport Sync is connected to a source on the amp.
-
Compile Shairport Sync with MQTT support and configure it to publish metadata over MQTT.
See the Shairport Sync MQTT documenation for more info.
Either the
publish_raw
orpublish_parsed
(or both) option may be used in the Shairport Sync config, as the same volume metadata is published for either option, but note that the volume topic name differs. See below.Hint: It's recommened to set the Shairport Sync
ignore_volume_control
option to"yes"
to disable the built-in software mixing and hardware audio device volume control. Explicitly set the hardware device volume to 100% (0 dB) and let the amp do the volume adjustment.Note: if you're running multiple instances of Shairport Sync, ensure that the
topic
configuration option is unique for each instance.Example partial
shairport-sync.conf
:general = { ⋮ name = "Whole-home Audio (Source 6)"; ignore_volume_control = "yes"; ⋮ } mqtt = { enabled = "yes"; topic = "shairport-ch6" publish_parsed = "yes"; ⋮ }
-
Configure source(s) in
mwha2mqttd.conf
to have the appropriateshairport.volume_topic
to match the Shairport and hardware configuration.When Shairport Sync is configured with:
publish_parsed = "yes"
, then thevolume_topic
should be of the form<shairport-topic>/volume
.publish_raw = "yes"
, then thevolume_topic
should be of the form<shairport-topic>/pvol
.
(where
<shairport-topic>
is the value ofmqtt.topic
in the Shairport config)Example partial
mwha2mqttd.conf
:[amp.sources] ⋮ 6 = { name = "AirPlay", shairport.volume_topic = "shairport-ch6/volume" }