d9c5066c29e371be6df639f6afbf8105f0309d6b
Pi Dashboard Servers
WebSocket servers that feed system stats, alarm audio, and status images to the ESP32-S3 RLCD dashboard.
File Structure
pi/
run_all.py # Launches both servers as child processes
stats_server.py # Real system stats over WebSocket (port 8765)
contents_server.py # Alarm audio + status images over WebSocket (port 8766)
mock_server.py # Drop-in replacement for stats_server with random data
audio_handler.py # WAV loading, PCM chunking, alarm streaming
image_handler.py # PNG to 1-bit monochrome conversion, alpha compositing
requirements.txt
assets/
alarm/ # WAV files for alarm audio
img/ # Status images (idle.png, on_alarm.png)
Requirements
Python 3.10+
pip install -r requirements.txt
Dependencies: websockets, psutil, Pillow
Running
Start both servers:
python run_all.py
Or run individually:
python stats_server.py # port 8765 only
python contents_server.py # port 8766 only
python mock_server.py # port 8765, random data (no psutil needed)
Servers
stats_server.py -- port 8765
Pushes a JSON object every 2 seconds with real system metrics from psutil:
cpu_pct,mem_pct,mem_used_mb,disk_pctcpu_temp(reads/sys/class/thermal/as fallback)uptime_hrs,net_rx_kbps,net_tx_kbpsservices(mocked until systemd integration)local_timefields for RTC sync (y,mo,d,h,m,s)
contents_server.py -- port 8766
Serves alarm audio and status images. Protocol:
Status image:
- Text frame:
{"type":"status_image","width":120,"height":120} - Binary frame: 1-bit monochrome bitmap (1800 bytes)
Alarm audio:
- Text frame:
{"type":"alarm_start","sample_rate":N,"channels":N,"bits":N} - Binary frames: raw PCM chunks (4096 bytes each, paced at ~90% real-time)
- Text frame:
{"type":"alarm_stop"}
On connect, sends idle.png as the status image. Alarm cycles switch to on_alarm.png during playback, then back to idle.png.
mock_server.py -- port 8765
Same JSON schema and 2-second push interval as stats_server.py, but all values are randomized. No psutil dependency -- useful for development on non-Pi machines.
Does not include local_time fields.
Modules
audio_handler.py
find_wav()-- finds the first.wavinassets/alarm/read_wav(path)-- reads WAV, returns(pcm_bytes, sample_rate, channels, bits)stream_alarm(ws, pcm, sr, ch, bits)-- streams one alarm cycle over WebSocket
image_handler.py
load_status_image(path)-- loads PNG, composites transparency onto white, converts to 1-bit 120x120 monochrome bitmap (black=1, MSB-first)send_status_image(ws, img_bytes)-- sends status image header + binary over WebSocket
Description
Languages
Python
91.9%
Shell
8.1%