mirror of
https://github.com/gesellix/Bose-SoundTouch.git
synced 2026-08-18 16:46:17 +00:00
Implements the speaker-side group API surface (path 1 of the two approaches gmuth outlined in issue #252): clients form, rename, and dissolve stereo pairs directly on the device, and the resulting GroupService.xml persists on disk in the same shape the device emits over /getGroup. What landed: - pkg/models/group.go: Status field + IsEmpty() helper, matching the GET /getGroup response shape (id-attr, masterDeviceId, roles, senderIPAddress). - pkg/client/client.go: GetGroup, AddGroup, UpdateGroup, RemoveGroup. The endpoint name is /getGroup (not /group, despite some wiki docs) — confirmed against a real ST-10's /supportedURLs. RemoveGroup uses GET per the wire spec. - cmd/soundtouch-cli/cmd_group.go + main.go: new `group` subcommand with status / create --left --right [--name] / rename / remove, mirroring gmuth's group.sh recipe. WebSocket notifications: - pkg/models/websocket.go: EventTypeGroupUpdated + GroupUpdatedEvent + dispatch helpers. The device fans this out to both LEFT and RIGHT speakers on every group mutation, including empty-group teardowns; the parse test covers both shapes. - pkg/client/websocket.go: OnGroupUpdated registration and dispatch. - cmd/soundtouch-cli/cmd_events.go: `group` filter + handleGroupEvent formatter. WebSocket observability (came up while validating the above against a real device): - New RawMessageHandler type + OnRawMessage hook that fires for every incoming frame before parsing, with the parse error alongside. - New --debug flag on `events subscribe` with modes all / unknown / errors. Raw output goes to stderr so it composes cleanly with shell redirects. The pkg/client refactor in this commit also adopts speaker.HTTPPort (introduced in the previous refactor) — the unexported defaultSoundTouchPort and three hard-coded 8090 literals are gone. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>