Skip to content

Status TV (Grafana wall screens)

Two wall-mounted TVs that show live Grafana dashboards from dash.aholadigital.com, driven by a single Raspberry Pi. Each screen plays its own Grafana playlist that rotates through six (CITY) or seven (ROAD) TV-sized dashboards, one every 2 minutes.

Screen Playlist Dashboards
Left (CITY) Status TV - CITY City 1–6: TMS overview → TMS services & WebSocket → Planner automations → Taxi grids → Production Vault → Security updates (stable)
Right (ROAD) Status TV - ROAD Road 1–7: eazytms Cloud SQL & VM → eazytms services → Ahola Transport → Ahola Special & logs → Road Web Infra → Backendsrv-1 → Road Web Infra apps (supervisord)

The TV dashboards are screen-sized copies of the team's dashboards, kept in the Grafana folder Status-TV and generated from the config repo. See Status TV Dashboards.

Playlist contents and the rotation interval are managed in Grafana (Dashboards → Playlists), not on the Pi. See Status TV Operations.

How it works

 ┌──────────────────────── Raspberry Pi 4 (status-tv, 10.10.75.9) ─────────────────────────┐
 │                                                                                         │
 │  labwc (Wayland desktop, auto-login)                                                    │
 │   ├─ kanshi ─────────── both HDMI outputs → 2560x1440@60, HDMI-A-1 left / HDMI-A-2 right│
 │   ├─ Chromium kiosk "status-tv-left"  ──► HDMI-A-1 (labwc window rule)                  │
 │   └─ Chromium kiosk "status-tv-right" ──► HDMI-A-2 (labwc window rule)                  │
 │              │                                                                          │
 │              │ http://127.0.0.1:3000/playlists/play/<uid>?kiosk                         │
 │              ▼                                                                          │
 │  nginx (listens on 127.0.0.1:3000 only)                                                 │
 │   adds "Authorization: Bearer <service-account token>"                                  │
 └──────────────┼──────────────────────────────────────────────────────────────────────────┘
                │ HTTPS
                ▼
     Grafana  https://dash.aholadigital.com   (Google SSO for people;
                                                read-only service account for the TV)

Why a proxy? Grafana's login is Google SSO, which doesn't work on an unattended screen: sessions expire and Google asks for re-authentication or 2FA. A Grafana service account never expires, but its token only works as an HTTP header, and a browser can't send it by itself. The local nginx adds the header to every request, so Chromium is permanently "logged in" with a Viewer-only identity that can be revoked from Grafana with one click.

Key facts

Hardware Raspberry Pi 4 Model B, 4 GB RAM, 64 GB SD card
OS Raspberry Pi OS (Debian 13 trixie, 64-bit), labwc desktop, auto-login as statusadmin
Address 10.10.75.9 (wired, eth0), hostname status-tv
Screens 2 × Samsung 4K TV, driven at 2560×1440 @ 60 Hz (a Pi 4 only does 4K at 30 Hz, and two 4K dashboards are too heavy for Chromium)
Grafana self-hosted 12.4 at https://dash.aholadigital.com
Grafana identity (TV) service account indola-status-tv (login sa-1-indola-status-tv), role Viewer, token never expires
Grafana identity (TV dashboard scripts) service account ai-dashboard-editor (login sa-1-ai-dashboard-editor): Viewer everywhere, Editor only in the Status-TV folder. Not on the Pi
Time sync internal NTP 172.31.0.20, 172.31.0.17 (public NTP is blocked on this network)
Secrets Proton Pass: the statusadmin SSH/sudo password and the Grafana service-account token
Config repo Attracs/devops-status-tv: every file on the Pi + the Ansible playbook that deploys it

Quick reference

Task How
Change which dashboards rotate, or the interval Grafana → Dashboards → Playlists → edit, then run ~/status-tv/restart.sh on the Pi
Change what a TV dashboard shows Edit grafana/build.py in devops-status-tv, build, check a screenshot, push. See Status TV Dashboards
Change config on the Pi (scripts, nginx, screen layout…) Edit it in devops-status-tv, then ./deploy.sh --check --diff and ./deploy.sh --diff
TVs on/off Automatic over HDMI-CEC: on 07:00–18:00 Mon–Fri. By hand: ~/status-tv/tv-power.sh on, off or status on the Pi. See TV power schedule
Restart both screens ssh statusadmin@10.10.75.9 '~/status-tv/restart.sh'
Show one fixed dashboard instead of a playlist Edit ~/status-tv/urls.conf on the Pi, then run restart.sh
Cut the TV's access to Grafana Grafana → Administration → Service accounts → indola-status-tv → Disable
See what the TVs are showing Take a screenshot

Security

  • The token is Viewer only. It can read dashboards the Viewer role can see, but it can't edit, save or administer anything.
  • nginx listens on 127.0.0.1 only, so the token proxy isn't reachable from the network. The default nginx site on port 80 is disabled.
  • On the Pi, the token is stored in /etc/nginx/grafana-token.conf (owner root, mode 600). The real token is kept in Proton Pass and never in documentation or git.
  • If the Pi is lost or stolen, disable or delete the indola-status-tv service account in Grafana. That's the only credential on the device that gives access to anything outside the Pi itself.

Subpages