Skip to content

Verification Request: homebridge-sonos-control-pro #1153

Closed

Description

@mathiashornbek

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

  1. github-actions commented on Aug 3, 2026

    @github-actions
    Contributor

    🔴 Failed Checks

    • Package JSON: keywords must include at least one of 'supports-hap' or 'supports-matter' — see Declaring Supported Transports
    • Config Schema JSON: schema is invalid - required should not be a boolean property on individual fields. In JSON Schema, required must be an array at the object level listing required property names. Remove "required": true/false from individual properties and use "required": ["property1", "property2"] at the object level instead.
    • GitHub Repo: should contain releases

    🟢 Passed Checks

    • Installation: successfully installed
    • Package JSON: homepage exists
    • Package JSON: bugs.url exists and seems a valid URL
    • Package JSON: keywords exist and contain 'homebridge-plugin'
    • Package JSON: 'preinstall' in scripts is not present
    • Package JSON: 'install' in scripts is not present
    • Package JSON: 'postinstall' in scripts is not present
    • Package JSON: engines.node property is compatible with Node 22
    • Package JSON: engines.node property is compatible with Node 24
    • Package JSON: engines.homebridge property is compatible with Homebridge 2.2.1
    • Package JSON: initializer function found
    • NPM Package: has not been deprecated
    • GitHub Repo: version in package.json (v3.1.7) matches NPM version (v3.1.7)
    • Config Schema JSON: exists and is valid JSON
    • Config Schema JSON: contains a valid pluginAlias
    • Config Schema JSON: pluginAlias matches the platform/accessory registered in code
    • Config Schema JSON: the pluginType is set to 'platform'
    • Config Schema JSON: contains a name schema property
    • Dependencies: homebridge is not declared as a runtime/peer/bundled dependency
    • Dependencies: hap-nodejs is not declared as a runtime/peer/bundled dependency
    • Security: no known vulnerabilities in dependencies
    • Security: code patterns flagged for manual review
    • Security: no privilege escalation attempts detected
    • GitHub Repo: repository is public
    • GitHub Repo: repository is not archived
    • GitHub Repo: issues are enabled

    🔍 For Manual Review

    The following items were detected and require manual review. We understand that these items may be false positives.

    • Security: accesses environment files in src/i18n/index.js

    ℹ️ Check Details

    • These checks were run against v3.1.7 of the plugin.
    • Link to the run workflow: visit →.

    📋 Next Steps

    • Once you have fixed these failures, comment /check on this issue to run the checks again — your request will not move forward until the checks are re-run.
    • If updating your package.json and config.schema.json files, don't forget to publish a new version to NPM.
    • Remember this is an automatic script: if you think something has been marked as a failure in error, let us know with a reply.
    • Feel free to ask any questions you have by replying to this issue.
  2. added
    awaiting-changesuse after review has started - awaiting user to make changes to plugin
    and removed
    pendingthe label given to a new verification/icon request
    on Aug 3, 2026
  3. mathiashornbek commented on Aug 3, 2026

    @mathiashornbek
    Author

    Thanks — all three are fixed in 3.1.8, now on npm and tagged with a release.

    keywords must declare a transport. Added supports-hap. The plugin publishes switch accessories through HAP and does nothing over Matter.

    config.schema.json was not valid JSON Schema. The name property carried "required": true, which is not a thing — required belongs at the object level as an array of property names. It is now:

    "schema": {
      "type": "object",
      "required": ["name"],
      "properties": { "name": { … }, "language": { … } }
    }

    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.7 and v3.1.8 both 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:

    Security: accesses environment files in src/i18n/index.js

    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):

    const candidates = [env.LC_ALL, env.LC_MESSAGES, env.LANG, env.LANGUAGE];
    for (const candidate of candidates) {
      const code = String(candidate).toLowerCase().split(/[._-]/)[0];
      if (LANGUAGES[code]) return code;
    }

    Four standard POSIX locale variables, read to pick between Danish and English. Nothing is written, nothing else in process.env is 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 to 127.0.0.1. The function takes env as an argument purely so the tests can pass a fake one.

    Happy to change anything else you spot. /check

  4. github-actions commented on Aug 3, 2026

    @github-actions
    Contributor

    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 /check on 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.

  5. mathiashornbek commented on Aug 3, 2026

    @mathiashornbek
    Author

    /check

  6. added
    pendingthe label given to a new verification/icon request
    and removed
    awaiting-changesuse after review has started - awaiting user to make changes to plugin
    on Aug 3, 2026
  7. github-actions commented on Aug 3, 2026

    @github-actions
    Contributor

    🟢 Passed Checks

    • Installation: successfully installed
    • Package JSON: homepage exists
    • Package JSON: bugs.url exists and seems a valid URL
    • Package JSON: keywords exist and contain 'homebridge-plugin'
    • Package JSON: keywords declare the supported transports ('supports-hap' and/or 'supports-matter')
    • Package JSON: 'preinstall' in scripts is not present
    • Package JSON: 'install' in scripts is not present
    • Package JSON: 'postinstall' in scripts is not present
    • Package JSON: engines.node property is compatible with Node 22
    • Package JSON: engines.node property is compatible with Node 24
    • Package JSON: engines.homebridge property is compatible with Homebridge 2.2.1
    • Package JSON: initializer function found
    • NPM Package: has not been deprecated
    • GitHub Repo: version in package.json (v3.1.8) matches NPM version (v3.1.8)
    • Config Schema JSON: exists and is valid JSON
    • Config Schema JSON: contains valid JSON Schema
    • Config Schema JSON: schema has valid type property
    • Config Schema JSON: schema has valid properties for object type
    • Config Schema JSON: contains a valid pluginAlias
    • Config Schema JSON: pluginAlias matches the platform/accessory registered in code
    • Config Schema JSON: the pluginType is set to 'platform'
    • Config Schema JSON: contains a name schema property
    • Dependencies: homebridge is not declared as a runtime/peer/bundled dependency
    • Dependencies: hap-nodejs is not declared as a runtime/peer/bundled dependency
    • Security: no known vulnerabilities in dependencies
    • Security: code patterns flagged for manual review
    • Security: no privilege escalation attempts detected
    • Runtime: homebridge installed successfully
    • Runtime: no config - homebridge should start without plugin configuration and plugin should not load
    • Runtime: platform only - plugin should start with just platform property
    • Runtime: minimal required - plugin should start with minimal required configuration
    • Runtime: full config - plugin should start with comprehensive configuration
    • Runtime: plugin shuts down cleanly within 12s of SIGTERM
    • Runtime: plugin restarts cleanly without port conflicts
    • GitHub Repo: repository is public
    • GitHub Repo: repository is not archived
    • GitHub Repo: issues are enabled
    • GitHub Repo: contains releases

    🔍 For Manual Review

    The following items were detected and require manual review. We understand that these items may be false positives.

    • Security: accesses environment files in src/i18n/index.js

    ℹ️ Check Details

    • These checks were run against v3.1.8 of the plugin.
    • Link to the run workflow: visit →.

    📋 Next Steps

    All checks passed successfully, nice work! Your plugin and/or icon will now be manually reviewed by the Homebridge team.

  8. mathiashornbek commented on Aug 3, 2026

    @mathiashornbek
    Author

    3.3.0 is now current.

  9. mathiashornbek commented on Aug 3, 2026

    @mathiashornbek
    Author

    3.4.0 is now the current version.

  10. mathiashornbek commented on Aug 3, 2026

    @mathiashornbek
    Author

    3.4.1 is now the current version.

  11. bwp91 commented on Aug 4, 2026

    @bwp91
    Contributor

    /check

  12. github-actions commented on Aug 4, 2026

    @github-actions
    Contributor

    🟢 Passed Checks

    • Installation: successfully installed
    • Package JSON: homepage exists
    • Package JSON: bugs.url exists and seems a valid URL
    • Package JSON: keywords exist and contain 'homebridge-plugin'
    • Package JSON: keywords declare the supported transports ('supports-hap' and/or 'supports-matter')
    • Package JSON: 'preinstall' in scripts is not present
    • Package JSON: 'install' in scripts is not present
    • Package JSON: 'postinstall' in scripts is not present
    • Package JSON: engines.node property is compatible with Node 22
    • Package JSON: engines.node property is compatible with Node 24
    • Package JSON: engines.homebridge property is compatible with Homebridge 2.2.1
    • Package JSON: initializer function found
    • NPM Package: has not been deprecated
    • GitHub Repo: version in package.json (v3.4.1) matches NPM version (v3.4.1)
    • Config Schema JSON: exists and is valid JSON
    • Config Schema JSON: contains valid JSON Schema
    • Config Schema JSON: schema has valid type property
    • Config Schema JSON: schema has valid properties for object type
    • Config Schema JSON: contains a valid pluginAlias
    • Config Schema JSON: pluginAlias matches the platform/accessory registered in code
    • Config Schema JSON: the pluginType is set to 'platform'
    • Config Schema JSON: contains a name schema property
    • Dependencies: homebridge is not declared as a runtime/peer/bundled dependency
    • Dependencies: hap-nodejs is not declared as a runtime/peer/bundled dependency
    • Security: no known vulnerabilities in dependencies
    • Security: code patterns flagged for manual review
    • Security: no privilege escalation attempts detected
    • Runtime: homebridge installed successfully
    • Runtime: no config - homebridge should start without plugin configuration and plugin should not load
    • Runtime: platform only - plugin should start with just platform property
    • Runtime: minimal required - plugin should start with minimal required configuration
    • Runtime: full config - plugin should start with comprehensive configuration
    • Runtime: plugin shuts down cleanly within 12s of SIGTERM
    • Runtime: plugin restarts cleanly without port conflicts
    • GitHub Repo: repository is public
    • GitHub Repo: repository is not archived
    • GitHub Repo: issues are enabled
    • GitHub Repo: contains releases

    🔍 For Manual Review

    The following items were detected and require manual review. We understand that these items may be false positives.

    • Security: accesses environment files in src/i18n/index.js

    ℹ️ Check Details

    • These checks were run against v3.4.1 of the plugin.
    • Link to the run workflow: visit →.

    📋 Next Steps

    All checks passed successfully, nice work! Your plugin and/or icon will now be manually reviewed by the Homebridge team.

  13. added a commit that references this issue on Aug 4, 2026
  14. added
    verifieduse when a plugin meets the criteria - adds the verified badge text
    on Aug 4, 2026
  15. github-actions commented on Aug 4, 2026

    @github-actions
    Contributor

    Congratulations! Your plugin has been verified!

    You can now add one of the Verified by Homebridge badges to your plugin's README:

    verified-by-homebridge

    [![verified-by-homebridge](https://img.shields.io/badge/_-verified-blueviolet?color=%23491F59&style=flat&logoColor=%23FFFFFF&logo=homebridge)](https://github.com/homebridge/homebridge/wiki/Verified-Plugins)
    

    verified-by-homebridge

    [![verified-by-homebridge](https://img.shields.io/badge/homebridge-verified-blueviolet?color=%23491F59&style=flat)](https://github.com/homebridge/homebridge/wiki/Verified-Plugins)
    

    verified-by-homebridge

    [![verified-by-homebridge](https://img.shields.io/badge/homebridge-verified-blueviolet?color=%23491F59&style=for-the-badge&logoColor=%23FFFFFF&logo=homebridge)](https://github.com/homebridge/homebridge/wiki/Verified-Plugins)
    

    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.

    • The Homebridge Team
  16. bwp91 commented on Aug 4, 2026

    @bwp91
    Contributor

    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!

  17. mathiashornbek commented on Aug 4, 2026

    @mathiashornbek
    Author

    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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    request-verificationverifieduse when a plugin meets the criteria - adds the verified badge text

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions