Fix startup/reload hangs, restore lost actions, add HA-parity feature… - #17
Merged
Merged
Conversation
…s (2025.2.2) Addresses the failure cascade reported in IndigoDomotics#16 and a series of related defects found reviewing the 2025.2.1 release. == Blocking network I/O on the dispatch thread (config UI freeze, IndigoDomotics#16) == The plugin's main thread — which also services every Indigo config dialog — was spending minutes in serial, sometimes unbounded, connect timeouts to offline players (verified by process sampling: 100% of samples blocked in socket connect()). The config screen could not open at all. - New is_host_reachable() 2s TCP probe; deviceStartComm now defers unreachable players immediately (device shows "offline" error state) instead of stalling ~40s each, and a background retry loop (runConcurrentThread, previously commented out entirely) re-starts them automatically when the network returns. - Removed the redundant 2x discover(timeout=5) sweeps per device; reuse startup discovery or direct SoCo(ip) — identical semantics. - Bounded every unbounded HTTP call on hot paths: SOAPSend requests.post (was infinite connect timeout), initZones /status/zp, getModelName, rootZPIP status fetch. - Startup skips playlists/favorites load when the reference player is unreachable. - deviceStopComm: network unsubscribe only if the player answers a 1s probe; otherwise cancel local auto-renew. Offline players previously blocked plugin stop until Indigo force-killed it on reload. == ZGT storm during announcements (IndigoDomotics#16) == Every zone change during an announcement walked all players with 5s fetches, melting down flaky networks (UPNP 1001, 20s read timeouts, "Host is down" on healthy speakers). - 3s debounce on refresh_group_topology_after_plugin_zone_change (only once the cache has first populated, so fast startup isn't starved). - 1s reachability probe + 30s negative cache per player in the ZGT walk. - Fixed "list.remove(x): x not in list" crash in the initZones error path. - "coord_dev missing" for players with no Indigo device now warns once per IP, then logs at debug. == State-list sync ("state key Grouped not defined") == Devices created before Grouped/GROUP_* were added to Devices.xml kept a stale server state list; three duplicated code blocks tried to "create" states via updateStateOnServer (impossible) and errored on every start. - initialize_custom_states now calls stateListOrDisplayStateIdChanged() to resync from Devices.xml and returns a refreshed device; all callers updated; duplicated broken blocks removed. - Fixed startup summary reading nonexistent "GROUP_Grouped" state. - Guarded soco.discover() returning None in startup. == Routed-subnet support (players on a different VLAN) == - find_sonos_interface_ip: when no local interface sits on the configured Sonos subnet, resolve the routed source IP via the OS routing table — announcements and eventing now work across routed VLANs instead of erroring "No interface found on target Sonos subnet". - getSoCoDeviceByIP / get_soco_device: direct SoCo(ip) instead of multicast discovery sweeps that can never cross a router ("No SoCo devices discovered" spam eliminated). == Restored lost/broken actions (all fell through to "Unknown or unsupported action" or crashed) == - ZP_RT_FavStation (RadioTime favourite stations — also used by alarms). - Bass, Treble (had no handler anywhere), Night Mode, Play Queue, Sleep Timer, TV input, Dump URI. - Pandora Thumbs Up/Down (actionPandoraThumbs method was missing). - Test SiriusXM Channel (malformed Actions.xml entry + missing callback). - Fixed dispatch-table signature mismatches: handleAction_ZP_SiriusXM (missing props — crashed on use) and handleAction_Q_Crossfade (arity). - Fixed py2 remnant urllib.unquote -> urllib.parse.unquote (crashed favourites playback). - Favourites router: x-sonosapi-hls: is generic HLS (Sonos Radio HD, Apple Music radio, ...) — only route to SiriusXM when the URI carries channel-linear:<guid>; other HLS/http favourites play via the generic URI+DIDL path. Removed stray early return when mode was empty. - SiriusXM handler accepts the GUID from favourite URI fragments. == New HA-parity features == - Equalizer actions: Speech Enhancement, Audio Delay (lip-sync 0-5), Surround on/off, Surround Level (TV/Music, -15..15), Music Playback Full Volume — RenderingControl SetEQ, mirroring Home Assistant/SoCo. - Native Sonos alarm management: new action lists household alarms live and enables/disables/toggles them (optional volume override). == Cleanup == - Removed both dead duplicate old_deviceStartComm methods (349 lines). - Removed invalid <ActionType> block from Actions.xml. - Downgraded routine warnings (ready-probe, cache misses) to debug. - Misc log-prefix corrections. Fixes IndigoDomotics#16 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Production follow-up to the IndigoDomotics#16 work: with a single player off the network, Indigo logged "timeout waiting for plugin response ... CalcDeviceFunc" and the log filled with repeated 10s DeviceProperties1.xml timeouts. Root cause: SoCo's .uid/.group/ .is_coordinator on a cold instance poll ZoneGroupState against the player's OWN IP — for an offline player that is a full network timeout on every access, and several hot loops (UID lookups, group evaluation, topology dumps) access them per player on the dispatch thread. - New _ip_probe_ok(): 1s reachability probe with the shared 30s negative cache; new safe_uid(): resolves a player UID from plugin cache -> SoCo's cache -> the Indigo device's ZP_LocalUID state -> (probe-gated) network. Offline players resolve instantly from state. - get_soco_by_uuid(): use safe_uid — was burning a 10s timeout per offline player on EVERY uuid lookup (the main log spam). - uuid map builder: safe_uid instead of raw soco.uid. - dump_groups_to_log PASS1/PASS2: skip unreachable players before touching soco.group. - Group-state reconcile loops (x3): probe-gate before is_coordinator/ .group access. - Cap soco.config.REQUEST_TIMEOUT at 5s (SoCo default is 20s). - Bump PluginVersion to 2025.2.3. Refs IndigoDomotics#16 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Author
|
Pushed |
SonosPlugin.__init__ assigns a local variable named 'soco' further down (uuid map builder), which makes 'soco' local to the whole method — so the new REQUEST_TIMEOUT line at the top raised "cannot access local variable 'soco' where it is not associated with a value" and the plugin could not start. Alias the module (import soco.config as _soco_config) instead. AST-scanned the rest of the file for the same module-shadowing use-before-assignment pattern: no other instances. Refs IndigoDomotics#16 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
… new features Replaces the changelog-style stub with a full README covering install, configuration (incl. routed-VLAN setups), devices/states, the complete actions catalog, the offline-resilience behaviour, restored actions, the new Equalizer/soundbar and native Sonos alarm features, and troubleshooting + version history. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
…s (2025.2.2)
Addresses the failure cascade reported in #16 and a series of related defects found reviewing the 2025.2.1 release.
== Blocking network I/O on the dispatch thread (config UI freeze, #16) == The plugin's main thread — which also services every Indigo config dialog — was spending minutes in serial, sometimes unbounded, connect timeouts to offline players (verified by process sampling: 100% of samples blocked in socket connect()). The config screen could not open at all.
== ZGT storm during announcements (#16) ==
Every zone change during an announcement walked all players with 5s fetches, melting down flaky networks (UPNP 1001, 20s read timeouts, "Host is down" on healthy speakers).
== State-list sync ("state key Grouped not defined") == Devices created before Grouped/GROUP_* were added to Devices.xml kept a stale server state list; three duplicated code blocks tried to "create" states via updateStateOnServer (impossible) and errored on every start.
== Routed-subnet support (players on a different VLAN) ==
== Restored lost/broken actions (all fell through to "Unknown or
unsupported action" or crashed) ==
== New HA-parity features ==
== Cleanup ==
Fixes #16