Add one-command install script and stability fixes
- Add install.sh for automated setup - Add all component files (wrapper, service, config, verify) - Add stability fixes section (WiFi PowerSave disable + Watchdog) - Update README with new installation instructions
This commit is contained in:
32
01-prerequisites.md
Normal file
32
01-prerequisites.md
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
# Prerequisites
|
||||||
|
|
||||||
|
## System Requirements
|
||||||
|
|
||||||
|
**Fresh Raspberry Pi OS (Lite/Bookworm recommended)**
|
||||||
|
|
||||||
|
The installation script will automatically install the required packages, but if you prefer manual installation:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo apt update && sudo apt upgrade -y
|
||||||
|
sudo apt install darkice icecast2 alsa-utils -y
|
||||||
|
sudo reboot
|
||||||
|
```
|
||||||
|
|
||||||
|
## Hardware Requirements
|
||||||
|
|
||||||
|
- Raspberry Pi (any model, including Pi Zero 2W)
|
||||||
|
- USB audio interface (record player → RCA/3.5mm → USB)
|
||||||
|
- Reliable power supply (USB audio hates undervoltage - use a quality power adapter)
|
||||||
|
- Network connection (WiFi or Ethernet)
|
||||||
|
|
||||||
|
## Software Requirements
|
||||||
|
|
||||||
|
- Raspberry Pi OS (Debian-based)
|
||||||
|
- Git (usually pre-installed)
|
||||||
|
- Sudo access
|
||||||
|
|
||||||
|
## Notes
|
||||||
|
|
||||||
|
- The Pi Zero 2W works great for this setup
|
||||||
|
- USB audio disconnections are fixed by the wrapper script and USB audio configuration
|
||||||
|
- A stable power supply is critical - undervoltage causes USB audio issues
|
||||||
30
02-deploy.sh
Executable file
30
02-deploy.sh
Executable file
@@ -0,0 +1,30 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
echo "🖥️ Deploying Record Player → Sonos AUX..."
|
||||||
|
|
||||||
|
cd /home/pi
|
||||||
|
|
||||||
|
# Copy files
|
||||||
|
cp 03-darkice-wrapper.sh .
|
||||||
|
cp 04-sonos-aux.service /etc/systemd/system/sonos-aux.service
|
||||||
|
cp darkice.cfg.example darkice.cfg # Edit your passwords!
|
||||||
|
|
||||||
|
chmod +x darkice-wrapper.sh
|
||||||
|
sudo chown root:audio darkice-wrapper.sh
|
||||||
|
sudo chmod 755 darkice-wrapper.sh
|
||||||
|
|
||||||
|
# Fix USB audio = card 0 always
|
||||||
|
echo "blacklist snd_bcm2835" | sudo tee -a /etc/modprobe.d/raspi-blacklist.conf
|
||||||
|
sudo sed -i 's/^options snd-usb-audio index=-2/#options snd-usb-audio index=-2/' /lib/modprobe.d/aliases.conf
|
||||||
|
|
||||||
|
# Icecast setup (one-time)
|
||||||
|
sudo systemctl enable icecast2
|
||||||
|
sudo systemctl start icecast2
|
||||||
|
|
||||||
|
# Systemd service
|
||||||
|
sudo systemctl daemon-reload
|
||||||
|
sudo systemctl enable sonos-aux.service
|
||||||
|
|
||||||
|
echo "✅ Reboot to finish: sudo reboot"
|
||||||
|
echo "Then check: journalctl -u sonos-aux.service -f"
|
||||||
24
03-darkice-wrapper.sh
Executable file
24
03-darkice-wrapper.sh
Executable file
@@ -0,0 +1,24 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
MAX_WAIT_SEC=90
|
||||||
|
SLEEP_STEP=2
|
||||||
|
DARKICE_CMD="/usr/bin/darkice -c /home/pi/darkice.cfg"
|
||||||
|
|
||||||
|
log() { echo "[$(date '+%H:%M:%S')] $*" >&2; }
|
||||||
|
|
||||||
|
log "⏳ Waiting for ALSA card 0 (USB audio)..."
|
||||||
|
|
||||||
|
elapsed=0
|
||||||
|
while ! arecord -l 2>/dev/null | grep -q "^card 0:"; do
|
||||||
|
if (( elapsed >= MAX_WAIT_SEC )); then
|
||||||
|
log "💥 FATAL: No card 0 after ${MAX_WAIT_SEC}s"
|
||||||
|
arecord -l || true
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
sleep "${SLEEP_STEP}"
|
||||||
|
elapsed=$((elapsed + SLEEP_STEP))
|
||||||
|
done
|
||||||
|
|
||||||
|
log "✅ Card 0 ready! Launching DarkIce."
|
||||||
|
exec ${DARKICE_CMD}
|
||||||
18
04-sonos-aux.service
Normal file
18
04-sonos-aux.service
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
[Unit]
|
||||||
|
Description=Record player AUX stream to Sonos
|
||||||
|
After=network-online.target sound.target icecast2.service
|
||||||
|
Wants=network-online.target
|
||||||
|
StartLimitIntervalSec=0
|
||||||
|
StartLimitBurst=0
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=simple
|
||||||
|
User=pi
|
||||||
|
Group=audio
|
||||||
|
WorkingDirectory=/home/pi
|
||||||
|
ExecStart=/home/pi/darkice-wrapper.sh
|
||||||
|
Restart=always
|
||||||
|
RestartSec=10
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
113
README.md
113
README.md
@@ -4,8 +4,9 @@
|
|||||||
> **Repo Structure:**
|
> **Repo Structure:**
|
||||||
```
|
```
|
||||||
├── README.md ← This file
|
├── README.md ← This file
|
||||||
|
├── install.sh ← 🚀 ONE-COMMAND INSTALL (NEW!)
|
||||||
├── 01-prerequisites.md
|
├── 01-prerequisites.md
|
||||||
├── 02-deploy.sh ← One-command setup
|
├── 02-deploy.sh ← Manual deploy script
|
||||||
├── 03-darkice-wrapper.sh ← USB wait + DarkIce launcher
|
├── 03-darkice-wrapper.sh ← USB wait + DarkIce launcher
|
||||||
├── 04-sonos-aux.service ← Systemd unit (Pi OS compatible)
|
├── 04-sonos-aux.service ← Systemd unit (Pi OS compatible)
|
||||||
├── darkice.cfg.example ← Your config template
|
├── darkice.cfg.example ← Your config template
|
||||||
@@ -14,12 +15,40 @@
|
|||||||
|
|
||||||
***
|
***
|
||||||
|
|
||||||
## Quick Deploy (New Pi)
|
## 🚀 One-Command Installation (Recommended)
|
||||||
|
|
||||||
|
**Just run this on your Pi Zero 2:**
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
git clone <your-gitea-repo>
|
curl -fsSL https://git.geertrademakers.nl/master/sonos-aux-recordplayer-pi/raw/branch/master/install.sh | bash
|
||||||
cd record-player-sonos-aux
|
```
|
||||||
|
|
||||||
|
Or with wget:
|
||||||
|
```bash
|
||||||
|
wget -qO- https://git.geertrademakers.nl/master/sonos-aux-recordplayer-pi/raw/branch/master/install.sh | bash
|
||||||
|
```
|
||||||
|
|
||||||
|
**What it does:**
|
||||||
|
- ✅ Installs all prerequisites (darkice, icecast2, alsa-utils)
|
||||||
|
- ✅ Clones/updates the repository
|
||||||
|
- ✅ Configures USB audio as card 0 (fixes disconnections!)
|
||||||
|
- ✅ Deploys all files and systemd service
|
||||||
|
- ✅ Sets up Icecast2
|
||||||
|
- ✅ Enables auto-start on boot
|
||||||
|
|
||||||
|
**After installation:**
|
||||||
|
1. Edit config: `nano /home/pi/darkice.cfg` (change password!)
|
||||||
|
2. Reboot: `sudo reboot`
|
||||||
|
3. Verify: `journalctl -u sonos-aux.service -f`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Quick Deploy (Manual - Alternative Method)
|
||||||
|
```bash
|
||||||
|
git clone https://git.geertrademakers.nl/master/sonos-aux-recordplayer-pi.git
|
||||||
|
cd sonos-aux-recordplayer-pi
|
||||||
chmod +x *.sh
|
chmod +x *.sh
|
||||||
sudo ./02-deploy.sh
|
sudo ./install.sh
|
||||||
```
|
```
|
||||||
|
|
||||||
**Full guide below** ↓
|
**Full guide below** ↓
|
||||||
@@ -187,6 +216,80 @@ curl -s http://localhost:8000/status-json.xsl | grep -o 'http[^<]*'
|
|||||||
1. Add Sonos radio station: `http://<pi-ip>:8000/rapi.mp3`
|
1. Add Sonos radio station: `http://<pi-ip>:8000/rapi.mp3`
|
||||||
2. Works with any Sonos speaker/group!
|
2. Works with any Sonos speaker/group!
|
||||||
|
|
||||||
|
## 🔧 Stability Fixes (Recommended for 24/7)
|
||||||
|
|
||||||
|
Raspberry Pi Zero W/2W often loses WiFi due to power management. These steps ensure rock-solid uptime.
|
||||||
|
|
||||||
|
### 1. Disable WiFi PowerSave (systemd service)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo nano /etc/systemd/system/wifi-powermanagement-off.service
|
||||||
|
```
|
||||||
|
|
||||||
|
```ini
|
||||||
|
[Unit]
|
||||||
|
Description=Disable WiFi Power Management
|
||||||
|
After=network.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=oneshot
|
||||||
|
ExecStart=/sbin/iwconfig wlan0 power off
|
||||||
|
RemainAfterExit=yes
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
|
```
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo systemctl daemon-reload
|
||||||
|
sudo systemctl enable wifi-powermanagement-off
|
||||||
|
sudo systemctl start wifi-powermanagement-off
|
||||||
|
```
|
||||||
|
|
||||||
|
**Verify:** `iwconfig` should show `Power Management:off` [web:27][web:28]
|
||||||
|
|
||||||
|
### 2. Hardware Watchdog (Network + Load Monitoring)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo apt install watchdog -y
|
||||||
|
sudo nano /etc/watchdog.conf
|
||||||
|
```
|
||||||
|
|
||||||
|
**Replace with this optimal config:**
|
||||||
|
```ini
|
||||||
|
watchdog-device = /dev/watchdog
|
||||||
|
interval = 20
|
||||||
|
retry-timeout = 180
|
||||||
|
ping = 192.168.1.1 # Your UniFi gateway
|
||||||
|
ping = 1.1.1.1 # Cloudflare backup
|
||||||
|
ping-count = 3
|
||||||
|
realtime = yes
|
||||||
|
priority = 50
|
||||||
|
max-load-1 = 24
|
||||||
|
max-load-5 = 0
|
||||||
|
max-load-15 = 0
|
||||||
|
```
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo systemctl enable watchdog
|
||||||
|
sudo systemctl start watchdog
|
||||||
|
```
|
||||||
|
|
||||||
|
**Test safely:** `sudo systemctl status watchdog` + `sudo journalctl -u watchdog -f`
|
||||||
|
|
||||||
|
### 3. Verify Everything
|
||||||
|
|
||||||
|
After reboot:
|
||||||
|
```bash
|
||||||
|
iwconfig # Power Management:off
|
||||||
|
systemctl status watchdog # active (running)
|
||||||
|
journalctl -u watchdog -n20 # Recent heartbeats
|
||||||
|
```
|
||||||
|
|
||||||
|
This combo prevents WiFi dropouts + auto-recovers from hangs/freezes while keeping your Sonos AUX stream running 24/7.
|
||||||
|
|
||||||
|
**Reference:** [Watchdog Service for Raspberry Pi](https://xavier.arnaus.net/blog/watchdog-service-for-raspberry-pi-machines)
|
||||||
|
|
||||||
## 🛠️ Troubleshooting
|
## 🛠️ Troubleshooting
|
||||||
|
|
||||||
| Issue | Fix |
|
| Issue | Fix |
|
||||||
|
|||||||
20
darkice.cfg.example
Normal file
20
darkice.cfg.example
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
[general]
|
||||||
|
duration = 0
|
||||||
|
bufferSecs = 2 # USB stability
|
||||||
|
reconnect = yes
|
||||||
|
|
||||||
|
[input]
|
||||||
|
device = plughw:0,0 # USB card 0 (fixed by modprobe)
|
||||||
|
sampleRate = 44100
|
||||||
|
bitsPerSample = 16
|
||||||
|
channel = 2
|
||||||
|
|
||||||
|
[icecast2-0]
|
||||||
|
bitrateMode = cbr
|
||||||
|
format = mp3
|
||||||
|
bitrate = 320
|
||||||
|
server = localhost
|
||||||
|
port = 8000
|
||||||
|
password = hackme # ← CHANGE to your Icecast source password
|
||||||
|
mountPoint = rapi.mp3 # Sonos URL: http://pi-ip:8000/rapi.mp3
|
||||||
|
name = Record Player
|
||||||
162
install.sh
Executable file
162
install.sh
Executable file
@@ -0,0 +1,162 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
# Master installation script for Record Player Pi → Sonos AUX
|
||||||
|
# Usage: curl -fsSL https://git.geertrademakers.nl/master/sonos-aux-recordplayer-pi/raw/branch/master/install.sh | bash
|
||||||
|
# Or: wget -qO- https://git.geertrademakers.nl/master/sonos-aux-recordplayer-pi/raw/branch/master/install.sh | bash
|
||||||
|
|
||||||
|
REPO_URL="https://git.geertrademakers.nl/master/sonos-aux-recordplayer-pi.git"
|
||||||
|
INSTALL_DIR="/home/pi/sonos-aux-recordplayer-pi"
|
||||||
|
USER_HOME="/home/pi"
|
||||||
|
|
||||||
|
log() {
|
||||||
|
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*" >&2
|
||||||
|
}
|
||||||
|
|
||||||
|
error() {
|
||||||
|
log "❌ ERROR: $*"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
success() {
|
||||||
|
log "✅ $*"
|
||||||
|
}
|
||||||
|
|
||||||
|
info() {
|
||||||
|
log "ℹ️ $*"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Check if running as root for certain operations
|
||||||
|
check_sudo() {
|
||||||
|
if ! sudo -n true 2>/dev/null; then
|
||||||
|
info "This script requires sudo privileges. You may be prompted for your password."
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Detect if we're on a Raspberry Pi
|
||||||
|
check_pi() {
|
||||||
|
if [ ! -f /proc/device-tree/model ] || ! grep -q "Raspberry Pi" /proc/device-tree/model 2>/dev/null; then
|
||||||
|
info "⚠️ Warning: This doesn't appear to be a Raspberry Pi. Continuing anyway..."
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Install prerequisites
|
||||||
|
install_prerequisites() {
|
||||||
|
info "Installing prerequisites..."
|
||||||
|
|
||||||
|
sudo apt-get update -qq
|
||||||
|
sudo apt-get install -y darkice icecast2 alsa-utils curl wget git || error "Failed to install prerequisites"
|
||||||
|
|
||||||
|
success "Prerequisites installed"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Clone or update repository
|
||||||
|
setup_repo() {
|
||||||
|
if [ -d "$INSTALL_DIR" ]; then
|
||||||
|
info "Repository exists, updating..."
|
||||||
|
cd "$INSTALL_DIR"
|
||||||
|
git pull || error "Failed to update repository"
|
||||||
|
else
|
||||||
|
info "Cloning repository..."
|
||||||
|
git clone "$REPO_URL" "$INSTALL_DIR" || error "Failed to clone repository"
|
||||||
|
cd "$INSTALL_DIR"
|
||||||
|
fi
|
||||||
|
|
||||||
|
success "Repository ready"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Fix USB audio to always be card 0
|
||||||
|
fix_usb_audio() {
|
||||||
|
info "Configuring USB audio as card 0..."
|
||||||
|
|
||||||
|
# Blacklist built-in audio
|
||||||
|
if ! grep -q "blacklist snd_bcm2835" /etc/modprobe.d/raspi-blacklist.conf 2>/dev/null; then
|
||||||
|
echo "blacklist snd_bcm2835" | sudo tee -a /etc/modprobe.d/raspi-blacklist.conf >/dev/null
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Fix USB audio index
|
||||||
|
if [ -f /lib/modprobe.d/aliases.conf ]; then
|
||||||
|
sudo sed -i 's/^options snd-usb-audio index=-2/#options snd-usb-audio index=-2/' /lib/modprobe.d/aliases.conf
|
||||||
|
fi
|
||||||
|
|
||||||
|
success "USB audio configuration updated (reboot required for full effect)"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Deploy files
|
||||||
|
deploy_files() {
|
||||||
|
info "Deploying files..."
|
||||||
|
|
||||||
|
# Copy wrapper script
|
||||||
|
sudo cp "$INSTALL_DIR/03-darkice-wrapper.sh" "$USER_HOME/darkice-wrapper.sh"
|
||||||
|
sudo chmod +x "$USER_HOME/darkice-wrapper.sh"
|
||||||
|
sudo chown root:audio "$USER_HOME/darkice-wrapper.sh"
|
||||||
|
sudo chmod 755 "$USER_HOME/darkice-wrapper.sh"
|
||||||
|
|
||||||
|
# Copy systemd service
|
||||||
|
sudo cp "$INSTALL_DIR/04-sonos-aux.service" /etc/systemd/system/sonos-aux.service
|
||||||
|
|
||||||
|
# Copy config if it doesn't exist
|
||||||
|
if [ ! -f "$USER_HOME/darkice.cfg" ]; then
|
||||||
|
cp "$INSTALL_DIR/darkice.cfg.example" "$USER_HOME/darkice.cfg"
|
||||||
|
info "📝 Created darkice.cfg - please edit password and mountPoint!"
|
||||||
|
else
|
||||||
|
info "darkice.cfg already exists, skipping..."
|
||||||
|
fi
|
||||||
|
|
||||||
|
success "Files deployed"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Setup Icecast
|
||||||
|
setup_icecast() {
|
||||||
|
info "Setting up Icecast2..."
|
||||||
|
|
||||||
|
sudo systemctl enable icecast2 || true
|
||||||
|
sudo systemctl start icecast2 || true
|
||||||
|
|
||||||
|
success "Icecast2 configured"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Setup systemd service
|
||||||
|
setup_service() {
|
||||||
|
info "Setting up systemd service..."
|
||||||
|
|
||||||
|
sudo systemctl daemon-reload
|
||||||
|
sudo systemctl enable sonos-aux.service
|
||||||
|
|
||||||
|
success "Systemd service enabled"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Main installation
|
||||||
|
main() {
|
||||||
|
log "🚀 Starting Record Player Pi → Sonos AUX installation..."
|
||||||
|
|
||||||
|
check_sudo
|
||||||
|
check_pi
|
||||||
|
|
||||||
|
install_prerequisites
|
||||||
|
setup_repo
|
||||||
|
fix_usb_audio
|
||||||
|
deploy_files
|
||||||
|
setup_icecast
|
||||||
|
setup_service
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
success "Installation complete!"
|
||||||
|
echo ""
|
||||||
|
info "Next steps:"
|
||||||
|
echo " 1. Edit darkice.cfg: nano $USER_HOME/darkice.cfg"
|
||||||
|
echo " - Change 'password' to your Icecast source password"
|
||||||
|
echo " - Change 'mountPoint' if desired"
|
||||||
|
echo ""
|
||||||
|
echo " 2. Reboot: sudo reboot"
|
||||||
|
echo ""
|
||||||
|
echo " 3. After reboot, verify:"
|
||||||
|
echo " - journalctl -u sonos-aux.service -f"
|
||||||
|
echo " - Or run: $INSTALL_DIR/verify.sh"
|
||||||
|
echo ""
|
||||||
|
echo " 4. Add to Sonos: http://<pi-ip>:8000/rapi.mp3"
|
||||||
|
echo ""
|
||||||
|
}
|
||||||
|
|
||||||
|
# Run main function
|
||||||
|
main "$@"
|
||||||
12
verify.sh
Executable file
12
verify.sh
Executable file
@@ -0,0 +1,12 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
echo "🔍 USB Audio Check:"
|
||||||
|
arecord -l | grep "card 0" || echo "⚠️ No card 0 found"
|
||||||
|
|
||||||
|
echo -e "\n📊 Service Status:"
|
||||||
|
systemctl status sonos-aux.service --no-pager || echo "⚠️ Service not running"
|
||||||
|
|
||||||
|
echo -e "\n📜 Last 20 log lines:"
|
||||||
|
journalctl -u sonos-aux.service -n20 --no-pager || echo "⚠️ No logs found"
|
||||||
|
|
||||||
|
echo -e "\n🌐 Icecast streams:"
|
||||||
|
curl -s http://localhost:8000/status-json.xsl 2>/dev/null | grep -o 'http[^<]*' || echo "⚠️ Icecast not responding"
|
||||||
Reference in New Issue
Block a user