Skip to content
yalt8826.com
← projects/
projects/tempo-air-quality/hackathonearth datateam

TEMPO Air Quality

An air-quality dashboard for ten US cities, built in a hackathon weekend around NASA's TEMPO satellite: live EPA readings, local weather, a model's estimate and a map.

Team of four · NASA Space Apps Challenge weekend · Oct 2025

01 / overview

How clean is the air right now?

TEMPO is a NASA instrument in geostationary orbit that measures air pollution over North America every hour. The challenge was to turn data like that into something people could act on. In a weekend, our team of four built a Flask dashboard for ten US cities. It pulls the current air quality index from the EPA, fetches local weather, runs a random forest, and plots it all on a map.

10US cities, each with four ZIP codes to fall back on
2live data sources: EPA AirNow and Open-Meteo
18features per prediction
21cities on the map, from Vancouver to Mexico City
02 / screens

The dashboard and the map.

Captured by running the original code again in November 2026. The EPA retired the AirNow API on 1 October 2026, so the app can no longer get live readings. Every number below comes from its fallbacks: the model's estimate with default weather.

01The landing page
02Analysis for one city: the past week, today's estimate and five days ahead
0321 cities across TEMPO's North American coverage on a Leaflet map
03 / how it works

From a city name to a coloured dot.

observeEPA AirNow API
current AQI by ZIP codetries four ZIPs per cityprefers PM2.5, then ozone
weatherOpen-Meteo
temperaturehumiditywindpressureUVrain
features18 per city-day
weatherhour · weekday · day of yearlatitude · longituderush-hour, weekend and season effects
modelscikit-learn
random forestgrid search, 5-fold CVStandardScalerpickled for reuse
serveFlask
JSON endpointsdashboard pageLeaflet mapfalls back to city baselines if the API is down
04 / what's real

Looking back a year later.

Going through the code again for this page, I found that only some of what the dashboard shows is measured. Here's an honest breakdown.

What the dashboard showsWhere it actually comes from
Current AQIEPA AirNow, live (until the API was retired in Oct 2026)real
WeatherOpen-Meteo, live, with fixed defaults whenever a request failsreal
Model's training labelsOne live reading per city, scaled by weather, rush-hour and weekend factors I wrote by hand, plus random noisesynthetic
Model accuracyMeasures how well the forest learned those hand-written factors, not real airmisleading
Past week and five-day outlookToday's reading multiplied by fixed weekday and trend factorssynthetic
NO₂ columnThe AQI multiplied by a constantnot TEMPO
the biggest gap

A TEMPO NO₂ data file was downloaded for the project, but the code never reads it. The satellite the project is named after never reaches the dashboard.

05 / doing it properly

What I'd build now.

The plumbing held up: live APIs with fallbacks, a model behind an endpoint, a map. The data science behind it doesn't hold up yet, and this is what I'd change.

satelliteActually read TEMPO

Open the Level-2 NO₂ granules with xarray, keep only good-quality pixels, and sample the column over each city.

labelsReal history as the target

Train on months of archived AirNow readings, not on numbers derived from a single live one.

evaluationSplit by time, compare to a baseline

Test on days the model has never seen, and report how much it beats “same as yesterday”. If it doesn't, say so.

That's the habit I took into my research afterwards: weather meta-learning is evaluated against climatology on held-out regions.