Skip to content
serberPublic

About

Air monitoring platform

Resources

Stars

6 stars

Watchers

0 watching

Forks

Latest commit

 

History

456 Commits

Folders and files

Repository files navigation

Air360

Air360 device in a Stevenson screen

Air360 is a multi-target air-quality firmware for an ESP32-S3 device: it reads a wide range of environmental sensors and uploads the same measurements to several services at once. Each upload target is enabled independently and has its own interval, so one device can publish to its own service, to a community network, and to your own database simultaneously — and if one target is unavailable, the others keep working.

Supported upload targets:

  • Air360 API — the project's native backend and public map (this repository).
  • Sensor.Community — the volunteer global air-quality network.
  • openSenseMap — the open environmental-data platform.
  • InfluxDB — your own time-series database (for Grafana and self-hosting).
  • Custom Upload — any HTTP endpoint you control.

This is the core of how Air360 positions itself: not as a walled-garden replacement for existing air-quality projects, but as a device that interoperates with them. Air360 keeps explicit compatibility with the Sensor.Community upload and registration flow (a device can still be registered on devices.sensor.community) and fetches your sensor mapping directly from openSenseMap — so you can join those ecosystems and Air360 at the same time, from one device.

Around that firmware, the repository also grows a native Air360 backend API and a public web portal.

New to Air360? The build guide walks through assembling, flashing, and configuring a device end to end.

At the device level, the project is centered on a local-first firmware runtime with setup AP onboarding, a station-mode web UI, configurable sensor support, and the multi-target backend uploads described above.

The repository intentionally separates:

  • docs/ for architecture, planning, deployment notes, and implementation-oriented navigation
  • firmware/ for the actual ESP-IDF device firmware
  • backend/ for the native Air360 API backend
  • portal/ for the user-facing web application

When documentation and code disagree, treat the relevant implementation directory as the source of truth for current behavior.

Overview

Based on the current tree, the repository now contains more than the original firmware replacement effort:

  • an ESP-IDF firmware runtime for esp32s3 with multi-target measurement uploads (Air360 API, Sensor.Community, openSenseMap, InfluxDB, Custom Upload)
  • compatibility with the Sensor.Community upload endpoint and registration flow
  • a Fastify-based Air360 backend with device registration, authenticated persisted ingest, public device lists, and measurement history queries
  • a Next.js public portal application
  • design and deployment documentation that connects those pieces

The older planning documents in docs/ still matter, but they should be read as design context unless the implementation confirms them.

Repository Layout

.
├── backend/
├── docs/
├── firmware/
├── portal/
├── CLAUDE.md
├── LICENSE
└── README.md
  • docs/ Project context, architecture notes, compatibility analysis, firmware docs, backend docs, and portal deployment notes.
  • firmware/ ESP-IDF firmware project for the device. This is the source of truth for implemented device behavior.
  • backend/ Native Air360 API backend in TypeScript/Fastify.
  • portal/ Next.js portal application.
  • CLAUDE.md Repository-level guidance. In particular, it separates design context in docs/ from implementation truth in firmware/.

Documentation Map

Start here depending on what you need.

Components

Firmware

The buildable device application lives in firmware/README.md.

Current firmware implementation includes:

  • ESP-IDF 6.x application for esp32s3
  • persisted device, sensor, and backend configuration in NVS
  • station-mode join with SNTP time sync, background time-sync retry, and setup AP fallback
  • local web UI at /, /status, /config, /sensors, and /backends
  • setup AP onboarding at /config with scanned SSID list from /wifi-scan
  • embedded frontend assets under firmware/main/webui/, served by the firmware at /assets/*
  • category-based sensor configuration, background polling, and bounded measurement queueing
  • multi-target backend upload support for Air360 API, Sensor.Community, openSenseMap, InfluxDB, and Custom Upload, each enabled independently with its own interval
  • Sensor.Community compatibility through the same device identity model exposed in the firmware UI as Short ID

Backend

The native API backend source lives in backend/. Backend documentation lives in docs/backend/README.md.

Current backend implementation includes:

  • Fastify service in TypeScript
  • GET /
  • device registration at PUT /v1/devices/:device_id/register
  • persisted batch ingest at PUT /v1/devices/:device_id/batches/:batch_id
  • public device list endpoints at GET /v1/devices and GET /v1/devices/offline
  • measurement history by public device ID at GET /v1/devices/:public_id/measurements?period=<period>

Portal

The web portal lives in portal/README.md.

Current portal implementation includes:

  • Next.js 16 / React 19 / TypeScript application
  • public home page at /
  • public device map at /map
  • device assembly guide at /build with shield-board and direct ESP32-S3 wiring paths
  • privacy page at /privacy
  • public device measurement charts at /devices/:public_id
  • deployment notes under docs/portal/

Getting Started

If you need to work on device behavior:

  1. Read firmware/README.md
  2. Then use docs/firmware/README.md as the firmware documentation map

If you need to publish a firmware beta or stable build:

  1. Read firmware/README.md for the release packaging workflow
  2. On main, run the release script from .claude/skills/air360-firmware-release-bundle/; it tags, builds, and packages the versioned bundle under firmware/release/

If you need to operate or provision a device rather than change firmware code:

  1. Read the build guide — assemble, flash, configure, and operate a device end to end
  2. For release binaries, flash the merged full.bin through https://espflash.app/
  3. Then use firmware/README.md only for build, flash, and implementation details

If you need to understand the Sensor.Community overlap specifically:

  1. Read this file for the project-level compatibility statement
  2. Read the backends guide for the actual registration and backend setup flow

If you need repository context first:

  1. Read this file
  2. Read docs/firmware/README.md
  3. Read docs/firmware/ARCHITECTURE.md

If you need backend work:

  1. Read backend/CLAUDE.md
  2. Read docs/backend/README.md

If you need portal work:

  1. Read portal/CLAUDE.md
  2. Read portal/README.md
  3. Read docs/portal/README.md

Current Status

Current implementation status appears to be:

  • firmware/ is the most substantial implemented part of the repository
  • backend/ is a native API backend with registration, authenticated ingest persistence, public device lists, measurement history, and reverse-geocoded display fields
  • portal/ is a public frontend with home, map, build guide, privacy page, and device measurement pages
  • many documents in docs/ still describe intended direction, rollout phases, and compatibility constraints rather than completed work

Development Notes

  • Keep repository-level docs focused on project navigation and boundaries between subsystems.
  • Keep firmware implementation details in firmware/README.md and docs/firmware/.
  • Keep backend operational details in docs/backend/.
  • Keep portal operational details in the portal docs.
  • Do not treat generated files under firmware/build/ as maintained source.
  • Preserve the distinction between planned behavior in docs/ and implemented behavior in firmware/, backend/, and portal/.

About

Air monitoring platform

Resources

Stars

6 stars

Watchers

0 watching

Forks

Releases

Contributors

Languages