Skip to main content

Operations

Day-to-day management of a running station.

Checking Status​

Quick status — what's playing, are services up:

systemctl status mpd icecast2 nginx pi3radio song-logger
mpc status

The web UI also shows a health indicator (green/amber/red dot) in the header, backed by the /api/health endpoint which reports load, disk, NAS mount status, and service states.

Deploying Changes​

All changes are deployed from your development machine — never edit files directly on the Pi. The workflow:

  1. Make changes locally
  2. Test in staging (mock data mode, no API keys needed)
  3. Promote to production
# Push to staging (port 8080, mock data)
rsync -av staging/ pi-user@your-pi:/var/www/radio-staging/

# Promote staging to production
cp -r staging/ public/
rsync -av public/ pi-user@your-pi:/var/www/radio/public/

# Deploy backend changes
rsync -av server/ pi-user@your-pi:/var/www/radio/
ssh pi-user@your-pi "sudo systemctl restart pi3radio"

Restarting Services​

Restart the Python API and reload Nginx:

sudo systemctl restart pi3radio
sudo systemctl reload nginx

Restart MPD (will briefly interrupt the stream):

sudo systemctl restart mpd

Recovery After Power Loss​

After a power cut or reboot, the NAS mount may not come back automatically. Run this sequence:

sudo mount -a # remount NAS
sudo systemctl restart mpd # restart MPD
/usr/local/bin/radio_scheduler.sh # re-run scheduler to resume programming

Log Files​

LogContents
/var/log/radio_playlist.logEvery song played (4 lines per song)
/var/log/radio_schedule.logHourly scheduler decisions
/var/log/mpd/mpd.logMPD errors and events
/var/log/icecast2/error.logIcecast errors
/var/log/nginx/error.logNginx errors

Tail the song log live:

tail -f /var/log/radio_playlist.log

Last 20 songs played:

grep "NOW PLAYING" /var/log/radio_playlist.log | tail -20

Database Backups​

Pull a copy of the database to your local machine:

rsync pi-user@your-pi:/var/www/radio/db.sqlite3 ./backups/db_$(date +%Y%m%d_%H%M%S).sqlite3

Query tagged songs from a local backup:

sqlite3 backups/db_latest.sqlite3 \
"SELECT s.artist, s.title, t.tag FROM songs s JOIN tags t ON s.id = t.song_id ORDER BY t.tag, s.artist;"

Song Tagging​

The web UI lets you tag any song in the recent playlist. Tags are stored in SQLite and used by the scheduler and stats views.

TagEffect
FavouriteMarks the song as a keeper
ReviewFlag to listen again before deciding
LiveMarks as a live recording
Bad MP3Flags poor quality rips
DuplicateFlags duplicates in the library
EjectAdds to exclude list — never plays again

Useful API Calls​

# What's playing right now
curl http://your-pi/api/playlist | python3 -m json.tool

# System health
curl http://your-pi/api/health | python3 -m json.tool

# All favourites
curl "http://your-pi/api/tags?tag=Favourite"

# Export full play history as CSV
curl http://your-pi/api/export -o plays.csv

Keyboard Shortcuts​

The web player supports keyboard shortcuts when focused in a browser:

KeyAction
SpacePlay / pause
→Skip to next track
FTag current track as Favourite
RTag current track as Review
LTag current track as Live