Status TV: Operations
Everyday tasks. Unless noted, commands run on the Pi as statusadmin
(ssh statusadmin@10.10.75.9).
What's on which screen
~/status-tv/urls.conf:
status-tv-left http://127.0.0.1:3000/playlists/play/hetzv9p?kiosk # Status TV - CITY
status-tv-right http://127.0.0.1:3000/playlists/play/hetrgxv?kiosk # Status TV - ROAD
| Screen | Output | Grafana playlist (uid) |
|---|---|---|
| Left | HDMI-A-1 | Status TV - CITY (hetzv9p) |
| Right | HDMI-A-2 | Status TV - ROAD (hetrgxv) |
Change the rotating dashboards or the interval
- Grafana → Dashboards → Playlists → Edit playlist.
- Add/remove/reorder dashboards, or change the interval (currently
2m). Save. Use the TV dashboards from the Status-TV folder (see Status TV Dashboards). - Restart the screens – a playlist's settings are only read when it starts:
~/status-tv/restart.sh
Notes:
- In a playlist, each dashboard opens with its saved defaults (time range,
refresh, variable values) – URL parameters can't be set per item. To change
what the TV shows (e.g. deploy=stable, last 12 h), change and save the
dashboard's defaults in Grafana. Be aware that anyone saving the dashboard
with different defaults also changes the TV.
- A dashboard taller than the screen is cut off – kiosk mode can't scroll.
That's why the playlists use the screen-sized TV dashboards from
Status TV Dashboards instead of the originals.
- Heavy dashboards (40+ panels) take 10–20 s to render on the Pi after each
switch. Keep the interval at minutes, not seconds.
- The service account must be able to view the dashboard (Viewer role +
folder permissions).
Edit a dashboard
The TV dashboards (stv-city-*, stv-road-*) are generated: change them in the
repo, not in the Grafana UI. See
Change a TV dashboard.
No restart needed – each playlist turn reloads the dashboard.
Show a single fixed dashboard instead of a playlist
Edit ~/status-tv/urls.conf and replace the playlist URL with a dashboard URL
on the local proxy, ending with &kiosk. Here the URL can carry its own
time range and variables:
status-tv-right http://127.0.0.1:3000/d/6752404e-fa3e-427b-b2a5-41362fee85d8/eazytms?orgId=1&from=now-12h&to=now&var-deploy=stable&refresh=30s&kiosk
(take the URL from the browser, replace https://dash.aholadigital.com with
http://127.0.0.1:3000, append &kiosk). Then ~/status-tv/restart.sh.
Commented-out single-dashboard examples are kept at the bottom of urls.conf.
Restart the screens
~/status-tv/restart.sh # on the Pi
ssh statusadmin@10.10.75.9 '~/status-tv/restart.sh' # from a laptop
Restarts only Chromium; takes ~30–40 s until both dashboards are drawn.
For a full restart: sudo reboot (everything comes back by itself in ~1 min).
Take a screenshot
ssh statusadmin@10.10.75.9 \
'XDG_RUNTIME_DIR=/run/user/$(id -u) WAYLAND_DISPLAY=wayland-0 grim -s 0.5 /tmp/s.png && cat /tmp/s.png && rm /tmp/s.png' > status-tv.png
grim -o HDMI-A-1 / -o HDMI-A-2 captures one screen only.
Health check
ssh statusadmin@10.10.75.9 '
uptime; vcgencmd measure_temp; vcgencmd get_throttled
timedatectl | grep synchronized
systemctl is-active nginx
curl -s http://127.0.0.1:3000/api/user | grep -o "\"login\":\"[^\"]*\""
pgrep -fa "kiosk.s[h]"'
Healthy: temp < 80 °C, throttled=0x0, clock synchronized, nginx active,
login sa-1-indola-status-tv, two kiosk.sh processes.
Rotate / replace the Grafana token
- Grafana → Administration → Service accounts →
indola-status-tv→ Add service account token. - On the Pi, put the new token in place and reload nginx:
sudo nano /etc/nginx/grafana-token.conf # proxy_set_header Authorization "Bearer glsa_…"; sudo nginx -t && sudo systemctl reload nginx curl -s http://127.0.0.1:3000/api/user # → sa-1-indola-status-tv - Delete the old token in Grafana.
- Update the token in Proton Pass and in your local
.env.
Revoke access (Pi lost/compromised, or decommissioning)
Grafana → Administration → Service accounts → indola-status-tv →
Disable (temporary) or Delete. The screens immediately stop getting
data. Nothing else on the Pi grants access to Grafana.
Change screen layout / resolution
~/.config/kanshi/config – profile dual for two screens, single for one.
After editing: pkill -HUP -x kanshi (or log out/reboot). Supported modes:
WAYLAND_DISPLAY=wayland-0 wlr-randr.
To swap left/right, either swap the position values in kanshi and the
outputs in ~/.config/labwc/rc.xml, or simply swap the cables.
Updating the Pi
sudo apt-get update && sudo apt-get full-upgrade -y && sudo reboot
All packages come from the official Debian / Raspberry Pi repositories.
Deploy config changes (Ansible)
Config files and the playbook are in
Attracs/devops-status-tv. On
your laptop (needs ansible, no sshpass):
git clone git@github.com:Attracs/devops-status-tv.git && cd devops-status-tv
cp .env.example .env # fill from Proton Pass
git config core.hooksPath .githooks # secret check before every commit
./deploy.sh --check --diff # dry run
./deploy.sh --diff # apply
A deploy with nothing to change reports changed=0 and doesn't touch the
screens. Change files in the repo rather than editing them on the Pi by hand,
otherwise the next deploy overwrites your edit.
TV power schedule
The Pi switches both TVs on and off through the HDMI cable (HDMI-CEC, which Samsung calls Anynet+). Default schedule: on 07:00–18:00 Monday to Friday, off at other times and at weekends.
- A systemd timer runs
~/status-tv/tv-power.sh autoat 07:00, at 18:00 and 2 minutes after every boot. The script works out what the TVs should be at that moment and sets it, so a reboot in the evening doesn't leave them on. - Change the times in
inventory.iniin the devops-status-tv repo (tv_on_time,tv_off_time,tv_dayswith 1=Mon … 7=Sun) and deploy.tv_power_schedule=falseswitches the schedule off. - By hand on the Pi:
~/status-tv/tv-power.sh status # on / standby per TV ~/status-tv/tv-power.sh on # switch on and select the Pi's input ~/status-tv/tv-power.sh off journalctl -u status-tv-tv-power.service # what the schedule did systemctl list-timers status-tv-tv-power.timer # next run
Requirements in both TVs (Settings → Connection → External Device Manager, and Settings → General → Eco Solution):
- Anynet+ (HDMI-CEC): On
- Auto Power Off: Off. Otherwise the TV switches itself off after 4 hours without a remote control button press, even with a picture.
- No Signal Power Off: Off, Energy Saving / Motion Lighting: Off
SSH access
Everyone uses their own SSH key. Public keys are in the repo under keys/, and
Ansible installs them on the Pi.
- Create a key with a passphrase and load it:
ssh-keygen -t ed25519 -f ~/.ssh/status-tv -C "<your email> status-tv" ssh-add ~/.ssh/status-tv - Add
~/.ssh/status-tv.pubto the repo askeys/<name>.pub, commit, and run (or ask someone with access to run)./deploy.sh --diff. - Test:
ssh -o PasswordAuthentication=no statusadmin@10.10.75.9 hostname
Password login over SSH is still allowed while the team adds their keys. After
that it will be switched off (ssh_keys_only=true in inventory.ini). The
password then only works for sudo and on the Pi's own keyboard and screen.
Keep the documentation in sync
Status TV Config files mirrors the files on the Pi. If you change a file on the Pi, update that page as well. Never put the real token in the documentation.