Control your entire Sonos system from Indigo — playback, volume, grouping, favourites, streaming services, announcements, soundbar tuning, and native Sonos alarms — as first-class Indigo devices, actions, and triggers.
Current version: 2025.2.11 · Requires Indigo 2025.2+ (API 3.4) · Bundled SoCo 0.30.9 · Python 3
This release makes the plugin fully self-healing around unreachable players — powered off, dropped off WiFi, or moved to a new IP address — and closes a long-standing event-subscription gap that could freeze a group's playback state.
- Runtime offline detection. Previously, self-healing only covered players that were offline when the plugin started. A player that died or changed IP address mid-run (the classic case: a router restart re-deals every DHCP lease at once) produced endless "No route to host" errors until you restarted the plugin. Now an active liveness sweep probes every player each minute — costing milliseconds for live players — so a dead player is detected within ~3 minutes even on a completely idle system, and immediately when commands are failing.
- Honest states for dead players. A detected-offline player is marked
offlinewith its playback state set to STOPPED — a powered-off player can no longer sit showing "playing", and a grouped coordinator no longer stamps its own playing state onto an offline group member. - Automatic recovery, including new IP addresses. Offline players are retried in the background: the moment one answers again it's brought back with fresh event subscriptions, and if it reappears at a different IP address it's re-found by its Sonos ID and the Indigo device's address is updated automatically — no delete-and-recreate, no control-page edits.
- Quiet logs while a player is down. Topology refreshes skip unreachable players instead of stalling 5–10 seconds per call and flooding the Event Log; all unreachable-player conditions log one concise warning line.
The plugin only subscribed to transport events for players that were group coordinators at startup. A player that started as a group member — or recovered from offline with a stale state — and was later made coordinator of a new group never delivered its "playing" events, so the whole group's states froze at STOPPED. Every player (except bonded satellites like Subs and surrounds) is now subscribed, matching Home Assistant's approach — group role changes at any time just work, and grouped players now receive their own volume events too.
- 2025.2.11 — fixes a 2025.2.10 regression that could silently stop all state updates (event listener drifting off port 1400 behind a firewall); adds an event-flow watchdog that detects sustained event silence and recovers automatically. Please update from 2025.2.10.
- 2025.2.10 — subscription re-subscribes no longer leave orphaned renew threads (warning-flood fix); bonded satellites identified by topology visibility, ending "None SID" errors for ordinary speakers used as surrounds.
- 2025.2.8 — grouped players no longer show a phantom "playing" state from their link stream to the coordinator.
- 2025.2.7 — event-subscription watchdog (states no longer freeze after a failed renewal — the old "works for days, then stops until restart") and a ~10x cut in per-event processing overhead.
- 2025.2.6 — Amazon Polly announcements fully repaired (four stacked bugs, some dating to 2024.0.8) and expanded to Amazon's complete voice range, including neural and generative voices, selectable per engine tier in the Voice menu.
- 2025.2.5 — volume/mute/EQ actions on a grouped player adjust that player, not the group master; bonded satellites excluded from announcement group-restore.
Full details for every release are in the version history below.
This release overhauls the announcement system end-to-end and fixes several bugs reported against 2025.2.3.
- Multi-zone announcements fixed — a grouping-semantics regression made the coordinator sequentially join every other zone's group instead of the zones joining the coordinator; announcements only played on one speaker. All selected zones now group correctly and play together.
- Polly TTS "Unable to locate credentials" fixed — Polly/IVONA/Pandora/SiriusXM/Microsoft credentials (and Apple voices) are loaded at plugin startup again, not only after re-saving the config dialog.
- TTS announcements fixed — all TTS engines wrote their audio where the announcement HTTP server never looked (silent 404s), and File announcements could measure a stale file's duration and cut off mid-play. All announcement audio now lives in one served location.
- Apple text-to-speech reworked — synthesis now uses macOS
say(the previousNSSpeechSynthesizerAPI is deprecated and renders silence for modern voices), the voice menu lists only voices that actually work, and output is Sonos-compatible 44.1 kHz WAV (the old AIFF output was an AIFF-C container Sonos rejects). - Device IP changes self-heal — a player that moves to a new DHCP address is found again by its Sonos id during background retry and its Indigo device address is updated automatically; no more delete-and-recreate or control-page edits (forum-requested).
- Stale group-state ghosts fixed — plugin caches are resynced from live topology after announcements, so Indigo device states track what the players are actually doing.
Announcements now snapshot every target zone (SoCo Snapshot/Restore — the same mechanism Home Assistant uses; selectable in Plugin Config, on by default) and afterwards rebuild the exact pre-announcement state: original groups re-form (including group members that weren't part of the announcement), standalone zones return to standalone, volumes/mutes restore, and interrupted music resumes at the same track and position. See the Known Limitation in the version history: cloud-queue sources (Alexa-initiated, Spotify Connect, AirPlay) cannot be programmatically resumed.
Players on a separate VLAN must be able to reach the Indigo Mac on tcp/8889 (announcements), tcp/8888 (album art), and tcp/1400 (event notifications) — a one-way firewall breaks all three silently while normal control keeps working. The plugin now detects players on a different subnet at startup and logs the exact rules needed, and a fetch watchdog reports when a player never pulled the announcement file.
The plugin log file always captures full debug detail (nothing is lost when the Event Log is set to normal), while Event Log noise — album-art fetch retries, per-event state chatter, startup floods — has been sharply reduced. Album-art fetches use longer timeouts, and the last unbounded HTTP calls got timeouts.
This release is a major reliability and completeness overhaul, addressing the failure cascade reported in IndigoDomotics/Sonos#16 and restoring a number of actions that had silently stopped working.
Previously, a single unplugged speaker could freeze the whole plugin — minutes-long startups, a config dialog that would not open, reloads needing a force-kill, and log storms hammering healthy players. All of that is fixed:
- Fast reachability probes everywhere — an offline player is detected in ~1 second, marked with an
offlinedevice state in Indigo, and skipped (with a 30-second back-off) instead of blocking the plugin in serial 10–20 s network timeouts. - Automatic recovery — offline players are re-checked in the background every 60 seconds and come back to life on their own when the network returns. No plugin restart needed.
- Every network call is time-bounded — no more unbounded HTTP requests anywhere on the hot path (SoCo's global request timeout is also capped at 5 s).
- Clean, fast plugin stop/reload — unsubscribing from an offline player no longer blocks shutdown, so reloads complete without Indigo force-killing the process.
- Announcement storm fix — group announcements no longer trigger a flood of topology fetches against every player for every zone change (debounced + probe-gated), which previously could knock healthy WiFi speakers off the network mid-announcement.
- Player UIDs resolve instantly from cached Indigo state — no repeated
DevicePropertiesfetches against dead players.
If your players live on a dedicated subnet (e.g. Sonos on 192.168.30.0/24, Indigo Mac on 192.168.1.0/24):
- Interface selection now falls back to the OS routing table when no local interface sits directly on the Sonos subnet — announcements and event subscriptions work across the router instead of failing with "No interface found on target Sonos subnet".
- All player communication is direct-by-IP; multicast discovery (which cannot cross a router) is never required and no longer spams warnings when it finds nothing.
An automated end-to-end audit (Actions.xml → plugin.py → handler) found 10 actions that were offered in the UI but did nothing (logging "Unknown or unsupported action") or crashed. All are restored and verified:
| Action | Status |
|---|---|
| Play RadioTime Favourite Station | Restored (was breaking alarm/announcement action groups) |
| Bass / Treble (set to level) | Restored — no handler existed at all |
| Night Mode | Restored |
| Play Queue | Restored |
| Sleep Timer | Restored |
| TV Input (soundbars) | Restored |
| Dump URI (diagnostics) | Restored |
| Pandora Thumbs Up / Thumbs Down | Restored — handler method was missing |
| Test SiriusXM Channel | Fixed malformed action definition + missing callback |
| Line-In | Fixed in 2025.2.1 (#15) |
Also fixed in this area:
- Sonos Favourites playback — a Python‑2 remnant (
urllib.unquote) crashed favourites; fixed. Favourite routing also corrected:x-sonosapi-hls:is a generic HLS scheme (Sonos Radio HD, Apple Music radio, …) and is no longer misrouted to the SiriusXM handler — only URIs carryingchannel-linear:<guid>are SiriusXM. Generic HLS/HTTP favourites now play via their stored URI + metadata. - SiriusXM from favourites — the handler now accepts the channel GUID embedded in a favourite's URI, not just the action's channel dropdown.
- Two latent dispatch-signature crashes (
ZP_SiriusXMmissingprops,Q_Crossfadearity) fixed. - Stale device state lists (the "state key Grouped not defined" error spam) are resynced automatically from Devices.xml on startup.
Feature set cross-checked against Home Assistant's Sonos integration; the following were added using the same SoCo/UPnP semantics:
Equalizer / soundbar controls (Actions → Sonos → Equalizer):
- Speech Enhancement on/off (Arc, Beam, Playbar dialog clarity)
- Audio Delay (Lip Sync) 0–5
- Surround Speakers on/off
- Surround Level (TV) −15…15
- Surround Level (Music) −15…15
- Music Playback Full Volume — full-volume vs ambient music on surrounds
Native Sonos alarm management (Actions → Sonos → Alarms):
- Set Alarm On/Off — lists your household's Sonos alarms live (
07:00 — Master Bedroom — DAILY — enabled), with Enable / Disable / Toggle and an optional volume override. Perfect for "disable the wake-up alarm on public holidays" style automations.
- Download the latest release and double-click
Sonos.indigoPlugin— Indigo installs and enables it. - Open Plugins → Sonos → Configure…:
- Reference ZonePlayer IP — any player's IP, or
auto. Used to load favourites/playlists/stations. - Sonos Target Subnet — the subnet your players live on (e.g.
192.168.30.0/24). If your Mac isn't directly on that subnet, the plugin automatically uses the routed interface — you don't need to change anything. - Announcement/streaming host + port, event processor settings, and optional Pandora / SiriusXM credentials.
- Reference ZonePlayer IP — any player's IP, or
- Create one Indigo device (type Sonos ZonePlayer) per player, entering each player's IP address. Use fixed IPs / DHCP reservations for your players.
Players that are offline when the plugin starts show an offline device state and are picked up automatically when they reappear.
Each ZonePlayer device exposes rich states usable in triggers and control pages, including transport state, track metadata + album art, volume/mute/bass/treble, grouping (Grouped, GROUP_Coordinator, GROUP_Name, ZonePlayerUUIDsInGroup), queue flags (repeat/shuffle/crossfade), and identity (ZP_LocalUID, model, serial).
Grouped players mirror the coordinator's enriched metadata states, so a control page bound to any group member shows what's actually playing.
- Transport: Play, Pause, Toggle Play/Pause, Stop, Next, Previous, Channel Up/Down
- Volume: set/up/down, mute on/off/toggle — per player and per group, plus relative group volume
- Equalizer: Bass, Treble (set or step), Loudness via player, Night Mode, Speech Enhancement, Audio Delay, Surround on/off + levels, Music Full Volume
- Music sources: Sonos Favourites, Sonos Playlists, RadioTime Favourite Stations, Sonos Radio, Pandora (+ Thumbs Up/Down), SiriusXM (+ channel list, test), Spotify/containers, Line-In, TV input, Play Queue
- Queue: Clear, Save, Crossfade, Repeat / Repeat One / Toggle, Shuffle / Toggle
- Grouping: Add player(s) to zone, Set standalone (one/all), with group-state resync
- Announcements: file/MP3 announcements over the built-in HTTP server, with automatic ungroup → announce → regroup and state save/restore; text-to-speech via Amazon Polly (full voice range incl. generative), Apple Speech, and Google TTS. Message and volume fields support Indigo substitutions — e.g.
%%v:12345678%%,%%d:12345678:stateId%%,%%t:"%-I:%M %p"%%— so announcements can speak live variable values, device states, and timestamps - Alarms: enable/disable/toggle native Sonos alarms, optional volume override
- Utilities: Save/Restore player states, Dump URI, group/topology diagnostic dumps (menu items)
- Announcements play no audio / artwork blank / states go stale, but control works (players on a separate VLAN) — the players pull announcements, album art, and push event notifications to the Indigo Mac. A one-way LAN→VLAN firewall breaks all three silently. Allow the Sonos VLAN → Indigo Mac on tcp/8889 (announcements), tcp/8888 (album art), and tcp/1400 (event notifications). The plugin logs a startup warning naming the exact rules when it detects players on another subnet.
- A player shows
offline— the plugin probes it every 60 s and will restore it automatically once reachable. Nothing to do. - Config dialog, favourites lists, or actions feel slow — check the log for a player timing out; one unreachable IP no longer blocks the plugin, but fixing the network (or deleting a decommissioned player's device) keeps logs clean.
- Favourite won't play — check the log: unknown favourite types are logged with their URI. Open an issue including that line.
- Menu → dump options — group topology, subscribed devices, and SiriusXM channel dumps are available as diagnostic aids under the plugin menu.
2025.2.11 — Important fix for a regression introduced in 2025.2.10 — please update. The 2025.2.10 subscription-cleanup change could momentarily drop the number of active event subscriptions to zero during startup, which makes the SoCo library stop its event listener; the immediate restart could then land on port 1401 instead of 1400. On networks that firewall the Sonos VLAN to tcp/1400 only, every event notification was silently dropped from that moment — device states appeared blank or frozen with no errors logged, and a restart could reproduce rather than fix it. Apologies to anyone bitten. Now: new subscriptions are always established before old ones are removed (the listener and its port can never move), a loud error is logged if the listener is ever found off its configured port, and a new event-flow watchdog monitors actual event arrivals — sustained silence (which lease-health checks cannot detect) triggers automatic re-subscription and, if needed, a full event-listener restart, with clear log messages throughout.
2025.2.10 — Fixes a flood of "subscription failed to renew" warnings: re-subscribing a player (offline recovery, subscription watchdog) left the old subscription objects' auto-renew threads running as orphans — once expired they can never renew, so each fired a warning every cycle forever. Old subscriptions are now properly torn down before re-subscribing (renew thread cancelled first — unsubscribing an already-expired subscription raises before reaching its own timer cancel), and the renew-failure warning is rate-limited to one per minute in the Event Log. Also: bonded satellites are now identified by topology visibility instead of model name — ordinary speakers bonded as rear surrounds (e.g. two Play:1s behind a Beam) no longer produce "subscription returned None SID" errors at startup.
2025.2.9 — Runtime offline detection and self-healing: a player that becomes unreachable while the plugin is running — powered off, dropped off WiFi, or moved to a new DHCP address (e.g. after a router restart re-deals every lease) — is now detected within ~3 minutes even on an idle system (an active liveness probe sweeps all players every minute; failed commands accelerate detection), marked offline with its state set to STOPPED, and handed to the background recovery loop, which reconnects when it returns or re-finds it by its Sonos ID at its new address automatically. An offline grouped player no longer inherits its coordinator's "playing" state, topology refreshes skip unreachable players instead of stalling and flooding the log, and soco-internal fetch failures log one concise warning. Event subscriptions are now established for every player (not only group coordinators at startup) — previously a player that was a group slave when the plugin started never received transport events, so if it later became a group's coordinator, that group's playback state froze at STOPPED. DHCP reservations for your players remain best practice.
2025.2.8 — Grouped players no longer show a phantom "playing" state. A grouped slave's own transport reports PLAYING for its link stream to the coordinator regardless of whether any audio is playing — the plugin now ignores slave link-stream transport events (a slave's state follows its coordinator) and verifies coordinatorship against the player's authoritative CurrentURI instead of soco's per-player group view, which can go stale.
2025.2.7 — Event-subscription watchdog: device states no longer freeze after a failed subscription renewal (the cause of "states stop updating after a few days until a plugin restart") — lapsed subscriptions are detected within a minute and re-subscribed automatically, with a log warning the moment a renewal fails. Major reduction in per-event overhead: group refresh now runs only for the player the event came from (not whenever any group existed anywhere), identical album art is no longer re-downloaded several times per track change, unchanged states are no longer re-pushed to grouped slaves, and a malformed cached group entry that polluted every evaluation pass is cleaned up. Announcement/action dialogs now advertise Indigo substitution support (always worked; now documented). Slow/offline players log one concise warning instead of a two-part error.
2025.2.6 — Amazon Polly announcements fixed: the Polly voice-loading routine had been lost in a years-old refactor, leaving the action dialog's Voice menu empty and saved actions failing with ValidationException ... voiceId ''. Voices now load at startup (Loaded Polly Voices... [N] in the log); actions saved while the menu was broken fall back to a default voice with a log warning — re-open and re-save the action to pick your voice.
2025.2.5 — Per-player controls fixed for grouped zones: Volume Up/Down, Volume, Mute, Bass, Treble, and all soundbar EQ actions now target the specific ZonePlayer named in the action instead of being redirected to the group coordinator (Group Volume/Group Mute remain the group-wide controls). Announcement group-restore now skips bonded satellites (surrounds/Sub bonded to a soundbar), eliminating harmless "could not re-join" warnings on home-theater setups.
2025.2.4 — Announcement system overhaul: multi-zone announcements fixed (grouping semantics regression), full group & playback restore after announcements — zones return to their exact pre-announcement groups (including group members that weren't part of the announcement) and music resumes at the same track/position via SoCo Snapshot/Restore (selectable in Plugin Config, on by default, with the legacy flow as fallback). Apple text-to-speech reworked onto macOS say (voice menu now lists only voices that actually render; output is Sonos-compatible 44.1 kHz WAV). Polly/IVONA/Pandora/SiriusXM credentials and Apple voices load at startup again. TTS audio unified onto the announcement HTTP server's folder (TTS previously 404'd; File announcements could probe a stale file's duration). Cross-VLAN diagnostics: startup warning + a fetch watchdog name the exact firewall rules needed (players must reach the Mac on tcp/8889 announcements, tcp/8888 album art, tcp/1400 event notifications). DHCP-moved players self-heal by matching their RINCON id in discovery and updating the device address automatically. Plugin log file now always captures full debug detail; Event Log noise sharply reduced. Album-art fetches use longer timeouts and no longer warn.
Known limitation — announcement playback resume: sources Sonos exposes as cloud queues — Alexa-initiated music, Spotify Connect, and AirPlay streams — cannot be restarted programmatically (Sonos provides no API to resume them; Home Assistant has the same limitation). After an announcement, grouping and volume are still restored for those zones, but that music will not auto-resume. Local queue playback, Sonos favourites, and radio streams all resume normally, at the same track and position.
2025.2.3 — Offline-player resilience (probe gating, UID caching, bounded timeouts, clean shutdown), routed-VLAN support, announcement topology-storm fix, state-list resync, 10 restored actions, favourites routing fixes, new Equalizer/soundbar actions, native Sonos alarm management. See PR #17.
2025.2.1 — Line-In action fix (#15); HTTPStreamer port leak and Polly prefs fixes (#14); dynamic install-path resolution (#13).
1.0.2 — SoCo 0.30.9 upgrade; rewritten subscriptions with fallback; VLAN-aware discovery; corrected volume/bass/treble controls; SiriusXM login + channel processing; Pandora auth ported to Python 3; artwork/metadata server; group metadata mirroring; diagnostic menu dumps.
Originally by Vic Solomon; Python 3 port and ongoing maintenance by the Indigo community (IndigoDomotics), with contributions from forum users and plugin contributors. Uses the SoCo library. Not affiliated with Sonos, Inc.
See LICENSE.