mirror of
https://github.com/gesellix/Bose-SoundTouch.git
synced 2026-08-19 00:56:16 +00:00
fix(install): reliable stop, VERSION flag, and on-device walkthrough
- aftertouch init script: stop) now waits up to 15 s for SIGTERM to take effect, then escalates to SIGKILL; prevents stale daemon processes after '/etc/init.d/aftertouch stop' returns (weissigera's workaround was manual 'killall aftertouch-service') - install.sh: add --version / -v CLI flag so the version to install can be passed as a command-line argument in addition to the VERSION env var; document the trade-off of the hard-coded default in a comment; update scripts/on-device-install/README.md with concrete usage examples for env-override, CLI flag, and rollback tip - docs/guides/ON-DEVICE-INSTALL-WALKTHROUGH.md: 10-step runbook derived from weissigera's field-tested procedure (issue #329 comment #4521280831): SSH connection, storage cleanup, install via install.sh, reboot, SSH tunnel, Health QuickFix, pairing verification, soundtouch-cli download, custom-radio preset setup, and final verification; troubleshooting table at the end Closes #329 (remaining two tasks) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 4.6
parent
124414943c
commit
73d0d4b176
@@ -0,0 +1,296 @@
|
||||
# On-Device Install Walkthrough
|
||||
|
||||
A complete end-to-end runbook for installing AfterTouch directly on a
|
||||
Bose SoundTouch speaker — from first SSH connection through verified
|
||||
radio preset playback.
|
||||
|
||||
**Credit:** This guide is based on a step-by-step walkthrough contributed
|
||||
by [weissigera](https://github.com/weissigera) in
|
||||
[issue #329](https://github.com/gesellix/Bose-SoundTouch/issues/329#issuecomment-4521280831),
|
||||
documenting a successful fresh installation on a SoundTouch 20 Series I.
|
||||
|
||||
For the installer reference and troubleshooting tips see
|
||||
[scripts/on-device-install/README.md](../../scripts/on-device-install/README.md).
|
||||
|
||||
---
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- SSH enabled on the speaker (the usual "Stick with remote_services" procedure).
|
||||
- Your machine can reach the speaker on the LAN.
|
||||
- The speaker's LAN IP address — replace `192.0.2.1` throughout with the
|
||||
actual address shown in your router or `arp -a`.
|
||||
|
||||
> **Note on SSH host-key negotiation:** SoundTouch speakers only advertise
|
||||
> legacy host-key algorithms (`ssh-rsa`, `ssh-dss`). Modern OpenSSH clients
|
||||
> reject these by default. The `-oHostKeyAlgorithms=+ssh-rsa` flag below
|
||||
> opts them back in. Without it you'll see
|
||||
> `no matching host key type found`.
|
||||
|
||||
---
|
||||
|
||||
## Step 1 — Connect to the speaker via SSH
|
||||
|
||||
```bash
|
||||
ssh -oHostKeyAlgorithms=+ssh-rsa root@192.0.2.1
|
||||
```
|
||||
|
||||
You should see a prompt such as `root@soundtouch-device:~#`.
|
||||
|
||||
---
|
||||
|
||||
## Step 2 — Check free space (and clean up if needed)
|
||||
|
||||
The persistent `/mnt/nv` partition typically has 20–40 MB free — enough for
|
||||
the AfterTouch binary (~12 MB) plus one backup. Check first:
|
||||
|
||||
```bash
|
||||
rw # remount rootfs read-write
|
||||
df -h /mnt/nv
|
||||
```
|
||||
|
||||
If you have an older installation with multiple backup or artefact files left
|
||||
behind by earlier upgrades, remove them:
|
||||
|
||||
```bash
|
||||
# List what's there
|
||||
ls -lh /mnt/nv/aftertouch/
|
||||
|
||||
# Remove specific stale files (adjust version numbers to what you see)
|
||||
rm -f /mnt/nv/aftertouch/aftertouch-service.v0.80.1.backup
|
||||
rm -f /mnt/nv/aftertouch/aftertouch-service.v0.86.0.backup
|
||||
rm -f /mnt/nv/aftertouch/aftertouch-service.v0.86.0.old
|
||||
rm -f /mnt/nv/aftertouch/aftertouch-service.new
|
||||
rm -f /mnt/nv/soundtouch-cli # cli binary if left there by hand
|
||||
rm -f /mnt/nv/aftertouch/soundtouch-cli
|
||||
|
||||
df -h /mnt/nv # confirm space recovered
|
||||
```
|
||||
|
||||
> **From v0.89.0 onwards the installer prunes stale artefacts automatically**
|
||||
> during every upgrade — manual cleanup should no longer be necessary on
|
||||
> fresh installs.
|
||||
|
||||
---
|
||||
|
||||
## Step 3 — Install (or upgrade) AfterTouch
|
||||
|
||||
Run the canonical one-liner. It downloads the binary and init script,
|
||||
creates `/mnt/nv/aftertouch/`, symlinks `/opt/aftertouch`, backs up the
|
||||
currently running binary, and starts the service:
|
||||
|
||||
```bash
|
||||
rw && curl -sSL https://raw.githubusercontent.com/gesellix/Bose-SoundTouch/main/scripts/on-device-install/install.sh | sh
|
||||
```
|
||||
|
||||
To target a specific version instead of the default:
|
||||
|
||||
```bash
|
||||
# Via environment variable (works with pipe-to-sh)
|
||||
VERSION=0.92.0 rw && curl -sSL https://raw.githubusercontent.com/gesellix/Bose-SoundTouch/main/scripts/on-device-install/install.sh | sh
|
||||
|
||||
# Via command-line flag (pass args after sh -s --)
|
||||
curl -sSL https://raw.githubusercontent.com/gesellix/Bose-SoundTouch/main/scripts/on-device-install/install.sh | sh -s -- --version 0.92.0
|
||||
```
|
||||
|
||||
Verify the installed version:
|
||||
|
||||
```bash
|
||||
wget -qO- http://localhost:8000/health
|
||||
```
|
||||
|
||||
The JSON response should include `"version":"v0.92.0"` (or whichever
|
||||
version you installed).
|
||||
|
||||
---
|
||||
|
||||
## Step 4 — Reboot the speaker
|
||||
|
||||
```bash
|
||||
sync
|
||||
reboot
|
||||
```
|
||||
|
||||
Wait 2–3 minutes for the speaker to come back up, then reconnect:
|
||||
|
||||
```bash
|
||||
ssh -oHostKeyAlgorithms=+ssh-rsa root@192.0.2.1
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Step 5 — Open an SSH tunnel and access the Admin UI
|
||||
|
||||
**Open a new terminal on your machine** (not inside the speaker's SSH
|
||||
session — see [issue #250](https://github.com/gesellix/Bose-SoundTouch/issues/250)
|
||||
for the port-forward-from-inside trap) and run:
|
||||
|
||||
```bash
|
||||
ssh -oHostKeyAlgorithms=+ssh-rsa -L 8000:localhost:8000 root@192.0.2.1
|
||||
```
|
||||
|
||||
Keep this terminal open. Navigate to **http://localhost:8000** in your
|
||||
browser.
|
||||
|
||||
> Skip this step if your speaker's firmware exposes port 8000 on the LAN
|
||||
> directly — you can reach `http://192.0.2.1:8000` without a tunnel in that
|
||||
> case.
|
||||
|
||||
---
|
||||
|
||||
## Step 6 — Run the Health QuickFix for empty `margeAccountUUID`
|
||||
|
||||
In the AfterTouch UI:
|
||||
|
||||
1. Open the **Health** tab.
|
||||
2. Run or refresh the health checks.
|
||||
3. Look for the warning:
|
||||
> *Speaker reports an empty `<margeAccountUUID>`*
|
||||
4. Click the **QuickFix** button (labelled "Fix", "Pair account", or
|
||||
"Apply QuickFix" depending on the version) and confirm.
|
||||
|
||||
Then reboot again to let the pairing take effect:
|
||||
|
||||
```bash
|
||||
sync
|
||||
reboot
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Step 7 — Verify pairing and sources
|
||||
|
||||
After the reboot reconnect via SSH and check:
|
||||
|
||||
```bash
|
||||
ssh -oHostKeyAlgorithms=+ssh-rsa root@192.0.2.1
|
||||
|
||||
# margeAccountUUID must NOT be empty after the QuickFix
|
||||
wget -qO- http://localhost:8090/info | grep margeAccountUUID
|
||||
|
||||
# Sources must include LOCAL_INTERNET_RADIO, TUNEIN, and RADIO_BROWSER
|
||||
wget -qO- http://localhost:8090/sources
|
||||
```
|
||||
|
||||
If `margeAccountUUID` is still empty, re-run the Health QuickFix (Step 6)
|
||||
and reboot again.
|
||||
|
||||
---
|
||||
|
||||
## Step 8 — Download soundtouch-cli (optional, for preset setup)
|
||||
|
||||
If you want to program preset buttons from the command line, download the
|
||||
CLI binary to the speaker's `/tmp` (tmpfs, so it survives only until the
|
||||
next reboot — which is fine for a one-time setup run):
|
||||
|
||||
```bash
|
||||
cd /tmp
|
||||
|
||||
curl -L --fail -o soundtouch-cli \
|
||||
https://github.com/gesellix/Bose-SoundTouch/releases/download/v0.92.0/soundtouch-cli-v0.92.0-linux-armv7
|
||||
chmod +x soundtouch-cli
|
||||
|
||||
/tmp/soundtouch-cli --version
|
||||
```
|
||||
|
||||
Replace `v0.92.0` with the version you installed.
|
||||
|
||||
---
|
||||
|
||||
## Step 9 — Store custom radio streams to preset buttons
|
||||
|
||||
Each station must be playing before it can be saved. The `sleep 5` gives
|
||||
the speaker time to buffer and confirm the stream before storing.
|
||||
|
||||
> **Press preset buttons briefly.** A long press on the physical hardware
|
||||
> overwrites the stored preset.
|
||||
|
||||
```bash
|
||||
# Preset 1 — Hitradio OE3
|
||||
/tmp/soundtouch-cli --host 127.0.0.1 source custom-radio \
|
||||
--url "http://orf-live.ors-shoutcast.at/oe3-q2a" \
|
||||
--name "Hitradio OE3" \
|
||||
--service-url "http://localhost:8000"
|
||||
sleep 5
|
||||
/tmp/soundtouch-cli --host 127.0.0.1 preset store-current --slot 1
|
||||
|
||||
# Preset 2 — Lounge FM
|
||||
/tmp/soundtouch-cli --host 127.0.0.1 source custom-radio \
|
||||
--url "http://188.138.9.183/digital.mp3" \
|
||||
--name "Lounge FM" \
|
||||
--service-url "http://localhost:8000"
|
||||
sleep 5
|
||||
/tmp/soundtouch-cli --host 127.0.0.1 preset store-current --slot 2
|
||||
|
||||
# Preset 3 — Country Nonstop
|
||||
/tmp/soundtouch-cli --host 127.0.0.1 source custom-radio \
|
||||
--url "https://stream.laut.fm/country-nonstop" \
|
||||
--name "Country Nonstop" \
|
||||
--service-url "http://localhost:8000"
|
||||
sleep 5
|
||||
/tmp/soundtouch-cli --host 127.0.0.1 preset store-current --slot 3
|
||||
|
||||
# Preset 4 — Radio Piterpan
|
||||
/tmp/soundtouch-cli --host 127.0.0.1 source custom-radio \
|
||||
--url "https://klasse1.fluidstream.eu/piterpan.mp3?FLID=8" \
|
||||
--name "Radio Piterpan" \
|
||||
--service-url "http://localhost:8000"
|
||||
sleep 5
|
||||
/tmp/soundtouch-cli --host 127.0.0.1 preset store-current --slot 4
|
||||
|
||||
# Preset 5 — kronehit
|
||||
/tmp/soundtouch-cli --host 127.0.0.1 source custom-radio \
|
||||
--url "https://secureonair.krone.at/kronehit-hp.mp3" \
|
||||
--name "kronehit" \
|
||||
--service-url "http://localhost:8000"
|
||||
sleep 5
|
||||
/tmp/soundtouch-cli --host 127.0.0.1 preset store-current --slot 5
|
||||
|
||||
# Preset 6 — Radio Niederösterreich
|
||||
/tmp/soundtouch-cli --host 127.0.0.1 source custom-radio \
|
||||
--url "http://orf-live.ors-shoutcast.at/noe-q2a" \
|
||||
--name "Radio Niederoesterreich" \
|
||||
--service-url "http://localhost:8000"
|
||||
sleep 5
|
||||
/tmp/soundtouch-cli --host 127.0.0.1 preset store-current --slot 6
|
||||
```
|
||||
|
||||
These are the stations from weissigera's setup (Austrian public and
|
||||
internet radio). Replace any or all of them with your own streams — the
|
||||
pattern is the same regardless of station.
|
||||
|
||||
---
|
||||
|
||||
## Step 10 — Verify presets and final reboot
|
||||
|
||||
```bash
|
||||
wget -qO- http://localhost:8090/presets
|
||||
```
|
||||
|
||||
You should see all six preset slots populated. Then do a final reboot and
|
||||
test the physical buttons:
|
||||
|
||||
```bash
|
||||
sync
|
||||
reboot
|
||||
```
|
||||
|
||||
After the speaker comes back up, press preset buttons 1–6 briefly — each
|
||||
should start playing the corresponding stream.
|
||||
|
||||
---
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
| Symptom | First check |
|
||||
|---------|------------|
|
||||
| SSH "no matching host key type" | Add `-oHostKeyAlgorithms=+ssh-rsa` |
|
||||
| Port 8000 not reachable from LAN | Use the SSH tunnel (Step 5) |
|
||||
| `margeAccountUUID` still empty after reboot | Re-run Health QuickFix, reboot again |
|
||||
| Radio source error 1005 | `margeAccountUUID` is empty — complete Step 6 first |
|
||||
| `http://localhost:8000` not responding after install | `logread \| grep aftertouch \| tail -20` |
|
||||
| No space left on device during install | Run the cleanup in Step 2; check `df -h /mnt/nv` |
|
||||
|
||||
For more detail on any of these, see
|
||||
[TROUBLESHOOTING.md](./TROUBLESHOOTING.md) and the
|
||||
[on-device installer README](../../scripts/on-device-install/README.md).
|
||||
@@ -2,6 +2,9 @@
|
||||
|
||||
Allows to run AfterTouch on SoundTouch devices directly, eliminating the need to run and maintain a separate server on the local network.
|
||||
|
||||
For a complete step-by-step walkthrough — from first SSH connection through verified radio preset playback — see
|
||||
[docs/guides/ON-DEVICE-INSTALL-WALKTHROUGH.md](../../docs/guides/ON-DEVICE-INSTALL-WALKTHROUGH.md).
|
||||
|
||||
## Disclaimer
|
||||
|
||||
### Invasiveness
|
||||
@@ -82,7 +85,31 @@ The init script's `status` now distinguishes "running with listener up" from "PI
|
||||
|
||||
## Updating AfterTouch
|
||||
|
||||
To update AfterTouch, simply run the installation command again. The installer will check if there's a new version available and update it if necessary.
|
||||
Run the installer again with the version you want to install. The script backs up the currently-running binary (named after its version), installs the new one, and prunes older leftover artefacts to keep `/mnt/nv` free.
|
||||
|
||||
**Install (or upgrade to) a specific version** — three equivalent ways:
|
||||
|
||||
```bash
|
||||
# 1. Environment variable (works when piping into sh)
|
||||
VERSION=0.92.0 rw && curl -sSL https://raw.githubusercontent.com/gesellix/Bose-SoundTouch/main/scripts/on-device-install/install.sh | sh
|
||||
|
||||
# 2. Command-line flag (pass args after `sh -s --`)
|
||||
rw && curl -sSL https://raw.githubusercontent.com/gesellix/Bose-SoundTouch/main/scripts/on-device-install/install.sh | sh -s -- --version 0.92.0
|
||||
|
||||
# 3. Download first, then run with a flag
|
||||
curl -sSLo install.sh https://raw.githubusercontent.com/gesellix/Bose-SoundTouch/main/scripts/on-device-install/install.sh
|
||||
sh install.sh --version 0.92.0
|
||||
```
|
||||
|
||||
Running **without** a version override installs the version hard-coded in the script (the latest release at the time the script was published). That default is updated with each release; if you're running from `main`, it reflects the most recent tagged version.
|
||||
|
||||
> **Tip — rollback:** if the new binary misbehaves, the installer left a `.backup` file alongside it:
|
||||
> ```bash
|
||||
> ls /mnt/nv/aftertouch/aftertouch-service*.backup
|
||||
> cp /mnt/nv/aftertouch/aftertouch-service.<old-version>.backup \
|
||||
> /mnt/nv/aftertouch/aftertouch-service
|
||||
> /etc/init.d/aftertouch restart
|
||||
> ```
|
||||
|
||||
## Uninstallation
|
||||
|
||||
|
||||
@@ -81,10 +81,24 @@ case "$1" in
|
||||
stop)
|
||||
echo "Stopping $DESC..."
|
||||
if [ -f "$PIDFILE" ]; then
|
||||
PID=$(cat "$PIDFILE")
|
||||
start-stop-daemon --stop \
|
||||
--quiet \
|
||||
--oknodo \
|
||||
--pidfile "$PIDFILE"
|
||||
# Wait up to 15 s for SIGTERM to take effect before escalating.
|
||||
# The Go HTTP server exits promptly on SIGTERM in normal conditions;
|
||||
# the loop handles the rare case where it is stuck in a blocking syscall.
|
||||
tries=0
|
||||
while [ $tries -lt 15 ] && kill -0 "$PID" 2>/dev/null; do
|
||||
sleep 1
|
||||
tries=$((tries + 1))
|
||||
done
|
||||
if kill -0 "$PID" 2>/dev/null; then
|
||||
echo "Warning: $NAME (PID $PID) still alive after ${tries}s; sending SIGKILL..." >&2
|
||||
kill -9 "$PID" 2>/dev/null || true
|
||||
sleep 1
|
||||
fi
|
||||
rm -f "$PIDFILE"
|
||||
else
|
||||
echo "No $NAME running (no PID file)." >&2
|
||||
|
||||
@@ -1,7 +1,31 @@
|
||||
#!/bin/bash
|
||||
set -eo pipefail
|
||||
|
||||
# Default version installed when no override is provided. Update this value
|
||||
# each time a new release is cut so that running the canonical one-liner
|
||||
# curl -sSL .../install.sh | sh
|
||||
# picks up the latest binary without extra arguments.
|
||||
#
|
||||
# Override via environment variable or the --version/-v flag:
|
||||
# VERSION=0.92.0 curl -sSL .../install.sh | sh
|
||||
# curl -sSL .../install.sh | sh -s -- --version 0.92.0
|
||||
VERSION=${VERSION:-0.91.0}
|
||||
|
||||
# Parse optional command-line arguments so the script can be invoked as:
|
||||
# install.sh --version 0.92.0
|
||||
# install.sh -v 0.92.0
|
||||
while [ $# -gt 0 ]; do
|
||||
case "$1" in
|
||||
--version|-v)
|
||||
if [ -z "$2" ]; then
|
||||
echo "ERROR: --version requires an argument." >&2; exit 1
|
||||
fi
|
||||
VERSION="$2"; shift 2;;
|
||||
--) shift; break;;
|
||||
*) echo "Unknown argument: $1" >&2; exit 1;;
|
||||
esac
|
||||
done
|
||||
|
||||
GH_REPO=${GH_REPO:-gesellix/Bose-SoundTouch}
|
||||
BINARY_URL=${BINARY_URL:-https://github.com/$GH_REPO/releases/download/v$VERSION/soundtouch-service-v$VERSION-linux-armv7}
|
||||
INIT_SCRIPT_URL=${INIT_SCRIPT_URL:-https://raw.githubusercontent.com/$GH_REPO/v$VERSION/scripts/on-device-install/aftertouch}
|
||||
|
||||
Reference in New Issue
Block a user