Skip to content

Add sensor platform for AirPatrol#158726

Merged
joostlek merged 7 commits intohome-assistant:devfrom
antondalgren:airpatrol-sensor
Dec 18, 2025
Merged

Add sensor platform for AirPatrol#158726
joostlek merged 7 commits intohome-assistant:devfrom
antondalgren:airpatrol-sensor

Conversation

@antondalgren
Copy link
Copy Markdown
Contributor

@antondalgren antondalgren commented Dec 11, 2025

Breaking change

Proposed change

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

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
  • I have followed the perfect PR recommendations
  • 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.

If user exposed functionality or configuration variables are added/changed:

If the code communicates with devices, web services, or third-party tools:

  • The manifest file has all fields filled out correctly.
    Updated and included derived files by running: python3 -m script.hassfest.
  • New or updated dependencies have been added to requirements_all.txt.
    Updated by running python3 -m script.gen_requirements_all.
  • For the updated dependencies - a link to the changelog, or at minimum a diff between library versions is added to the PR description.

To help with the load of incoming pull requests:

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

This PR adds a sensor platform to the AirPatrol integration, introducing temperature and humidity sensor entities that expose room temperature and humidity data from AirPatrol climate devices.

Key changes:

  • Adds sensor platform with temperature and humidity sensors
  • Implements test fixtures to support platform-specific testing
  • Updates test snapshots to reflect new test parametrization

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
homeassistant/components/airpatrol/sensor.py Implements new sensor platform with temperature and humidity entities using the coordinator pattern
homeassistant/components/airpatrol/const.py Adds Platform.SENSOR to the list of supported platforms
tests/components/airpatrol/conftest.py Adds load_platforms fixture to enable platform-specific test isolation
tests/components/airpatrol/test_sensor.py Adds comprehensive sensor entity tests using snapshot testing with multiple data scenarios
tests/components/airpatrol/test_climate.py Updates climate tests to use the new load_platforms parametrization for better test isolation
tests/components/airpatrol/snapshots/test_sensor.ambr Snapshot data for sensor entity tests covering both data present and unavailable states
tests/components/airpatrol/snapshots/test_climate.ambr Updated snapshot names to reflect new test parametrization

Comment thread homeassistant/components/airpatrol/sensor.py Outdated
Comment thread homeassistant/components/airpatrol/sensor.py Outdated
Comment thread tests/components/airpatrol/test_sensor.py Outdated
Comment thread homeassistant/components/airpatrol/sensor.py
Comment thread homeassistant/components/airpatrol/sensor.py Outdated
Comment on lines +85 to +93
@property
def climate_data(self) -> dict[str, Any]:
"""Return the climate data for this unit."""
return self.device_data.get("climate") or {}

@property
def available(self) -> bool:
"""Return if the sensor is available."""
return super().available and bool(self.climate_data)
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.

This already is in the base entity

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.

Not really, it's in the climate entity. Should we move it to the base entity instead?

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.

Oh, it's in both. We can remove it from the climate entity then, but lets do that in a later PR. We can use the entity.py one here now

Comment thread homeassistant/components/airpatrol/sensor.py Outdated
@home-assistant home-assistant Bot marked this pull request as draft December 11, 2025 15:50
@home-assistant
Copy link
Copy Markdown
Contributor

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.

@antondalgren antondalgren marked this pull request as ready for review December 11, 2025 18:58
@home-assistant home-assistant Bot requested a review from joostlek December 11, 2025 18:58
Comment thread tests/components/airpatrol/conftest.py Outdated
@joostlek joostlek changed the title Added sensor platform for AirPatrol Add sensor platform for AirPatrol Dec 12, 2025
Comment on lines +85 to +93
@property
def climate_data(self) -> dict[str, Any]:
"""Return the climate data for this unit."""
return self.device_data.get("climate") or {}

@property
def available(self) -> bool:
"""Return if the sensor is available."""
return super().available and bool(self.climate_data)
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.

Oh, it's in both. We can remove it from the climate entity then, but lets do that in a later PR. We can use the entity.py one here now

Comment on lines +13 to +29
@pytest.mark.parametrize(
"climate_data",
[
{
"ParametersData": {
"PumpPower": "on",
"PumpTemp": "22.000",
"PumpMode": "cool",
"FanSpeed": "max",
"Swing": "off",
},
"RoomTemp": "22.5",
"RoomHumidity": "45",
},
None,
],
)
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.

Okay, snapshot tests are great because they are easy to make and they test a lot. However, they are bad at testing change. So in this case I would just opt to create a second test where you test what you'd expect when the climate data is None. That test is definitely smaller and makes the intention of the test a lot clearer

@home-assistant home-assistant Bot marked this pull request as draft December 12, 2025 12:56
@antondalgren antondalgren marked this pull request as ready for review December 12, 2025 14:16
@home-assistant home-assistant Bot requested a review from joostlek December 12, 2025 14:16
Comment on lines +41 to +44
@property
def climate_data(self) -> dict[str, Any]:
"""Return the climate data for this unit."""
return self.device_data.get("climate") or {}
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.

Suggested change
@property
def climate_data(self) -> dict[str, Any]:
"""Return the climate data for this unit."""
return self.device_data.get("climate") or {}
@property
def climate_data(self) -> dict[str, Any]:
"""Return the climate data for this unit."""
return self.device_data["climate"]

def available(self) -> bool:
"""Return if entity is available."""
return super().available and self._unit_id in self.coordinator.data
return super().available and bool(self.climate_data)
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.

I'd change this to 2 in statements

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.

Like this?

    super().available
    and self._unit_id in self.coordinator.data
    and "climate" in self.device_data
    and bool(self.climate_data)

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.

without the bool one

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.

I need to have the bool one since I'm checking if the climate field is "None", not only if the key exists.

@joostlek
Copy link
Copy Markdown
Member

The parent PR is now merged, can you please make your docs PR point to the right repository?

Comment thread homeassistant/components/airpatrol/entity.py Outdated
@antondalgren
Copy link
Copy Markdown
Contributor Author

The parent PR is now merged, can you please make your docs PR point to the right repository?

Thanks! All done and ready for this to be merged.

@joostlek joostlek merged commit 33dcde7 into home-assistant:dev Dec 18, 2025
36 checks passed
@github-actions github-actions Bot locked and limited conversation to collaborators Dec 19, 2025
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants