homebridge-unifi-play
v1.0.0
Published
Control the volume of UniFi Play speakers from Apple Home and Siri.
Maintainers
Readme
homebridge-unifi-play
Control the volume of UniFi Play speakers from Apple Home and Siri.
Each speaker appears as a 0–100 % slider. Volume changes made in the UniFi Play app show up in the Home app automatically — the device pushes its own state, so nothing is polled.
Tested against a UniFi Play Audio Port (UPL-PORT). The PowerAmp (UPL-AMP) speaks
the same protocol and should work, but is untested — reports welcome.
Why not Google Cast
The Audio Port is also a Google Cast receiver on port 8009 and accepts SET_VOLUME
without complaint — it just does not change anything you can hear. Both channels, read
from the same device at the same moment:
| Channel | Reports |
| --- | --- |
| Cast :8009 | volume 0.0 |
| MQTT :8883 | volume 30, source lineIn |
Two separate volume domains. This plugin uses MQTT on port 8883 — the channel the UniFi Play app itself uses, and the only one that reaches the audio path, including the analog Line In passthrough.
Requirements
- Homebridge 1.8 or later
- Node 22 or 24
- A UniFi Play speaker reachable from the Homebridge host on TCP port 8883
Installation
From the Homebridge UI
Open the Plugins tab, search for UniFi Play, and click Install. Then click Settings on the plugin tile and add your speaker.
From the command line
sudo npm install -g homebridge-unifi-playFrom source
Useful if you want to run an unreleased version or make changes:
git clone https://github.com/timdre/homebridge-unifi-play.git
cd homebridge-unifi-play
npm install
npm run build
sudo npm install -g .Restart Homebridge afterwards. On an hb-service installation:
sudo hb-service restartTo pick up later changes, git pull and repeat npm install && npm run build && sudo npm install -g ..
Configuration
Use the Homebridge UI settings screen, or add a platform block to config.json:
{
"platforms": [
{
"platform": "UniFiPlay",
"name": "UniFi Play",
"devices": [
{
"name": "Office Speaker",
"ip": "192.168.1.100"
},
{
"name": "Kitchen Speaker",
"ip": "192.168.1.101"
}
]
}
]
}| Field | Required | Default | Notes |
| --- | --- | --- | --- |
| name | yes | — | Name shown in the Home app |
| ip | yes | — | Give the speaker a DHCP reservation so it cannot move |
| restoreVolume | no | 20 | Level used when switching on with no previous level |
Only the IP is needed — the MAC address is learned from the device's MQTT topic.
Behaviour
- Exposed as a Fan, not a Lightbulb. A Lightbulb would be caught by "Hey Siri, turn off all the lights" and by every light scene, silencing the speakers for reasons that would look like a bug.
- Off means volume 0. The device has no mute command — the UniFi Play app does the same thing. Switching back on restores the previous level.
- Unreachable shows as "No Response" in the Home app rather than a stale 0 %, which would read as "muted".
- Reconnects every 5 seconds and re-syncs automatically.
Troubleshooting
The plugin ships a CLI that works without Homebridge:
cd $(npm root -g)/homebridge-unifi-play
node dist/probe.js 192.168.1.100 # read current state
node dist/probe.js 192.168.1.100 --volume 55 # set the volume
node dist/probe.js 192.168.1.100 --watch # stream changes, Ctrl-C to stop--watch is the fastest way to confirm that turning the dial in the UniFi Play app
reaches the plugin. If probe.js cannot connect, neither can Homebridge — check the IP
and that nothing blocks TCP 8883 between the two.
Limitations
- The MQTT client certificate is the one shipped inside the UniFi Play app (valid until 2033-09-25) and is not device-specific. If Ubiquiti ever rotates it, connections break until the certificate is refreshed. This is the plugin's only external dependency.
- Volume only. The protocol also covers input selection, EQ, zones and announcements; none of that is implemented here.
- No auto-discovery — Audio Ports do not answer the UniFi UDP discovery probe, so each speaker is configured by IP.
- A speaker's identity is its IP address. Change the IP in the config and HomeKit treats it as a new accessory: the old one disappears along with its room assignment, scenes and automations. Set a DHCP reservation before you add the speaker and this never comes up.
Development
npm install
npm run lint
npm run build
npm test # builds, then runs the offline codec and volume-mapping checks
npm run watch # build, link, and run Homebridge against ./test/hbConfigCredits
The wire protocol and the bundled MQTT certificate come from
ha-unifiplay by Will Beeching, whose
docs/api.md is the reference for this device family. Licensed MIT; see LICENSE.
Built from the Homebridge plugin template.
