[PR #6] [MERGED] feat(airquality): air quality widget — European AQI + pollen forecast #6

Closed
opened 2026-08-09 19:09:25 +02:00 by zaph0d · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/niels-emmer/wall-cast/pull/6
Author: @niels-emmer
Created: 3/23/2026
Status: Merged
Merged: 3/23/2026
Merged by: @niels-emmer

Base: mainHead: feat/air-quality


📝 Commits (4)

  • 1a64115 feat(airquality): add air quality widget with AQI and pollen forecast
  • 45760a5 fix(airquality): add Air Quality to rotator slot type dropdown
  • b9e6b10 docs: update CLAUDE.md, README, and example config for air quality widget
  • 78ff7b0 chore(memory): mark rules rewrite plan as complete

📊 Changes

13 files changed (+510 additions, -18 deletions)

View changed files

📝 CLAUDE.md (+4 -1)
📝 README.md (+3 -2)
📝 backend/app/config.py (+2 -0)
📝 backend/app/main.py (+2 -1)
backend/app/routers/airquality.py (+169 -0)
📝 config/wall-cast.example.yaml (+4 -4)
📝 docs/config-reference.md (+25 -1)
📝 docs/memory/records/rules-rewrite-plan.md (+2 -2)
📝 frontend/src/admin/AdminPanel.tsx (+8 -6)
frontend/src/hooks/use-air-quality.ts (+33 -0)
📝 frontend/src/i18n/translations.ts (+35 -0)
frontend/src/widgets/airquality/AirQualityWidget.tsx (+220 -0)
📝 frontend/src/widgets/base-registry.ts (+3 -1)

📄 Description

Summary

  • New airquality widget (large slot) showing European AQI index, pollutant chips (PM2.5, PM10, NO₂, O₃, Dust), and a 4-day pollen bar chart (birch, grass, alder, mugwort, ragweed)
  • Data from open-meteo.com CAMS model — no API key required, same provider already used for weather
  • Pollen species absent from the forecast (off-season) are filtered server-side; widget gracefully shows "None" when all species are inactive
  • Widget added to admin panel rotator slot dropdown and to the default main rotator for new screens
  • Full nl/en translations

Changes

  • backend/app/routers/airquality.py — new /api/airquality router; _parse() aggregates hourly pollen → daily max and classifies levels; 1 h cache
  • frontend/src/hooks/use-air-quality.ts — TanStack Query hook (1 h refetch)
  • frontend/src/widgets/airquality/AirQualityWidget.tsx — AQI card + pollen bar chart
  • frontend/src/widgets/base-registry.ts — widget registered
  • frontend/src/admin/AdminPanel.tsx — added to ROTATOR_SLOT_TYPES dropdown and default new-screen rotator
  • frontend/src/i18n/translations.ts — nl + en strings for AQI levels, pollen species, pollen levels
  • docs/config-reference.md — new airquality widget section, refresh table, API keys table
  • README.md / CLAUDE.md — widget table, project layout, data sources, API endpoints all updated
  • config/wall-cast.example.yaml — airquality added to main rotator; removed invalid speedtest_bytes_* fields

Test plan

  • Deploy on server: git pull && docker compose up --build -d
  • Add airquality slot to a rotator via Admin → Screens → rotator → Add slot → Air Quality
  • Confirm AQI card renders with index, level label, and pollutant chips
  • Confirm pollen section shows species rows with coloured bars (or "None" if off-season)
  • Confirm widget cycles correctly in the rotator without errors

🤖 Generated with Claude Code


🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/niels-emmer/wall-cast/pull/6 **Author:** [@niels-emmer](https://github.com/niels-emmer) **Created:** 3/23/2026 **Status:** ✅ Merged **Merged:** 3/23/2026 **Merged by:** [@niels-emmer](https://github.com/niels-emmer) **Base:** `main` ← **Head:** `feat/air-quality` --- ### 📝 Commits (4) - [`1a64115`](https://github.com/niels-emmer/wall-cast/commit/1a6411587c4a48cab96816b3f92eb8e31a1000f9) feat(airquality): add air quality widget with AQI and pollen forecast - [`45760a5`](https://github.com/niels-emmer/wall-cast/commit/45760a5d9d5c3eea013c963ea26696e50f0a9080) fix(airquality): add Air Quality to rotator slot type dropdown - [`b9e6b10`](https://github.com/niels-emmer/wall-cast/commit/b9e6b10760973b1fdb2c0fababa96b0afc816cd7) docs: update CLAUDE.md, README, and example config for air quality widget - [`78ff7b0`](https://github.com/niels-emmer/wall-cast/commit/78ff7b0c3471fdeec06001206b79f3348a657d19) chore(memory): mark rules rewrite plan as complete ### 📊 Changes **13 files changed** (+510 additions, -18 deletions) <details> <summary>View changed files</summary> 📝 `CLAUDE.md` (+4 -1) 📝 `README.md` (+3 -2) 📝 `backend/app/config.py` (+2 -0) 📝 `backend/app/main.py` (+2 -1) ➕ `backend/app/routers/airquality.py` (+169 -0) 📝 `config/wall-cast.example.yaml` (+4 -4) 📝 `docs/config-reference.md` (+25 -1) 📝 `docs/memory/records/rules-rewrite-plan.md` (+2 -2) 📝 `frontend/src/admin/AdminPanel.tsx` (+8 -6) ➕ `frontend/src/hooks/use-air-quality.ts` (+33 -0) 📝 `frontend/src/i18n/translations.ts` (+35 -0) ➕ `frontend/src/widgets/airquality/AirQualityWidget.tsx` (+220 -0) 📝 `frontend/src/widgets/base-registry.ts` (+3 -1) </details> ### 📄 Description ## Summary - New `airquality` widget (large slot) showing European AQI index, pollutant chips (PM2.5, PM10, NO₂, O₃, Dust), and a 4-day pollen bar chart (birch, grass, alder, mugwort, ragweed) - Data from open-meteo.com CAMS model — no API key required, same provider already used for weather - Pollen species absent from the forecast (off-season) are filtered server-side; widget gracefully shows "None" when all species are inactive - Widget added to admin panel rotator slot dropdown and to the default main rotator for new screens - Full nl/en translations ## Changes - `backend/app/routers/airquality.py` — new `/api/airquality` router; `_parse()` aggregates hourly pollen → daily max and classifies levels; 1 h cache - `frontend/src/hooks/use-air-quality.ts` — TanStack Query hook (1 h refetch) - `frontend/src/widgets/airquality/AirQualityWidget.tsx` — AQI card + pollen bar chart - `frontend/src/widgets/base-registry.ts` — widget registered - `frontend/src/admin/AdminPanel.tsx` — added to `ROTATOR_SLOT_TYPES` dropdown and default new-screen rotator - `frontend/src/i18n/translations.ts` — nl + en strings for AQI levels, pollen species, pollen levels - `docs/config-reference.md` — new `airquality` widget section, refresh table, API keys table - `README.md` / `CLAUDE.md` — widget table, project layout, data sources, API endpoints all updated - `config/wall-cast.example.yaml` — airquality added to main rotator; removed invalid `speedtest_bytes_*` fields ## Test plan - [ ] Deploy on server: `git pull && docker compose up --build -d` - [ ] Add `airquality` slot to a rotator via Admin → Screens → rotator → Add slot → Air Quality - [ ] Confirm AQI card renders with index, level label, and pollutant chips - [ ] Confirm pollen section shows species rows with coloured bars (or "None" if off-season) - [ ] Confirm widget cycles correctly in the rotator without errors 🤖 Generated with [Claude Code](https://claude.com/claude-code) --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
zaph0d 2026-08-09 19:09:25 +02:00
Sign in to join this conversation.
No labels
pull-request
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
github-mirrors/wall-cast#6
No description provided.