Skip to content

Add air quality LED indicator#101

Merged
bharvey88 merged 1 commit into
ApolloAutomation:betafrom
bharvey88:add-air-quality-led-indicator
Jun 25, 2026
Merged

Add air quality LED indicator#101
bharvey88 merged 1 commit into
ApolloAutomation:betafrom
bharvey88:add-air-quality-led-indicator

Conversation

@bharvey88

@bharvey88 bharvey88 commented Jun 25, 2026

Copy link
Copy Markdown
Contributor

Version: 26.6.25.1

Adds an air quality LED indicator that drives the onboard RGB LEDs from the AIR-1's own readings. Everything lives in Core.yaml, so AIR-1 / BLE / Factory all get it via the core package.

Adds:

  • Air Quality LED Source select (Off / NowCast AQI / CO2 / VOC Index), default Off. A selected source colors the LEDs on a six-step green→maroon severity scale.
  • Air Quality LED Brightness slider (5-100%, default 100%).

Color thresholds:

  • NowCast AQI: <=50 / <=100 / <=150 / <=200 / <=300 / >300
  • CO2 (ppm): <=800 / <=1000 / <=1500 / <=2000 / <=2500 / >2500
  • VOC index: <80 / <150 / <250 / <400 / >=400 (matches the VOC Quality text sensor; tops out at purple)

Design notes:

  • Event-driven: each source sensor's on_value fires the updater only when it's the selected source, so the LED tracks readings at their real cadence (AQI/VOC ~10s, CO2 60s) with no polling.
  • Off clears the LED once, then leaves it alone, so manual RGB Light control still works.
  • A millis() guard skips the early-boot window so the select's restore_value publish can't write the light before it's initialized; the updater also defers while statusCheck/testScript own the LED.
  • An unavailable source (NaN, e.g. CO2 with no module) clears the LED rather than showing a stale color.

Fixes: N/A

Breaks: Nothing. New entities only, default Off.

Verified on hardware and with a full esphome 2026.6.2 compile.

Docs: ApolloAutomation/docs page updated (Air Quality LED Source / Brightness).

Checks:

  • Documentation Updated
  • Build Number Incremented In AIR-1.yaml

(Version substitution lives in Core.yaml, which feeds AIR-1.yaml.)

🤖 Generated with Claude Code

@coderabbitai

coderabbitai Bot commented Jun 25, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

Core.yaml bumps the integration version, adds a source select for the air quality LED, defines shared LED update logic keyed to NowCast AQI, CO2, or VOC Index, and runs that logic every 10 seconds.

Changes

Air quality LED control

Layer / File(s) Summary
LED source select and version bump
Integrations/ESPHome/Core.yaml
substitutions.version is updated and air_quality_led_source is added with four options and an on_value trigger to update_air_quality_led.
LED update script and interval refresh
Integrations/ESPHome/Core.yaml
update_air_quality_led adds boot/status/test gating, source-based sensor reads, NaN handling, banded RGB output, and a 10-second interval execution.

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant air_quality_led_source
  participant update_air_quality_led
  participant Interval10s as 10-second interval
  participant nowcast_aqi
  participant co2
  participant sen55_voc
  participant rgb_light

  User->>air_quality_led_source: choose Off / NowCast AQI / CO2 / VOC Index
  air_quality_led_source->>update_air_quality_led: on_value executes
  Interval10s->>update_air_quality_led: execute every 10 seconds
  alt Off
    update_air_quality_led->>rgb_light: turn off
  else NowCast AQI
    update_air_quality_led->>nowcast_aqi: read value
    update_air_quality_led->>rgb_light: set fixed RGB color
  else CO2
    update_air_quality_led->>co2: read value
    update_air_quality_led->>rgb_light: set fixed RGB color
  else VOC Index
    update_air_quality_led->>sen55_voc: read value
    update_air_quality_led->>rgb_light: set fixed RGB color
  end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • ApolloAutomation/AIR-1#89: Adds the nowcast_aqi sensor entity that update_air_quality_led reads when the source is set to NowCast AQI.

Suggested labels

new-feature

Suggested reviewers

  • TrevorSchirmer

Poem

I wiggle my ears and blink the light,
AQI, CO2, or VOC at night.
Ten little hops keep colors in view,
Off means off — a tidy thing to do.
🐰✨ My burrow now glows just right.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly matches the main change: adding an air quality LED indicator feature.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@Integrations/ESPHome/Core.yaml`:
- Around line 707-710: The 10-second interval is reapplying air-quality LED
updates unconditionally, which can override `statusCheck` and `testScript` while
they are already controlling `rgb_light`. Update the `interval` block and
`update_air_quality_led` flow so it only runs when no other script owns the LED,
or centralize all `rgb_light` writes through a single arbiter/guard that
`statusCheck`, `testScript`, and the air-quality updater all consult before
changing state.
- Around line 667-693: The source-selection logic in the metric update handler
leaves rgb_light unchanged when the chosen reading is NaN, so stale colors
persist after switching to a warming-up sensor. Update the branch handling in
the lambda that maps src values like "AQI", "CO2", and "VOC Index" to clear or
turn off rgb_light before each early return triggered by isnan(x), so the LED no
longer shows the previous metric until a valid sample arrives.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: c55a1a98-dab8-4d91-9156-b189c0c36143

📥 Commits

Reviewing files that changed from the base of the PR and between 651019a and 4c4cd6d.

📒 Files selected for processing (2)
  • Integrations/ESPHome/AIR-1.yaml
  • Integrations/ESPHome/Core.yaml

Comment thread Integrations/ESPHome/Core.yaml
Comment thread Integrations/ESPHome/Core.yaml Outdated
bharvey88 added a commit to bharvey88/AIR-1 that referenced this pull request Jun 25, 2026
update_air_quality_led now bails while statusCheck or testScript is
running, so the 10s interval no longer overrides the button-press status
flash or the boot self-test colors mid-display. The next interval restores
the air-quality color after those scripts release the LED.

Addresses CodeRabbit review on ApolloAutomation#101.

🤖 Generated with [Claude Code](https://claude.com/claude-code)
bharvey88 added a commit to bharvey88/AIR-1 that referenced this pull request Jun 25, 2026
The NaN early returns in update_air_quality_led left the previous
source's color lit, so switching to a warming-up source (or CO2 on a
unit with no CO2 module, which stays unknown) showed a stale, misleading
color. Turn rgb_light off on those returns so an unavailable source reads
as off instead of the old metric's color.

Addresses CodeRabbit review on ApolloAutomation#101.

🤖 Generated with [Claude Code](https://claude.com/claude-code)
bharvey88 added a commit to bharvey88/AIR-1 that referenced this pull request Jun 25, 2026
The on_boot LED nudge ran at priority 500, before the esp32_rmt_led_strip
light finished setup, so update_air_quality_led's light call faulted
(store access fault in AddressableLight::schedule_show). Move the
component.update + script.execute to a separate priority -100 on_boot
entry so it runs after rgb_light is ready. Original boot actions stay at
priority 500.

Addresses crash reported on ApolloAutomation#101.

🤖 Generated with [Claude Code](https://claude.com/claude-code)
@bharvey88 bharvey88 force-pushed the add-air-quality-led-indicator branch from 4b1b952 to 3f7d21d Compare June 25, 2026 21:21
bharvey88 added a commit to bharvey88/AIR-1 that referenced this pull request Jun 25, 2026
Even at on_boot priority -100 the addressable rgb_light isn't ready, so
calling update_air_quality_led during boot still faulted (store access
fault in AddressableLight::schedule_show). Drop the boot-time script call
entirely; the 10s interval (which runs after setup) and Home Assistant own
all LED writes. Keep the early component.update: scd40 so a CO2-selected
device still has data by the first interval.

Addresses crash reported on ApolloAutomation#101.

🤖 Generated with [Claude Code](https://claude.com/claude-code)
Comment thread Integrations/ESPHome/Core.yaml
Drive the AIR-1's onboard RGB LEDs from air-quality readings. Everything
lives in Core.yaml, so all variants pick it up via the core package.

- "Air Quality LED Source" select (Off / NowCast AQI / CO2 / VOC Index),
  default Off. A selected source colors the LEDs on a six-step
  green->maroon severity scale; thresholds match each metric's range, and
  the VOC bands line up with the VOC Quality text sensor.
- "Air Quality LED Brightness" slider (5-100%, default 100%).

Event-driven: each source sensor's on_value fires the updater only when it
is the selected source, so the LED tracks readings at their real cadence
with no polling. Selecting Off clears the LED once, then leaves it for
manual use. A millis() guard skips the early-boot window so the select's
restore-publish can't write the light before it is initialized, and the
updater defers while statusCheck/testScript own the LED. An unavailable
source (NaN, e.g. CO2 with no module) clears the LED instead of showing a
stale color. Bumps version to 26.6.25.1.

Verified on hardware and with a full esphome 2026.6.2 compile.

🤖 Generated with [Claude Code](https://claude.com/claude-code)
@bharvey88 bharvey88 force-pushed the add-air-quality-led-indicator branch from 7b8c7a8 to cc1b87c Compare June 25, 2026 23:26
@bharvey88 bharvey88 changed the title Add air quality LED indicator (NowCast AQI / CO2 / VOC) Add air quality LED indicator Jun 25, 2026

@firstof9 firstof9 left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

@bharvey88 bharvey88 merged commit 6a6c388 into ApolloAutomation:beta Jun 25, 2026
10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants