Music Display (Raspberry Pi LED Matrix)¶
RGB LED matrix display for Raspberry Pi showing album art (via HEOS/Denon or Navidrome), MBTA transit predictions, and sports scores.
Overview¶
┌─────────────────────────────────────────────────────────────┐
│ RASPBERRY PI 4 │
│ 10.89.97.151 │
│ │
│ ┌─────────────────┐ ┌─────────────────┐ │
│ │ music-display │ │ music-display │ │
│ │ service │ │ web UI │ │
│ │ (display.py) │ │ (web.py) │ │
│ │ │ │ :8080 │ │
│ └────────┬────────┘ └─────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────┐ │
│ │ 64x64 RGB LED │ │
│ │ Matrix │ │
│ │ (Adafruit HAT) │ │
│ └─────────────────┘ │
└─────────────────────────────────────────────────────────────┘
│ │ │
│ HEOS CLI │ Subsonic API │ MBTA API
▼ ▼ ▼
┌────────────┐ ┌──────────────┐ ┌──────────────┐
│ Denon │ │ Navidrome │ │ MBTA API │
│ Receiver │ │ (arr-stack) │ │ (public) │
└────────────┘ └──────────────┘ └──────────────┘
Hardware¶
- Raspberry Pi 4 (any RAM size)
- 64x64 RGB LED Matrix (HUB75 interface)
- Adafruit RGB Matrix HAT or Bonnet
Network¶
| Service | Address |
|---|---|
| Pi SSH | pi@10.89.97.151 |
| Web UI | http://10.89.97.151:8080 |
Features¶
Album Art Display¶
- Shows currently playing track from Navidrome
- Artist name overlay (configurable position)
- Smooth transitions between tracks
MBTA Transit Widget¶
- Live train/bus predictions
- Route colors and direction filtering
- Configurable stops, routes, time windows
- Bus support (yellow badges with route + destination)
- Rail support (route color badges with stop name)
Idle Modes¶
When nothing is playing: - Clock - Current time and date - Transit - MBTA predictions - Static - Last album art - Dim - Low brightness - Blank - Display off
File Structure¶
/home/pi/music-display/
├── display.py # Main display service
├── web.py # Web UI (Flask, port 8080)
├── config.json # User configuration
├── stops.db # SQLite cache for MBTA stops
├── core/
│ ├── config.py # Configuration management
│ ├── manager.py # Widget lifecycle manager
│ └── renderer.py # Matrix display output (black_threshold here)
├── widgets/
│ ├── base.py # Widget base class
│ ├── music.py # Album art widget
│ ├── clock.py # Clock widget
│ ├── transit.py # MBTA transit widget
│ └── sports.py # ESPN sports scores widget
└── sources/
├── navidrome.py # Navidrome/Subsonic API client
├── heos.py # HEOS/Denon receiver client
└── mbta.py # MBTA API client + stops cache
Systemd Services¶
# Main display service
sudo systemctl status music-display
sudo systemctl restart music-display
# Web UI service
sudo systemctl status music-display-web
sudo systemctl restart music-display-web
Deployment¶
From Proxmox Host¶
# Deploy latest code
ssh pi@10.89.97.151 "cd /home/pi/music-display && git pull origin feature-ui && sudo systemctl restart music-display-web"
# Or use the intent
/intents:deploy-music-display
Manual on Pi¶
cd /home/pi/music-display
git pull origin feature-ui
sudo systemctl restart music-display-web
sudo systemctl restart music-display # If main.py changed
Configuration¶
All settings managed via Web UI at http://10.89.97.151:8080
Display Settings¶
- Brightness - LED brightness (10-100%)
- Rotation - Display rotation (0/90/180/270)
- Text Position - Artist overlay position (top/bottom)
- Idle Mode - What to show when not playing
- Black Threshold - Crush near-black pixels to pure black (0-255, default 0)
Black Threshold¶
Album art often has regions that are almost black but not quite. On an LED matrix, these near-black pixels still emit light, appearing as grey rather than true black (LED off). The black_threshold setting fixes this by clamping any pixel where R, G, and B are all below the threshold to pure black (0,0,0).
Recommended values:
- 0 - Disabled (default)
- 15-25 - Subtle, preserves dark detail
- 30-40 - Aggressive, maximizes true blacks
Configuration:
This setting hot-reloads within 2 seconds when config.json changes.
MBTA Transit Settings¶
- Stops - Search and add MBTA stops
- Routes - Filter by specific routes
- Directions - Filter inbound/outbound per route
- Time Window - Min/max minutes to show
- Rows - Number of predictions to display
Matrix Hardware¶
- Hardware Mapping - adafruit-hat / adafruit-hat-pwm
- GPIO Slowdown - Pi generation (1-4)
- PWM Bits - Color depth vs flicker tradeoff
Operations¶
Check Status¶
# Service status
ssh pi@10.89.97.151 'systemctl status music-display music-display-web'
# View logs
ssh pi@10.89.97.151 'journalctl -u music-display -n 50'
ssh pi@10.89.97.151 'journalctl -u music-display-web -n 50'
Restart Services¶
ssh pi@10.89.97.151 'sudo systemctl restart music-display'
ssh pi@10.89.97.151 'sudo systemctl restart music-display-web'
View Config¶
Troubleshooting¶
Display Flickering¶
- Try
adafruit-hat-pwmhardware mapping (requires audio disabled) - Increase GPIO slowdown for Pi 4
- Reduce PWM bits (7 = less flicker, 11 = more colors)
MBTA Not Loading Stops¶
- Click "Load Stops" button in Web UI
- Wait ~30 seconds for 8000+ stops to cache
- Search should work after cache loads
Web UI Not Accessible¶
ssh pi@10.89.97.151 'sudo systemctl restart music-display-web'
ssh pi@10.89.97.151 'journalctl -u music-display-web -n 20'
Source Code¶
Repository: https://github.com/jakecelentano/music-display
Branch: feature-ui (current development)
Music Sources¶
The display supports multiple music sources for "now playing" data:
HEOS (Default)¶
Gets playback info directly from the Denon receiver via HEOS CLI protocol. This is the authoritative source for what's actually playing.
Benefits: - Shows what's actually playing on the receiver - Works with any input (Spotify, AirPlay, DLNA, Navidrome, etc.) - No scrobble confusion from multiple clients
Cover Art Fallback Chain: 1. HEOS metadata image URL (if provided) 2. Navidrome album search (local library) 3. iTunes Search API (free, public)
Configuration:
Navidrome¶
Uses Subsonic API to get now-playing from scrobbles. Useful if not using HEOS.
Configuration:
{
"music": {
"source": "navidrome"
},
"navidrome": {
"url": "https://navidrome.example.com",
"username": "user",
"password": "pass"
}
}
Related Documentation¶
- Music Control - Web remote for Denon/HEOS
- Music Stack (Navidrome) - Music streaming server
- arr-stack Overview - Media server VM