This is an interface that allows control of an HTD Lync whole-house audio system via MQTT. It interfaces to the Lync unit via its serial port (currently only over a TCP socket, not directly).
-
Prerequisites
- Node.js >= 4.2.6 (including npm).
- Lync6 or Lync12 connected to a serial to ethernet (TCP socket) bridge
-
Install:
sudo npm install -g htd2mqtt
-
Start:
htd2mqtt --help
- You will likely need to specify the TCP serial bridge's IP (
-b
) and port (-p
) - You can also specify the MQTT topic prefix with
-t
, including slashes (e.g.-t "home/htd"
).
- You will likely need to specify the TCP serial bridge's IP (
-
Example command line:
htd2mqtt -t "house/htd" -u "http://mqtt-server" -b "192.168.0.16" -p 2101
Topics take the form htd/status/<zone>/<item>
where <zone> is the zone number (1-12)
and <item> is one of the below items.
Note that updates/responses are not always sent by the device, such as when nothing has changed as a result of a command (e.g. changing zones to the same zone).
Power status of the zone, either ON
or OFF
.
Mute status of the zone, either ON
(muted) or OFF
(unmuted).
DnD (Do Not Disturb) status of the zone, either ON
or OFF
.
Current numeric source of the zone, from 1
through 18
.
Current numeric volume of the zone, from 0
(min) through 60
(max).
Current percentage volume of the zone, from 0
(min) through 100
(max).
Whether the zone exists 1
or not 0
.
Whether the keypad is attached 1
or not 0
.
Either on
, off
, or end
. These are currently untested.
Name of the zone, as a string.
Names of all the sources for this zone as a string, enumerated by <source> 1
through 18
. For example, htd/2/sourcename/11
would report the name of source 11 on zone 2.
Topics take the form htd/set/<zone>/<command>
where <zone> is the zone number from
0
through 12
and <command> is one of the below commands.
Note that a zone of 0
can often be used as a "broadcast" to send the same command to
all zones at once.
Set power state of a zone (1-12) or all zones (0), either On
or Off
(case
insensitive).
Set mute state of a zone (1-12) or all zones (0), either On
to mute or Off
to unmute
(case insensitive).
Set DnD state of a zone (1-12) or all zones (0), either On
or Off
(case
insensitive).
Change the current numeric source of a zone (1-12) or all zones (0), from 1
through 18
.
Note that sending this command to a zone that is off will turn it on.
Set the numeric volume of a zone (1-12), from 0
(min) through 60
(max). Using a zone
of 0 for changing all zones at once is not supported.
Note that strangeness occurs when setting the volume of a zone that is off. The keypad will turn on and show only the volume digits, even though the zone remains off.
Same as volume
, except it accepts volume as a percentage from 0
(min) through 100
(max).
Read-only connection status of the program:
2
when both the serial port and MQTT are connected.1
when only MQTT is connected (i.e. serial port is not).0
when the program exits or MQTT disconnects.
Force a manual update of values using one of the following payloads:
status
Basic zone status for all zones, including power, mute, volume, source, etc.zonenames
Reads all zone names.sourcenames
Reads all source names on all zones. Code is buggy, do not use!fullstatus
Full status of device, including zone and source names. Firmware is buggy, not recommended.all
The "safe" way to query all device status at once. Currently doesstatus
andzonenames
.
You can easily start this program on boot using systemd.
First, as root, create /usr/lib/systemd/system/htd2mqtt.service
with the following contents:
[Unit]
Description=Bridge from HTD Lync system to MQTT
Wants=network-online.target
After=network-online.target
[Service]
Type=simple
ExecStart=/usr/local/bin/htd2mqtt -t "htd" -u "http://mqtt-server" -b "192.168.0.16" -p 2101
Restart=always
User=<user>
Group=<group>
# Give a reasonable amount of time for the server to start up/shut down
TimeoutSec=300
[Install]
WantedBy=multi-user.target
Note: Be sure to edit the htd2mqtt command line args to match your setup as well as change the User and Group to what the program should run as.
Below are example OpenHAB item configurations for some of the basic functions. Note that msq
should
be replaced with the name used in your OpenHAB MQTT configuration. The Volume_Percent
item works
very well as a Dimmer item as built-in sitemap controls, Hue emulation, etc. can control it easily.
Switch Audio_Zone_All_Power "Whole House Audio Power" (Audio) {mqtt=">[msq:htd/set/0/power:command:OFF:default]"}
Switch Audio_Zone_All_Mute "Whole House Audio Mute" (Audio) {mqtt=">[msq:htd/set/0/mute:command:*:default]"}
Number Audio_Bridge_Connection_Status "Audio Bridge Connection Status [%d]" (Audio) {mqtt="<[msq:htd/connected:state:default]"}
String Audio_Bridge_Update "Audio Bridge Update Request [%s]" (Audio) {mqtt=">[msq:htd/set/0/update:command:*:default]"}
Switch Audio_Zone_1_Power "Zone 1 Audio Power" (Audio) {mqtt=">[msq:htd/set/1/power:command:*:default], <[msq:htd/status/1/power:state:default]"}
Switch Audio_Zone_1_Mute "Zone 1 Audio Mute" (Audio) {mqtt=">[msq:htd/set/1/mute:command:*:default], <[msq:htd/status/1/mute:state:default]"}
Number Audio_Zone_1_Volume "Zone 1 Audio Volume [%d]" (Audio) {mqtt=">[msq:htd/set/1/volume:command:*:default], <[msq:htd/status/1/volume:state:default]"}
Dimmer Audio_Zone_1_Volume_Percent "Zone 1 Audio Volume [%d %%]" (Audio) {mqtt=">[msq:htd/set/1/volumepercent:command:*:default], <[msq:htd/status/1/volumepercent:state:default]"}
Number Audio_Zone_1_Source "Zone 1 Audio Source [%d]" (Audio) {mqtt=">[msq:htd/set/1/source:command:*:default], <[msq:htd/status/1/source:state:default]"}
Switch Audio_Zone_1_DND "Zone 1 Audio DND" (Audio) {mqtt=">[msq:htd/set/1/dnd:command:*:default], <[msq:htd/status/1/dnd:state:default]"}
String Audio_Zone_1_Zone_Name "Zone 1 Audio Zone Name [%s]" (Audio) {mqtt="<[msq:htd/status/1/name:state:default]"}
Contact Audio_Zone_1_Zone_Exists "Zone 1 Audio Zone Exists [MAP(contact_to_truefalse.map):%s]" (Audio) {mqtt="<[msq:htd/status/1/exists:state:MAP(onezero_to_contact.map)]"}
Contact Audio_Zone_1_Keypad_Present "Zone 1 Audio Keypad Present [MAP(contact_to_truefalse.map):%s]" (Audio) {mqtt="<[msq:htd/status/1/keypadpresent:state:MAP(onezero_to_contact.map)]"}
These items rely on two map files that will need to be created in the transform directory:
contact_to_truefalse.map
CLOSED=False
OPEN=True
-=unknown
undefined=unknown
onezero_to_contact.map
0=CLOSED
1=OPEN
undefined=unknown
You can find the two map files and a helper script for generating a full list of
items in the openhab
directory in this repository.
MIT © Andy Swing