Point-in-time announcement
This page records the May 25 launch. Photo Flash later moved its queue from KV to D1, added Cloudflare Media plus a working Pi fallback, and disabled automatic shown-media deletion. Use the linked Photo Flash explanation for current behavior.
What’s new
Three independent surfaces shipped today, all visible from /admin/tv-health:
- A real TV health dashboard. The floor-plan view at
/admin/tv-healthnow joins slot identity (Bar Left / Bar Right / etc.) with live heartbeats, computes fresh/stale/missing/unpaired per slot, and lets the operator pair a TV from their phone via QR or 6-digit code. Rich-metric tile drill-down shows buildId, viewport, memory, last JS error, connection state — everything you’d want when a screen looks off. - Photo flash with patron uploads. Patrons can now scan a QR at the bar and drop a photo at pub.ihnyc-rc.org/up. The DJ approves from
/admin/dj-mode, the photo takes over the projector for a few seconds, then the playlist resumes. iOS HEIC photos transcode automatically. There’s an auto-approve mode for trusted nights. - The Pi reports on itself. A new lightweight Python service on the pub Pi posts CPU/memory/disk/temperature/uptime every 30s. The dashboard shows it as a “Pi · djpi-01 · last seen 30s ago · CPU 18% · Mem 24%” card, expanding to per-metric tiles. Plus a separate “Platform” card showing Cloudflare edge colo and reachability latencies for every KV/R2 binding the worker uses.
Why this matters
Before today the only signal that something was wrong with a TV was “someone walked past it and noticed”. And the only signal that something was wrong with the Pi was the audio capture going silent — a 5-minute lag minimum. Today, the operator can answer:
- “Which TVs are healthy right now?” — one glance at the floor plan
- “When did Bar Left last successfully fetch the event data?” — open the tile, read the heartbeat section
- “Is the Pi okay?” — Pi card, green dot if recent
- “Is Cloudflare being weird in our region?” — Platform card, look at the colo + probe latencies
For DJ nights, photo flash turns the projector into a participatory surface without giving up moderation. Patrons can submit, the DJ approves, the bar feels alive instead of just played-at.
What changed for residents
Mostly nothing visible — the dashboard, the Pi reporter, and most of the DJ-mode internals are behind Cloudflare Access (operators only). The one resident-facing surface is /up:
- Land on the page, tap to choose a photo or video, hit “Send to the wall →”
- If it’s during a DJ set with auto-approve on, the photo appears within a few seconds
- Otherwise the DJ taps approve and the photo appears next time the rotation comes around
iPhone HEIC photos work out of the box — they’re converted to JPEG on upload before being stored.
What changed for operators
The admin surface at /admin (Overview) now shows a health dot — green when everything’s fresh, amber on drift, red when a TV is missing or a binding probe is failing. The same dot appears on the TVs and Slots tabs. Click into either to see the floor plan, claim orphans, or manage slot identities directly.
Pairing a new TV: open /tv/pair on the screen, scan the QR or type the 6-digit code into /admin/tv-health on a phone, pick which slot. Token gets stored, TV reloads to /tv/, ping starts flowing. ~30 seconds end-to-end.
If a TV browser is reporting but isn’t paired yet (a fresh install, or a re-pair while the old token is still cached), it shows up as an orphan in the dashboard. Operator claims it → next heartbeat adopts the new slot identity, TV reloads automatically. The TV never has to be touched physically.
Under the hood
- Slot identity lives in a Durable Object (
TV_PAIRING); heartbeats land in R2; the dashboard endpoint fans them out withPromise.alland degrades independently per source. See tv-health. - Photo flash at launch used three R2 prefixes plus a queue in KV. The current system keeps queue/history rows in D1 and uses KV only for live coordination. See photo-flash.
- Pi reporter is a separate systemd service from
pi-capture— failure is non-critical, the song-ID pipeline keeps running. The dashboard card hides cleanly when no report exists, so installs without a Pi don’t see a permanent red banner. See pi-status-reporter.
What’s next
- Pi-side video transcoder daemon — shipped after this announcement and now acts as the fallback when Cloudflare Media cannot prepare a video
- Patron block list — no operator UI exists in the current code
- Mobile responsive polish on the admin pages — the floor plan and tile detail work on phones now, but the slot management table on
/admin/slotsstill benefits from a horizontal scroll on small screens
Related docs
- tv-health
- photo-flash
- pi-status-reporter
- 2026-05-21-aes67-now-live — last week’s announcement, the AES67 audio pipeline that this stack sits next to