-
-
Compare air quality across multiple cities at once, color-coded using the same AQI scale as the main reading
-
Real historical AQI data, not simulated — collected automatically every hour via a scheduled job running independently in the cloud.
-
Live AQI for Lahore
-
Personalized health advisory for adult with asthma, includes a risk score and specific, guidance grounded in WHO/EPA air quality thresholds
-
The same city, different profile — switching to "Child" changes the advice entirely.
Inspiration
During smog season, Lahore regularly hits "hazardous" AQI levels — but every app I checked just showed a number. A number doesn't tell a parent whether it's safe to send their kid outside, or tell someone with asthma what to actually do that day. Public health messaging stays generic ("wear a mask") when the right response is completely different depending on who you are. I wanted to build something that closes that gap — not another AQI display, but a genuinely personalized health advisor.
What it does
AawazAir takes live air quality data for any city worldwide and turns it into:
- A calculated EPA AQI (0–500 scale) from real PM2.5 data — not just a passthrough of a raw API number
- A personalized health advisory, factoring in age group (child/elderly) and health conditions (asthma, pregnant), grounded in WHO/EPA guidance, with prioritized advice when multiple conditions apply
- A 7-day trend chart built from real, automatically-collected historical data
- Multi-city comparison, so you can check air quality across several places at once
How I built it
- Backend: Python/Flask, with a from-scratch implementation of the EPA's PM2.5-to-AQI breakpoint formula, and a rule-based advisory engine structured as a lookup table (explainable, not a black box)
- Data pipeline: Cities aren't hardcoded — any city a user checks is automatically added to a
tracked_citiestable, and a GitHub Actions workflow runs every hour, pulling live AQI for every tracked city and logging it to a Supabase (Postgres) database. This means the historical trend and forecast data are genuinely real, continuously accumulating in the background, independent of whether anyone's actively using the app. - Frontend: Vanilla HTML/CSS/JS with Chart.js, deliberately kept framework-free to match my current skill level while still building something that felt like a real, cohesive product
- Deployment: Railway, chosen after hitting a card-verification wall on Render mid-build
Challenges I ran into
Several, and I want to be honest about them rather than pretend it was smooth:
- Supabase Row Level Security silently blocked reads/writes via the public API key, with no obvious error — took real debugging to trace an empty result back to RLS rather than a code bug
- An OpenWeatherMap API key activation delay looked identical to an invalid key for nearly two hours, including after generating a brand-new account and key, before I realized new keys just need time to activate
- An environment variable name mismatch (
OWM_API_KEYlocally vs.OPENWEATHER_API_KEYin GitHub Actions secrets) caused the automated hourly data collection to fail silently for a while — a good reminder that.envfiles and CI secrets are two completely separate systems that don't sync automatically - A broken ISP-level DNS resolver made my own deployed site look "down" even though global DNS checks confirmed it was live everywhere else — fixed by switching to Google's public DNS
Accomplishments that I'm proud of
- The historical data powering the trend chart and forecast feature is real, not simulated — collected automatically, hourly, since early in the build
- The advisory engine correctly combines and prioritizes advice when someone has multiple health conditions, rather than just picking one
- Debugging through several genuinely gnarly, stacked infrastructure issues (RLS, API activation delays, env var mismatches, DNS) without giving up on getting the real system working end to end
What I learned
How much of building something "real" is actually about the boring infrastructure layer — environment variables, database permissions, DNS — rather than the feature code itself. I also learned to separate "the code is wrong" from "the infrastructure is misconfigured" as two very different debugging paths, which saved a lot of time once I started checking that distinction first.
What's next for AawazAir
- SMS-based AQI alerts for users without reliable smartphone/data access
- Urdu language support
- Push notifications when air quality crosses a dangerous threshold for a saved profile
- Partnering with schools or clinics to use it as an actual outdoor-activity planning tool
- Expanding the advisory rule set with input from real public health professionals
Log in or sign up for Devpost to join the conversation.