From 8e61ed39fde4a9edc27813baac8a18d1e5e23e76 Mon Sep 17 00:00:00 2001 From: Tobias Sauerwein Date: Fri, 30 Jul 2021 20:07:23 +0200 Subject: [PATCH] Fix flaky netatmo tests (#53644) --- homeassistant/components/netatmo/climate.py | 30 +++++++-------------- homeassistant/components/netatmo/helper.py | 26 ++++++++++++++++++ homeassistant/components/netatmo/select.py | 16 ++++++----- tests/components/netatmo/test_select.py | 9 ++++--- 4 files changed, 50 insertions(+), 31 deletions(-) diff --git a/homeassistant/components/netatmo/climate.py b/homeassistant/components/netatmo/climate.py index 1eaf47f7162..6622c891df1 100644 --- a/homeassistant/components/netatmo/climate.py +++ b/homeassistant/components/netatmo/climate.py @@ -58,6 +58,7 @@ from .data_handler import ( HOMESTATUS_DATA_CLASS_NAME, NetatmoDataHandler, ) +from .helper import get_all_home_ids, update_climate_schedules from .netatmo_entity_base import NetatmoBase _LOGGER = logging.getLogger(__name__) @@ -131,9 +132,6 @@ async def async_setup_entry( if not home_data or home_data.raw_data == {}: raise PlatformNotReady - if HOMEDATA_DATA_CLASS_NAME not in data_handler.data: - raise PlatformNotReady - entities = [] for home_id in get_all_home_ids(home_data): for room_id in home_data.rooms[home_id]: @@ -145,12 +143,12 @@ async def async_setup_entry( if home_status and room_id in home_status.rooms: entities.append(NetatmoThermostat(data_handler, home_id, room_id)) - hass.data[DOMAIN][DATA_SCHEDULES][home_id] = { - schedule_id: schedule_data.get("name") - for schedule_id, schedule_data in ( - data_handler.data[HOMEDATA_DATA_CLASS_NAME].schedules[home_id].items() - ) - } + hass.data[DOMAIN][DATA_SCHEDULES].update( + update_climate_schedules( + home_ids=get_all_home_ids(home_data), + schedules=data_handler.data[HOMEDATA_DATA_CLASS_NAME].schedules, + ) + ) hass.data[DOMAIN][DATA_HOMES] = { home_id: home_data.get("name") @@ -257,7 +255,8 @@ class NetatmoThermostat(NetatmoBase, ClimateEntity): assert device self.hass.data[DOMAIN][DATA_DEVICE_IDS][self._home_id] = device.id - async def handle_event(self, event: dict) -> None: + @callback + def handle_event(self, event: dict) -> None: """Handle webhook events.""" data = event["data"] @@ -617,14 +616,3 @@ class NetatmoThermostat(NetatmoBase, ClimateEntity): device_info: DeviceInfo = super().device_info device_info["suggested_area"] = self._room_data["name"] return device_info - - -def get_all_home_ids(home_data: pyatmo.HomeData | None) -> list[str]: - """Get all the home ids returned by NetAtmo API.""" - if home_data is None: - return [] - return [ - home_data.homes[home_id]["id"] - for home_id in home_data.homes - if "modules" in home_data.homes[home_id] - ] diff --git a/homeassistant/components/netatmo/helper.py b/homeassistant/components/netatmo/helper.py index 7e8f32817dd..d824013ed27 100644 --- a/homeassistant/components/netatmo/helper.py +++ b/homeassistant/components/netatmo/helper.py @@ -1,7 +1,11 @@ """Helper for Netatmo integration.""" +from __future__ import annotations + from dataclasses import dataclass from uuid import UUID, uuid4 +import pyatmo + @dataclass class NetatmoArea: @@ -15,3 +19,25 @@ class NetatmoArea: mode: str show_on_map: bool uuid: UUID = uuid4() + + +def get_all_home_ids(home_data: pyatmo.HomeData | None) -> list[str]: + """Get all the home ids returned by NetAtmo API.""" + if home_data is None: + return [] + return [ + home_data.homes[home_id]["id"] + for home_id in home_data.homes + if "modules" in home_data.homes[home_id] + ] + + +def update_climate_schedules(home_ids: list[str], schedules: dict) -> dict: + """Get updated list of all climate schedules.""" + return { + home_id: { + schedule_id: schedule_data.get("name") + for schedule_id, schedule_data in schedules[home_id].items() + } + for home_id in home_ids + } diff --git a/homeassistant/components/netatmo/select.py b/homeassistant/components/netatmo/select.py index 718d7e440b9..387fb8f0acc 100644 --- a/homeassistant/components/netatmo/select.py +++ b/homeassistant/components/netatmo/select.py @@ -13,7 +13,6 @@ from homeassistant.exceptions import PlatformNotReady from homeassistant.helpers.dispatcher import async_dispatcher_connect from homeassistant.helpers.entity_platform import AddEntitiesCallback -from .climate import get_all_home_ids from .const import ( DATA_HANDLER, DATA_SCHEDULES, @@ -23,6 +22,7 @@ from .const import ( SIGNAL_NAME, ) from .data_handler import HOMEDATA_DATA_CLASS_NAME, NetatmoDataHandler +from .helper import get_all_home_ids, update_climate_schedules from .netatmo_entity_base import NetatmoBase _LOGGER = logging.getLogger(__name__) @@ -42,8 +42,12 @@ async def async_setup_entry( if not home_data or home_data.raw_data == {}: raise PlatformNotReady - if HOMEDATA_DATA_CLASS_NAME not in data_handler.data: - raise PlatformNotReady + hass.data[DOMAIN][DATA_SCHEDULES].update( + update_climate_schedules( + home_ids=get_all_home_ids(home_data), + schedules=data_handler.data[HOMEDATA_DATA_CLASS_NAME].schedules, + ) + ) entities = [ NetatmoScheduleSelect( @@ -51,8 +55,7 @@ async def async_setup_entry( home_id, list(hass.data[DOMAIN][DATA_SCHEDULES][home_id].values()), ) - for home_id in get_all_home_ids(home_data) - if home_id in hass.data[DOMAIN][DATA_SCHEDULES] + for home_id in hass.data[DOMAIN][DATA_SCHEDULES] ] _LOGGER.debug("Adding climate schedule select entities %s", entities) @@ -105,7 +108,8 @@ class NetatmoScheduleSelect(NetatmoBase, SelectEntity): ) ) - async def handle_event(self, event: dict) -> None: + @callback + def handle_event(self, event: dict) -> None: """Handle webhook events.""" data = event["data"] diff --git a/tests/components/netatmo/test_select.py b/tests/components/netatmo/test_select.py index 8be010cc802..f0e7cde7359 100644 --- a/tests/components/netatmo/test_select.py +++ b/tests/components/netatmo/test_select.py @@ -19,10 +19,6 @@ async def test_select_schedule_thermostats(hass, config_entry, caplog, netatmo_a select_entity = "select.netatmo_myhome" assert hass.states.get(select_entity).state == "Default" - assert hass.states.get(select_entity).attributes[ATTR_OPTIONS] == [ - "Default", - "Winter", - ] # Fake backend response changing schedule response = { @@ -32,8 +28,13 @@ async def test_select_schedule_thermostats(hass, config_entry, caplog, netatmo_a "push_type": "home_event_changed", } await simulate_webhook(hass, webhook_id, response) + await hass.async_block_till_done() assert hass.states.get(select_entity).state == "Winter" + assert hass.states.get(select_entity).attributes[ATTR_OPTIONS] == [ + "Default", + "Winter", + ] # Test setting a different schedule with patch(