mirror of
https://github.com/gesellix/Bose-SoundTouch.git
synced 2026-08-24 14:47:23 +00:00
Introduces a standalone `soundtouch-backup` CLI with three subcommands: - `all`: authenticates with the Bose cloud, backs up account data, then reads device IPs from devices.xml and backs up each reachable speaker - `cloud`: fetches account profile, devices, sources, presets, and full endpoint from streaming.bose.com - `local`: backs up each speaker via HTTP API (12 endpoints) and optionally via SSH (individual files + /opt/Bose/etc/ and /mnt/nv/BoseApp-Persistence/1/ directories) Also centralises pkg/service/ssh → pkg/ssh so both the service and the backup tool share the same SSH client; adds ReadFile and ReadDir methods, and handles the firmware quirk where cat exits 1 on empty files. Output is a single dated .tar.gz or .zip archive. Example flow: ```shell gesellix@Mac Bose-SoundTouch % go run ./cmd/soundtouch-backup all --output _/cloud-backup --email user@example.com Password: Authenticating as user@example.com... ✓ Authenticated (account ID: 1234567) ✓ email address (107 bytes) ✓ devices (1492 bytes) ✓ sources (1111 bytes) ✓ presets (2585 bytes) ✓ full account (55037 bytes) Found 2 device(s) in cloud account, attempting local backup... ✓ ST20: 12 files via HTTP ⚠ ST20: SSH skipped /etc/remote_services (Process exited with status 1) ⚠ ST20: SSH empty file /mnt/nv/remote_services ✓ ST20: 64 files via SSH ✓ ST10: 12 files via HTTP ⚠ ST10: SSH empty file /etc/remote_services ⚠ ST10: SSH skipped /mnt/nv/remote_services (Process exited with status 1) ✓ ST10: 48 files via SSH Archive written: _/cloud-backup/soundtouch-backup-2026-05-02.tar.gz (141 files) ``` --------- Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
213 lines
9.4 KiB
Markdown
213 lines
9.4 KiB
Markdown
# soundtouch-backup
|
|
|
|
A standalone tool for backing up Bose SoundTouch data — both your **cloud account** (presets, devices, sources) and the **local filesystem** of each speaker — before the Bose cloud services shut down on May 6, 2026.
|
|
|
|
## Overview
|
|
|
|
| Subcommand | What it backs up |
|
|
|------------|----------------------------------------------------------------------------------------------------|
|
|
| `all` | Cloud account **and** all paired speakers in one step — the recommended starting point |
|
|
| `cloud` | Bose account profile, paired devices, cloud presets, music service sources |
|
|
| `local` | Speaker HTTP API data (presets, sources, volume, …) and optionally device filesystem files via SSH |
|
|
|
|
Output is a single `.tar.gz` archive (or `.zip`) with a dated root directory.
|
|
|
|
## Building
|
|
|
|
```bash
|
|
make build-backup
|
|
# binary: ./build/soundtouch-backup
|
|
```
|
|
|
|
Or install alongside the other tools:
|
|
|
|
```bash
|
|
make install
|
|
```
|
|
|
|
## Usage
|
|
|
|
### Combined backup (recommended)
|
|
|
|
The `all` command is the simplest way to capture everything: it authenticates with the Bose cloud, backs up your account data, then reads the IP addresses from `devices.xml` and backs up each reachable speaker over HTTP.
|
|
|
|
```bash
|
|
# Interactive — prompts for email and password
|
|
soundtouch-backup all
|
|
|
|
# Non-interactive
|
|
soundtouch-backup all --email you@example.com --password secret
|
|
|
|
# Include SSH filesystem backup for each speaker
|
|
soundtouch-backup all --ssh
|
|
|
|
# Environment variables
|
|
BOSE_EMAIL=you@example.com BOSE_PASSWORD=secret soundtouch-backup all --ssh
|
|
```
|
|
|
|
**Flags**
|
|
|
|
| Flag | Short | Default | Description |
|
|
|--------------|--------|---------------------------------------|--------------------------------------------------------|
|
|
| `--email` | `-e` | — | Bose account email (`$BOSE_EMAIL`) |
|
|
| `--password` | `--pw` | — | Bose account password (`$BOSE_PASSWORD`) |
|
|
| `--ssh` | | on | Also capture filesystem files via SSH for each speaker |
|
|
| `--output` | `-o` | `soundtouch-backup-YYYY-MM-DD.tar.gz` | Output archive path |
|
|
| `--format` | | `tar.gz` | Archive format: `tar.gz` or `zip` |
|
|
|
|
Speakers that are offline or unreachable at the time of backup are skipped with a `✗` warning; the cloud data is still saved.
|
|
|
|
---
|
|
|
|
### Cloud backup
|
|
|
|
Backs up data from your Bose account at `streaming.bose.com`. Credentials are prompted interactively if not supplied as flags.
|
|
|
|
```bash
|
|
# Interactive — prompts for email, masked password input
|
|
soundtouch-backup cloud
|
|
|
|
# Non-interactive
|
|
soundtouch-backup cloud --email you@example.com --password secret
|
|
|
|
# Environment variables (avoids secrets in shell history)
|
|
BOSE_EMAIL=you@example.com BOSE_PASSWORD=secret soundtouch-backup cloud
|
|
|
|
# Zip output
|
|
soundtouch-backup cloud --format zip --output my-bose-cloud.zip
|
|
```
|
|
|
|
**Flags**
|
|
|
|
| Flag | Short | Default | Description |
|
|
|--------------|--------|---------------------------------------|---------------------------------------------------|
|
|
| `--email` | `-e` | — | Bose account email (`$BOSE_EMAIL`) |
|
|
| `--password` | `--pw` | — | Bose account password (`$BOSE_PASSWORD`) |
|
|
| `--output` | `-o` | `soundtouch-backup-YYYY-MM-DD.tar.gz` | Output archive path (`$SOUNDTOUCH_BACKUP_OUTPUT`) |
|
|
| `--format` | | `tar.gz` | Archive format: `tar.gz` or `zip` |
|
|
|
|
**What gets fetched**
|
|
|
|
| File in archive | Source endpoint |
|
|
|--------------------------|---------------------------------------------------------------------------------|
|
|
| `cloud/emailaddress.xml` | `GET /streaming/account/{id}/emailaddress` |
|
|
| `cloud/devices.xml` | `GET /streaming/account/{id}/devices` |
|
|
| `cloud/sources.xml` | `GET /streaming/account/{id}/sources` |
|
|
| `cloud/presets.xml` | `GET /streaming/account/{id}/presets/all` |
|
|
| `cloud/full.xml` | `GET /streaming/account/{id}/full` (may overlap with the above; skipped if 4xx) |
|
|
|
|
---
|
|
|
|
### Local backup
|
|
|
|
Backs up each speaker over its HTTP API on port 8090. With `--ssh`, also captures key filesystem files via SSH.
|
|
|
|
```bash
|
|
# Auto-discover all speakers on the local network
|
|
soundtouch-backup local
|
|
|
|
# Specific speaker
|
|
soundtouch-backup local --host 192.168.178.28
|
|
|
|
# Multiple speakers
|
|
soundtouch-backup local --host 192.168.178.28 --host 192.168.178.35
|
|
|
|
# Include SSH filesystem backup
|
|
soundtouch-backup local --ssh
|
|
|
|
# Longer discovery window on busy networks
|
|
soundtouch-backup local --discover-timeout 10s
|
|
```
|
|
|
|
**Flags**
|
|
|
|
| Flag | Short | Default | Description |
|
|
|----------------------|-------|---------------------------------------|--------------------------------------------------|
|
|
| `--host` | `-H` | — | Speaker host/IP, repeatable (`$SOUNDTOUCH_HOST`) |
|
|
| `--port` | `-p` | `8090` | Speaker HTTP port (`$SOUNDTOUCH_PORT`) |
|
|
| `--discover` | `-d` | auto | Force mDNS/UPnP discovery |
|
|
| `--discover-timeout` | | `5s` | Discovery timeout |
|
|
| `--ssh` | | on | Also capture filesystem files via SSH |
|
|
| `--output` | `-o` | `soundtouch-backup-YYYY-MM-DD.tar.gz` | Output archive path |
|
|
| `--format` | | `tar.gz` | Archive format: `tar.gz` or `zip` |
|
|
|
|
**What gets fetched via HTTP**
|
|
|
|
| File | Device endpoint |
|
|
|---------------------|-----------------|
|
|
| `info.xml` | `/info` |
|
|
| `name.xml` | `/name` |
|
|
| `presets.xml` | `/presets` |
|
|
| `sources.xml` | `/sources` |
|
|
| `now_playing.xml` | `/now_playing` |
|
|
| `volume.xml` | `/volume` |
|
|
| `bass.xml` | `/bass` |
|
|
| `balance.xml` | `/balance` |
|
|
| `capabilities.xml` | `/capabilities` |
|
|
| `network_info.xml` | `/networkInfo` |
|
|
| `clock_display.xml` | `/clockDisplay` |
|
|
| `zone.xml` | `/getZone` |
|
|
|
|
Endpoints that return HTTP 4xx (not supported on the device model) are silently skipped.
|
|
|
|
**What gets fetched via SSH** (`--ssh`)
|
|
|
|
SSH connects as `root@<host>:22` with an empty password, which is the default for SoundTouch firmware.
|
|
|
|
Individual files:
|
|
|
|
| Remote path | Notes |
|
|
|---------------------------|--------------------------------------------|
|
|
| `/etc/hosts` | DNS redirect state |
|
|
| `/etc/resolv.conf` | DNS resolver configuration |
|
|
| `/etc/remote_services` | Service registration (post-migration only) |
|
|
| `/mnt/nv/remote_services` | Alternative location for remote services |
|
|
|
|
Directories (all regular files recursively):
|
|
|
|
| Remote path | Contents |
|
|
|----------------------------------|----------------------------------------------------------------------------|
|
|
| `/opt/Bose/etc/` | Full Bose configuration directory, including `SoundTouchSdkPrivateCfg.xml` |
|
|
| `/mnt/nv/BoseApp-Persistence/1/` | Persisted app state |
|
|
|
|
Missing files and directories are silently skipped with a `⚠` warning.
|
|
|
|
---
|
|
|
|
## Archive structure
|
|
|
|
Both subcommands write into a single dated archive:
|
|
|
|
```
|
|
soundtouch-backup-2026-05-02/
|
|
├── cloud/
|
|
│ ├── emailaddress.xml
|
|
│ ├── devices.xml
|
|
│ ├── sources.xml
|
|
│ └── presets.xml
|
|
└── local/
|
|
├── A_Sound_Machine/
|
|
│ ├── info.xml
|
|
│ ├── presets.xml
|
|
│ ├── sources.xml
|
|
│ ├── volume.xml
|
|
│ ├── …
|
|
│ └── ssh/
|
|
│ ├── etc/
|
|
│ │ ├── hosts
|
|
│ │ └── resolv.conf
|
|
│ ├── opt/Bose/etc/
|
|
│ │ └── SoundTouchSdkPrivateCfg.xml
|
|
│ └── mnt/nv/BoseApp-Persistence/1/
|
|
└── Sound_Machinechen/
|
|
└── …
|
|
```
|
|
|
|
Running `cloud` and `local` separately produces two archives. To combine them, use the same `--output` path for both invocations — each adds its own subdirectory so they won't collide (`.tar.gz` does not support appending; use `--format zip` if you need a single archive from two runs, or just keep them separate).
|
|
|
|
## See also
|
|
|
|
- [Cloud Shutdown Survival Guide](../../docs/guides/SURVIVAL-GUIDE.md) — full migration context
|
|
- [`soundtouch-cli`](../soundtouch-cli/) — live device control
|
|
- [`soundtouch-service`](../soundtouch-service/) — local cloud replacement
|