511.org MUNI Stop Status
A fullscreen kiosk app that displays live arrival predictions for a single SF Muni stop, built for a Raspberry Pi 3 + 5" touchscreen running full time.
- Live next-arrival predictions from the 511.org SF Bay Open Data Transit API
(SIRI
StopMonitoring), each with a per-route badge from the NextBusPico project and an on-time / late / early tag (predicted vs scheduled). - Service alerts for the watched line/stop, shown when there's a disruption.
- A footer with current weather (Open-Meteo, no API key) and sunrise/sunset times for the stop's location.
- Updates about once a minute (combined request rate stays under the 60 / 3600s limit), with a "time since last update" indicator.
- Large fonts, tuned for a 5" display. Blue text during the day, orange at night — switched by real sunrise/sunset for the Pi's location.
- On first start a line → direction → stop picker appears (the direction step separates the inbound/outbound copies of a stop, which share a name); the choice is saved and the app boots straight into the arrivals view afterwards.
- A menu (Change Stop / Quit) appears only after pointer movement or touch, then auto-hides.
- Go + Fyne — single binary, OpenGL via X11.
tzcoord— system timezone → coordinates.go-sunrise— sunrise/sunset times.- Open-Meteo — current weather (free, no API key).
Get a free API key from https://511.org/open-data (request a token under Open
Data). The key is read from a .env file in the working directory:
511ORG_API_KEY=your-key-here
.env is git-ignored. The selected stop is persisted to
$XDG_CONFIG_HOME/wheres-that-muni/settings.json (falls back to ~/.config/...).
Requires Go 1.25+ (the tzcoord dependency's go.mod declares go 1.25) and an
X11/Wayland session with OpenGL. On Debian/Ubuntu the Fyne build deps are
libgl1-mesa-dev xorg-dev.
make # list all targets (default)
make run # run locally
make test # unit tests
make lint # golangci-lint (run `make lint-install` once to get it)
make build # compile ./muni-displayThe Pi is ARM and the dev machine is AMD64. Cross-compiling Fyne (CGO + OpenGL) is
error-prone, so the app is built natively on the Pi. From the dev machine,
make deploy rsyncs the source to the Pi and runs go build there over SSH:
make deployIt needs the Pi's SSH login and target directory. Set them once in your
git-ignored .env (alongside the API key) so make deploy takes no arguments:
PI_HOST=pi@your-pi.local
PI_DIR=/home/pi/wheres-that-muni
You can also pass them ad hoc — make deploy PI_HOST=pi@your-pi.local PI_DIR=/home/pi/wheres-that-muni — and when unset the Makefile defaults to
pi@raspberrypi.local / /home/pi/wheres-that-muni.
The app runs from the Pi's graphical session (DISPLAY=:0), not an SSH shell; add
it to the desktop autostart to launch on boot. See
docs/deploy-raspberry-pi.md for the one-time Pi
setup (build deps, Go 1.25, API key, autostart), and
docs/reference/511-sf-bay-transit.md for
the API reference.
Apache License 2.0 — see LICENSE. Copyright 2026 Bradley Erickson.
The route badge graphics in assets/badges/ are from the NextBusPico
project.
