Files
pi-dashboard/pi/README.md
Mikkeli Matlock 37bdc8bb1b pi features docs
2026-02-15 22:14:06 +09:00

2.8 KiB

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_pct
  • cpu_temp (reads /sys/class/thermal/ as fallback)
  • uptime_hrs, net_rx_kbps, net_tx_kbps
  • services (mocked until systemd integration)
  • local_time fields for RTC sync (y, mo, d, h, m, s)

contents_server.py -- port 8766

Serves alarm audio and status images. Protocol:

Status image:

  1. Text frame: {"type":"status_image","width":120,"height":120}
  2. Binary frame: 1-bit monochrome bitmap (1800 bytes)

Alarm audio:

  1. Text frame: {"type":"alarm_start","sample_rate":N,"channels":N,"bits":N}
  2. Binary frames: raw PCM chunks (4096 bytes each, paced at ~90% real-time)
  3. 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 .wav in assets/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