This repository contains the AirGradient ESP-IDF firmware monorepo for AirGradient product models.
The project is organized around shared reusable components and thin product-specific application roots. The goal is to keep firmware logic testable, readable, and reusable across multiple AirGradient devices.
Today it includes:
- shared firmware components under
components/ - the AirGradient Go portable monitor under
products/go/ - a thin reference ESP-IDF product under
products/reference/ - host-side test entrypoints under
tests/
components/- shared AirGradient ESP-IDF components, including shared drivers, HALs, services, and third-party code when it belongs to a shared component responsibilityproducts/- AirGradient product-specific ESP-IDF application rootstests/- top-level host-test entrypoint
- shared capability code lives in
components/ - product-specific wiring and BSP live in
products/ - application logic should stay host-testable where practical
- product application roots should stay thin
. "$HOME/Tools/esp/esp-idf/export.sh"
# AirGradient Go
idf.py -C products/go build
# Reference product
idf.py -C products/reference buildcmake -S tests -B tests/build -DCMAKE_EXPORT_COMPILE_COMMANDS=ON
cmake --build tests/build
ctest --test-dir tests/build --output-on-failureFor clangd or Neovim LSP, this repo can generate compile databases in multiple build roots:
tests/build/compile_commands.jsonfor native host testsproducts/go/build/compile_commands.jsonfor the AGo ESP-IDF buildproducts/reference/build/compile_commands.jsonfor the reference ESP-IDF build
To create a single root-level compile_commands.json for editor discovery,
build whichever targets you need, then merge them:
python scripts/merge_compile_commands.pyThe merge prefers host-test entries for shared files that appear in both databases, then includes the remaining firmware-only entries.
Start at the layer that matches your task:
components/README.md— shared component layout; each component carries its ownREADME.mdproducts/README.md— product application roots; each product carries its ownREADME.md,ARCHITECTURE.md,docs/, andspecs/tests/README.md— host-test workflow
When adding or editing any Markdown file:
docs/STYLE.md— documentation style guidedocs/templates/— copy-pasteable templates per doc type
Before opening a PR, verify the relevant firmware build succeeds and all relevant host tests pass:
. "$HOME/Tools/esp/esp-idf/export.sh"
idf.py -C products/<product> build
cmake -S tests -B tests/build -DCMAKE_EXPORT_COMPILE_COMMANDS=ON
cmake --build tests/build
ctest --test-dir tests/build --output-on-failureUpdate related documentation after the implementation changes are complete and before final verification. For Markdown changes, run the documentation lint or the full pre-commit suite.
Install the pre-commit hook once per clone so staged Markdown is checked and staged C/C++ files are formatted locally before each commit:
pip install pre-commit
pre-commit installThe same pre-commit hooks run on every pull request via
pre-commit.yml, including clang-format
and Markdown lint. PRs that fail formatting or lint checks are blocked.
GitHub Actions also initializes submodules, populates ESP-IDF managed
components, then configures, builds, and runs the native host-test suite on
every pull request and push to main via
host-tests.yml.
To run the hooks on the currently staged files before committing:
pre-commit run