mirror of
https://github.com/gesellix/Bose-SoundTouch.git
synced 2026-08-18 08:36:13 +00:00
docs: rewrite README and survival guide for post-shutdown user journey
Rewrite README.md to be concise and tool-focused (no code snippets), clearly presenting all five tools and their use cases. Expand the soundtouch-service section to cover both user scenarios and redirect method trade-offs. Rewrite SURVIVAL-GUIDE.md around the same two scenarios with step-by-step instructions. Remove deprecated hosts-file method from all user-facing docs; update MIGRATION-SAFETY.md, HTTPS-SETUP.md, and SOUNDTOUCH-SERVICE.md to reflect only the two supported methods (XML redirect and DNS/DHCP). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 4.6
parent
16ab9dbba1
commit
6b90d2c994
@@ -1,549 +1,126 @@
|
||||
# Bose SoundTouch Toolkit
|
||||
|
||||
A comprehensive solution for controlling and preserving Bose SoundTouch devices, including a Go library, CLI tool, and a local service for cloud emulation.
|
||||
|
||||
[](https://pkg.go.dev/github.com/gesellix/bose-soundtouch)
|
||||
[](https://goreportcard.com/report/github.com/gesellix/bose-soundtouch)
|
||||
[](https://opensource.org/licenses/MIT)
|
||||
|
||||
> **Note**: This is an independent project based on the [official Bose SoundTouch Web API documentation](https://assets.bosecreative.com/m/496577402d128874/original/SoundTouch-Web-API.pdf). Not affiliated with or endorsed by Bose Corporation.
|
||||
> Independent project. Not affiliated with or endorsed by Bose Corporation.
|
||||
|
||||
## Features
|
||||
## Context: Cloud Shutdown
|
||||
|
||||
- ✅ **Complete API Coverage**: All available SoundTouch Web API endpoints implemented
|
||||
- 🎵 **Media Control**: Play, pause, stop, volume, bass, balance, source selection
|
||||
- 🔔 **Smart Notifications**: TTS messages, URL audio content, notification beeps (ST-10)
|
||||
- 🏠 **Multiroom Support**: Create and manage zones across multiple speakers
|
||||
- ⚡ **Real-time Events**: WebSocket connection for live device state monitoring
|
||||
- 🔍 **Device Discovery**: Automatic discovery via UPnP/SSDP and mDNS
|
||||
- 📻 **Content Navigation**: Browse and search TuneIn, Pandora, Spotify, local music
|
||||
- 📻 **Custom Radio**: Play any stream URL via [flexible proxying](docs/guides/CLI-REFERENCE.md#custom-radio-selection-via-soundtouch-service)
|
||||
- 📻 **RadioBrowser**: Access thousands of internet radio stations via [radio-browser.info](docs/reference/radio-browser.md)
|
||||
- 🎙️ **Station Management**: Add and play radio stations without presets
|
||||
- 🖥️ **CLI Tool**: Comprehensive command-line interface
|
||||
- 🌐 **SoundTouch Service**: Emulate Bose cloud services for offline device operation
|
||||
- 🔧 **Service Migration**: Migrate devices to use local services instead of Bose cloud (XML, Hosts, or DNS redirection)
|
||||
- 🔍 **DNS Discovery & Interception**: Dynamic DNS server for intercepting and logging Bose service queries (requires port 53)
|
||||
- 📊 **DNS Discovery Analysis**: Track and deduplicate all device DNS queries to discover hidden hostnames
|
||||
- 📊 **Traffic Analysis**: Proxy and log device communications
|
||||
- 📝 **HTTP Recording**: Persist interactions as re-playable `.http` files
|
||||
- 🔄 **Endpoint Mirroring**: Asynchronously mirror local requests to Bose cloud for parity testing
|
||||
- ⚖️ **Parity Logging**: Detect and record discrepancies between local and official Bose responses
|
||||
- 🧹 **Session Management**: Manage and cleanup recorded interaction sessions
|
||||
- 🔒 **Production Ready**: Extensive testing with real SoundTouch hardware
|
||||
- 🌐 **Cross-Platform**: Windows, macOS, Linux support
|
||||
Bose is shutting down SoundTouch cloud services on **May 6, 2026**. After that, music service browsing, preset sync, and the official SoundTouch app stop working. This toolkit lets you keep your speakers fully functional.
|
||||
|
||||
## Quick Start
|
||||
See the [Survival Guide](https://gesellix.github.io/Bose-SoundTouch/guides/SURVIVAL-GUIDE.html) for the full picture.
|
||||
|
||||
### Installation
|
||||
---
|
||||
|
||||
## Tools
|
||||
|
||||
### soundtouch-service — AfterTouch
|
||||
|
||||
A local server that replaces the Bose cloud ("AfterTouch"). Once your speaker is redirected to it, you have full control without any Bose cloud dependency. The built-in web UI at `http://localhost:8000` handles all setup — no config files needed to get started.
|
||||
|
||||
**Two scenarios:**
|
||||
|
||||
**Before shutdown — migrate your existing setup**
|
||||
While the Bose cloud is still running, use `soundtouch-backup` to save your account data. The local service web UI then helps with the migration so your speaker keeps its presets and credentials.
|
||||
|
||||
**After shutdown or factory reset — start fresh**
|
||||
Create a local account, configure your speakers, and start using them immediately. No Bose infrastructure required.
|
||||
|
||||
**Redirecting your speaker**
|
||||
|
||||
The service needs a stable address on your local network (e.g. `soundtouch.fritz.box` or `soundtouch.local`). The speaker must then be redirected to resolve the Bose cloud hostnames to that address. Two supported methods:
|
||||
|
||||
| Method | How it works | Notes |
|
||||
|--------------|-------------------------------------|--------------------------------------------------------------|
|
||||
| XML redirect | Upload a config XML via the Web API | Surgical; covers only registered endpoints; best for testing |
|
||||
| DNS/DHCP | Serve custom DNS on your network | Covers all devices at once; requires port 53 and TLS |
|
||||
|
||||
The web UI walks you through each method. DNS redirect requires HTTPS — the service manages its own CA certificate and the web UI guides you through trusting it on each speaker.
|
||||
|
||||
> **Note:** A hosts-file method (direct SSH edits to `/etc/hosts`) also exists in the codebase but is deprecated and not exposed in the web UI.
|
||||
|
||||
**Enabling SSH via USB stick**
|
||||
|
||||
Some setup steps require SSH access to the speaker. Enable it once per device: create a file named `remote_services` on a FAT-formatted USB drive (the drive may need its bootable flag set — see [SoundCork issue #172](https://github.com/deborahgu/soundcork/issues/172)), and insert it while the speaker is powered on. After reboot, root SSH is available with no password.
|
||||
|
||||
See [Device Initial Setup](https://gesellix.github.io/Bose-SoundTouch/guides/DEVICE-INITIAL-SETUP.html) and [Migration Guide](https://gesellix.github.io/Bose-SoundTouch/guides/MIGRATION-SAFETY.html) for step-by-step instructions.
|
||||
|
||||
---
|
||||
|
||||
### soundtouch-backup
|
||||
|
||||
Backs up your Bose cloud account (presets, paired devices, music sources) and each speaker's local state before the shutdown. Run `soundtouch-backup all` to capture everything in one step; it authenticates with the Bose cloud, then polls each paired speaker over the local network.
|
||||
|
||||
See the [soundtouch-backup README](cmd/soundtouch-backup/README.md) for usage.
|
||||
|
||||
---
|
||||
|
||||
### soundtouch-cli
|
||||
|
||||
Command-line control of any SoundTouch device: play/pause/volume, presets, source selection, multiroom zones, device discovery, and more. Works entirely over the local network — no cloud dependency. Well-suited for scripting and home automation.
|
||||
|
||||
See the [CLI Reference](https://gesellix.github.io/Bose-SoundTouch/guides/CLI-REFERENCE.html) for full usage.
|
||||
|
||||
---
|
||||
|
||||
### soundtouch-web
|
||||
|
||||
A standalone web UI for device control — play, pause, volume, preset selection, real-time status — served from a local Go binary. Complements `soundtouch-service` when you want a dedicated device-control interface separate from the setup/admin UI.
|
||||
|
||||
See the [soundtouch-web README](cmd/soundtouch-web/README.md) for usage.
|
||||
|
||||
---
|
||||
|
||||
### Go library
|
||||
|
||||
`pkg/client` provides a Go API for all SoundTouch device endpoints: media control, volume, presets, sources, zones, real-time WebSocket events, and device discovery. Use it to build your own integrations.
|
||||
|
||||
#### Install CLI and Service Tools
|
||||
```bash
|
||||
go install github.com/gesellix/bose-soundtouch/cmd/soundtouch-cli@latest
|
||||
go install github.com/gesellix/bose-soundtouch/cmd/soundtouch-service@latest
|
||||
```
|
||||
|
||||
#### Add Library to Your Project
|
||||
```bash
|
||||
go get github.com/gesellix/bose-soundtouch
|
||||
```
|
||||
|
||||
### CLI Usage
|
||||
See the [API Reference](https://gesellix.github.io/Bose-SoundTouch/reference/API-ENDPOINTS.html) and [pkg.go.dev](https://pkg.go.dev/github.com/gesellix/bose-soundtouch) for documentation.
|
||||
|
||||
Find SoundTouch devices on your network:
|
||||
```bash
|
||||
soundtouch-cli discover devices
|
||||
```
|
||||
|
||||
Control a device (replace `192.168.1.100` with your speaker's IP):
|
||||
```bash
|
||||
# Basic information
|
||||
soundtouch-cli --host 192.168.1.100 info
|
||||
|
||||
# Media controls
|
||||
soundtouch-cli --host 192.168.1.100 play start
|
||||
soundtouch-cli --host 192.168.1.100 volume set --level 50
|
||||
|
||||
# Preset management
|
||||
soundtouch-cli --host 192.168.1.100 preset list
|
||||
```
|
||||
|
||||
For full CLI documentation, see the [CLI Reference](https://gesellix.github.io/Bose-SoundTouch/guides/CLI-REFERENCE.html).
|
||||
|
||||
### SoundTouch Service (Cloud Shutdown Protection)
|
||||
|
||||
The `soundtouch-service` is a local server that emulates Bose's cloud services. This is critical for keeping your speakers functional after the **Bose Cloud Shutdown in May 2026**.
|
||||
|
||||
#### Key Features:
|
||||
- **🏠 Local Emulation**: BMX and Marge service implementation
|
||||
- **🔌 Easy Setup**: Activate SSH via USB stick (`remote_services` file)
|
||||
- **🔧 Device Migration**: Seamlessly transition devices to local control
|
||||
- **🌐 Web Management UI**: Easy browser-based setup and management
|
||||
- **💾 Persistent Data**: Store presets, recents, and sources locally
|
||||
- **🔄 Endpoint Mirroring**: Asynchronously mirror local requests to Bose cloud for parity testing
|
||||
- **⚖️ Parity Logging**: Detect and record discrepancies between local and official Bose responses
|
||||
- **📝 HTTP Recording**: Persist all interactions as re-playable `.http` files
|
||||
- **🧹 Session Management**: Manage and cleanup recorded interaction sessions
|
||||
|
||||
#### Quick Start:
|
||||
```bash
|
||||
# Start the service
|
||||
soundtouch-service
|
||||
```
|
||||
Open `http://localhost:8000` in your browser to manage your devices. Documentation is also available directly through the web interface.
|
||||
|
||||
For a comprehensive guide on transitioning your system, see the [Bose Cloud Shutdown: Survival Guide](https://gesellix.github.io/Bose-SoundTouch/guides/SURVIVAL-GUIDE.html).
|
||||
|
||||
Detailed service configuration and Docker instructions can be found in [SoundTouch Service Guide](https://gesellix.github.io/Bose-SoundTouch/guides/SOUNDTOUCH-SERVICE.html).
|
||||
|
||||
For professional migration tips and safety measures, see the [Migration & Safety Guide](https://gesellix.github.io/Bose-SoundTouch/guides/MIGRATION-SAFETY.html).
|
||||
|
||||
### Library Usage
|
||||
|
||||
#### Basic Control
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
|
||||
"github.com/gesellix/bose-soundtouch/pkg/client"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// Connect to your SoundTouch device
|
||||
c := client.NewClient(&client.Config{
|
||||
Host: "192.168.1.100",
|
||||
Port: 8090,
|
||||
})
|
||||
|
||||
// Get device information
|
||||
info, err := c.GetDeviceInfo()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
fmt.Printf("Device: %s\n", info.Name)
|
||||
|
||||
// Control playback
|
||||
err = c.Play()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
// Set volume
|
||||
err = c.SetVolume(50)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### Device Discovery
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"log"
|
||||
"time"
|
||||
|
||||
"github.com/gesellix/bose-soundtouch/pkg/discovery"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// Discover SoundTouch devices
|
||||
service := discovery.NewService(5 * time.Second)
|
||||
devices, err := service.DiscoverDevices(context.Background())
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
for _, device := range devices {
|
||||
fmt.Printf("Found: %s at %s:%d\n",
|
||||
device.Name, device.Host, device.Port)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### Real-time Events
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"log"
|
||||
|
||||
"github.com/gesellix/bose-soundtouch/pkg/client"
|
||||
"github.com/gesellix/bose-soundtouch/pkg/models"
|
||||
)
|
||||
|
||||
func main() {
|
||||
c := client.NewClient(&client.Config{
|
||||
Host: "192.168.1.100",
|
||||
Port: 8090,
|
||||
})
|
||||
|
||||
// Subscribe to device events
|
||||
events, err := c.SubscribeToEvents(context.Background())
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
for event := range events {
|
||||
switch e := event.(type) {
|
||||
case *models.NowPlayingUpdated:
|
||||
fmt.Printf("Now playing: %s by %s\n", e.Track, e.Artist)
|
||||
case *models.VolumeUpdated:
|
||||
fmt.Printf("Volume changed to: %d\n", e.ActualVolume)
|
||||
case *models.ConnectionStateUpdated:
|
||||
fmt.Printf("Connection state: %s\n", e.State)
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### Preset Management
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
|
||||
"github.com/gesellix/bose-soundtouch/pkg/client"
|
||||
"github.com/gesellix/bose-soundtouch/pkg/models"
|
||||
)
|
||||
|
||||
func main() {
|
||||
c := client.NewClient(&client.Config{
|
||||
Host: "192.168.1.100",
|
||||
Port: 8090,
|
||||
})
|
||||
|
||||
// Get current presets
|
||||
presets, err := c.GetPresets()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
fmt.Printf("Found %d presets\n", len(presets.Preset))
|
||||
|
||||
// Store currently playing content as preset 1
|
||||
err = c.StoreCurrentAsPreset(1)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
// Store Spotify playlist as preset 2
|
||||
spotifyContent := &models.ContentItem{
|
||||
Source: "SPOTIFY",
|
||||
Type: "uri",
|
||||
Location: "spotify:playlist:37i9dQZF1DXcBWIGoYBM5M",
|
||||
SourceAccount: "your_username",
|
||||
IsPresetable: true,
|
||||
ItemName: "Today's Top Hits",
|
||||
}
|
||||
err = c.StorePreset(2, spotifyContent)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
// Store radio station as preset 3
|
||||
radioContent := &models.ContentItem{
|
||||
Source: "TUNEIN",
|
||||
Type: "stationurl",
|
||||
Location: "/v1/playbook/station/s33828",
|
||||
IsPresetable: true,
|
||||
ItemName: "K-LOVE Radio",
|
||||
}
|
||||
err = c.StorePreset(3, radioContent)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
// Select preset 1
|
||||
err = c.SelectPreset(1)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
fmt.Println("Preset management complete!")
|
||||
}
|
||||
```
|
||||
|
||||
#### Multiroom Zones
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/gesellix/bose-soundtouch/pkg/client"
|
||||
"github.com/gesellix/bose-soundtouch/pkg/models"
|
||||
)
|
||||
|
||||
func main() {
|
||||
master := client.NewClient(&client.Config{
|
||||
Host: "192.168.1.100", // Master speaker
|
||||
Port: 8090,
|
||||
})
|
||||
|
||||
// Create a multiroom zone
|
||||
zone := &models.Zone{
|
||||
Master: "192.168.1.100",
|
||||
Members: []models.ZoneMember{
|
||||
{IPAddress: "192.168.1.101"}, // Living room
|
||||
{IPAddress: "192.168.1.102"}, // Kitchen
|
||||
},
|
||||
}
|
||||
|
||||
err := master.SetZone(zone)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
fmt.Println("Multiroom zone created!")
|
||||
}
|
||||
```
|
||||
|
||||
#### Speaker Notifications (ST-10 only)
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/gesellix/bose-soundtouch/pkg/client"
|
||||
)
|
||||
|
||||
func main() {
|
||||
c := client.NewClient(&client.Config{
|
||||
Host: "192.168.1.100",
|
||||
Port: 8090,
|
||||
})
|
||||
|
||||
// Play Text-to-Speech message (language code "EN", "DE", etc.)
|
||||
err := c.PlayTTS("Welcome home!", "your-app-key", "EN", 70)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
// Play audio content from URL
|
||||
err = c.PlayURL(
|
||||
"https://example.com/doorbell.mp3",
|
||||
"your-app-key",
|
||||
"Doorbell",
|
||||
"Front Door",
|
||||
"Visitor Alert",
|
||||
80,
|
||||
)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
// Play notification beep
|
||||
err = c.PlayNotificationBeep()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
fmt.Println("Notifications sent!")
|
||||
}
|
||||
```
|
||||
|
||||
## Supported Devices
|
||||
|
||||
This library supports all Bose SoundTouch-compatible devices, including:
|
||||
|
||||
- SoundTouch 10, 20, 30 series
|
||||
- SoundTouch Portable
|
||||
- Wave SoundTouch music system
|
||||
- SoundTouch-enabled Bose speakers
|
||||
|
||||
**Tested Hardware**:
|
||||
- ✅ SoundTouch 10
|
||||
- ✅ SoundTouch 20
|
||||
|
||||
## API Coverage
|
||||
|
||||
| Feature | Status | Description |
|
||||
|---------|--------|-------------|
|
||||
| Device Info | ✅ Complete | Device details, name, capabilities |
|
||||
| Media Control | ✅ Complete | Play/pause/stop, track navigation |
|
||||
| Volume & Audio | ✅ Complete | Volume, bass, balance control |
|
||||
| Source Selection | ✅ Complete | Spotify, Bluetooth, AUX, etc. |
|
||||
| Content Navigation | ✅ Complete | Browse music libraries, radio stations |
|
||||
| Station Management | ✅ Complete | Search, add, remove stations |
|
||||
| Preset Management | ✅ Complete | Store, select, remove presets |
|
||||
| Real-time Events | ✅ Complete | WebSocket event streaming |
|
||||
| Multiroom Zones | ✅ Complete | Zone creation and management |
|
||||
| Speaker Notifications | ✅ Complete | TTS, URL audio, beep alerts (ST-10) |
|
||||
| System Settings | ✅ Complete | Clock, display, network info |
|
||||
| Advanced Audio | ✅ Complete | DSP controls, tone controls |
|
||||
|
||||
**API Limitations**: None - all documented SoundTouch Web API functionality is implemented, including endpoints discovered via the comprehensive [SoundTouch Plus Wiki](https://github.com/thlucas1/homeassistantcomponent_soundtouchplus/wiki/SoundTouch-WebServices-API).
|
||||
---
|
||||
|
||||
## Documentation
|
||||
|
||||
- 📖 [Contributing Guide](CONTRIBUTING.md) - How to contribute to the project
|
||||
- 📚 [API Reference](https://gesellix.github.io/Bose-SoundTouch/reference/API-ENDPOINTS.html) - Complete endpoint documentation
|
||||
- 🔧 [CLI Reference](https://gesellix.github.io/Bose-SoundTouch/guides/CLI-REFERENCE.html) - Command-line tool guide
|
||||
- 🌐 [SoundTouch Service Guide](https://gesellix.github.io/Bose-SoundTouch/guides/SOUNDTOUCH-SERVICE.html) - Local service setup and migration
|
||||
- 🎯 [Getting Started](https://gesellix.github.io/Bose-SoundTouch/guides/GETTING-STARTED.html) - Detailed setup and usage
|
||||
- 📻 [Preset Quick Start](https://gesellix.github.io/Bose-SoundTouch/PRESET-QUICKSTART.md) - Favorite content management
|
||||
- 🧭 [Navigation Guide](https://gesellix.github.io/Bose-SoundTouch/NAVIGATION-GUIDE.md) - Content browsing and station management
|
||||
- 📋 [Navigation API Reference](https://gesellix.github.io/Bose-SoundTouch/API-NAVIGATION-REFERENCE.md) - Navigation API documentation
|
||||
- ⚙️ [Advanced Features](https://gesellix.github.io/Bose-SoundTouch/reference/SYSTEM-ENDPOINTS.html) - Advanced functionality
|
||||
- 🏠 [Multiroom Setup](https://gesellix.github.io/Bose-SoundTouch/reference/ZONE-MANAGEMENT.html) - Zone configuration guide
|
||||
- ⚡ [WebSocket Events](https://gesellix.github.io/Bose-SoundTouch/reference/WEBSOCKET-EVENTS.html) - Real-time event handling
|
||||
- 🔔 [Speaker Notifications](https://gesellix.github.io/Bose-SoundTouch/reference/SPEAKER-ENDPOINT.html) - TTS and audio notifications guide
|
||||
- 🔍 [Device Discovery](https://gesellix.github.io/Bose-SoundTouch/reference/DISCOVERY.html) - Discovery configuration
|
||||
- 🛠️ [Troubleshooting](https://gesellix.github.io/Bose-SoundTouch/guides/TROUBLESHOOTING.html) - Common issues and solutions
|
||||
- [Getting Started](https://gesellix.github.io/Bose-SoundTouch/guides/GETTING-STARTED.html)
|
||||
- [Survival Guide](https://gesellix.github.io/Bose-SoundTouch/guides/SURVIVAL-GUIDE.html)
|
||||
- [Device Initial Setup](https://gesellix.github.io/Bose-SoundTouch/guides/DEVICE-INITIAL-SETUP.html)
|
||||
- [Migration & Safety Guide](https://gesellix.github.io/Bose-SoundTouch/guides/MIGRATION-SAFETY.html)
|
||||
- [CLI Reference](https://gesellix.github.io/Bose-SoundTouch/guides/CLI-REFERENCE.html)
|
||||
- [SoundTouch Service Guide](https://gesellix.github.io/Bose-SoundTouch/guides/SOUNDTOUCH-SERVICE.html)
|
||||
- [HTTPS & CA Setup](https://gesellix.github.io/Bose-SoundTouch/guides/HTTPS-SETUP.html)
|
||||
- [API Reference](https://gesellix.github.io/Bose-SoundTouch/reference/API-ENDPOINTS.html)
|
||||
|
||||
## Development
|
||||
---
|
||||
|
||||
### Prerequisites
|
||||
- Go 1.25.6 or later
|
||||
- Optional: SoundTouch device for testing
|
||||
## Related projects
|
||||
|
||||
### Building from Source
|
||||
```bash
|
||||
# Clone the repository
|
||||
git clone https://github.com/gesellix/bose-soundtouch.git
|
||||
cd Bose-SoundTouch
|
||||
- **[SoundCork](https://github.com/deborahgu/soundcork)** (Deborah Kaplan et al.) — Python service interception; pioneered the cloud emulation approach this project builds on
|
||||
- **[SoundCork Stockholm App](https://github.com/krahl/soundcork-stockholm-app)** — Companion app for SoundCork
|
||||
- **[SoundTouch Plus](https://github.com/thlucas1/homeassistantcomponent_soundtouchplus)** (Todd Lucas) — Home Assistant integration; extensive undocumented API documentation
|
||||
- **[ÜberBöse API](https://github.com/julius-d/ueberboese-api)** (Julius) — API research and advanced endpoint discovery
|
||||
- **[Bose SoundTouch Hook](https://github.com/CodeFinder2/bose-soundtouch-hook)** (Adrian Böckenkamp) — `LD_PRELOAD` hooking for reverse engineering device internals
|
||||
|
||||
# Install dependencies
|
||||
go mod download
|
||||
|
||||
# Build CLI tool
|
||||
make build
|
||||
|
||||
# Run tests
|
||||
make test
|
||||
|
||||
# Install CLI locally
|
||||
go install ./cmd/soundtouch-cli
|
||||
```
|
||||
|
||||
### Contributing
|
||||
|
||||
We welcome contributions! Please see our [Contributing Guide](CONTRIBUTING.md) for details on:
|
||||
|
||||
- Setting up your development environment
|
||||
- Coding guidelines and best practices
|
||||
- Testing with real devices
|
||||
- Submitting pull requests
|
||||
|
||||
## Examples
|
||||
|
||||
Check out the [examples/](examples/) directory for more usage patterns:
|
||||
|
||||
- **Basic HTTP Client**: Simple device control
|
||||
- **Preset Management**: Store and manage favorite content
|
||||
- **Navigation & Stations**: Browse content and manage radio stations
|
||||
- **WebSocket Events**: Real-time monitoring
|
||||
- **Device Discovery**: Finding devices on your network
|
||||
- **Multiroom Management**: Zone operations
|
||||
- **Advanced Audio**: DSP and tone controls
|
||||
|
||||
## License
|
||||
|
||||
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
|
||||
|
||||
## Disclaimer
|
||||
|
||||
This is an independent project based on the official Bose SoundTouch Web API documentation provided by Bose Corporation. It is not affiliated with, endorsed by, or supported by Bose Corporation. Use at your own risk.
|
||||
|
||||
SoundTouch is a trademark of Bose Corporation.
|
||||
|
||||
## SoundTouch End of Life Notice
|
||||
|
||||
**Important:** Bose has announced that [SoundTouch cloud support will end on May 6, 2026](https://www.bose.com/soundtouch-end-of-life).
|
||||
|
||||
**What will continue to work:**
|
||||
- ✅ Local API control (this library's primary functionality)
|
||||
- ✅ Bluetooth, AirPlay, Spotify Connect, and AUX streaming
|
||||
- ✅ Remote control features (Play, Pause, Skip, Volume)
|
||||
- ✅ Multiroom grouping
|
||||
|
||||
**What will stop working:**
|
||||
- ❌ Cloud-based preset sync between devices and SoundTouch app
|
||||
- ❌ Browsing music services directly from the SoundTouch app
|
||||
- ❌ Cloud-based features and updates
|
||||
|
||||
**What continues to work:**
|
||||
- ✅ Local preset management via this API client (store, select, remove)
|
||||
- ✅ Direct content playback (stations, playlists, etc.)
|
||||
|
||||
This Go library will continue to work as it uses the local Web API for direct device control, which is unaffected by the cloud service discontinuation. The local preset management functionality implemented in this library (discovered through the [SoundTouch Plus Wiki](https://github.com/thlucas1/homeassistantcomponent_soundtouchplus/wiki/SoundTouch-WebServices-API)) provides an alternative to the cloud-based preset features that will be discontinued.
|
||||
|
||||
**Community Alternatives**: See the [Related Projects & Credits](#related-projects--credits) section below for additional tools like SoundCork that provide cloud service alternatives and the SoundTouch Plus project that offers comprehensive Home Assistant integration.
|
||||
|
||||
## Related Projects & Credits
|
||||
|
||||
This project builds upon the excellent work of several community projects:
|
||||
|
||||
### SoundCork 🍾
|
||||
- **Project**: [SoundCork - SoundTouch API Intercept](https://github.com/deborahgu/soundcork)
|
||||
- **Authors**: Deborah Kaplan and contributors
|
||||
- **Our Implementation**: The `soundtouch-service` in this project is heavily inspired by SoundCork's Python implementation. SoundCork pioneered the approach of intercepting and emulating Bose's cloud services, providing the foundation for offline SoundTouch operation.
|
||||
- **Key Contributions**: Service emulation architecture, BMX/Marge endpoint discovery, device migration strategies
|
||||
- **License**: MIT License
|
||||
|
||||
### ÜberBöse API 🎵
|
||||
- **Project**: [ÜberBöse API](https://github.com/julius-d/ueberboese-api)
|
||||
- **Author**: Julius
|
||||
- **Our Implementation**: This project provided valuable insights into advanced SoundTouch API endpoints and helped make our implementation more complete, particularly for content navigation and advanced device features.
|
||||
- **Key Contributions**: Extended API endpoint documentation, advanced feature discovery
|
||||
- **License**: MIT License
|
||||
|
||||
### SoundTouch Plus 🏠
|
||||
- **Project**: [SoundTouch Plus Home Assistant Component](https://github.com/thlucas1/homeassistantcomponent_soundtouchplus)
|
||||
- **Wiki**: [SoundTouch WebServices API Documentation](https://github.com/thlucas1/homeassistantcomponent_soundtouchplus/wiki/SoundTouch-WebServices-API)
|
||||
- **Author**: Todd Lucas
|
||||
- **Our Implementation**: The comprehensive API documentation in the SoundTouch Plus Wiki provided invaluable insights into undocumented endpoints beyond the official API, enabling our preset management and content navigation features.
|
||||
- **Key Contributions**: Extensive API endpoint documentation, real-world usage patterns
|
||||
- **License**: MIT License
|
||||
|
||||
### SoundTouch Hook 🪝
|
||||
- **Project**: [Bose SoundTouch Hook](https://github.com/CodeFinder2/bose-soundtouch-hook)
|
||||
- **Author**: Adrian Böckenkamp
|
||||
- **Our Implementation**: This project provides a powerful framework for intercepting and hooking into internal device processes using `LD_PRELOAD`. It was instrumental in verifying internal function calls and understanding how the device validates cloud domains.
|
||||
- **Key Contributions**: Reverse engineering framework, process hooking, cross-compilation toolchain
|
||||
- **License**: GPL-3.0 License
|
||||
|
||||
### Community Ecosystem
|
||||
|
||||
These projects together form a comprehensive ecosystem for SoundTouch device management:
|
||||
|
||||
- **This Project**: Go library + CLI + service for programmatic control and offline operation
|
||||
- **SoundCork**: Python-based service interception and cloud replacement
|
||||
- **SoundTouch Plus**: Home Assistant integration with extensive device support
|
||||
- **ÜberBöse**: API research and advanced endpoint discovery
|
||||
- **SoundTouch Hook**: Advanced reverse engineering and process instrumentation
|
||||
|
||||
We are grateful to these projects and their maintainers for paving the way and providing the foundation that made this comprehensive Go implementation possible. The SoundTouch community's collaborative approach to reverse engineering and documentation has been invaluable.
|
||||
|
||||
### Contributing Back
|
||||
|
||||
If you discover new endpoints, features, or improvements through this library, please consider contributing back to these projects as well. The stronger our community ecosystem becomes, the better we can support SoundTouch devices beyond Bose's official support timeline.
|
||||
---
|
||||
|
||||
## Support
|
||||
|
||||
- 🐛 **Bug Reports**: [Create an issue](https://github.com/gesellix/bose-soundtouch/issues/new)
|
||||
- 💡 **Feature Requests**: [Start a discussion](https://github.com/gesellix/bose-soundtouch/discussions)
|
||||
- ❓ **Questions**: Check [existing discussions](https://github.com/gesellix/bose-soundtouch/discussions)
|
||||
- 📖 **Documentation**: [Online Documentation](https://gesellix.github.io/Bose-SoundTouch/)
|
||||
- 🔍 **New Discoveries**: [Undocumented Community Features](https://gesellix.github.io/Bose-SoundTouch/UNDOCUMENTED-COMMUNITY-FEATURES.md)
|
||||
- 🌐 **Upstream Analysis**: [Upstream URLs & Domains](https://gesellix.github.io/Bose-SoundTouch/analysis/UPSTREAM-URLS.html)
|
||||
- 🔧 **Redirection Guide**: [Device Redirect Methods](https://gesellix.github.io/Bose-SoundTouch/analysis/DEVICE-REDIRECT-METHODS.html)
|
||||
- 🐣 **Initial Setup**: [Device Initial Setup Variants](https://gesellix.github.io/Bose-SoundTouch/guides/DEVICE-INITIAL-SETUP.html)
|
||||
- 📜 **Logging & Debugging**: [Device Logging Guide](https://gesellix.github.io/Bose-SoundTouch/DEVICE-LOGGING.md)
|
||||
- 🔒 **HTTPS & CA Setup**: [HTTPS & Custom CA Guide](https://gesellix.github.io/Bose-SoundTouch/guides/HTTPS-SETUP.html)
|
||||
- Bug reports: [GitHub Issues](https://github.com/gesellix/bose-soundtouch/issues/new)
|
||||
- Questions & discussions: [GitHub Discussions](https://github.com/gesellix/bose-soundtouch/discussions)
|
||||
|
||||
---
|
||||
|
||||
**Star this project** ⭐ if you find it useful!
|
||||
|
||||
---
|
||||
|
||||
## License
|
||||
|
||||
MIT — see [LICENSE](LICENSE).
|
||||
|
||||
SoundTouch is a trademark of Bose Corporation.
|
||||
|
||||
+60
-74
@@ -1,81 +1,64 @@
|
||||
# HTTPS Setup & Custom CA Certificate
|
||||
# HTTPS & Custom CA Certificate
|
||||
|
||||
To use the `/etc/hosts` redirection method safely, SoundTouch devices must communicate over HTTPS. This requires the device to trust the AfterTouch Root CA certificate used by the local service.
|
||||
SoundTouch speakers communicate with cloud services over HTTPS. For the local service to work over HTTPS, speakers must trust the AfterTouch Root CA. The service manages this automatically — it generates a CA on first start and the web UI guides you through installing it on each speaker as part of the migration flow.
|
||||
|
||||
## 1. Automated Migration (Hosts Method)
|
||||
---
|
||||
|
||||
The `soundtouch-service` can automatically configure a device to use the `/etc/hosts` method:
|
||||
## How TLS works in AfterTouch
|
||||
|
||||
```bash
|
||||
curl -X POST "http://localhost:8000/setup/migrate/{deviceIP}?method=hosts"
|
||||
The service includes a built-in HTTPS listener (default port `8443`) that presents a certificate covering all Bose cloud hostnames. The certificate is signed by the AfterTouch Root CA, which is generated automatically on first start and stored in `data/certs/`.
|
||||
|
||||
**Domain coverage** — the certificate covers:
|
||||
- Wildcard: `*.api.bose.io`, `*.api.bosecm.com`
|
||||
- Specific: `streaming.bose.com`, `bmx.bose.com`, `stats.bose.com`, `updates.bose.com`, `worldwide.bose.com`, `bose-prod.apigee.net`, `media.bose.io`, `downloads.bose.com`, `voice.api.bose.io`, and more
|
||||
|
||||
> **Note**: The hostname you configure as `HTTPS_SERVER_URL` (e.g. `https://soundtouch.fritz.box:8443`) is also added as a Subject Alternative Name, ensuring valid TLS for direct browser or API access.
|
||||
|
||||
---
|
||||
|
||||
## CA trust installation (via web UI)
|
||||
|
||||
The migration flow in the web UI includes a CA trust step that:
|
||||
1. Uploads the Root CA to the speaker via SSH
|
||||
2. Appends it to the speaker's shared trust store (`/etc/pki/tls/certs/ca-bundle.crt`)
|
||||
3. Verifies connectivity over HTTPS
|
||||
|
||||
This is handled automatically — you don't need to manage CA files manually unless you're doing an advanced or manual setup.
|
||||
|
||||
---
|
||||
|
||||
## Downloading the CA certificate
|
||||
|
||||
You can download the Root CA for manual installation on other devices (phones, PCs, additional speakers):
|
||||
|
||||
```
|
||||
http://<server>:8000/setup/ca.crt
|
||||
```
|
||||
|
||||
This command will:
|
||||
1. Connect to the device via SSH.
|
||||
2. Update `/etc/hosts` to point Bose domains to the service IP.
|
||||
3. Inject the auto-generated AfterTouch Root CA into the device's trust store (`/etc/pki/tls/certs/ca-bundle.crt`).
|
||||
4. Reboot the device.
|
||||
---
|
||||
|
||||
## 2. Managing the Root CA
|
||||
## Binding to port 443
|
||||
|
||||
The AfterTouch service automatically generates a Root CA when it first starts.
|
||||
Speakers expect HTTPS on the default port 443. Since binding to port 443 requires elevated privileges, you have three options:
|
||||
|
||||
- **CA Certificate**: `data/certs/ca.crt`
|
||||
- **CA Private Key**: `data/certs/ca.key`
|
||||
1. **Port forwarding (recommended)**: Run the service on port 8443 and forward port 443 to it using `iptables` or your firewall/router.
|
||||
2. **Capabilities**: Grant the binary permission to bind low ports: `sudo setcap 'cap_net_bind_service=+ep' ./soundtouch-service`
|
||||
3. **Reverse proxy**: Use Nginx or Caddy in front of the service (see below).
|
||||
|
||||
### Downloading the CA Certificate
|
||||
You can download the CA certificate for manual installation on other devices (like your phone or PC) from:
|
||||
`http://<server-ip>:8000/setup/ca.crt`
|
||||
---
|
||||
|
||||
### 3. Built-in HTTPS Support
|
||||
## Reverse proxy (optional)
|
||||
|
||||
The `soundtouch-service` now includes a built-in HTTPS listener. This simplifies the `/etc/hosts` redirection method by automatically presenting the correct certificates for Bose domains.
|
||||
|
||||
- **HTTPS Port**: Configurable via `HTTPS_PORT` environment variable (defaults to `8443`).
|
||||
- **HTTPS Server URL**: Configurable via `HTTPS_SERVER_URL` (e.g., `https://mysoundtouch.local:8443`). If not set, the service attempts to guess it using the system hostname.
|
||||
- **Domain Coverage**: Automatically presents a certificate with comprehensive coverage using wildcard certificates (`*.api.bose.io`, `*.api.bosecm.com`) plus specific domains (`streaming.bose.com`, `updates.bose.com`, `stats.bose.com`, `bmx.bose.com`, `worldwide.bose.com`, `bose-prod.apigee.net`, etc.).
|
||||
- **Wildcard Support**: Uses RFC-compliant wildcard certificates for automatic coverage of all API subdomains, including event analytics endpoints like `events.api.bosecm.com`, `eventsdev.api.bosecm.com`, and future API services.
|
||||
- **TLS Error Logging**: Comprehensive logging of TLS handshake attempts, certificate matching, and connection failures for debugging DNS redirection issues.
|
||||
- **Automatic Setup**: On first start, it generates a server certificate signed by your AfterTouch local Root CA.
|
||||
|
||||
#### TLS Security & Debugging
|
||||
|
||||
The built-in HTTPS listener is configured to use modern and secure TLS settings while maintaining compatibility with SoundTouch devices (which support up to TLS 1.2 with OpenSSL 1.0.2).
|
||||
|
||||
- **Minimum TLS Version**: TLS 1.2
|
||||
- **Preferred Cipher Suites**:
|
||||
- `ECDHE-RSA-AES128-GCM-SHA256`
|
||||
- **TLS Debugging**: Detailed logging of:
|
||||
- Certificate requests by domain (`[TLS] Certificate request for ServerName: events.api.bosecm.com`)
|
||||
- Wildcard certificate matching (`[TLS] ✅ Serving certificate for events.api.bosecm.com (matched *.api.bosecm.com)`)
|
||||
- Handshake failures (`[TLS] ❌ Handshake failed from 192.168.1.50: tls: certificate not found`)
|
||||
- Successful connections (`[TLS] ✅ Successful connection from 192.168.1.50`)
|
||||
- `ECDHE-RSA-AES256-GCM-SHA384`
|
||||
- `ECDHE-RSA-CHACHA20-POLY1305`
|
||||
- `RSA-AES128-GCM-SHA256` (Legacy support)
|
||||
- `RSA-AES256-GCM-SHA384` (Legacy support)
|
||||
|
||||
#### Binding to Port 443
|
||||
SoundTouch devices expect HTTPS on the default port 443. Since binding to port 443 usually requires root privileges, you have two options:
|
||||
|
||||
1. **Port Forwarding (Recommended)**: Run the service on a high port (e.g., 8443) and use `iptables` or your firewall to forward traffic from 443 to 8443.
|
||||
2. **Capabilities**: Grant the binary permission to bind to low ports: `sudo setcap 'cap_net_bind_service=+ep' ./soundtouch-service`.
|
||||
3. **Reverse Proxy**: Use Nginx or Caddy as described below.
|
||||
|
||||
### 4. Reverse Proxy (Optional)
|
||||
|
||||
1. **Generate a certificate** for the Bose domains signed by your Root CA.
|
||||
2. **Configure Nginx** to use this certificate and proxy requests to `soundtouch-service`.
|
||||
If you prefer to use Nginx or another proxy for TLS termination:
|
||||
|
||||
```nginx
|
||||
server {
|
||||
listen 443 ssl;
|
||||
server_name streaming.bose.com bmx.bose.com stats.bose.com updates.bose.com;
|
||||
|
||||
ssl_certificate /path/to/generated-cert.crt;
|
||||
ssl_certificate_key /path/to/generated-cert.key;
|
||||
ssl_certificate /path/to/data/certs/server.crt;
|
||||
ssl_certificate_key /path/to/data/certs/server.key;
|
||||
|
||||
# Secure TLS configuration (matches soundtouch-service defaults)
|
||||
ssl_protocols TLSv1.2;
|
||||
ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-CHACHA20-POLY1305:AES128-GCM-SHA256:AES256-GCM-SHA384';
|
||||
|
||||
@@ -87,23 +70,26 @@ server {
|
||||
}
|
||||
```
|
||||
|
||||
## 5. Manual CA Injection (Legacy/Manual)
|
||||
---
|
||||
|
||||
If you prefer to inject the CA certificate manually:
|
||||
## Manual CA injection (advanced)
|
||||
|
||||
1. Copy `ca.crt` to the device:
|
||||
```bash
|
||||
scp data/certs/ca.crt root@{deviceIP}:/tmp/
|
||||
```
|
||||
2. Append it to the trust store on the device:
|
||||
```bash
|
||||
ssh root@{deviceIP} "(rw || mount -o remount,rw /) && cat /tmp/ca.crt >> /etc/pki/tls/certs/ca-bundle.crt"
|
||||
```
|
||||
If you need to inject the CA manually (e.g. without the web UI migration flow):
|
||||
|
||||
## 6. Verifying Connectivity
|
||||
```bash
|
||||
# Copy the CA to the speaker
|
||||
scp data/certs/ca.crt root@<SPEAKER-IP>:/tmp/
|
||||
|
||||
You can verify that your device can correctly reach the `soundtouch-service` over HTTPS using the management web UI.
|
||||
# Make the filesystem writable and append the CA to the trust store
|
||||
ssh root@<SPEAKER-IP> "(rw || mount -o remount,rw /) && cat /tmp/ca.crt >> /etc/pki/tls/certs/ca-bundle.crt"
|
||||
```
|
||||
|
||||
In the **Migration Summary** for a device, you will find an **HTTPS Connection Test** section:
|
||||
- **Test with Explicit CA.crt**: Uploads a temporary copy of the Root CA to the device and uses `curl --cacert` to verify the connection. Use this to verify your HTTPS setup *before* modifying the device's shared trust store.
|
||||
- **Test with Shared Trust Store**: Uses the device's default trust store. Use this to verify that your CA injection was successful and the device now natively trusts your local server.
|
||||
---
|
||||
|
||||
## TLS compatibility
|
||||
|
||||
SoundTouch speakers run OpenSSL 1.0.2, supporting up to TLS 1.2. The service is configured accordingly:
|
||||
|
||||
- **Minimum TLS version**: TLS 1.2
|
||||
- **Preferred cipher suites**: `ECDHE-RSA-AES128-GCM-SHA256`, `ECDHE-RSA-AES256-GCM-SHA384`, `ECDHE-RSA-CHACHA20-POLY1305`
|
||||
- **Legacy support**: `RSA-AES128-GCM-SHA256`, `RSA-AES256-GCM-SHA384`
|
||||
@@ -1,4 +1,4 @@
|
||||
### Professional Migration & Safety Guide
|
||||
# Migration & Safety Guide
|
||||
|
||||
Starting a migration on real hardware requires a "Safety First" approach. This guide outlines the safety features implemented in the `soundtouch-service` and provides a checklist for a successful migration.
|
||||
|
||||
@@ -14,8 +14,8 @@ The following features are built into the `soundtouch-service` to ensure stabili
|
||||
|
||||
Before you proceed with the actual migration, follow these steps:
|
||||
|
||||
1. **Enable SSH Access (Prerequisite)**: This toolkit requires SSH access to your speakers, which is not enabled by default.
|
||||
- Create an empty file named `remote_services` on a USB stick.
|
||||
1. **Enable SSH Access (Prerequisite)**: This toolkit requires SSH access to your speakers, which is not enabled by default.
|
||||
- Create a file named `remote_services` on a FAT-formatted USB drive. The drive may need its bootable flag set — see [SoundCork issue #172](https://github.com/deborahgu/soundcork/issues/172) for details.
|
||||
- Insert the USB stick into the SoundTouch speaker's **SERVICE** port.
|
||||
- Reboot the speaker (unplug and replug).
|
||||
- The speaker will now allow SSH connections as `root` with no password.
|
||||
@@ -27,10 +27,11 @@ Before you proceed with the actual migration, follow these steps:
|
||||
4. **Validate SSH Access**: Confirm the device responds to SSH without a password.
|
||||
- In the Web UI **Migration** tab, select your speaker and verify that the "SSH Connection" status shows ✅ Success.
|
||||
- This toolkit automatically handles the necessary SSH parameters (ciphers and key exchanges) required by older Bose firmware.
|
||||
5. **Migration Methods**:
|
||||
- **XML Migration (Default)**: Less invasive, only changes the application config. Best for simple redirection.
|
||||
- **Hosts Migration**: Modifies `/etc/hosts` on the device. Good for system-wide redirection of specific domains.
|
||||
- **ResolvConf Migration**: Points the device to the AfterTouch DNS server. Best for discovering unknown Bose endpoints and dynamic interception. **Note**: This method requires the DNS Discovery Server to be running on port 53. The service includes a pre-flight check to ensure the server is properly bound before allowing this migration.
|
||||
5. **Migration Methods**:
|
||||
- **XML redirect (default)**: Uploads a config file to the speaker via the Web API. Less invasive — only changes the application-level service URLs. Best for testing or single-device migration.
|
||||
- **DNS/DHCP redirect**: Configures the speaker to use a custom DNS server that resolves Bose hostnames to the local service. Best for all-device coverage; requires the AfterTouch DNS server running on port 53. The service includes a pre-flight check before applying this method.
|
||||
|
||||
The web UI walks you through both methods. Both require the CA certificate to be trusted on the speaker for HTTPS to work — the web UI handles this as part of the migration flow.
|
||||
6. **Monitor Logs**: Run the `soundtouch-service` with `DEBUG` or `INFO` logging to see the step-by-step progress of the migration.
|
||||
|
||||
#### 🔄 Rollback Strategy
|
||||
|
||||
@@ -7,7 +7,7 @@ The `soundtouch-service` is a comprehensive local server that emulates Bose's cl
|
||||
The service provides:
|
||||
|
||||
- **🏠 Local Service Emulation**: Complete BMX (Bose Media eXchange) and Marge service implementation
|
||||
- **🔧 Device Migration**: Seamlessly migrate devices from Bose cloud to local services via XML config, `/etc/hosts`, or `/etc/resolv.conf`
|
||||
- **🔧 Device Migration**: Migrate devices from Bose cloud to local services via XML redirect or DNS/DHCP redirect
|
||||
- **🔍 DNS Discovery & Interception**: Built-in DNS server to discover unknown Bose endpoints and selectively intercept cloud traffic
|
||||
- **📊 Traffic Proxying**: Inspect and log all device communications for debugging
|
||||
- **🌐 Web Management UI**: Browser-based interface for device management
|
||||
@@ -169,7 +169,7 @@ The service supports multiple ways to configure its behavior. When multiple sour
|
||||
| `DISCOVERY_INTERVAL` | `--discovery-interval` | Device discovery interval | `5m` |
|
||||
| `ENABLE_DNS_DISCOVERY` | `--dns-discovery` | Enable DNS discovery server | `false` |
|
||||
| `DNS_UPSTREAM` | `--dns-upstream` | Upstream DNS server for non-Bose queries | `8.8.8.8` |
|
||||
| `DNS_BIND_ADDR` | `--dns-bind` | Bind address for the DNS discovery server (standard port `:53` is required for `resolv.conf` migration) | `:53` |
|
||||
| `DNS_BIND_ADDR` | `--dns-bind` | Bind address for the DNS discovery server (standard port `:53` is required for DNS/DHCP migration) | `:53` |
|
||||
| `MIRROR_ENABLED` | | Enable background mirroring of specific endpoints to Bose cloud | `false` |
|
||||
| `MIRROR_ENDPOINTS` | | Comma-separated list of path patterns to mirror (e.g., `/streaming/account/*/device/*/recent`) | `[]` |
|
||||
| `INTERNAL_PATHS` | `--internal-paths` | Paths for internal requests to exclude from recording (e.g., `/setup/*`, `/web/*`) | `[]` |
|
||||
@@ -247,7 +247,7 @@ curl "http://192.168.1.100:8090/presets"
|
||||
curl "http://localhost:8000/events/192.168.1.100"
|
||||
```
|
||||
|
||||
#### ResolvConf Migration (DHCP-Aware DNS Redirection)
|
||||
#### DNS/DHCP Migration (DHCP-Aware DNS Redirection)
|
||||
|
||||
The most robust and flexible DNS-based migration method. It utilizes the device's persistent `/mnt/nv/rc.local` script to inject a priority DNS hook into the system's DHCP configuration.
|
||||
|
||||
@@ -665,7 +665,7 @@ find data/stats/ -name "*.json" -mtime +90 -delete
|
||||
- `GET /setup/discovery-status`: Check if a scan is currently in progress.
|
||||
- `POST /setup/sync/{deviceIP}`: Fetch presets, recents, and sources from a device.
|
||||
- `GET /setup/summary/{deviceIP}`: Get a detailed migration readiness summary.
|
||||
- `POST /setup/migrate/{deviceIP}`: Migrate a device using the specified method (XML/Hosts).
|
||||
- `POST /setup/migrate/{deviceIP}`: Migrate a device using the specified method (XML or DNS).
|
||||
- `GET /setup/ca.crt`: Download the Root CA certificate for manual installation.
|
||||
|
||||
#### `GET /setup/interactions`
|
||||
|
||||
@@ -1,85 +1,107 @@
|
||||
### Bose Cloud Shutdown: Survival Guide for SoundTouch
|
||||
# Bose Cloud Shutdown: Survival Guide
|
||||
|
||||
With Bose's announcement of discontinuing cloud support for SoundTouch devices in May 2026, this project provides the necessary tools to keep your speakers fully functional using a local emulation service.
|
||||
Bose is shutting down SoundTouch cloud services on **May 6, 2026**. After that date, the following stop working:
|
||||
|
||||
This guide explains how to set up the `soundtouch-service` to run your devices independently of Bose's servers.
|
||||
- Music service browsing (TuneIn, Spotify connect via app, etc.)
|
||||
- Preset and recently-played sync
|
||||
- The official SoundTouch app
|
||||
- Software update checks
|
||||
|
||||
What **continues to work** regardless:
|
||||
- Local playback controls via `soundtouch-cli`, `soundtouch-web`, or any app that uses the local Web API
|
||||
- Bluetooth, AUX, and AirPlay inputs
|
||||
- Multiroom zones (local, peer-to-peer)
|
||||
|
||||
**AfterTouch** — the `soundtouch-service` — restores everything in the first list by running a local replacement for the Bose cloud on your own network.
|
||||
|
||||
---
|
||||
|
||||
### Supported Use Cases
|
||||
## How it works
|
||||
|
||||
1. **Local Service Emulation**: The service emulates Bose's BMX (Bose Media eXchange) and Marge services, which handle content registries, presets, recents, and software update checks.
|
||||
2. **Traffic Redirection**: Tools are provided to redirect your speakers to this local service instead of `*.bose.com`.
|
||||
3. **Offline Operation**: Once redirected, the speakers function without needing to reach Bose's servers.
|
||||
4. **Preset & Recent Management**: Captures and stores presets and "recently played" items locally.
|
||||
The service emulates the Bose cloud endpoints that speakers call for music service browsing, device registration, preset sync, and update checks. Once a speaker is redirected to point at the local service instead of Bose's servers, it operates independently. The built-in web UI at `http://<server>:8000` handles all setup steps.
|
||||
|
||||
---
|
||||
|
||||
### Setup Steps
|
||||
## Prerequisites
|
||||
|
||||
To set up your SoundTouch system for local-only operation, follow these steps:
|
||||
### 1. A machine that's always on
|
||||
|
||||
#### 1. Install and Start the Service
|
||||
Run the `soundtouch-service` on a machine that is always on (like a Raspberry Pi or a NAS) within your local network.
|
||||
The service must run on a host that's available whenever your speakers are in use — a Raspberry Pi, NAS, home server, or similar. The host needs a stable local address (e.g. `soundtouch.fritz.box` or a fixed IP) reachable from your speakers.
|
||||
|
||||
```bash
|
||||
# Install the service
|
||||
go install github.com/gesellix/bose-soundtouch/cmd/soundtouch-service@latest
|
||||
See [Raspberry Pi Setup](RASPBERRY-PI.md) and the [SoundTouch Service Guide](SOUNDTOUCH-SERVICE.md) for deployment options, including Docker.
|
||||
|
||||
# Start the service (defaults to http://localhost:8000)
|
||||
soundtouch-service
|
||||
```
|
||||
### 2. SSH access on your speakers (for migration)
|
||||
|
||||
#### 2. Access the Management UI
|
||||
Open your web browser and navigate to the service's web interface:
|
||||
`http://<your-server-ip>:8000/`, e.g. `http://localhost:8000/`
|
||||
Redirecting a speaker's service URLs requires writing to its configuration. This is done via SSH. Enable it once per device:
|
||||
|
||||
*Note: The service also supports a `/web/` path for management.*
|
||||
1. Create a file named `remote_services` on a FAT-formatted USB drive. The drive may need its bootable flag set — see [SoundCork issue #172](https://github.com/deborahgu/soundcork/issues/172) for details.
|
||||
2. Insert the drive into the speaker's USB port while it's powered on.
|
||||
3. Power-cycle the speaker (unplug and replug). After boot, root SSH is available with no password.
|
||||
|
||||
#### 3. Enable SSH on Your Speakers
|
||||
To migrate your speakers, the service needs SSH access. You can enable it by:
|
||||
1. Creating an empty file named `remote_services` on a USB stick.
|
||||
2. Inserting the USB stick into the SoundTouch speaker's service port.
|
||||
3. Rebooting the speaker (unplug/replug).
|
||||
|
||||
**Verify SSH Access:**
|
||||
- Confirm the device responds to SSH without a password: `ssh -o HostKeyAlgorithms=+ssh-rsa -o PubkeyAcceptedAlgorithms=+ssh-rsa root@<IP>`
|
||||
- Or use the **Migration** tab in the Web UI to see if the device shows a "✅ Success" status for SSH.
|
||||
Once enabled, you can log in as `root` (no password).
|
||||
|
||||
#### 4. Setup Through the Web UI
|
||||
The web interface handles the entire process in a guided flow. Before proceeding, we strongly recommend reviewing the [Migration & Safety Guide](MIGRATION-SAFETY.md).
|
||||
|
||||
* **Step 1: Settings**: Configure your server's IP or domain. This ensures the speakers know where to find the local services.
|
||||
* **Step 2: Devices**: The service automatically scans for SoundTouch devices on your network. If a device is not found, you can manually add its IP address.
|
||||
* **Step 3: Data Sync**: Select your device and click "Start Sync". This will automatically fetch your presets, recents, and configured sources from the speaker and store them in the local `data/` directory.
|
||||
* **Step 4: Migration**: Choose your redirection method (XML Recommended) and click "Confirm Migration". After the migration, reboot your speaker to apply the changes.
|
||||
|
||||
#### 5. Verify Your Local Data
|
||||
Once migrated, your speaker will use the data captured during the Sync step.
|
||||
* The service stores data in the `data/` directory, organized by device serial number (e.g., `data/default/devices/<SERIAL>/`).
|
||||
* **Automatic Capture**: As you use the device (changing presets, playing new music), the service continues to "learn" and update your local files.
|
||||
You can leave SSH enabled for future maintenance, or disable it once migration is complete.
|
||||
|
||||
---
|
||||
|
||||
### Comparison with other implementations (soundcork)
|
||||
Our implementation (`soundtouch-service`) is largely compatible with the Python-based `soundcork` project but offers several advantages:
|
||||
- **Web UI**: Integrated management interface for discovery and migration.
|
||||
- **Surgical Migration**: Uses XML-based redirection by default, which is less invasive than `/etc/hosts`.
|
||||
- **Automated SSL**: Handles Root CA injection automatically for secure communication.
|
||||
- **Proxy Support**: Can proxy requests to original Bose servers while "learning" your configuration.
|
||||
## Scenario A: Migrate before the shutdown
|
||||
|
||||
Do this while the Bose cloud is still running. Your existing presets and listening history are preserved.
|
||||
|
||||
**Step 1 — Back up your data.**
|
||||
Run `soundtouch-backup all` to save your Bose account data (presets, paired devices, music sources) and each speaker's local state. See the [soundtouch-backup README](../../cmd/soundtouch-backup/README.md) for usage.
|
||||
|
||||
**Step 2 — Start the service and open the web UI** at `http://<server>:8000`.
|
||||
|
||||
**Step 3 — Configure the server URL.**
|
||||
In the Settings tab, set the server URL to the address your speakers can reach (e.g. `http://soundtouch.fritz.box:8000`). If you plan to use DNS/DHCP redirect, also configure the HTTPS server URL.
|
||||
|
||||
**Step 4 — Add your speaker.**
|
||||
The service discovers devices on your network automatically. If a speaker doesn't appear, add it manually by IP address.
|
||||
|
||||
**Step 5 — Sync device data.**
|
||||
Click "Sync" on the device to pull its current presets, recents, and sources from the Bose cloud into the local service's datastore.
|
||||
|
||||
**Step 6 — Migrate.**
|
||||
The web UI offers two redirect methods and walks you through each step:
|
||||
|
||||
| Method | How it works | When to use |
|
||||
|--------------|--------------------------------------------------------|----------------------------------------------------------|
|
||||
| XML redirect | Uploads a config file to the speaker via the Web API | Testing; simpler setup; covers only registered endpoints |
|
||||
| DNS/DHCP | Custom DNS resolves Bose hostnames to the local server | All devices at once; full coverage |
|
||||
|
||||
Both methods require TLS when the speaker uses HTTPS to contact the service. The web UI guides you through installing the service's CA certificate on the speaker (requires SSH).
|
||||
|
||||
**Step 7 — Reboot the speaker.**
|
||||
Power-cycle the speaker to apply the changes. After reboot it contacts the local service instead of Bose's cloud.
|
||||
|
||||
---
|
||||
|
||||
### Alternative: DNS Redirection (No SSH)
|
||||
If you prefer not to modify your speakers via SSH, you can use a local DNS server (like Pi-hole, AdGuard Home, or Unbound) to point the following domains to your local server's IP:
|
||||
## Scenario B: Set up after the shutdown (or after a factory reset)
|
||||
|
||||
* `bmx.bose.com`
|
||||
* `streaming.bose.com`
|
||||
* `updates.bose.com`
|
||||
* `stats.bose.com`
|
||||
* `content.api.bose.io`
|
||||
If the Bose cloud is gone, or you've factory-reset a speaker, there's no existing account to migrate from. You start fresh with a local account.
|
||||
|
||||
*Note: DNS redirection for HTTPS services requires the speakers to trust your local service's SSL certificate. The SSH-based migration handles this automatically by injecting the CA.*
|
||||
**Step 1 — Set up DNS/DHCP redirect first** (recommended).
|
||||
Configure your network's DNS to resolve the Bose cloud hostnames to the local service's address before the speaker tries to register. This way, when the speaker boots and attempts to register, it reaches AfterTouch automatically instead of failing to reach Bose.
|
||||
|
||||
See the [SoundTouch Service Guide](SOUNDTOUCH-SERVICE.md) for the built-in DNS server configuration and the list of hostnames to redirect.
|
||||
|
||||
**Step 2 — Connect the speaker to Wi-Fi.**
|
||||
Use the speaker's built-in AP mode or BLE setup flow. See [Device Initial Setup](DEVICE-INITIAL-SETUP.md) for factory reset button sequences and Wi-Fi provisioning.
|
||||
|
||||
**Step 3 — Start the service and open the web UI** at `http://<server>:8000`.
|
||||
|
||||
**Step 4 — Add the speaker.**
|
||||
After connecting to Wi-Fi, the speaker should appear in the web UI automatically (or add it manually by IP). If DNS redirect is already in place, the speaker is already communicating with AfterTouch.
|
||||
|
||||
**Step 5 — Migrate** (if not already using DNS redirect).
|
||||
If you didn't set up DNS first, use the XML redirect method from the web UI to update the speaker's service URLs. The web UI walks you through the steps including CA certificate setup.
|
||||
|
||||
**Step 6 — Reboot the speaker.**
|
||||
Power-cycle to ensure all changes take effect.
|
||||
|
||||
---
|
||||
|
||||
## After migration
|
||||
|
||||
Once migrated, your speaker uses the local service for music browsing, preset sync, and device registration. The web UI at `http://<server>:8000` is your management interface going forward. Back up the `data/` directory periodically in case you need to restore.
|
||||
|
||||
For safety measures, rollback options, and technical details about the migration process, see the [Migration & Safety Guide](MIGRATION-SAFETY.md).
|
||||
|
||||
Reference in New Issue
Block a user