-
-
Notifications
You must be signed in to change notification settings - Fork 34.5k
Remove old Airthings devices #145914
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: dev
Are you sure you want to change the base?
Remove old Airthings devices #145914
Changes from all commits
c3c7b16
8f43881
19b8bd5
b6e16df
b162150
b69827f
705c7ef
a672ec5
d7f4b8e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,36 @@ | ||
"""Tests for the Airthings integration.""" | ||
|
||
from airthings import Airthings, AirthingsDevice | ||
|
||
from homeassistant.core import HomeAssistant | ||
|
||
from .const import TEST_DATA | ||
|
||
from tests.common import MockConfigEntry | ||
|
||
|
||
async def setup_integration(hass: HomeAssistant) -> MockConfigEntry: | ||
"""Set up the Airthings integration in Home Assistant.""" | ||
entry = MockConfigEntry( | ||
domain="airthings", | ||
data=TEST_DATA, | ||
) | ||
entry.add_to_hass(hass) | ||
|
||
await hass.config_entries.async_setup(entry.entry_id) | ||
await hass.async_block_till_done() | ||
|
||
return entry | ||
|
||
|
||
class MockAirthings(Airthings): | ||
"""Mock Airthings class to simulate device data.""" | ||
|
||
def __init__(self, devices) -> None: | ||
"""Initialize with a dictionary of devices.""" | ||
super().__init__(client_id="", secret="", websession=None) | ||
self.devices = devices | ||
|
||
async def update_devices(self) -> dict[str, AirthingsDevice]: | ||
"""Mock method to return devices.""" | ||
return self.devices | ||
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
"""Constants for Airthings integration tests.""" | ||
|
||
from homeassistant.components.airthings import AirthingsDevice | ||
from homeassistant.components.airthings.const import CONF_SECRET | ||
from homeassistant.const import CONF_ID | ||
|
||
TEST_DATA = { | ||
CONF_ID: "client_id", | ||
CONF_SECRET: "secret", | ||
} | ||
|
||
WAVE_RADON: dict[str, AirthingsDevice] = { | ||
"2950000001": AirthingsDevice( | ||
device_id="2950000001", | ||
name="Basement", | ||
sensors={ | ||
"battery": 100, | ||
"humidity": 75.0, | ||
"radonShortTermAvg": 537.0, | ||
"rssi": -76, | ||
"temp": 16.6, | ||
}, | ||
is_active=None, | ||
location_name="Home", | ||
device_type="WAVE_GEN2", | ||
product_name="Wave", | ||
) | ||
} | ||
|
||
WAVE_ENHANCE: dict[str, AirthingsDevice] = { | ||
"3210000001": AirthingsDevice( | ||
device_id="3210000001", | ||
name="Bedroom", | ||
sensors={ | ||
"battery": 35, | ||
"co2": 551.0, | ||
"humidity": 43.0, | ||
"lux": 1.0, | ||
"pressure": 985.0, | ||
"rssi": -67, | ||
"sla": 34.0, | ||
"temp": 21.9, | ||
"voc": 158.0, | ||
}, | ||
is_active=None, | ||
location_name="Home", | ||
device_type="WAVE_ENHANCE", | ||
product_name="Wave Enhance", | ||
), | ||
} | ||
Comment on lines
+30
to
+50
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not sure if you have that, but if there's an easy way you go from JSON to an AirthingsDevice you could put all this data in a JSON fixture and load it |
||
|
||
VIEW_PLUS: dict[str, AirthingsDevice] = { | ||
"2960000001": AirthingsDevice( | ||
device_id="2960000001", | ||
name="Office", | ||
sensors={ | ||
"battery": 77, | ||
"co2": 876.0, | ||
"humidity": 42.0, | ||
"pm1": 3.0, | ||
"pm25": 3.0, | ||
"pressure": 985.0, | ||
"radonShortTermAvg": 15.0, | ||
"rssi": 0, | ||
"temp": 24.5, | ||
"voc": 1842.0, | ||
}, | ||
is_active=None, | ||
location_name="Office", | ||
device_type="VIEW_PLUS", | ||
product_name="View Plus", | ||
), | ||
} | ||
|
||
THREE_DEVICES: dict[str, AirthingsDevice] = { | ||
**WAVE_RADON, | ||
**WAVE_ENHANCE, | ||
**VIEW_PLUS, | ||
} | ||
|
||
TWO_DEVICES: dict[str, AirthingsDevice] = { | ||
**WAVE_RADON, | ||
**VIEW_PLUS, | ||
} |
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. move this to test_init.py |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,127 @@ | ||
"""Test Airthings devices, and ensure old devices are removed.""" | ||
|
||
from unittest.mock import patch | ||
|
||
from airthings import AirthingsError | ||
|
||
from homeassistant.core import HomeAssistant | ||
from homeassistant.helpers import device_registry as dr | ||
|
||
from . import MockAirthings, setup_integration | ||
from .const import TEST_DATA, THREE_DEVICES, TWO_DEVICES | ||
|
||
|
||
async def test_setup_integration( | ||
hass: HomeAssistant, | ||
device_registry: dr.DeviceRegistry, | ||
) -> None: | ||
"""Test that the Airthings integration is set up correctly.""" | ||
|
||
with patch( | ||
"homeassistant.components.airthings.Airthings", | ||
return_value=MockAirthings(TWO_DEVICES), | ||
): | ||
entry = await setup_integration(hass) | ||
|
||
assert entry is not None | ||
assert entry.domain == "airthings" | ||
|
||
assert len(device_registry.devices) == len(TWO_DEVICES) | ||
|
||
|
||
async def test_add_new_device( | ||
hass: HomeAssistant, | ||
device_registry: dr.DeviceRegistry, | ||
) -> None: | ||
"""Test that a new Airthings device is added correctly.""" | ||
|
||
with patch( | ||
"homeassistant.components.airthings.Airthings", | ||
return_value=MockAirthings(TWO_DEVICES), | ||
): | ||
entry = await setup_integration(hass) | ||
|
||
assert entry is not None | ||
assert entry.domain == "airthings" | ||
assert entry.data == TEST_DATA | ||
assert len(device_registry.devices) == len(TWO_DEVICES) | ||
|
||
# Add device | ||
with patch( | ||
"homeassistant.components.airthings.Airthings", | ||
return_value=MockAirthings(THREE_DEVICES), | ||
): | ||
await hass.config_entries.async_reload(entry.entry_id) | ||
await hass.async_block_till_done() | ||
|
||
assert len(device_registry.devices) == len(THREE_DEVICES) | ||
|
||
|
||
async def test_setup_integration_no_devices( | ||
hass: HomeAssistant, | ||
device_registry: dr.DeviceRegistry, | ||
) -> None: | ||
"""Test that the Airthings integration handles no devices correctly.""" | ||
|
||
with patch( | ||
"homeassistant.components.airthings.Airthings", | ||
return_value=MockAirthings({}), | ||
): | ||
entry = await setup_integration(hass) | ||
|
||
assert entry is not None | ||
assert entry.domain == "airthings" | ||
assert entry.data == TEST_DATA | ||
assert len(device_registry.devices) == 0 | ||
|
||
|
||
async def test_remove_old_devices( | ||
hass: HomeAssistant, | ||
device_registry: dr.DeviceRegistry, | ||
) -> None: | ||
"""Test that old devices are removed when new data is fetched.""" | ||
|
||
with patch( | ||
"homeassistant.components.airthings.Airthings", | ||
return_value=MockAirthings(THREE_DEVICES), | ||
): | ||
entry = await setup_integration(hass) | ||
|
||
assert entry is not None | ||
assert entry.domain == "airthings" | ||
assert entry.data == TEST_DATA | ||
assert len(device_registry.devices) == len(THREE_DEVICES) | ||
|
||
with patch( | ||
"homeassistant.components.airthings.Airthings", | ||
return_value=MockAirthings(TWO_DEVICES), | ||
): | ||
await hass.config_entries.async_reload(entry.entry_id) | ||
await hass.async_block_till_done() | ||
|
||
assert len(device_registry.devices) == len(TWO_DEVICES) | ||
|
||
|
||
async def test_failing_api_call( | ||
hass: HomeAssistant, | ||
device_registry: dr.DeviceRegistry, | ||
) -> None: | ||
"""Test that the integration handles API call failures gracefully.""" | ||
|
||
with patch( | ||
"homeassistant.components.airthings.Airthings", | ||
return_value=MockAirthings(THREE_DEVICES), | ||
): | ||
entry = await setup_integration(hass) | ||
|
||
assert len(device_registry.devices) == len(THREE_DEVICES) | ||
|
||
# Simulate an API failure | ||
with patch( | ||
"homeassistant.components.airthings.Airthings.update_devices", | ||
side_effect=AirthingsError("API call failed"), | ||
): | ||
await hass.config_entries.async_reload(entry.entry_id) | ||
await hass.async_block_till_done() | ||
|
||
assert len(device_registry.devices) == len(THREE_DEVICES) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would recommend to not create an extension like this at all, rather just use a
This way is way more versaitle and easier to update