Repository navigation
Description
Plugin Name
homebridge-sonos-control-pro
Link To GitHub Repo
https://github.com/mathiashornbek/homebridge-sonos-control-pro
Plugin Icon (Optional)
https://raw.githubusercontent.com/mathiashornbek/homebridge-sonos-control-pro/main/docs/icon.png
The plugin does not offer the same nor less functionality than that of any existing verified plugin.
🟢 Yes
The plugin successfully installs and does not start unless it is configured.
🟢 Yes
The plugin does not require the user to run Homebridge in a TTY or with non-standard startup parameters, even for initial configuration.
🟢 Yes
The plugin does not contain any analytics or calls that enable you to track the user.
🟢 Yes
If the plugin needs to write files to disk (cache, keys, etc.), it stores them inside the Homebridge storage directory.
🟢 Yes
The plugin does not throw unhandled exceptions, the plugin must catch and log its own errors.
🟢 Yes
More Information
What it does
Sonos Control Pro turns a multi-room music scene into a single switch in Apple Home. Not a speaker — a scene: who leads, what plays, who joins, who is kept out, and the volume for each room, applied as one press.
The scene is built in a visual editor inside the Homebridge Plugin Settings GUI. Everything in that editor — speakers, favourites, playlists, radio stations, current volumes, current groups — is read live from the household over UPnP. There is not one UUID, IP address or room name for the user to type.
Why it is not another Sonos plugin
I looked at what is already verified before building this. The existing Sonos plugins model speakers: each room becomes an accessory with volume and play/pause, and a few can join or leave a group. That is a different product from this one, and this plugin does not replace it — you would install this one instead of hand-grouping in the Sonos app, not instead of a speaker accessory.
What is here that I could not find in a verified plugin:
-
One press composes the whole house. A single "Start music in a group" action picks the group leader, the source, who joins, who leaves and a volume per speaker, then executes it as an ordered plan: volumes land before anything makes a sound, then the source starts, then grouping, then play modes. A speaker left at 60 % last night cannot startle anyone.
-
"Everyone except…" that maintains itself. A scene is described by shape, not by a list of names. Buy a speaker next month and it is in that scene without the user editing anything. Rename a room in the Sonos app and every affected scene is flagged by name in the UI rather than silently doing less.
-
Targets with live filters. Every action takes a target — all speakers / chosen / all except / the group around X / the leader of X — and then a filter evaluated at press time: whatever they are doing, only those playing right now, only the silent ones, only group leaders. +5 %, only those playing turns up the kitchen without waking the bedroom. This is the piece I most wanted and could not find anywhere.
-
Scenes, not just actions. 30 actions across playback, volume, grouping, sound settings and sequencing (wait, remember state, restore state, run another scene), composed into a list, with an optional condition — is anything playing? is it between 22:00 and 06:00? is the kitchen above 30 %? — and a second branch for when it is not met. Switches can be momentary (runs and turns itself back off) or stateful, where turning it off runs a second list.
-
Templates and backups. Four starter scenes that hydrate themselves from the household on first press, so a new install is working in under a minute. Every save leaves a timestamped backup; the newest 20 are restorable from the UI, and the whole set exports and imports as JSON.
-
An activity log. Every run, step by step, with its duration and the speaker's own answer, so a slow or partial scene can be diagnosed without reading a log file.
Against the criteria
Dynamic platform. api.registerPlatform with configureAccessory; accessories are registered and unregistered as scenes are added and removed, so the switches in Apple Home follow the editor live.
Settings GUI. A custom UI (customUi: true) built on @homebridge/plugin-ui-utils — the only runtime dependency in the package. The Homebridge form itself shows two fields, name and language, because everything else belongs in the editor.
Node.js. engines declares Node 18/20/22/24 and Homebridge ^1.8.0 || ^2.0.0-beta.0. The suite is run on Node 22 and Node 24 in CI on every push.
Installs without configuration. No preinstall, install, postinstall or prepare script, no native module, no bin. With no platform block Homebridge never constructs the class; with a minimal one it starts, finds nothing and says so.
No TTY. Nothing reads process.stdin or process.argv. Initial setup is entirely in the settings GUI.
No analytics. No telemetry, no analytics, no outbound connection of any kind other than SSDP on the local network, port 1400 on the speakers themselves, and 127.0.0.1. The settings page loads no external script, font or stylesheet — everything is local to the plugin. There is no Sonos cloud account and no Sonos SDK: the protocol layer is hand-written and tested against a mock household that speaks real SOAP over real HTTP.
Files on disk. Everything lives under /sonos-control-pro/ — scenes.json, backups/, and a runtime.json holding the port and per-start token for the loopback control API (mode 0600). Nothing is written to config.json, the working directory, /tmp or the home directory, so a bad edit cannot take the bridge down. Writes are atomic and a corrupt file is quarantined rather than fatal.
Errors. Every scene run is wrapped and reported through the plugin's own result object; fan-out uses Promise.allSettled; every setInterval callback catches; the SSDP socket, the loopback server and the SOAP client all carry 'error' listeners; JSON.parse is always guarded. Failures are logged by the plugin, in the user's language, with the speaker's own answer attached.
Testing
npm test # 127 unit and integration tests
npm run test:ui # 100 checks driving the real settings UI in Chromium
Both run in CI on Node 22 and Node 24. The tests exercise the actual protocol rather than a stub: test/mock-sonos.js is a fake Sonos household that speaks real SOAP over real HTTP on loopback, with configurable latency, real queue update IDs, and speakers that can appear mid-run.
The suite is hermetic. It binds only to 127.0.0.1, on ports the operating system hands out, and the SSDP sweep is stubbed everywhere — so running npm test on a network that has real Sonos speakers on it neither finds them nor touches them. A test reads the test files and fails if any of them forgets.
Housekeeping
-
Published to npm as homebridge-sonos-control-pro.
-
Source on GitHub, issues enabled, with bug-report and feature-request templates.
-
MIT licensed.
-
A GitHub release with notes for each version, and a changelog that says what changed and why.
-
English and Danish throughout — the editor, every action, every help text and every line in the Homebridge log. No setting means "follow the machine", falling back to English.
Happy to make any changes the review asks for. Thank you for taking the time.
Activity
github-actions commentedon Aug 3, 2026
🔴 Failed Checks
keywordsmust include at least one of'supports-hap'or'supports-matter'— see Declaring Supported Transportsrequiredshould not be a boolean property on individual fields. In JSON Schema,requiredmust be an array at the object level listing required property names. Remove"required": true/falsefrom individual properties and use"required": ["property1", "property2"]at the object level instead.🟢 Passed Checks
homepageexistsbugs.urlexists and seems a valid URLkeywordsexist and contain'homebridge-plugin''preinstall'inscriptsis not present'install'inscriptsis not present'postinstall'inscriptsis not presentengines.nodeproperty is compatible with Node 22engines.nodeproperty is compatible with Node 24engines.homebridgeproperty is compatible with Homebridge 2.2.1pluginAliaspluginAliasmatches the platform/accessory registered in codepluginTypeis set to'platform'nameschema propertyhomebridgeis not declared as a runtime/peer/bundled dependencyhap-nodejsis not declared as a runtime/peer/bundled dependency🔍 For Manual Review
The following items were detected and require manual review. We understand that these items may be false positives.
ℹ️ Check Details
v3.1.7of the plugin.📋 Next Steps
/checkon this issue to run the checks again — your request will not move forward until the checks are re-run.package.jsonandconfig.schema.jsonfiles, don't forget to publish a new version to NPM.mathiashornbek commentedon Aug 3, 2026
Thanks — all three are fixed in 3.1.8, now on npm and tagged with a release.
keywordsmust declare a transport. Addedsupports-hap. The plugin publishes switch accessories through HAP and does nothing over Matter.config.schema.jsonwas not valid JSON Schema. Thenameproperty carried"required": true, which is not a thing —requiredbelongs at the object level as an array of property names. It is now:Homebridge rendered the form correctly either way, which is exactly why it survived this long. There is now a test asserting the schema's shape, so it cannot come back.
Releases. My mistake — I had pushed the tag and assumed that was the same thing.
v3.1.7andv3.1.8both have proper releases with notes now, and every version from here will.On the manual-review item, so you do not have to go digging:
That is the language setting reading the machine's locale, and only when the user has chosen Follow the system (or has not chosen anything):
Four standard POSIX locale variables, read to pick between Danish and English. Nothing is written, nothing else in
process.envis touched, and the value never leaves the process — there is no telemetry and no outbound connection in this plugin other than to the speakers on the local network and to127.0.0.1. The function takesenvas an argument purely so the tests can pass a fake one.Happy to change anything else you spot.
/checkgithub-actions commentedon Aug 3, 2026
It looks like you wanted to re-run the checks, but the checks have not been started.
To run them, please add a new comment with
/checkon a line by itself (it can be the only thing in the comment). It will not be picked up when it is part of a longer line.mathiashornbek commentedon Aug 3, 2026
/check
github-actions commentedon Aug 3, 2026
🟢 Passed Checks
homepageexistsbugs.urlexists and seems a valid URLkeywordsexist and contain'homebridge-plugin'keywordsdeclare the supported transports ('supports-hap'and/or'supports-matter')'preinstall'inscriptsis not present'install'inscriptsis not present'postinstall'inscriptsis not presentengines.nodeproperty is compatible with Node 22engines.nodeproperty is compatible with Node 24engines.homebridgeproperty is compatible with Homebridge 2.2.1typepropertypropertiesfor object typepluginAliaspluginAliasmatches the platform/accessory registered in codepluginTypeis set to'platform'nameschema propertyhomebridgeis not declared as a runtime/peer/bundled dependencyhap-nodejsis not declared as a runtime/peer/bundled dependency🔍 For Manual Review
The following items were detected and require manual review. We understand that these items may be false positives.
ℹ️ Check Details
v3.1.8of the plugin.📋 Next Steps
All checks passed successfully, nice work! Your plugin and/or icon will now be manually reviewed by the Homebridge team.
mathiashornbek commentedon Aug 3, 2026
3.3.0 is now current.
mathiashornbek commentedon Aug 3, 2026
3.4.0 is now the current version.
mathiashornbek commentedon Aug 3, 2026
3.4.1 is now the current version.
bwp91 commentedon Aug 4, 2026
/check
github-actions commentedon Aug 4, 2026
🟢 Passed Checks
homepageexistsbugs.urlexists and seems a valid URLkeywordsexist and contain'homebridge-plugin'keywordsdeclare the supported transports ('supports-hap'and/or'supports-matter')'preinstall'inscriptsis not present'install'inscriptsis not present'postinstall'inscriptsis not presentengines.nodeproperty is compatible with Node 22engines.nodeproperty is compatible with Node 24engines.homebridgeproperty is compatible with Homebridge 2.2.1typepropertypropertiesfor object typepluginAliaspluginAliasmatches the platform/accessory registered in codepluginTypeis set to'platform'nameschema propertyhomebridgeis not declared as a runtime/peer/bundled dependencyhap-nodejsis not declared as a runtime/peer/bundled dependency🔍 For Manual Review
The following items were detected and require manual review. We understand that these items may be false positives.
ℹ️ Check Details
v3.4.1of the plugin.📋 Next Steps
All checks passed successfully, nice work! Your plugin and/or icon will now be manually reviewed by the Homebridge team.
verify: homebridge-sonos-control-pro
github-actions commentedon Aug 4, 2026
Congratulations! Your plugin has been verified!
You can now add one of the Verified by Homebridge badges to your plugin's README:
Your plugin is now also eligible to display a ❤️ Donate button on its tile in the Homebridge UI. See https://github.com/homebridge/homebridge/wiki/Donation-Links for instructions.
Interested in getting a
@homebridge-plugins/scope for your plugin? See our Homebridge Scoped Plugins program.If for any reason in the future you can no longer maintain your plugin, please consider transferring it to our Homebridge Plugins organization.
Don't forget to join the official Homebridge Discord server, where plugin developers can get tips and advice from other developers and the Homebridge project team in the #plugin-development channel!
As a verified plugin, you can request a channel in the Discord server to discuss your plugin with users and other developers. Just ask in the #plugin-development channel.
Thank you for your contribution to the Homebridge community.
bwp91 commentedon Aug 4, 2026
Hi @mathiashornbek, thanks for the thorough request and for turning the fixes around so quickly — the transport keyword, schema and releases were all sorted within the day. The scene/orchestration approach is a nice addition alongside the existing Sonos plugins, and I've added your icon too. Thanks for contributing to Homebridge!
mathiashornbek commentedon Aug 4, 2026
Thanks Ben — and thanks for adding the icon.
The review was really useful. I'd have shipped the keyword and the schema thing without noticing either of them, so good to have a second pair of eyes on it.
Glad the scene angle makes sense to you too — that was the bit I kept wishing existed. Cheers for taking the time.