Sonos rooms over the local network, represented as one household coordinator with dynamically
presented media_player nodes.
- Core discovers a player with mDNS (
_sonos._tcp) or SSDP. - The household driver reads the keyless, local Zone Group Topology snapshot on port 1400.
- Every visible Sonos room is presented and auto-adopted. Its current Sonos title is matched exactly to a Juno room; a genuinely new title creates a room. Imported ids or historical stable keys are not used for room matching.
- Without a key, ordinary playback and volume commands use keyless UPnP/SOAP on port 1400. If a LAN-authorized Sonos API key is configured, the driver additionally opens the Control API websocket on port 1443 for push state, metadata, favourites, playlists, and queue loading.
The player id is stable; the group id is not. Transport, queue, favourites loading, playlist loading, and Line-In are always sent to the player's current group. Volume and mute are sent to the player. Favourites and playlist listings are sent to the household.
The newer local websocket requires X-Sonos-Api-Key during its HTTP upgrade. It identifies and
authorizes the control integration; it is not a household password and is not derived from the
speakers. Without an accepted key, Sonos rejects the websocket. Juno therefore uses the player's
older local UPnP services for transport, seek, skip, crossfade, volume, and mute. Live Control API
events and household-library features remain unavailable.
Discovery, room adoption, and ordinary control do not require it. They use mDNS/SSDP and local UPnP. This means a household can be found, filed into the correct rooms, and controlled without a cloud round trip or homeowner credential.
Sonos's current documentation says its Control API on the LAN is not available for wide release. A key created for the public cloud Control API is therefore not guaranteed to authorize the LAN websocket. Juno needs a Sonos-authorized Connected Home integration for a packaged key to work here; this is an integration/product credential, not something every homeowner should have to create.
References:
For the public cloud Control API, register a Sonos developer account, create a control
integration in Integration Manager, supply its name, description, and category, choose a unique
name key, and save it to generate credentials. Cloud playback control also requires OAuth with a
publicly routable HTTPS redirect URI, the playback-control-all scope, and server-side handling
of the client secret.
That self-service cloud credential does not imply LAN access. Current Sonos documentation says LAN Control API access is not generally released, and Works with Sonos certification is by invitation. For production local control, contact Sonos about Connected Home partner access and explicit LAN authorization for the integration.
The UPnP/SOAP backend on port 1400 covers discovery, topology, play, pause, stop, seek, skip,
crossfade, discrete and relative volume, and mute without a developer key or cloud round trip.
Commands are still exposed through the same media_player contract, so the rest of Juno does not
care which Sonos backend is active.
GENA event subscriptions are not implemented yet. The driver reads volume, mute, and transport once when it binds and confirms state after its own successful commands; changes made in another app are pushed live only when the authorized websocket is available.
Without a key:
- play, pause, stop, seek, and skip;
- per-room volume and mute;
- crossfade;
- room discovery, topology, and initial playback/volume state.
With an authorized websocket key, additionally:
- independent repeat and shuffle controls;
- metadata and live state;
- Sonos Favourites and Sonos Playlists;
- analogue Line-In and TV input where the player reports support.
Still missing:
- grouping or ungrouping rooms from Juno;
- failover when the one player holding the household socket disappears;
- keyless GENA push events, favourites/playlists, and independent shuffle/repeat;
- search, Recently Played, and arbitrary service-content loading.
cargo build --release --target wasm32-wasip1Releases are built by junohouse/driver-ci: push to
main for a beta, or tag v1.2.0 for a release.