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 <noreply@anthropic.com>
This commit is contained in:
Tobias Gesellchen
2026-08-30 22:27:56 +02:00
co-authored by Claude Sonnet 5
parent 342cd47e6a
commit 68d8719be0
2 changed files with 11 additions and 4 deletions
+8 -3
View File
@@ -1428,9 +1428,14 @@ func (c *Client) GetZoneMembers() ([]string, error) {
// An empty <group/> 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
+3 -1
View File
@@ -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