The display service PNG-encoded its frame to /tmp/led_matrix_preview.png
at 5 fps, 24/7 — identical frames, no viewers, per-call imports and a
chmod every write. On the devpi baseline the display service idles at
~92% CPU; this was one of its biggest fixed costs.
- New pure policy (src/common/snapshot_policy.py, unit-tested off-Pi):
WRITE changed frames at full rate only while a viewer is watching,
at a 30s idle cadence otherwise; NEVER re-encode unchanged frames —
bump mtime (os.utime) every 20s instead, keeping the health check's
snapshot-age liveness proxy (60s threshold in api_v3) green. Cross-
referencing comments guard the two constants.
- Viewer detection: the web SSE display broadcaster (which only runs
while browsers are subscribed) touches /tmp/led_matrix_preview_viewer
each loop; the display service stats it at most 1/s. On viewer
arrival the write clock resets so the first frame lands within ~1s.
- Hoisted the per-call pathlib/permission_utils imports; directory
permissions ensured once instead of every frame.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FqzC1nzTWL4kaqgMaQZFam