Find pollution the city average hides, trace it to a likely source, and alert the authority that can act.
Built for the Clean Air & Climate Resilience challenge · Live in Delhi-NCR, Kanpur and Coimbatore
Live site · Demo video · API docs · Validation · Design notes · Deploy guide
| Problem | India has only a few hundred official air monitors and reports a 24-hour city average. A three-hour plume from a landfill or bus depot never shows up, nobody knows its source, and the source is often in another district or state. |
| Solution | AirWatch combines government monitors, low-cost and home sensors, residents' photos, satellite data, wind and fire detections. It spots unusual pollution, names likely sources, forecasts busy routes, and alerts the responsible authority. Google Gemini reads residents' photos, translates their complaints into English, and writes plain-language alert briefs. |
| Proof | Deployed and updating hourly. It has already sent a real cross-state request (Uttar Pradesh → East Delhi). 1,077 backend and 166 frontend tests run in CI. |
| Honesty | Every number shows its uncertainty. Where there is no data, it says "unknown", never "clean". |
| Term | Meaning |
|---|---|
| CPCB | Central Pollution Control Board, India's national body that runs the official monitors and the Air Quality Index. State boards (DPCC for Delhi, UPPCB, TNPCB) run monitors too. |
| PM2.5 | Fine particles up to 2.5 micrometres (about 30 times thinner than a hair), mostly from burning and vehicles. The most harmful pollutant: it reaches deep into the lungs. India's 24-hour limit is 60 µg/m³. |
| PM10 | Coarser particles up to 10 micrometres, mostly road and construction dust. India's 24-hour limit is 100 µg/m³. |
| µg/m³ | Micrograms of pollutant in one cubic metre of air. |
| AQI | Air Quality Index, 0–500. Good (0–50) · Satisfactory · Moderate · Poor · Very poor · Severe (401–500). |
| WHO guideline | The World Health Organization's 2021 health advice: a 24-hour average of at most 15 µg/m³ PM2.5 and 45 µg/m³ PM10. That is 4× and about 2× stricter than India's legal limits. AirWatch shows each monitor's last 24 hours as a multiple of it, such as 24 h avg 3.2× WHO. |
| Hotspot | A monitor reading far above what its neighbouring monitors predict, for several hours. |
| Back-trajectory | Tracing the wind backwards from a hotspot to find where the polluted air came from. |
| Federated learning | Cities train one shared model by exchanging what their models learned, never their raw data. |
AirWatch uses three kinds of data and keeps them separate, so a ₹15,000 sensor is never mistaken for a ₹1-crore government monitor.
| Tier | Sources | Strength | Weakness |
|---|---|---|---|
| 1 · Ground truth | CPCB and state monitors (via OpenAQ), CPCB's live AQI (via data.gov.in) | Accurate | Few |
| 2 · Dense | Community sensors, residents' photos and home sensor readings | Everywhere | Less accurate |
| 3 · Complete | Sentinel-5P satellite, CAMS air-quality model (hourly, with a 72 h outlook), Open-Meteo wind, NASA FIRMS fires | Covers everything, every hour | Coarse; the model is checked against monitors |
flowchart LR
D["Collect data hourly"] --> H["Detect hotspots"] --> S["Trace likely source"]
S --> A["Alert local district"]
S --> C["Ask neighbouring district to act"]
D --> F["Forecast busy routes"]
D --> X["Share models between cities"]
| Challenge asks for | AirWatch | Screen |
|---|---|---|
| Citizen photos | Measures haze from a photo; rejects dark, blurry or over-bright images | Contribute |
| Citizen sensor readings | Accepts PM2.5/PM10 from home sensors and compares each with the nearest monitor | Contribute |
| Citizen complaints | Every submission gets a reference number and a PDF report naming the responsible authorities | Contribute → Your reports |
| Satellite and weather data | Daily Sentinel-5P gases; hourly wind for tracing sources; the CAMS regional model for every hour monitors miss, compared against them | Overview, Live map, Forecast |
| Detect hidden hotspots | Flags monitors far above their neighbours' prediction, with ranked likely sources | Live map |
| Forecast spikes on corridors | 24/48/72-hour outlook along busy routes, plus the best time to travel | Forecast |
| Alert authorities | Routes each hotspot to the district that contains it, with deadlines and resolution notes | Authority console |
| Coordinate across cities and states | If the source is in another district or state, that authority is asked to act too | Authority console |
| Share models, interoperability | Federated learning (weights only) and a standard GeoJSON exchange API | Federation |
| Google AI | Gemini reads residents' photos for a visible source (computer vision), translates Tamil and Hindi complaints into English for officials, and writes plain-language alert briefs (GenAI). Every number it writes is checked against its source | Contribute, Authority console |
| Accessible to everyone | A spoken guide on every screen in English, Hindi and Tamil | Listen button |
| Overview | Live map | Contribute |
|---|---|---|
![]() |
![]() |
![]() |
- Overview (opens on Delhi, which has the most monitors): the official AQI, recent monitor readings (each with its last 24 hours against the WHO guideline), which data exists for this city, top hotspots, and alerts sent. While CPCB's official index is out of date, AirWatch's own index from the monitors' latest hour takes its place, labelled as AirWatch's and shown beside CPCB's last figure. With no hourly figure at all, CPCB's daily bulletin leads; its line stays under the card either way.
- Live map: monitors (filled circles), community sensors (dashed rings), residents' readings (squares) and hotspots. Each hotspot lists likely sources with a percentage, such as Khora → Ghazipur landfill, 69%.
- Forecast: choose a route and a horizon. The strip shows the forecast and a safer upper bound; stretches without monitors are marked unknown. When to travel shows the best departure hour, for example leaving at 20:00 instead of 16:00 avoids about 25% of exposure.
- Authority console: open, overdue, cross-boundary and undelivered alerts. Officials sign in to acknowledge and resolve alerts with a note. Summarise with Gemini writes a two-sentence brief and a suggested first step for any alert.
- Federation: each city's data coverage, and whether sharing models actually helped.
- Contribute: send a photo or sensor reading, describe the problem, and download a PDF complaint report. Google Gemini suggests what the photo shows, such as "Likely open burning of waste, 82% confidence", and that goes into the PDF too. Tamil and Hindi descriptions print as written, with Gemini's English translation beneath them for the official who receives the report.
| Where | What Gemini does | Type | Safeguard |
|---|---|---|---|
| Contribute → Photograph | Names the pollution source visible in a resident's photo (burning waste, industrial smoke, construction dust, vehicle exhaust…), with its confidence and one sentence on what it sees. Flags photos that are not of outdoor air. | Computer vision | Shown as an AI suggestion, never a measurement. A copy without location data is sent; the photo is not stored. If Gemini is down, the submission still works. |
| Contribute → PDF report | Translates a description written in Tamil, Hindi or another language into English, printed beneath the resident's own words. | GenAI (translation) | Labelled as a machine translation; the resident's words stay the record. A translation containing a number the original does not is discarded. Each distinct text is translated once and stored. |
| Authority console → Summarise with Gemini | Writes a plain-English brief of the alert and a suggested first inspection. | GenAI | Gemini gets only the alert's own figures. Every number in its answer is checked against them; a brief with an invented number is discarded, never shown. |
Model: Gemini 3.6 Flash, falling back to Gemini 3.1 Flash-Lite when busy.
Listen: the headphones button explains the current screen aloud in English, हिन्दी or தமிழ் (Sarvam AI voice), with the text shown alongside. Tap any paragraph to play from there.
Works on phones: the screens move to a bottom bar and the hotspot list becomes a pull-up sheet.
- The Uttar Pradesh monitor at Prashant Garden, Khora read 74 µg/m³ where its neighbours predicted 20.
- AirWatch alerted the Gautam Buddha Nagar district administration (Uttar Pradesh).
- Tracing the wind backwards ranked the Ghazipur landfill first, at 69%. The landfill is in East Delhi.
- So the East Delhi district administration was also asked to act, across a state line.
None of this was configured by hand; it came from live data.
Measured on real monitors, with 95% confidence intervals. Full details are in docs/VALIDATION.md.
| Question | Result |
|---|---|
| Can we estimate air at a place with no monitor? | Simple distance-weighted averaging: error 11.75 µg/m³. Machine-learning models did worse, so the simple method is used. |
| Which forecast works best? | The typical daily pattern: error 15.8 µg/m³ at 24 h, better than every ML model (17.4) and "same as now" (21.7). |
| Does sharing models between cities help? | Not proven yet: Kanpur has too little data to tell. |
| Does detection catch a known pollution event? | Yes. Anand Vihar, 381 µg/m³ vs 40 predicted, source ranked first. This check runs on every build. |
We publish results where ML lost, because a wrong number is worse than a simple, honest one.
- Cost: about US$20 a month for one small cloud server running everything. All data sources are free.
- Cheaper coverage: a home sensor costs up to ~₹20,000, against ₹1–1.5 crore for an official station.
- New city in five steps:
- Deploy with two scripts (guide).
- Load district boundaries.
- Confirm which office receives alerts.
- Invite residents to contribute.
- Join the federation.
- No shared database needed: each state keeps its own data, so the design works across state lines.
| Part | Built with |
|---|---|
| Backend | Python 3.12, FastAPI, PostgreSQL 16 + PostGIS + TimescaleDB, H3 grid |
| Analysis | NumPy, LightGBM, Flower (federated learning), Google Earth Engine |
| Frontend | React, TypeScript, Vite, Tailwind CSS, Leaflet + OpenStreetMap |
| AI services | Google Gemini (photo reading, complaint translation, alert briefs), Sarvam AI (voice), fpdf2 (PDF reports) |
| Hosting | Docker Compose, Caddy (HTTPS), hourly worker, nightly backups |
Code quality is enforced in CI: strict typing, linting, 1,000+ tests, database migration checks and a replay of a real pollution event. Conventions are in CLAUDE.md.
backend/app/ core · external clients · repositories (SQL) · ml · services · routes · documents · guides
federated/ federated learning server and nodes
ml/ validation scripts behind every published figure
frontend/src/ one folder per screen, shared UI, hooks, API client
infra/ Docker, Caddy, deploy and backup scripts
Needs Docker, Node 20+ and Python 3.12. Copy .env.example to .env and add free keys for OpenAQ,
data.gov.in and NASA FIRMS, plus a Google Gemini key from aistudio.google.com. Earth Engine and
Sarvam AI are optional.
npm install
npm run db:up && npm run db:migrate && npm run seed
npm run worker:once # fetch current data for all cities
npm run backfill -- --city delhi --pollutant pm25 # two weeks of history
npm run dev # API :8000, web :5173Check the claims:
npm run check # lint, types and all tests
npm run demo:replay # the Anand Vihar event must print PASS
npm run ml:validate-loso # estimate-where-no-monitor test
npm run ml:validate-forecast # forecast comparison
npm run fl:validate # does federation help?Deploy on a server: docs/DEPLOY_AWS.md.
Interactive docs: /docs.
| Endpoint | Returns |
|---|---|
GET /v1/official-aqi · /stations · /sensors · /satellite |
Official AQI, monitor readings with 24-hour averages against the WHO guideline, community sensors, satellite data |
GET /v1/live-index?city=delhi |
AirWatch's index from each monitor's latest hourly PM2.5 and PM10, on CPCB's scale |
GET /v1/bulletin?city=kanpur |
The city's line in CPCB's daily AQI bulletin: the 24-hour average to 4 pm IST |
GET /v1/regional-model?city=coimbatore&pollutant=pm10 |
CAMS modelled hours, 72 h outlook, and the model's bias against the city's monitors |
GET /v1/hotspots |
Hotspots with likely sources |
GET /v1/forecast/corridor · /exposure/advisory |
Route forecast and best time to travel |
GET /v1/alerts · POST /v1/alerts/{id}/acknowledge · /resolve |
Alerts and operator actions |
GET /v1/alerts/{id}/brief |
Gemini-written brief of an alert, with every figure checked |
POST /v1/citizen/reports · /sensor-readings · GET /v1/citizen/complaints/{ref}/pdf |
Citizen photos, sensor readings and PDF reports |
GET /v1/federation/status · /interop/* |
Model sharing results and data exchange for partner cities |
GET /v1/guide/{screen}?language=ta |
Spoken screen guide (text and audio) |
- SMS and email alerts alongside today's webhook, and a separate login for each officer.
- Hosting on Google Cloud in India (Mumbai,
asia-south1), so hourly state-board feeds such as TNPCB's can be read directly as well as CPCB's. - Calibrated citizen data: photos and household sensors join the analysis once enough readings taken beside official monitors have been collected to correct them.
- Federation across states: each state's board runs its own node, connected securely.
Data: OpenAQ · CPCB via data.gov.in, via TNPCB (tnpcb.gov.in) and CPCB's daily AQI bulletin · DPCC, IMD and CPCB via the World Air Quality Index Project (aqicn.org, backup feed) · NASA FIRMS · Open-Meteo · Copernicus Sentinel-5P via Google Earth Engine · © OpenStreetMap contributors. Voice: Sarvam AI.
MIT licence.




