Skip to content

Add Rabbit Air air quality sensor#172993

Open
MagikalUnicorn wants to merge 3 commits into
home-assistant:devfrom
MagikalUnicorn:rabbitair-air-quality-sensor
Open

Add Rabbit Air air quality sensor#172993
MagikalUnicorn wants to merge 3 commits into
home-assistant:devfrom
MagikalUnicorn:rabbitair-air-quality-sensor

Conversation

@MagikalUnicorn
Copy link
Copy Markdown
Contributor

@MagikalUnicorn MagikalUnicorn commented Jun 4, 2026

Proposed change

Add an air quality sensor to the Rabbit Air integration.

image

The sensor uses the existing Rabbit Air coordinator data and exposes the quality value from python-rabbitair as a Home Assistant enum sensor with the following states:

  • lowest
  • low
  • medium
  • high
  • highest

This also adds translations and an icon for the new sensor.

This is the first of many sensors to be added, I'd like to make sure I have the basic approach right before adding more in bulk.

The change was co-authored by OpenAI Codex 5.5.

Type of change

  • Dependency upgrade
  • Bugfix (non-breaking change which fixes an issue)
  • New integration (thank you!)
  • New feature (which adds functionality to an existing integration)
  • Deprecation (breaking change to happen in the future)
  • Breaking change (fix/feature causing existing functionality to break)
  • Code quality improvements to existing code or addition of tests

Additional information

  • This PR fixes or closes issue: fixes #
  • This PR is related to issue:
  • Link to documentation pull request: home-assistant/home-assistant.io#45749
  • Link to developer documentation pull request:
  • Link to frontend pull request:

Checklist

  • I understand the code I am submitting and can explain how it works.
  • The code change is tested and works locally.
  • Local tests pass. Your PR cannot be merged unless tests pass
  • There is no commented out code in this PR.
  • I have followed the [development checklist][dev-checklist]
  • I have followed the [perfect PR recommendations][perfect-pr]
  • The code has been formatted using Ruff (ruff format homeassistant tests)
  • Tests have been added to verify that the new code works.
  • Any generated code has been carefully reviewed for correctness and compliance with project standards.

Validation

  • uv run ruff check homeassistant/components/rabbitair tests/components/rabbitair
  • uv run ruff format --check homeassistant/components/rabbitair tests/components/rabbitair
  • uv run pytest tests/components/rabbitair
  • uv run --with tqdm python -m script.hassfest --integration-path homeassistant/components/rabbitair

@home-assistant
Copy link
Copy Markdown
Contributor

home-assistant Bot commented Jun 4, 2026

Hey there @rabbit-air, mind taking a look at this pull request as it has been labeled with an integration (rabbitair) you are listed as a code owner for? Thanks!

Code owner commands

Code owners of rabbitair can trigger bot actions by commenting:

  • @home-assistant close Closes the pull request.
  • @home-assistant mark-draft Mark the pull request as draft.
  • @home-assistant ready-for-review Remove the draft status from the pull request.
  • @home-assistant rename Awesome new title Renames the pull request.
  • @home-assistant reopen Reopen the pull request.
  • @home-assistant unassign rabbitair Removes the current integration label and assignees on the pull request, add the integration domain after the command.
  • @home-assistant update-branch Update the pull request branch with the base branch.
  • @home-assistant add-label needs-more-information Add a label (needs-more-information, problem in dependency, problem in custom component, problem in config, problem in device, feature-request) to the pull request.
  • @home-assistant remove-label needs-more-information Remove a label (needs-more-information, problem in dependency, problem in custom component, problem in config, problem in device, feature-request) on the pull request.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Note

Copilot was unable to run its full agentic suite in this review.

This PR adds an air quality sensor entity to the Rabbit Air integration, exposing the device's air quality reading (lowest, low, medium, high, highest) as a Home Assistant sensor.

Changes:

  • Adds a new sensor.py platform file with an enum-based air quality sensor entity.
  • Registers the sensor platform and adds corresponding strings, icons, and test coverage.
  • Updates the shared get_mock_state helper to include the quality attribute.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
homeassistant/components/rabbitair/init.py Registers the new SENSOR platform
homeassistant/components/rabbitair/sensor.py New sensor entity for air quality
homeassistant/components/rabbitair/strings.json Adds translation strings for the sensor states
homeassistant/components/rabbitair/icons.json Adds icon for the sensor entity
tests/components/rabbitair/test_config_flow.py Extends get_mock_state with quality param
tests/components/rabbitair/test_sensor.py New test file for the air quality sensor

Comment thread homeassistant/components/rabbitair/sensor.py Outdated
Comment thread tests/components/rabbitair/test_sensor.py Outdated
) -> None:
"""Initialize the entity."""
super().__init__(coordinator, entry)
self._attr_name = entry.title
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Hmm, shouldn't we set _attr_has_entity_name = True at the base entity and then set _attr_name = None here?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Updated. _attr_has_entity_name = True is now set on RabbitAirBaseEntity, and the fan entity sets _attr_name = None to preserve the primary device entity naming pattern.

Comment on lines +57 to +63
self._attr_native_value = _quality_value(coordinator.data.quality)

@callback
def _handle_coordinator_update(self) -> None:
"""Handle updated data from the coordinator."""
self._attr_native_value = _quality_value(self.coordinator.data.quality)
super()._handle_coordinator_update()
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Instead I'd implement the native_value property

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Updated. The air quality sensor now implements native_value as a property based on the coordinator data instead of storing _attr_native_value and updating it manually.

Comment on lines +30 to +39
entry = MockConfigEntry(
domain=DOMAIN,
data={
CONF_HOST: TEST_HOST,
CONF_ACCESS_TOKEN: TEST_TOKEN,
CONF_MAC: TEST_MAC,
},
title=TEST_TITLE,
unique_id=TEST_UNIQUE_ID,
)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

can we make this a test fixture?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Updated. The repeated MockConfigEntry setup is now in a mock_config_entry fixture.

Comment on lines +42 to +45
with patch(
"rabbitair.UdpClient.get_state",
return_value=get_mock_state(quality=Quality.High),
):
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Can we patch it where we use it?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Updated. The tests now patch homeassistant.components.rabbitair.coordinator.Client.get_state, where the integration uses the client.

@home-assistant home-assistant Bot marked this pull request as draft June 4, 2026 08:53
@home-assistant
Copy link
Copy Markdown
Contributor

home-assistant Bot commented Jun 4, 2026

Please take a look at the requested changes, and use the Ready for review button when you are done, thanks 👍

Learn more about our pull request process.

Copilot AI review requested due to automatic review settings June 4, 2026 09:03
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 8 out of 8 changed files in this pull request and generated 1 comment.

Comment on lines +39 to +40
if entry.runtime_data.data.quality is not None:
async_add_entities([RabbitAirAirQualitySensor(entry.runtime_data, entry)])
Copy link
Copy Markdown
Contributor Author

@MagikalUnicorn MagikalUnicorn Jun 4, 2026

Choose a reason for hiding this comment

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

@joostlek - I’m not sure we can definitively know which current and future Rabbit Air models support quality, though my assumption is that they all will do. Given that, would you prefer that we always create the air quality sensor and let it report unknown when the device returns quality=None, or keep the current setup-time check and only create the entity when the first fetched state includes a quality value?

@MagikalUnicorn
Copy link
Copy Markdown
Contributor Author

Thanks for your reviews, @joostlek. For the future sensors, do you want them as individual PRs, or grouped into say 2-3 per PR, or just done in bulk?

@joostlek
Copy link
Copy Markdown
Member

joostlek commented Jun 4, 2026

What future sensors? I'd recommend to keep it to a well scoped PR

@MagikalUnicorn
Copy link
Copy Markdown
Contributor Author

MagikalUnicorn commented Jun 4, 2026

The base library exposes a lot more sensors I intend to surface through HA, so wanted to ask how you'd prefer those be added - individually per PR, or grouped - for example, filter sensors, particulate sensors, etc...

@MagikalUnicorn MagikalUnicorn marked this pull request as ready for review June 4, 2026 12:38
@home-assistant home-assistant Bot requested a review from joostlek June 4, 2026 12:38
@joostlek
Copy link
Copy Markdown
Member

joostlek commented Jun 4, 2026

You can probably split on how you feel like makes sense, if a specific entity contains more logic it might make sense to split for example

@joostlek
Copy link
Copy Markdown
Member

joostlek commented Jun 4, 2026

Please open a docs PR

MagikalUnicorn added a commit to MagikalUnicorn/home-assistant.io that referenced this pull request Jun 4, 2026
## Proposed change

Document the Rabbit Air air quality sensor added in home-assistant/core#172993.

## Type of change

- [ ] Spelling, grammar or other readability improvements (`current` branch).
- [x] Adjusted missing or incorrect information in the current documentation (`current` branch).
- [ ] Added documentation for a new integration I'm adding to Home Assistant (`next` branch).
- [ ] Added documentation for a new feature I'm adding to Home Assistant (`next` branch).
@MagikalUnicorn
Copy link
Copy Markdown
Contributor Author

Link to documentation pull request: home-assistant/home-assistant.io#45749

MagikalUnicorn added a commit to MagikalUnicorn/home-assistant.io that referenced this pull request Jun 5, 2026
Document the Rabbit Air air quality sensor added in home-assistant/core#172993.

- [ ] Spelling, grammar or other readability improvements (`current` branch).
- [x] Adjusted missing or incorrect information in the current documentation (`current` branch).
- [ ] Added documentation for a new integration I'm adding to Home Assistant (`next` branch).
- [ ] Added documentation for a new feature I'm adding to Home Assistant (`next` branch).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants