From 68d8719be044edfb5791b4b1fca8558e4e4f7ab4 Mon Sep 17 00:00:00 2001 From: Tobias Gesellchen Date: Sun, 30 Aug 2026 21:43:15 +0200 Subject: [PATCH] docs(client): correct GetGroup's non-ST10 behavior claim The exported GetGroup doc comment claimed non-ST10 devices reply to /getGroup "harmlessly" with an empty group. Verified against real hardware this is wrong: a SoundTouch 20 does not reply at all -- the request hangs until the client's own timeout (10-30s depending on how the Client was constructed) instead of returning quickly. Confirmed by direct request against a real ST20 (curl, 8s timeout, zero bytes back) and cross-checked against two actively-paired real ST10 units, which both replied in ~30-40ms with full group data. This matters beyond prose accuracy: the newer stereoPairCapable gate in websocket.go's UpdateDeviceStatus is load-bearing, not an optimization. A future contributor trusting the old (wrong, and more prominent/exported) doc could reasonably "simplify" by removing that gate, reintroducing a 10-30s hang on every poll cycle for every SoundTouch 20/30 on the network. Rewrote the doc to state the real behavior and point at the gate that depends on it; the websocket.go comment now defers to this doc instead of independently (and incorrectly worded) restating it. Co-Authored-By: Claude Sonnet 5 --- pkg/client/client.go | 11 ++++++++--- pkg/service/soundtouchweb/websocket.go | 4 +++- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/pkg/client/client.go b/pkg/client/client.go index ae13adb2..46bcf733 100644 --- a/pkg/client/client.go +++ b/pkg/client/client.go @@ -1428,9 +1428,14 @@ func (c *Client) GetZoneMembers() ([]string, error) { // An empty response is reported as a zero-value Group; callers can // distinguish with (*Group).IsEmpty(). // -// ST-10 is the only product that supports stereo pairs; on other devices -// the call is harmless but will always return an empty group. The endpoint -// is named /getGroup on the device (mirroring /getZone), even though some +// ST-10 is the only product that supports stereo pairs. Verified against +// real hardware: a SoundTouch 20 does not reply to /getGroup at all -- the +// request hangs until the client's own timeout (30s by default, see +// DefaultConfig) rather than returning an empty group quickly. Callers on +// a poll cycle must gate this call behind a stereo-pair-capable model check +// (see stereoPairCapable in pkg/service/soundtouchweb) instead of relying on +// a fast, harmless response on unsupported models. The endpoint is named +// /getGroup on the device (mirroring /getZone), even though some // third-party wikis document it as plain /group. func (c *Client) GetGroup() (*models.Group, error) { var g models.Group diff --git a/pkg/service/soundtouchweb/websocket.go b/pkg/service/soundtouchweb/websocket.go index 9df2b365..e2dfb742 100644 --- a/pkg/service/soundtouchweb/websocket.go +++ b/pkg/service/soundtouchweb/websocket.go @@ -303,7 +303,9 @@ func (app *WebApp) UpdateDeviceStatus(_ string, conn *webtypes.DeviceConnection) return } - // /getGroup is ST10-only; ST20/ST30 may accept the request but never reply. + // /getGroup must be gated to ST10 models -- see Client.GetGroup's doc + // comment (verified against real hardware: a ST20 never replies at all, + // hanging until the client's timeout instead of returning quickly). stereoCapable := stereoPairCapable(conn.DeviceInfo) var groupGeneration uint64