airq 1.1.0

CLI air quality checker with pollution front detection, maps, and PDF reports
Documentation

airq

Crates.io License: MIT

Check air quality from your terminal. Any city in the world, no API key needed.

By default merges two data sources for more accurate results:

  • Open-Meteo — global model (PM2.5, PM10, CO, NO2, O3, SO2, UV)
  • Sensor.Community — citizen science sensors (15,000+ real sensors worldwide)

Install

brew install fortunto2/tap/airq     # Homebrew (macOS & Linux)
cargo install airq                  # crates.io (any platform)

Or download prebuilt binaries from GitHub Releases.

Quick start

airq --city gazipasa
Resolved city: Gazipaşa, Türkiye
Sources: Open-Meteo (model) + Sensor.Community (1 sensors, 5km median)
--------------------------------------------------
PM2.5  9.6 avg  (12.7 model, 6.5 sensors) μg/m³
PM10   14.7 avg  (16.2 model, 13.1 sensors) μg/m³
CO    159.0 μg/m³
NO2   1.9 μg/m³
O3    73.0 μg/m³
SO2   1.1 μg/m³
UV Index: 0 ☀️ (Low)
Wind:   5.2 km/h ↙ NE (gusts 8)
--------------------------------------------------
🟢 US AQI: 40 | EU AQI: 29 — Good

Commands

Any city in the world

airq --city tokyo
airq --city "new york"
airq --city berlin
airq --city анталья

By coordinates

airq --lat 55.75 --lon 37.62

History (sparkline)

airq history --city istanbul --days 5
Istanbul, Türkiye — last 5 days
2026-03-09: ██░░░ 10.9 µg/m³ (AQI 44 🟢)
2026-03-10: ███░░ 20.7 µg/m³ (AQI 57 🟡)
2026-03-11: ███░░ 21.5 µg/m³ (AQI 68 🟡)
2026-03-12: ███░░ 17.3 µg/m³ (AQI 68 🟡)
2026-03-13: ███░░ 20.3 µg/m³ (AQI 64 🟡)

Top cities by AQI

airq top --country turkey
airq top --country russia --count 10
airq top --country usa --json
# City              AQI  PM2.5
1 Delhi             210  🟣 58.9
2 Mumbai            87   🟡 29.3
3 Bangalore         62   🟡 17.5
4 Chennai           54   🟡 13.7
5 Kolkata           43   🟢 10.2

Any country in the world — 10,000+ cities built-in. Use airq top --country x --list to see all.

Compare providers

airq compare --city berlin                       # area median (all sensors in 5km)
airq compare --city gazipasa --sensor-id 77955   # specific sensor
Berlin, Germany — Provider Comparison
Sensor.Community: 143 sensors, 5km radius
┌──────────┬───────────┬─────────────────┬─────────┐
│ Metric   │ Open-Meteo│     Area Median │ Average │
├──────────┼───────────┼─────────────────┼─────────┤
│ PM2.5    │       4.2 │             6.8 │     5.5 │
│ PM10     │       5.3 │            11.1 │     8.2 │
│ US AQI   │        31 │       28 (calc) │      29 │
└──────────┴───────────┴─────────────────┴─────────┘

Single provider

airq --city berlin --provider open-meteo          # model only
airq --city berlin --provider sensor-community --sensor-id 72203  # sensor only

JSON output

All commands support --json:

airq --city berlin --json
airq history --city tokyo --days 7 --json
airq top --country usa --json
airq compare --city berlin --json

Pollution front detection

Detect pollution fronts moving between cities using cross-correlation analysis:

airq front --city gazipasa --radius 150 --days 3
Analyzing pollution fronts around Gazipaşa, Türkiye...
Nearby cities (150km radius):
  Alanya (42km NW), Manavgat (97km NW), Karaman (129km NE)...

Current wind: 5.2 km/h ↙ NE

Spike detection (last 72h):
  🟡 Alanya: 16.8 µg/m³ (+2.6) 2026-03-15 20:00
  🟢 Manavgat: 12.0 µg/m³ (+2.0) 2026-03-15 20:00

Pollution fronts detected:
  ↘ Manavgat → Gazipaşa | 5 km/h SE | lag 20h | corr 87%
  ⚠ Manavgat → Gazipaşa front detected (lag 20h, 5 km/h)

Uses Z-score spike detection, cross-correlation with time-lag, and haversine geometry to track pollution movement.

HTML report with map

Generate a visual report with Leaflet.js map showing cities, front arrows, and analysis tables:

airq report --city hamburg --radius 150 --days 3         # HTML only
airq report --city hamburg --radius 150 --days 3 --pdf   # HTML + PDF

Opens in any browser. PDF export uses Chrome headless or wkhtmltopdf.

Find nearby sensors

airq nearby --city gazipasa --radius 10

Configuration

Set up a default city and favorites list so you don't have to type --city every time:

airq init --city tokyo          # set default city
airq                            # now just works — uses tokyo

Config file: ~/.config/airq/config.toml

default_city = "tokyo"
cities = ["tokyo", "berlin", "istanbul", "new york"]

With a favorites list, check all cities at once:

airq --all
# City              AQI  PM2.5
1 Istanbul          98   🟡 34.6
2 New York          72   🟡 22.0
3 Berlin            31   🟢 4.2
4 Tokyo             35   🟢 8.3

How it works

By default (--provider all), airq fetches both sources in parallel and averages PM2.5/PM10. Each value shows the breakdown:

PM2.5  4.9 avg  (4.2 model, 5.7 sensors) μg/m³
  • model = Open-Meteo atmospheric reanalysis (global, ~11km grid)
  • sensors = median of all Sensor.Community sensors within 5km (filters outliers)

If no sensors nearby, falls back to model only with a note.

AQI scale

AQI Category Color
0–50 Good 🟢
51–100 Moderate 🟡
101–150 Unhealthy for Sensitive Groups 🟠
151–200 Unhealthy 🔴
201–300 Very Unhealthy 🟣
301–500 Hazardous 🟤

US AQI from Open-Meteo API. EU AQI also shown. For sensor-only data, AQI calculated using EPA formula.

Front detection methodology

The front and report commands use cross-correlation analysis to detect pollution movement:

  1. Spike detection — Z-score on hourly PM2.5 differences. Flags sudden changes (z > 2σ)
  2. Cross-correlation — compares time-series between city/sensor pairs with lags -24h to +24h. Peak correlation reveals transit time
  3. Speed & direction — haversine distance / time lag = front speed. Bearing calculated from coordinates
  4. Dual-source — when both Open-Meteo (model) and Sensor.Community (ground sensors) are available, correlations are weighted and merged. Agreement boosts confidence
  5. Sensor clustering — nearby sensors (~5km) are grouped into zones for spatial analysis. Reports show individual sensor locations with PM2.5 heatmap overlay

See examples/ for sample reports.

Data sources

License

MIT