From ada6b7875c2a7f4a54ba9dd93c70a93047d71874 Mon Sep 17 00:00:00 2001 From: David Bonnes Date: Wed, 28 Aug 2024 21:40:57 +0100 Subject: [PATCH] Add evohome test for setup (#123129) * allow for different systems * installation is a load_json_*fixture param * allow installation to be parameterized * test setup of various systems * add more fixtures * test setup of integration * tweak test * tweak const * add expected state/services * extend setup test * tidy up * tidy up tweaks * code tweaks * refactor expected results dicts * woops * refatcor serialize * refactor test * tweak * tweak code * rename symbol * ensure actual I/O remains blocked * tweak * typo * use constants * Update conftest.py Co-authored-by: Martin Hjelmare * change filename * add config fixture * config is a fixture * config is a fixture now 2 * lint * lint * refactor * lint * lint * restore email addr * use const * use snapshots instead of helper class * doctweak * correct snapshot --------- Co-authored-by: Martin Hjelmare --- tests/components/evohome/conftest.py | 126 ++- tests/components/evohome/const.py | 9 + .../fixtures/{ => default}/schedule_dhw.json | 0 .../fixtures/{ => default}/schedule_zone.json | 0 .../{ => default}/status_2738909.json | 0 .../fixtures/{ => default}/user_account.json | 0 .../{ => default}/user_locations.json | 4 +- .../fixtures/h032585/status_111111.json | 31 + .../fixtures/h032585/temperatures.json | 3 + .../fixtures/h032585/user_locations.json | 79 ++ .../fixtures/h099625/status_111111.json | 44 + .../fixtures/h099625/user_locations.json | 113 +++ .../fixtures/minimal/status_2738909.json | 28 + .../fixtures/minimal/user_locations.json | 120 +++ .../fixtures/system_004/status_3164610.json | 33 + .../fixtures/system_004/user_locations.json | 99 ++ .../evohome/snapshots/test_init.ambr | 863 ++++++++++++++++++ tests/components/evohome/test_init.py | 25 + tests/components/evohome/test_storage.py | 30 +- 19 files changed, 1549 insertions(+), 58 deletions(-) rename tests/components/evohome/fixtures/{ => default}/schedule_dhw.json (100%) rename tests/components/evohome/fixtures/{ => default}/schedule_zone.json (100%) rename tests/components/evohome/fixtures/{ => default}/status_2738909.json (100%) rename tests/components/evohome/fixtures/{ => default}/user_account.json (100%) rename tests/components/evohome/fixtures/{ => default}/user_locations.json (99%) create mode 100644 tests/components/evohome/fixtures/h032585/status_111111.json create mode 100644 tests/components/evohome/fixtures/h032585/temperatures.json create mode 100644 tests/components/evohome/fixtures/h032585/user_locations.json create mode 100644 tests/components/evohome/fixtures/h099625/status_111111.json create mode 100644 tests/components/evohome/fixtures/h099625/user_locations.json create mode 100644 tests/components/evohome/fixtures/minimal/status_2738909.json create mode 100644 tests/components/evohome/fixtures/minimal/user_locations.json create mode 100644 tests/components/evohome/fixtures/system_004/status_3164610.json create mode 100644 tests/components/evohome/fixtures/system_004/user_locations.json create mode 100644 tests/components/evohome/snapshots/test_init.ambr create mode 100644 tests/components/evohome/test_init.py diff --git a/tests/components/evohome/conftest.py b/tests/components/evohome/conftest.py index 260330896b7..82c5cd76024 100644 --- a/tests/components/evohome/conftest.py +++ b/tests/components/evohome/conftest.py @@ -2,8 +2,10 @@ from __future__ import annotations +from collections.abc import Callable from datetime import datetime, timedelta -from typing import Any, Final +from http import HTTPMethod +from typing import Any from unittest.mock import MagicMock, patch from aiohttp import ClientSession @@ -16,75 +18,112 @@ from homeassistant.core import HomeAssistant from homeassistant.setup import async_setup_component from homeassistant.util.json import JsonArrayType, JsonObjectType -from .const import ACCESS_TOKEN, REFRESH_TOKEN +from .const import ACCESS_TOKEN, REFRESH_TOKEN, USERNAME from tests.common import load_json_array_fixture, load_json_object_fixture -TEST_CONFIG: Final = { - CONF_USERNAME: "username", - CONF_PASSWORD: "password", -} - -def user_account_config_fixture() -> JsonObjectType: +def user_account_config_fixture(install: str) -> JsonObjectType: """Load JSON for the config of a user's account.""" - return load_json_object_fixture("user_account.json", DOMAIN) + try: + return load_json_object_fixture(f"{install}/user_account.json", DOMAIN) + except FileNotFoundError: + return load_json_object_fixture("default/user_account.json", DOMAIN) -def user_locations_config_fixture() -> JsonArrayType: +def user_locations_config_fixture(install: str) -> JsonArrayType: """Load JSON for the config of a user's installation (a list of locations).""" - return load_json_array_fixture("user_locations.json", DOMAIN) + return load_json_array_fixture(f"{install}/user_locations.json", DOMAIN) -def location_status_fixture(loc_id: str) -> JsonObjectType: +def location_status_fixture(install: str, loc_id: str | None = None) -> JsonObjectType: """Load JSON for the status of a specific location.""" - return load_json_object_fixture(f"status_{loc_id}.json", DOMAIN) + if loc_id is None: + _install = load_json_array_fixture(f"{install}/user_locations.json", DOMAIN) + loc_id = _install[0]["locationInfo"]["locationId"] # type: ignore[assignment, call-overload, index] + return load_json_object_fixture(f"{install}/status_{loc_id}.json", DOMAIN) -def dhw_schedule_fixture() -> JsonObjectType: +def dhw_schedule_fixture(install: str) -> JsonObjectType: """Load JSON for the schedule of a domesticHotWater zone.""" - return load_json_object_fixture("schedule_dhw.json", DOMAIN) + try: + return load_json_object_fixture(f"{install}/schedule_dhw.json", DOMAIN) + except FileNotFoundError: + return load_json_object_fixture("default/schedule_dhw.json", DOMAIN) -def zone_schedule_fixture() -> JsonObjectType: +def zone_schedule_fixture(install: str) -> JsonObjectType: """Load JSON for the schedule of a temperatureZone zone.""" - return load_json_object_fixture("schedule_zone.json", DOMAIN) + try: + return load_json_object_fixture(f"{install}/schedule_zone.json", DOMAIN) + except FileNotFoundError: + return load_json_object_fixture("default/schedule_zone.json", DOMAIN) -async def mock_get( - self: Broker, url: str, **kwargs: Any -) -> JsonArrayType | JsonObjectType: - """Return the JSON for a HTTP get of a given URL.""" +def mock_get_factory(install: str) -> Callable: + """Return a get method for a specified installation.""" - # a proxy for the behaviour of the real web API - if self.refresh_token is None: - self.refresh_token = f"new_{REFRESH_TOKEN}" + async def mock_get( + self: Broker, url: str, **kwargs: Any + ) -> JsonArrayType | JsonObjectType: + """Return the JSON for a HTTP get of a given URL.""" - if self.access_token_expires is None or self.access_token_expires < datetime.now(): - self.access_token = f"new_{ACCESS_TOKEN}" - self.access_token_expires = datetime.now() + timedelta(minutes=30) + # a proxy for the behaviour of the real web API + if self.refresh_token is None: + self.refresh_token = f"new_{REFRESH_TOKEN}" - # assume a valid GET, and return the JSON for that web API - if url == "userAccount": # userAccount - return user_account_config_fixture() + if ( + self.access_token_expires is None + or self.access_token_expires < datetime.now() + ): + self.access_token = f"new_{ACCESS_TOKEN}" + self.access_token_expires = datetime.now() + timedelta(minutes=30) - if url.startswith("location"): - if "installationInfo" in url: # location/installationInfo?userId={id} - return user_locations_config_fixture() - if "location" in url: # location/{id}/status - return location_status_fixture("2738909") + # assume a valid GET, and return the JSON for that web API + if url == "userAccount": # userAccount + return user_account_config_fixture(install) - elif "schedule" in url: - if url.startswith("domesticHotWater"): # domesticHotWater/{id}/schedule - return dhw_schedule_fixture() - if url.startswith("temperatureZone"): # temperatureZone/{id}/schedule - return zone_schedule_fixture() + if url.startswith("location"): + if "installationInfo" in url: # location/installationInfo?userId={id} + return user_locations_config_fixture(install) + if "location" in url: # location/{id}/status + return location_status_fixture(install) - pytest.xfail(f"Unexpected URL: {url}") + elif "schedule" in url: + if url.startswith("domesticHotWater"): # domesticHotWater/{id}/schedule + return dhw_schedule_fixture(install) + if url.startswith("temperatureZone"): # temperatureZone/{id}/schedule + return zone_schedule_fixture(install) + + pytest.fail(f"Unexpected request: {HTTPMethod.GET} {url}") + + return mock_get -@patch("evohomeasync2.broker.Broker.get", mock_get) -async def setup_evohome(hass: HomeAssistant, test_config: dict[str, str]) -> MagicMock: +async def block_request( + self: Broker, method: HTTPMethod, url: str, **kwargs: Any +) -> None: + """Fail if the code attempts any actual I/O via aiohttp.""" + + pytest.fail(f"Unexpected request: {method} {url}") + + +@pytest.fixture +def evo_config() -> dict[str, str]: + "Return a default/minimal configuration." + return { + CONF_USERNAME: USERNAME, + CONF_PASSWORD: "password", + } + + +@patch("evohomeasync.broker.Broker._make_request", block_request) +@patch("evohomeasync2.broker.Broker._client", block_request) +async def setup_evohome( + hass: HomeAssistant, + test_config: dict[str, str], + install: str = "default", +) -> MagicMock: """Set up the evohome integration and return its client. The class is mocked here to check the client was instantiated with the correct args. @@ -93,6 +132,7 @@ async def setup_evohome(hass: HomeAssistant, test_config: dict[str, str]) -> Mag with ( patch("homeassistant.components.evohome.evo.EvohomeClient") as mock_client, patch("homeassistant.components.evohome.ev1.EvohomeClient", return_value=None), + patch("evohomeasync2.broker.Broker.get", mock_get_factory(install)), ): mock_client.side_effect = EvohomeClient diff --git a/tests/components/evohome/const.py b/tests/components/evohome/const.py index 0b298db533a..c25a259e602 100644 --- a/tests/components/evohome/const.py +++ b/tests/components/evohome/const.py @@ -8,3 +8,12 @@ ACCESS_TOKEN: Final = "at_1dc7z657UKzbhKA..." REFRESH_TOKEN: Final = "rf_jg68ZCKYdxEI3fF..." SESSION_ID: Final = "F7181186..." USERNAME: Final = "test_user@gmail.com" + +# The h-numbers refer to issues in HA's core repo +TEST_INSTALLS: Final = ( + "minimal", # evohome (single zone, no DHW) + "default", # evohome (multi-zone, with DHW & ghost zones) + "h032585", # VisionProWifi (no preset_mode for TCS) + "h099625", # RoundThermostat + "system_004", # RoundModulation +) diff --git a/tests/components/evohome/fixtures/schedule_dhw.json b/tests/components/evohome/fixtures/default/schedule_dhw.json similarity index 100% rename from tests/components/evohome/fixtures/schedule_dhw.json rename to tests/components/evohome/fixtures/default/schedule_dhw.json diff --git a/tests/components/evohome/fixtures/schedule_zone.json b/tests/components/evohome/fixtures/default/schedule_zone.json similarity index 100% rename from tests/components/evohome/fixtures/schedule_zone.json rename to tests/components/evohome/fixtures/default/schedule_zone.json diff --git a/tests/components/evohome/fixtures/status_2738909.json b/tests/components/evohome/fixtures/default/status_2738909.json similarity index 100% rename from tests/components/evohome/fixtures/status_2738909.json rename to tests/components/evohome/fixtures/default/status_2738909.json diff --git a/tests/components/evohome/fixtures/user_account.json b/tests/components/evohome/fixtures/default/user_account.json similarity index 100% rename from tests/components/evohome/fixtures/user_account.json rename to tests/components/evohome/fixtures/default/user_account.json diff --git a/tests/components/evohome/fixtures/user_locations.json b/tests/components/evohome/fixtures/default/user_locations.json similarity index 99% rename from tests/components/evohome/fixtures/user_locations.json rename to tests/components/evohome/fixtures/default/user_locations.json index cf59aa9ae8a..f2f4091a2dc 100644 --- a/tests/components/evohome/fixtures/user_locations.json +++ b/tests/components/evohome/fixtures/default/user_locations.json @@ -246,7 +246,7 @@ }, { "zoneId": "3450733", - "modelType": "xx", + "modelType": "xxx", "setpointCapabilities": { "maxHeatSetpoint": 35.0, "minHeatSetpoint": 5.0, @@ -268,7 +268,7 @@ "setpointValueResolution": 0.5 }, "name": "Spare Room", - "zoneType": "xx" + "zoneType": "xxx" } ], "dhw": { diff --git a/tests/components/evohome/fixtures/h032585/status_111111.json b/tests/components/evohome/fixtures/h032585/status_111111.json new file mode 100644 index 00000000000..0ea535c2461 --- /dev/null +++ b/tests/components/evohome/fixtures/h032585/status_111111.json @@ -0,0 +1,31 @@ +{ + "locationId": "111111", + "gateways": [ + { + "gatewayId": "222222", + "temperatureControlSystems": [ + { + "systemId": "416856", + "zones": [ + { + "zoneId": "416856", + "temperatureStatus": { + "temperature": 21.5, + "isAvailable": true + }, + "activeFaults": [], + "setpointStatus": { + "targetHeatTemperature": 21.5, + "setpointMode": "FollowSchedule" + }, + "name": "THERMOSTAT" + } + ], + "activeFaults": [], + "systemModeStatus": { "mode": "Heat", "isPermanent": true } + } + ], + "activeFaults": [] + } + ] +} diff --git a/tests/components/evohome/fixtures/h032585/temperatures.json b/tests/components/evohome/fixtures/h032585/temperatures.json new file mode 100644 index 00000000000..a2015c94f46 --- /dev/null +++ b/tests/components/evohome/fixtures/h032585/temperatures.json @@ -0,0 +1,3 @@ +{ + "416856": 21.5 +} diff --git a/tests/components/evohome/fixtures/h032585/user_locations.json b/tests/components/evohome/fixtures/h032585/user_locations.json new file mode 100644 index 00000000000..b4ea2e5c420 --- /dev/null +++ b/tests/components/evohome/fixtures/h032585/user_locations.json @@ -0,0 +1,79 @@ +[ + { + "locationInfo": { + "locationId": "111111", + "name": "My Home", + "timeZone": { + "timeZoneId": "GMTStandardTime", + "displayName": "(UTC+00:00) Dublin, Edinburgh, Lisbon, London", + "offsetMinutes": 0, + "currentOffsetMinutes": 60, + "supportsDaylightSaving": true + } + }, + "gateways": [ + { + "gatewayInfo": { + "gatewayId": "222222", + "mac": "00D02DEE0000", + "crc": "1234", + "isWiFi": false + }, + "temperatureControlSystems": [ + { + "systemId": "416856", + "modelType": "VisionProWifiRetail", + "zones": [ + { + "zoneId": "416856", + "modelType": "VisionProWifiRetail", + "setpointCapabilities": { + "vacationHoldCapabilities": { + "isChangeable": true, + "isCancelable": true, + "minDuration": "1.00:00:00", + "maxDuration": "365.23:45:00", + "timingResolution": "00:15:00" + }, + "maxHeatSetpoint": 32.0, + "minHeatSetpoint": 4.5, + "valueResolution": 0.5, + "canControlHeat": true, + "canControlCool": false, + "allowedSetpointModes": [ + "PermanentOverride", + "FollowSchedule", + "TemporaryOverride", + "VacationHold" + ], + "maxDuration": "1.00:00:00", + "timingResolution": "00:15:00" + }, + "scheduleCapabilities": { + "maxSwitchpointsPerDay": 4, + "minSwitchpointsPerDay": 0, + "timingResolution": "00:15:00", + "setpointValueResolution": 0.5 + }, + "name": "THERMOSTAT", + "zoneType": "Thermostat" + } + ], + "allowedSystemModes": [ + { + "systemMode": "Off", + "canBePermanent": true, + "canBeTemporary": false + }, + { + "systemMode": "Heat", + "canBePermanent": true, + "canBeTemporary": false + } + ] + } + ] + } + ] + } +] diff --git a/tests/components/evohome/fixtures/h099625/status_111111.json b/tests/components/evohome/fixtures/h099625/status_111111.json new file mode 100644 index 00000000000..149d8aba783 --- /dev/null +++ b/tests/components/evohome/fixtures/h099625/status_111111.json @@ -0,0 +1,44 @@ +{ + "locationId": "111111", + "gateways": [ + { + "gatewayId": "222222", + "temperatureControlSystems": [ + { + "systemId": "8557535", + "zones": [ + { + "zoneId": "8557539", + "temperatureStatus": { + "temperature": 21.5, + "isAvailable": true + }, + "activeFaults": [], + "setpointStatus": { + "targetHeatTemperature": 21.5, + "setpointMode": "FollowSchedule" + }, + "name": "THERMOSTAT" + }, + { + "zoneId": "8557541", + "temperatureStatus": { + "temperature": 21.5, + "isAvailable": true + }, + "activeFaults": [], + "setpointStatus": { + "targetHeatTemperature": 21.5, + "setpointMode": "FollowSchedule" + }, + "name": "THERMOSTAT" + } + ], + "activeFaults": [], + "systemModeStatus": { "mode": "Auto", "isPermanent": true } + } + ], + "activeFaults": [] + } + ] +} diff --git a/tests/components/evohome/fixtures/h099625/user_locations.json b/tests/components/evohome/fixtures/h099625/user_locations.json new file mode 100644 index 00000000000..cc32caccc73 --- /dev/null +++ b/tests/components/evohome/fixtures/h099625/user_locations.json @@ -0,0 +1,113 @@ +[ + { + "locationInfo": { + "locationId": "111111", + "name": "My Home", + "timeZone": { + "timeZoneId": "FLEStandardTime", + "displayName": "(UTC+02:00) Helsinki, Kyiv, Riga, Sofia, Tallinn, Vilnius", + "offsetMinutes": 120, + "currentOffsetMinutes": 180, + "supportsDaylightSaving": true + } + }, + "gateways": [ + { + "gatewayInfo": { + "gatewayId": "222222", + "mac": "00D02DEE0000", + "crc": "1234", + "isWiFi": false + }, + "temperatureControlSystems": [ + { + "systemId": "8557535", + "modelType": "EvoTouch", + "zones": [ + { + "zoneId": "8557539", + "modelType": "RoundWireless", + "setpointCapabilities": { + "maxHeatSetpoint": 35.0, + "minHeatSetpoint": 5.0, + "valueResolution": 0.5, + "canControlHeat": true, + "canControlCool": false, + "allowedSetpointModes": [ + "PermanentOverride", + "FollowSchedule", + "TemporaryOverride" + ], + "maxDuration": "1.00:00:00", + "timingResolution": "00:10:00" + }, + "scheduleCapabilities": { + "maxSwitchpointsPerDay": 6, + "minSwitchpointsPerDay": 0, + "timingResolution": "00:10:00", + "setpointValueResolution": 0.5 + }, + "name": "Thermostat", + "zoneType": "Thermostat" + }, + { + "zoneId": "8557541", + "modelType": "RoundWireless", + "setpointCapabilities": { + "maxHeatSetpoint": 35.0, + "minHeatSetpoint": 5.0, + "valueResolution": 0.5, + "canControlHeat": true, + "canControlCool": false, + "allowedSetpointModes": [ + "PermanentOverride", + "FollowSchedule", + "TemporaryOverride" + ], + "maxDuration": "1.00:00:00", + "timingResolution": "00:10:00" + }, + "scheduleCapabilities": { + "maxSwitchpointsPerDay": 6, + "minSwitchpointsPerDay": 0, + "timingResolution": "00:10:00", + "setpointValueResolution": 0.5 + }, + "name": "Thermostat 2", + "zoneType": "Thermostat" + } + ], + "allowedSystemModes": [ + { + "systemMode": "Auto", + "canBePermanent": true, + "canBeTemporary": false + }, + { + "systemMode": "AutoWithEco", + "canBePermanent": true, + "canBeTemporary": true, + "maxDuration": "1.00:00:00", + "timingResolution": "01:00:00", + "timingMode": "Duration" + }, + { + "systemMode": "Away", + "canBePermanent": true, + "canBeTemporary": true, + "maxDuration": "99.00:00:00", + "timingResolution": "1.00:00:00", + "timingMode": "Period" + }, + { + "systemMode": "HeatingOff", + "canBePermanent": true, + "canBeTemporary": false + } + ] + } + ] + } + ] + } +] diff --git a/tests/components/evohome/fixtures/minimal/status_2738909.json b/tests/components/evohome/fixtures/minimal/status_2738909.json new file mode 100644 index 00000000000..4b344314a67 --- /dev/null +++ b/tests/components/evohome/fixtures/minimal/status_2738909.json @@ -0,0 +1,28 @@ +{ + "locationId": "2738909", + "gateways": [ + { + "gatewayId": "2499896", + "temperatureControlSystems": [ + { + "systemId": "3432522", + "zones": [ + { + "zoneId": "3432576", + "name": "Main Room", + "temperatureStatus": { "temperature": 19.0, "isAvailable": true }, + "setpointStatus": { + "targetHeatTemperature": 17.0, + "setpointMode": "FollowSchedule" + }, + "activeFaults": [] + } + ], + "activeFaults": [], + "systemModeStatus": { "mode": "AutoWithEco", "isPermanent": true } + } + ], + "activeFaults": [] + } + ] +} diff --git a/tests/components/evohome/fixtures/minimal/user_locations.json b/tests/components/evohome/fixtures/minimal/user_locations.json new file mode 100644 index 00000000000..932686d8728 --- /dev/null +++ b/tests/components/evohome/fixtures/minimal/user_locations.json @@ -0,0 +1,120 @@ +[ + { + "locationInfo": { + "locationId": "2738909", + "name": "My Home", + "streetAddress": "1 Main Street", + "city": "London", + "country": "UnitedKingdom", + "postcode": "E1 1AA", + "locationType": "Residential", + "useDaylightSaveSwitching": true, + "timeZone": { + "timeZoneId": "GMTStandardTime", + "displayName": "(UTC+00:00) Dublin, Edinburgh, Lisbon, London", + "offsetMinutes": 0, + "currentOffsetMinutes": 60, + "supportsDaylightSaving": true + }, + "locationOwner": { + "userId": "2263181", + "username": "user_2263181@gmail.com", + "firstname": "John", + "lastname": "Smith" + } + }, + "gateways": [ + { + "gatewayInfo": { + "gatewayId": "2499896", + "mac": "00D02DEE0000", + "crc": "1234", + "isWiFi": false + }, + "temperatureControlSystems": [ + { + "systemId": "3432522", + "modelType": "EvoTouch", + "zones": [ + { + "zoneId": "3432576", + "modelType": "HeatingZone", + "setpointCapabilities": { + "maxHeatSetpoint": 35.0, + "minHeatSetpoint": 5.0, + "valueResolution": 0.5, + "canControlHeat": true, + "canControlCool": false, + "allowedSetpointModes": [ + "PermanentOverride", + "FollowSchedule", + "TemporaryOverride" + ], + "maxDuration": "1.00:00:00", + "timingResolution": "00:10:00" + }, + "scheduleCapabilities": { + "maxSwitchpointsPerDay": 6, + "minSwitchpointsPerDay": 1, + "timingResolution": "00:10:00", + "setpointValueResolution": 0.5 + }, + "name": "Main Room", + "zoneType": "RadiatorZone" + } + ], + "allowedSystemModes": [ + { + "systemMode": "HeatingOff", + "canBePermanent": true, + "canBeTemporary": false + }, + { + "systemMode": "Auto", + "canBePermanent": true, + "canBeTemporary": false + }, + { + "systemMode": "AutoWithReset", + "canBePermanent": true, + "canBeTemporary": false + }, + { + "systemMode": "AutoWithEco", + "canBePermanent": true, + "canBeTemporary": true, + "maxDuration": "1.00:00:00", + "timingResolution": "01:00:00", + "timingMode": "Duration" + }, + { + "systemMode": "Away", + "canBePermanent": true, + "canBeTemporary": true, + "maxDuration": "99.00:00:00", + "timingResolution": "1.00:00:00", + "timingMode": "Period" + }, + { + "systemMode": "DayOff", + "canBePermanent": true, + "canBeTemporary": true, + "maxDuration": "99.00:00:00", + "timingResolution": "1.00:00:00", + "timingMode": "Period" + }, + { + "systemMode": "Custom", + "canBePermanent": true, + "canBeTemporary": true, + "maxDuration": "99.00:00:00", + "timingResolution": "1.00:00:00", + "timingMode": "Period" + } + ] + } + ] + } + ] + } +] diff --git a/tests/components/evohome/fixtures/system_004/status_3164610.json b/tests/components/evohome/fixtures/system_004/status_3164610.json new file mode 100644 index 00000000000..a9ef3f6ee28 --- /dev/null +++ b/tests/components/evohome/fixtures/system_004/status_3164610.json @@ -0,0 +1,33 @@ +{ + "locationId": "3164610", + "gateways": [ + { + "gatewayId": "2938388", + "temperatureControlSystems": [ + { + "systemId": "4187769", + "zones": [ + { + "zoneId": "4187768", + "temperatureStatus": { "temperature": 19.5, "isAvailable": true }, + "activeFaults": [], + "setpointStatus": { + "targetHeatTemperature": 15.0, + "setpointMode": "PermanentOverride" + }, + "name": "Thermostat" + } + ], + "activeFaults": [], + "systemModeStatus": { "mode": "Auto", "isPermanent": true } + } + ], + "activeFaults": [ + { + "faultType": "GatewayCommunicationLost", + "since": "2023-05-04T18:47:36.7727046" + } + ] + } + ] +} diff --git a/tests/components/evohome/fixtures/system_004/user_locations.json b/tests/components/evohome/fixtures/system_004/user_locations.json new file mode 100644 index 00000000000..9defab8b6ee --- /dev/null +++ b/tests/components/evohome/fixtures/system_004/user_locations.json @@ -0,0 +1,99 @@ +[ + { + "locationInfo": { + "locationId": "3164610", + "name": "Living room", + "streetAddress": "1 Main Road", + "city": "Boomtown", + "country": "Netherlands", + "postcode": "1234XX", + "locationType": "Residential", + "useDaylightSaveSwitching": true, + "timeZone": { + "timeZoneId": "WEuropeStandardTime", + "displayName": "(UTC+01:00) Amsterdam, Berlijn, Bern, Rome, Stockholm, Wenen", + "offsetMinutes": 60, + "currentOffsetMinutes": 120, + "supportsDaylightSaving": true + }, + "locationOwner": { + "userId": "2624305", + "username": "user_2624305@gmail.com", + "firstname": "Chris", + "lastname": "Jones" + } + }, + "gateways": [ + { + "gatewayInfo": { + "gatewayId": "2938388", + "mac": "00D02D5A7000", + "crc": "1234", + "isWiFi": false + }, + "temperatureControlSystems": [ + { + "systemId": "4187769", + "modelType": "EvoTouch", + "zones": [ + { + "zoneId": "4187768", + "modelType": "RoundModulation", + "setpointCapabilities": { + "maxHeatSetpoint": 35.0, + "minHeatSetpoint": 5.0, + "valueResolution": 0.5, + "canControlHeat": true, + "canControlCool": false, + "allowedSetpointModes": [ + "PermanentOverride", + "FollowSchedule", + "TemporaryOverride" + ], + "maxDuration": "1.00:00:00", + "timingResolution": "00:10:00" + }, + "scheduleCapabilities": { + "maxSwitchpointsPerDay": 6, + "minSwitchpointsPerDay": 0, + "timingResolution": "00:10:00", + "setpointValueResolution": 0.5 + }, + "name": "Thermostat", + "zoneType": "Thermostat" + } + ], + "allowedSystemModes": [ + { + "systemMode": "Auto", + "canBePermanent": true, + "canBeTemporary": false + }, + { + "systemMode": "AutoWithEco", + "canBePermanent": true, + "canBeTemporary": true, + "maxDuration": "1.00:00:00", + "timingResolution": "01:00:00", + "timingMode": "Duration" + }, + { + "systemMode": "Away", + "canBePermanent": true, + "canBeTemporary": true, + "maxDuration": "99.00:00:00", + "timingResolution": "1.00:00:00", + "timingMode": "Period" + }, + { + "systemMode": "HeatingOff", + "canBePermanent": true, + "canBeTemporary": false + } + ] + } + ] + } + ] + } +] diff --git a/tests/components/evohome/snapshots/test_init.ambr b/tests/components/evohome/snapshots/test_init.ambr new file mode 100644 index 00000000000..210c45354a5 --- /dev/null +++ b/tests/components/evohome/snapshots/test_init.ambr @@ -0,0 +1,863 @@ +# serializer version: 1 +# name: test_entities[default] + list([ + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'current_temperature': 19.7, + 'friendly_name': 'My Home', + 'hvac_modes': list([ + , + , + ]), + 'icon': 'mdi:thermostat', + 'max_temp': 35, + 'min_temp': 7, + 'preset_mode': 'eco', + 'preset_modes': list([ + 'Reset', + 'eco', + 'away', + 'home', + 'Custom', + ]), + 'status': dict({ + 'active_system_faults': list([ + ]), + 'system_id': '3432522', + 'system_mode_status': dict({ + 'is_permanent': True, + 'mode': 'AutoWithEco', + }), + }), + 'supported_features': , + }), + 'context': , + 'entity_id': 'climate.my_home', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'heat', + }), + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'current_temperature': None, + 'friendly_name': 'Dead Zone', + 'hvac_modes': list([ + , + , + ]), + 'max_temp': 35.0, + 'min_temp': 5.0, + 'preset_mode': 'none', + 'preset_modes': list([ + 'none', + 'temporary', + 'permanent', + ]), + 'status': dict({ + 'active_faults': list([ + ]), + 'setpoint_status': dict({ + 'setpoint_mode': 'FollowSchedule', + 'target_heat_temperature': 17.0, + }), + 'setpoints': dict({ + 'next_sp_from': '2024-08-14T23:00:00-07:00', + 'next_sp_temp': 18.1, + 'this_sp_from': '2024-08-14T15:00:00-07:00', + 'this_sp_temp': 15.9, + }), + 'temperature_status': dict({ + 'is_available': False, + }), + 'zone_id': '3432521', + }), + 'supported_features': , + 'temperature': 17.0, + }), + 'context': , + 'entity_id': 'climate.dead_zone', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'heat', + }), + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'current_temperature': 19.0, + 'friendly_name': 'Main Room', + 'hvac_modes': list([ + , + , + ]), + 'max_temp': 35.0, + 'min_temp': 5.0, + 'preset_mode': 'permanent', + 'preset_modes': list([ + 'none', + 'temporary', + 'permanent', + ]), + 'status': dict({ + 'active_faults': list([ + dict({ + 'faultType': 'TempZoneActuatorCommunicationLost', + 'since': '2022-03-02T15:56:01', + }), + ]), + 'setpoint_status': dict({ + 'setpoint_mode': 'PermanentOverride', + 'target_heat_temperature': 17.0, + }), + 'setpoints': dict({ + 'next_sp_from': '2024-08-14T23:00:00-07:00', + 'next_sp_temp': 18.1, + 'this_sp_from': '2024-08-14T15:00:00-07:00', + 'this_sp_temp': 15.9, + }), + 'temperature_status': dict({ + 'is_available': True, + 'temperature': 19.0, + }), + 'zone_id': '3432576', + }), + 'supported_features': , + 'temperature': 17.0, + }), + 'context': , + 'entity_id': 'climate.main_room', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'heat', + }), + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'current_temperature': 19.0, + 'friendly_name': 'Front Room', + 'hvac_modes': list([ + , + , + ]), + 'max_temp': 35.0, + 'min_temp': 5.0, + 'preset_mode': 'temporary', + 'preset_modes': list([ + 'none', + 'temporary', + 'permanent', + ]), + 'status': dict({ + 'active_faults': list([ + dict({ + 'faultType': 'TempZoneActuatorLowBattery', + 'since': '2022-03-02T04:50:20', + }), + ]), + 'setpoint_status': dict({ + 'setpoint_mode': 'TemporaryOverride', + 'target_heat_temperature': 21.0, + 'until': '2022-03-07T11:00:00-08:00', + }), + 'setpoints': dict({ + 'next_sp_from': '2024-08-14T23:00:00-07:00', + 'next_sp_temp': 18.1, + 'this_sp_from': '2024-08-14T15:00:00-07:00', + 'this_sp_temp': 15.9, + }), + 'temperature_status': dict({ + 'is_available': True, + 'temperature': 19.0, + }), + 'zone_id': '3432577', + }), + 'supported_features': , + 'temperature': 21.0, + }), + 'context': , + 'entity_id': 'climate.front_room', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'heat', + }), + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'current_temperature': 20.0, + 'friendly_name': 'Kitchen', + 'hvac_modes': list([ + , + , + ]), + 'max_temp': 35.0, + 'min_temp': 5.0, + 'preset_mode': 'none', + 'preset_modes': list([ + 'none', + 'temporary', + 'permanent', + ]), + 'status': dict({ + 'active_faults': list([ + ]), + 'setpoint_status': dict({ + 'setpoint_mode': 'FollowSchedule', + 'target_heat_temperature': 17.0, + }), + 'setpoints': dict({ + 'next_sp_from': '2024-08-14T23:00:00-07:00', + 'next_sp_temp': 18.1, + 'this_sp_from': '2024-08-14T15:00:00-07:00', + 'this_sp_temp': 15.9, + }), + 'temperature_status': dict({ + 'is_available': True, + 'temperature': 20.0, + }), + 'zone_id': '3432578', + }), + 'supported_features': , + 'temperature': 17.0, + }), + 'context': , + 'entity_id': 'climate.kitchen', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'heat', + }), + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'current_temperature': 20.0, + 'friendly_name': 'Bathroom Dn', + 'hvac_modes': list([ + , + , + ]), + 'max_temp': 35.0, + 'min_temp': 5.0, + 'preset_mode': 'none', + 'preset_modes': list([ + 'none', + 'temporary', + 'permanent', + ]), + 'status': dict({ + 'active_faults': list([ + ]), + 'setpoint_status': dict({ + 'setpoint_mode': 'FollowSchedule', + 'target_heat_temperature': 16.0, + }), + 'setpoints': dict({ + 'next_sp_from': '2024-08-14T23:00:00-07:00', + 'next_sp_temp': 18.1, + 'this_sp_from': '2024-08-14T15:00:00-07:00', + 'this_sp_temp': 15.9, + }), + 'temperature_status': dict({ + 'is_available': True, + 'temperature': 20.0, + }), + 'zone_id': '3432579', + }), + 'supported_features': , + 'temperature': 16.0, + }), + 'context': , + 'entity_id': 'climate.bathroom_dn', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'heat', + }), + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'current_temperature': 21.0, + 'friendly_name': 'Main Bedroom', + 'hvac_modes': list([ + , + , + ]), + 'max_temp': 35.0, + 'min_temp': 5.0, + 'preset_mode': 'none', + 'preset_modes': list([ + 'none', + 'temporary', + 'permanent', + ]), + 'status': dict({ + 'active_faults': list([ + ]), + 'setpoint_status': dict({ + 'setpoint_mode': 'FollowSchedule', + 'target_heat_temperature': 16.0, + }), + 'setpoints': dict({ + 'next_sp_from': '2024-08-14T23:00:00-07:00', + 'next_sp_temp': 18.1, + 'this_sp_from': '2024-08-14T15:00:00-07:00', + 'this_sp_temp': 15.9, + }), + 'temperature_status': dict({ + 'is_available': True, + 'temperature': 21.0, + }), + 'zone_id': '3432580', + }), + 'supported_features': , + 'temperature': 16.0, + }), + 'context': , + 'entity_id': 'climate.main_bedroom', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'heat', + }), + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'current_temperature': 19.5, + 'friendly_name': 'Kids Room', + 'hvac_modes': list([ + , + , + ]), + 'max_temp': 35.0, + 'min_temp': 5.0, + 'preset_mode': 'none', + 'preset_modes': list([ + 'none', + 'temporary', + 'permanent', + ]), + 'status': dict({ + 'active_faults': list([ + ]), + 'setpoint_status': dict({ + 'setpoint_mode': 'FollowSchedule', + 'target_heat_temperature': 17.0, + }), + 'setpoints': dict({ + 'next_sp_from': '2024-08-14T23:00:00-07:00', + 'next_sp_temp': 18.1, + 'this_sp_from': '2024-08-14T15:00:00-07:00', + 'this_sp_temp': 15.9, + }), + 'temperature_status': dict({ + 'is_available': True, + 'temperature': 19.5, + }), + 'zone_id': '3449703', + }), + 'supported_features': , + 'temperature': 17.0, + }), + 'context': , + 'entity_id': 'climate.kids_room', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'heat', + }), + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'away_mode': 'on', + 'current_temperature': 23, + 'friendly_name': 'Domestic Hot Water', + 'icon': 'mdi:thermometer-lines', + 'max_temp': 60, + 'min_temp': 43, + 'operation_list': list([ + 'auto', + 'on', + 'off', + ]), + 'operation_mode': 'off', + 'status': dict({ + 'active_faults': list([ + ]), + 'dhw_id': '3933910', + 'setpoints': dict({ + 'next_sp_from': '2024-08-14T22:30:00-07:00', + 'next_sp_state': 'On', + 'this_sp_from': '2024-08-14T14:30:00-07:00', + 'this_sp_state': 'Off', + }), + 'state_status': dict({ + 'mode': 'PermanentOverride', + 'state': 'Off', + }), + 'temperature_status': dict({ + 'is_available': True, + 'temperature': 23.0, + }), + }), + 'supported_features': , + 'target_temp_high': None, + 'target_temp_low': None, + 'temperature': None, + }), + 'context': , + 'entity_id': 'water_heater.domestic_hot_water', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'off', + }), + ]) +# --- +# name: test_entities[h032585] + list([ + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'current_temperature': 21.5, + 'friendly_name': 'My Home', + 'hvac_modes': list([ + , + , + ]), + 'icon': 'mdi:thermostat', + 'max_temp': 35, + 'min_temp': 7, + 'status': dict({ + 'active_system_faults': list([ + ]), + 'system_id': '416856', + 'system_mode_status': dict({ + 'is_permanent': True, + 'mode': 'Heat', + }), + }), + 'supported_features': , + }), + 'context': , + 'entity_id': 'climate.my_home', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'heat', + }), + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'current_temperature': 21.5, + 'friendly_name': 'THERMOSTAT', + 'hvac_modes': list([ + , + , + ]), + 'max_temp': 32.0, + 'min_temp': 4.5, + 'preset_mode': 'none', + 'preset_modes': list([ + 'none', + 'temporary', + 'permanent', + ]), + 'status': dict({ + 'active_faults': list([ + ]), + 'setpoint_status': dict({ + 'setpoint_mode': 'FollowSchedule', + 'target_heat_temperature': 21.5, + }), + 'setpoints': dict({ + 'next_sp_from': '2024-08-14T23:00:00-07:00', + 'next_sp_temp': 18.1, + 'this_sp_from': '2024-08-14T15:00:00-07:00', + 'this_sp_temp': 15.9, + }), + 'temperature_status': dict({ + 'is_available': True, + 'temperature': 21.5, + }), + 'zone_id': '416856', + }), + 'supported_features': , + 'temperature': 21.5, + }), + 'context': , + 'entity_id': 'climate.thermostat', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'heat', + }), + ]) +# --- +# name: test_entities[h099625] + list([ + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'current_temperature': 21.5, + 'friendly_name': 'My Home', + 'hvac_modes': list([ + , + , + ]), + 'icon': 'mdi:thermostat', + 'max_temp': 35, + 'min_temp': 7, + 'preset_mode': None, + 'preset_modes': list([ + 'eco', + 'away', + ]), + 'status': dict({ + 'active_system_faults': list([ + ]), + 'system_id': '8557535', + 'system_mode_status': dict({ + 'is_permanent': True, + 'mode': 'Auto', + }), + }), + 'supported_features': , + }), + 'context': , + 'entity_id': 'climate.my_home', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'heat', + }), + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'current_temperature': 21.5, + 'friendly_name': 'THERMOSTAT', + 'hvac_modes': list([ + , + , + ]), + 'max_temp': 35.0, + 'min_temp': 5.0, + 'preset_mode': 'none', + 'preset_modes': list([ + 'none', + 'temporary', + 'permanent', + ]), + 'status': dict({ + 'active_faults': list([ + ]), + 'setpoint_status': dict({ + 'setpoint_mode': 'FollowSchedule', + 'target_heat_temperature': 21.5, + }), + 'setpoints': dict({ + 'next_sp_from': '2024-08-14T21:00:00-07:00', + 'next_sp_temp': 18.1, + 'this_sp_from': '2024-08-14T13:00:00-07:00', + 'this_sp_temp': 15.9, + }), + 'temperature_status': dict({ + 'is_available': True, + 'temperature': 21.5, + }), + 'zone_id': '8557539', + }), + 'supported_features': , + 'temperature': 21.5, + }), + 'context': , + 'entity_id': 'climate.thermostat', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'heat', + }), + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'current_temperature': 21.5, + 'friendly_name': 'THERMOSTAT', + 'hvac_modes': list([ + , + , + ]), + 'max_temp': 35.0, + 'min_temp': 5.0, + 'preset_mode': 'none', + 'preset_modes': list([ + 'none', + 'temporary', + 'permanent', + ]), + 'status': dict({ + 'active_faults': list([ + ]), + 'setpoint_status': dict({ + 'setpoint_mode': 'FollowSchedule', + 'target_heat_temperature': 21.5, + }), + 'setpoints': dict({ + 'next_sp_from': '2024-08-14T21:00:00-07:00', + 'next_sp_temp': 18.1, + 'this_sp_from': '2024-08-14T13:00:00-07:00', + 'this_sp_temp': 15.9, + }), + 'temperature_status': dict({ + 'is_available': True, + 'temperature': 21.5, + }), + 'zone_id': '8557541', + }), + 'supported_features': , + 'temperature': 21.5, + }), + 'context': , + 'entity_id': 'climate.thermostat_2', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'heat', + }), + ]) +# --- +# name: test_entities[h118169] + list([ + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'current_temperature': 21.5, + 'friendly_name': 'My Home', + 'hvac_modes': list([ + , + , + ]), + 'icon': 'mdi:thermostat', + 'max_temp': 35, + 'min_temp': 7, + 'status': dict({ + 'active_system_faults': list([ + ]), + 'system_id': '333333', + 'system_mode_status': dict({ + 'is_permanent': True, + 'mode': 'Heat', + }), + }), + 'supported_features': , + }), + 'context': , + 'entity_id': 'climate.my_home', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'heat', + }), + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'current_temperature': 21.5, + 'friendly_name': 'THERMOSTAT', + 'hvac_modes': list([ + , + , + ]), + 'max_temp': 32.0, + 'min_temp': 4.5, + 'preset_mode': 'none', + 'preset_modes': list([ + 'none', + 'temporary', + 'permanent', + ]), + 'status': dict({ + 'active_faults': list([ + ]), + 'setpoint_status': dict({ + 'setpoint_mode': 'FollowSchedule', + 'target_heat_temperature': 21.5, + }), + 'setpoints': dict({ + 'next_sp_from': '2024-08-14T23:00:00-07:00', + 'next_sp_temp': 18.1, + 'this_sp_from': '2024-08-14T15:00:00-07:00', + 'this_sp_temp': 15.9, + }), + 'temperature_status': dict({ + 'is_available': True, + 'temperature': 21.5, + }), + 'zone_id': '444444', + }), + 'supported_features': , + 'temperature': 21.5, + }), + 'context': , + 'entity_id': 'climate.thermostat', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'heat', + }), + ]) +# --- +# name: test_entities[minimal] + list([ + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'current_temperature': 19.0, + 'friendly_name': 'My Home', + 'hvac_modes': list([ + , + , + ]), + 'icon': 'mdi:thermostat', + 'max_temp': 35, + 'min_temp': 7, + 'preset_mode': 'eco', + 'preset_modes': list([ + 'Reset', + 'eco', + 'away', + 'home', + 'Custom', + ]), + 'status': dict({ + 'active_system_faults': list([ + ]), + 'system_id': '3432522', + 'system_mode_status': dict({ + 'is_permanent': True, + 'mode': 'AutoWithEco', + }), + }), + 'supported_features': , + }), + 'context': , + 'entity_id': 'climate.my_home', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'heat', + }), + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'current_temperature': 19.0, + 'friendly_name': 'Main Room', + 'hvac_modes': list([ + , + , + ]), + 'max_temp': 35.0, + 'min_temp': 5.0, + 'preset_mode': 'none', + 'preset_modes': list([ + 'none', + 'temporary', + 'permanent', + ]), + 'status': dict({ + 'active_faults': list([ + ]), + 'setpoint_status': dict({ + 'setpoint_mode': 'FollowSchedule', + 'target_heat_temperature': 17.0, + }), + 'setpoints': dict({ + 'next_sp_from': '2024-08-14T23:00:00-07:00', + 'next_sp_temp': 18.1, + 'this_sp_from': '2024-08-14T15:00:00-07:00', + 'this_sp_temp': 15.9, + }), + 'temperature_status': dict({ + 'is_available': True, + 'temperature': 19.0, + }), + 'zone_id': '3432576', + }), + 'supported_features': , + 'temperature': 17.0, + }), + 'context': , + 'entity_id': 'climate.main_room', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'heat', + }), + ]) +# --- +# name: test_entities[system_004] + list([ + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'current_temperature': 19.5, + 'friendly_name': 'Living room', + 'hvac_modes': list([ + , + , + ]), + 'icon': 'mdi:thermostat', + 'max_temp': 35, + 'min_temp': 7, + 'preset_mode': None, + 'preset_modes': list([ + 'eco', + 'away', + ]), + 'status': dict({ + 'active_system_faults': list([ + ]), + 'system_id': '4187769', + 'system_mode_status': dict({ + 'is_permanent': True, + 'mode': 'Auto', + }), + }), + 'supported_features': , + }), + 'context': , + 'entity_id': 'climate.living_room', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'heat', + }), + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'current_temperature': 19.5, + 'friendly_name': 'Thermostat', + 'hvac_modes': list([ + , + , + ]), + 'max_temp': 35.0, + 'min_temp': 5.0, + 'preset_mode': 'permanent', + 'preset_modes': list([ + 'none', + 'temporary', + 'permanent', + ]), + 'status': dict({ + 'active_faults': list([ + ]), + 'setpoint_status': dict({ + 'setpoint_mode': 'PermanentOverride', + 'target_heat_temperature': 15.0, + }), + 'setpoints': dict({ + 'next_sp_from': '2024-08-14T22:00:00-07:00', + 'next_sp_temp': 18.1, + 'this_sp_from': '2024-08-14T14:00:00-07:00', + 'this_sp_temp': 15.9, + }), + 'temperature_status': dict({ + 'is_available': True, + 'temperature': 19.5, + }), + 'zone_id': '4187768', + }), + 'supported_features': , + 'temperature': 15.0, + }), + 'context': , + 'entity_id': 'climate.thermostat', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'heat', + }), + ]) +# --- diff --git a/tests/components/evohome/test_init.py b/tests/components/evohome/test_init.py new file mode 100644 index 00000000000..b717b19e6cd --- /dev/null +++ b/tests/components/evohome/test_init.py @@ -0,0 +1,25 @@ +"""The tests for evohome.""" + +from __future__ import annotations + +import pytest +from syrupy import SnapshotAssertion + +from homeassistant.core import HomeAssistant + +from .conftest import setup_evohome +from .const import TEST_INSTALLS + + +@pytest.mark.parametrize("install", TEST_INSTALLS) +async def test_entities( + hass: HomeAssistant, + evo_config: dict[str, str], + install: str, + snapshot: SnapshotAssertion, +) -> None: + """Test entities and state after setup of a Honeywell TCC-compatible system.""" + + await setup_evohome(hass, evo_config, install=install) + + assert hass.states.async_all() == snapshot diff --git a/tests/components/evohome/test_storage.py b/tests/components/evohome/test_storage.py index e87b847a9ff..32cd49a1539 100644 --- a/tests/components/evohome/test_storage.py +++ b/tests/components/evohome/test_storage.py @@ -8,7 +8,6 @@ from typing import Any, Final, NotRequired, TypedDict import pytest from homeassistant.components.evohome import ( - CONF_PASSWORD, CONF_USERNAME, DOMAIN, STORAGE_KEY, @@ -56,11 +55,6 @@ ACCESS_TOKEN_EXP_DTM, ACCESS_TOKEN_EXP_STR = dt_pair(dt_util.now() + timedelta(h USERNAME_DIFF: Final = f"not_{USERNAME}" USERNAME_SAME: Final = USERNAME -TEST_CONFIG: Final = { - CONF_USERNAME: USERNAME_SAME, - CONF_PASSWORD: "password", -} - TEST_DATA: Final[dict[str, _TokenStoreT]] = { "sans_session_id": { SZ_USERNAME: USERNAME_SAME, @@ -93,13 +87,14 @@ DOMAIN_STORAGE_BASE: Final = { async def test_auth_tokens_null( hass: HomeAssistant, hass_storage: dict[str, Any], + evo_config: dict[str, str], idx: str, ) -> None: """Test loading/saving authentication tokens when no cached tokens in the store.""" hass_storage[DOMAIN] = DOMAIN_STORAGE_BASE | {"data": TEST_DATA_NULL[idx]} - mock_client = await setup_evohome(hass, TEST_CONFIG) + mock_client = await setup_evohome(hass, evo_config, install="minimal") # Confirm client was instantiated without tokens, as cache was empty... assert SZ_REFRESH_TOKEN not in mock_client.call_args.kwargs @@ -120,13 +115,16 @@ async def test_auth_tokens_null( @pytest.mark.parametrize("idx", TEST_DATA) async def test_auth_tokens_same( - hass: HomeAssistant, hass_storage: dict[str, Any], idx: str + hass: HomeAssistant, + hass_storage: dict[str, Any], + evo_config: dict[str, str], + idx: str, ) -> None: """Test loading/saving authentication tokens when matching username.""" hass_storage[DOMAIN] = DOMAIN_STORAGE_BASE | {"data": TEST_DATA[idx]} - mock_client = await setup_evohome(hass, TEST_CONFIG) + mock_client = await setup_evohome(hass, evo_config, install="minimal") # Confirm client was instantiated with the cached tokens... assert mock_client.call_args.kwargs[SZ_REFRESH_TOKEN] == REFRESH_TOKEN @@ -146,7 +144,10 @@ async def test_auth_tokens_same( @pytest.mark.parametrize("idx", TEST_DATA) async def test_auth_tokens_past( - hass: HomeAssistant, hass_storage: dict[str, Any], idx: str + hass: HomeAssistant, + hass_storage: dict[str, Any], + evo_config: dict[str, str], + idx: str, ) -> None: """Test loading/saving authentication tokens with matching username, but expired.""" @@ -158,7 +159,7 @@ async def test_auth_tokens_past( hass_storage[DOMAIN] = DOMAIN_STORAGE_BASE | {"data": test_data} - mock_client = await setup_evohome(hass, TEST_CONFIG) + mock_client = await setup_evohome(hass, evo_config, install="minimal") # Confirm client was instantiated with the cached tokens... assert mock_client.call_args.kwargs[SZ_REFRESH_TOKEN] == REFRESH_TOKEN @@ -181,14 +182,17 @@ async def test_auth_tokens_past( @pytest.mark.parametrize("idx", TEST_DATA) async def test_auth_tokens_diff( - hass: HomeAssistant, hass_storage: dict[str, Any], idx: str + hass: HomeAssistant, + hass_storage: dict[str, Any], + evo_config: dict[str, str], + idx: str, ) -> None: """Test loading/saving authentication tokens when unmatched username.""" hass_storage[DOMAIN] = DOMAIN_STORAGE_BASE | {"data": TEST_DATA[idx]} mock_client = await setup_evohome( - hass, TEST_CONFIG | {CONF_USERNAME: USERNAME_DIFF} + hass, evo_config | {CONF_USERNAME: USERNAME_DIFF}, install="minimal" ) # Confirm client was instantiated without tokens, as username was different...