Watch the airplanes flying overhead, live on your real Vestaboard.
VestaSpotter is a self-hosted service that turns your Vestaboard into a live split-flap aircraft tracker for the planes passing overhead. Point it at your viewing location's coordinates and your nearest airport, and the board flips to show you exactly what's up there in real time β airline, flight number, route, aircraft type, tail number, sighting count, and a status footer.
Works anywhere you'd want to spot airplanes: apartment window, house deck, backyard, rooftop, RV, lake cabin, office. Detection geometry (radius, altitude bounds, field of view) is fully configurable for everything from a single-window near-airport view to a 360Β° rural open-sky setup.
It also includes a web dashboard for remote control + statistics, daily history, watch lists, custom-livery callouts, and (if you live near DC) a POTUS movement detector that catches the Park Police helicopter pattern preceding presidential helicopter departures.
The board, rendering a real flight passing overhead:
π¦UA 1234 IAD -- DCA
DEP 842P // 848P π¨+6M
ARR 945P // 950P π¨+5M
π¨N12345 2018 7X SEEN
β¬β¬ BOEING 737-800 β¬β¬
π©DCA 47 ARR / 35 DEP
- π¦ = airline brand tile (United blue, American red, Southwest orange, etc.)
- DEP/ARR rows: scheduled // actual times + delay tile (green β€ 0min, yellow 1-14, red 15+)
- Yellow tile next to tail = "king of the hill" (most-seen tail in your DB)
- Row 5: white tile bookends for normal aircraft, yellow for rare types or custom liveries
- Row 6: green/yellow/red status tile based on FlightAware airport-delay color + your personal arr/dep counts for today
Live tracking
- Predictive detection β projects trajectories forward so the board is already flapping by the time the plane enters your view
- Configurable view geometry (orientation, FOV, radius, altitude bounds)
- Auto-detects runway flow from the ratio of your recent arrivals vs departures
- Skips polling + pushing during configurable quiet hours (overnight API budget saver)
Dashboard (/)
- Live board preview
- Today's stats: planes seen, ARR/DEP split, runway flow indicator
- Hourly heatmap, daily history
- King-of-the-hill leaderboard, aircraft type leaderboard
- Helicopter activity tracking
- Recent activity feed
- FlightAware spend monitor (so you don't get a surprise bill)
- Pause controls, watch list, scheduled mode profiles
- Public guest view at
/live(controls + costs hidden β safe to share)
Customization (drop YAML files, no code required)
liveries.yamlβ tail numbers β custom livery names (Astrojet retro, breast cancer pink, etc.)airport_rare_{CODE}.yamlβ aircraft types that are rare at your specific airportaircraft_names.yamlβ short display names for ICAO type codes
π See docs/CUSTOMIZATION.md for a complete guide on what to put in these files, where to find livery data, and how to research what's rare at YOUR specific airport. A starter template ships at backend/airport_rare_TEMPLATE.yaml.
Follow Flights (track family/friends' trips end-to-end)
- Queue any number of upcoming flights via the dashboard (flight # + date + custom label)
- Board auto-takes-over 3 hours before each scheduled departure
- Cycles through every phase: PRE_FLIGHT β BOARDING β TAXI β AIRBORNE β APPROACH β LANDED β POST_LANDED
- AIRBORNE check-ins every 15 min with live altitude, speed, "city below" via reverse geocode, and a 16-tile progress bar from origin β destination
- Real-time turbulence indicator from AWC SIGMET data β frontier tile + row 4 text both color-coded (smooth/light/mod/severe). Tiles to the left of the frontier preserve historical weather, so the bar becomes a visible flight log
- Handles delays, cancellations, diversions, gate changes, baggage claim
- Auto-removes from queue 30 min after gate arrival; next queued flight takes over (or board returns to overhead mode)
Optional: POTUS detector (DC-area users)
- Detects when Park Police helicopters do orbital patrol patterns over the White House
- Cross-references factba.se's POTUS schedule to differentiate real movements from routine drills
- Pre-empts normal flight display with a red-white-blue alert board
- A Vestaboard with a Vestaboard+ subscription (for the Cloud Read/Write API key)
- Something to run the app on β a Mac Mini, Raspberry Pi, NUC, $5 VPS, etc. The app is lightweight (~50MB RAM)
- Internet access for the Vestaboard cloud, FlightAware AeroAPI, and OpenSky Network
Optional but recommended: a separate domain or subdomain pointed at your server for the dashboard.
| Service | Cost | Used for |
|---|---|---|
| Vestaboard | Hardware + Vestaboard+ sub | The board itself + Cloud R/W API key |
| FlightAware AeroAPI | Free tier ($5/mo credit), then pay-as-you-go | Flight enrichment (route, aircraft type, tail, delay) |
| OpenSky Network | Free | Real-time aircraft positions |
Expected FA cost on default settings: ~$10-15/month for a typical single-location install. The dashboard's built-in cost monitor will warn you if you trend higher.
git clone https://github.com/jakesgoodapps/vestaspotter
cd vestaspotter
# Run the interactive setup wizard β writes .env for you
python3 configure.py
# Build + start
docker compose up -d --build
# Visit the dashboard
open http://localhost:8011/Leave DRY_RUN=true for the first session. Watch the dashboard's board preview match what you'd expect from looking up at the sky. When confident, flip DRY_RUN=false in .env and restart.
Same as Option A, plus put it behind a reverse proxy of your choice (Traefik, nginx, Caddy) if you want a public URL for the dashboard. Pin your container as a systemd / launchd service if your platform doesn't restart Docker on boot.
If you're running on a server with an existing Docker reverse-proxy network, copy docker-compose.override.example.yml to docker-compose.override.yml (gitignored) and adjust the networks/binding to match your setup β Docker Compose will merge it with the base file automatically.
VestaSpotter is a single FastAPI container β drops into any Docker-hosting platform. The data/ directory should be a persistent volume (~10MB). No DB required.
See .env.example for the full annotated list. Key vars:
| Var | What |
|---|---|
VESTABOARD_API_KEY |
From the Vestaboard app β Settings β Developer |
DRY_RUN |
true = log renders without touching the physical board. Use this first. |
FLIGHTAWARE_API_KEY |
Personal-tier AeroAPI key |
OPENSKY_CLIENT_ID/SECRET |
Optional but recommended β 10Γ the rate limit |
LATITUDE / LONGITUDE |
Your viewing spot's coordinates |
ORIENTATION_DEG |
Compass bearing your viewing direction faces (0=N, 90=E, 180=S, 270=W). Irrelevant if FIELD_OF_VIEW_DEG=360 |
FIELD_OF_VIEW_DEG |
Angular width of your visible sky. 120 = single window, 180 = wide window/balcony, 270 = corner unit, 360 = open sky (yard/deck/rooftop) |
RADIUS_NM |
Detection radius. 3-5 near a major airport, 10-20 further out, 50+ for rural cruise-traffic spotting |
MAX_ALTITUDE_FT / MIN_ALTITUDE_FT |
Altitude band. Defaults (200-8000) work near-airport; bump max higher to catch cruise traffic, bump min higher if you don't want ground-level clutter |
LOCAL_TIMEZONE |
IANA name for "today" math (e.g., America/New_York) |
AIRPORT_CODE |
Nearest IATA airport for arr/dep classification + footer |
PREDICT_SECONDS_AHEAD |
Trajectory lookahead. Higher = more lead time, more false positives. 100 is a good default. |
ENABLE_POTUS_DETECTOR |
DC-only. Default false. |
QUIET_HOURS_START/END |
Skip everything during this window (HH:MM local) |
OpenSky Network ββ> Aircraft positions
|
v
AircraftTracker ββ> filter to overhead (distance, altitude, FOV, predictive lookahead)
|
v
FlightEnricher ββ> FlightAware enrichment (route, schedule, type, owner)
+ OpenSky metadata (year built)
+ custom_data (liveries.yaml, airport_rare_{code}.yaml, aircraft_names.yaml)
+ sightings_db (sighting count for this tail)
|
v
data_pipeline ββ> EnrichedAircraft β AircraftView (board-shaped)
|
v
formatter ββ> 6Γ22 int matrix (Vestaboard char codes)
|
v
VestaboardClient (Cloud) ββ> POST https://rw.vestaboard.com/
All state persists in data/ as SQLite databases + small JSON files. Wipe data/ to reset everything except your .env.
PRs welcome. Especially:
- New
airport_rare_{CODE}.yamlfiles for airports beyond DCA β see docs/CUSTOMIZATION.md for the format + sourcing guide. Goal: every major US airport ships with a community-maintained file. - Additions to
liveries.yamlfor cool tail-specific paint jobs (heritage liveries, breast cancer pink, etc.) - Additions to
airline_colors.pyfor international or regional carriers whose tile color is wrong - Translations to other languages (UI text is short β would be fun)
- Bug reports + feature ideas in GitHub Issues
By submitting a contribution you agree it can be distributed under the project's PolyForm Noncommercial license (and re-licensed by the maintainer under commercial terms for paid installs).
PolyForm Noncommercial 1.0.0. See LICENSE.
Free for personal use, hobby projects, education, research, and nonprofits β install it on your own Vestaboard at home, in your hackerspace, in a school, etc.
Commercial use requires a separate license. If you're a hotel, restaurant, aviation venue, museum, airline lounge, real estate office, or any other for-profit deployment, please reach out: jake@jakesgoodapps.com. Happy to license it (often cheaply) for venue installs, with optional support / custom branding / multi-board sync on top.
- Vestaboard β the physical board hardware
- FlightAware AeroAPI β flight enrichment
- OpenSky Network β aircraft positions
- factba.se β POTUS schedule data
- hexdb.io β aircraft registry (we now use OpenSky metadata directly, but hexdb was the first attempt)
Built and tested against DCA. If you build a cool airport-specific YAML or livery list for your own area, send a PR!