diff --git a/homeassistant/components/husqvarna_automower/__init__.py b/homeassistant/components/husqvarna_automower/__init__.py index c7d698663135c3faf2f64a2397fbec9d41ae38c7..0bb58fa45635f066d76b70f1c2fad04daa1f6601 100644 --- a/homeassistant/components/husqvarna_automower/__init__.py +++ b/homeassistant/components/husqvarna_automower/__init__.py @@ -14,6 +14,7 @@ from homeassistant.helpers import ( config_entry_oauth2_flow, device_registry as dr, ) +from homeassistant.util import dt as dt_util from . import api from .const import DOMAIN @@ -48,7 +49,11 @@ async def async_setup_entry(hass: HomeAssistant, entry: AutomowerConfigEntry) -> aiohttp_client.async_get_clientsession(hass), session, ) - automower_api = AutomowerSession(api_api) + time_zone_str = str(dt_util.DEFAULT_TIME_ZONE) + automower_api = AutomowerSession( + api_api, + await dt_util.async_get_time_zone(time_zone_str), + ) try: await api_api.async_get_access_token() except ClientResponseError as err: diff --git a/homeassistant/components/husqvarna_automower/button.py b/homeassistant/components/husqvarna_automower/button.py index bbc6316c54150a012908fa98a64fa54b7d9361c0..22a732ec54c98e1431f4cc6c63d6ad2453499fd1 100644 --- a/homeassistant/components/husqvarna_automower/button.py +++ b/homeassistant/components/husqvarna_automower/button.py @@ -11,7 +11,6 @@ from aioautomower.session import AutomowerSession from homeassistant.components.button import ButtonEntity, ButtonEntityDescription from homeassistant.core import HomeAssistant from homeassistant.helpers.entity_platform import AddEntitiesCallback -from homeassistant.util import dt as dt_util from . import AutomowerConfigEntry from .coordinator import AutomowerDataUpdateCoordinator @@ -24,19 +23,6 @@ from .entity import ( _LOGGER = logging.getLogger(__name__) -async def _async_set_time( - session: AutomowerSession, - mower_id: str, -) -> None: - """Set datetime for the mower.""" - # dt_util returns the current (aware) local datetime, set in the frontend. - # We assume it's the timezone in which the mower is. - await session.commands.set_datetime( - mower_id, - dt_util.now(), - ) - - @dataclass(frozen=True, kw_only=True) class AutomowerButtonEntityDescription(ButtonEntityDescription): """Describes Automower button entities.""" @@ -58,7 +44,7 @@ MOWER_BUTTON_TYPES: tuple[AutomowerButtonEntityDescription, ...] = ( key="sync_clock", translation_key="sync_clock", available_fn=_check_error_free, - press_fn=_async_set_time, + press_fn=lambda session, mower_id: session.commands.set_datetime(mower_id), ), ) diff --git a/homeassistant/components/husqvarna_automower/calendar.py b/homeassistant/components/husqvarna_automower/calendar.py index 87fac58beb26262d712a3886f5ed60fb2e6e4a9d..d4162af0c5c52289ba9d1afa203ca6f779f5fc3e 100644 --- a/homeassistant/components/husqvarna_automower/calendar.py +++ b/homeassistant/components/husqvarna_automower/calendar.py @@ -60,8 +60,8 @@ class AutomowerCalendarEntity(AutomowerBaseEntity, CalendarEntity): ] return CalendarEvent( summary=make_name_string(work_area_name, program_event.schedule_no), - start=program_event.start.replace(tzinfo=dt_util.DEFAULT_TIME_ZONE), - end=program_event.end.replace(tzinfo=dt_util.DEFAULT_TIME_ZONE), + start=program_event.start, + end=program_event.end, rrule=program_event.rrule_str, ) diff --git a/homeassistant/components/husqvarna_automower/manifest.json b/homeassistant/components/husqvarna_automower/manifest.json index 17d32c270d98205b16c5da8aef5517b302dd7b85..d22d23583badad08d565009e7d29f32812000350 100644 --- a/homeassistant/components/husqvarna_automower/manifest.json +++ b/homeassistant/components/husqvarna_automower/manifest.json @@ -7,5 +7,5 @@ "documentation": "https://www.home-assistant.io/integrations/husqvarna_automower", "iot_class": "cloud_push", "loggers": ["aioautomower"], - "requirements": ["aioautomower==2024.10.0"] + "requirements": ["aioautomower==2024.10.3"] } diff --git a/homeassistant/components/husqvarna_automower/sensor.py b/homeassistant/components/husqvarna_automower/sensor.py index b9a6fb164869cfe1f459194fe0d8692f77b29579..4576c4152a00507efd67a31552e6f6b411614278 100644 --- a/homeassistant/components/husqvarna_automower/sensor.py +++ b/homeassistant/components/husqvarna_automower/sensor.py @@ -4,8 +4,8 @@ from collections.abc import Callable, Mapping from dataclasses import dataclass from datetime import datetime import logging +from operator import attrgetter from typing import TYPE_CHECKING, Any -from zoneinfo import ZoneInfo from aioautomower.model import ( MowerAttributes, @@ -14,7 +14,6 @@ from aioautomower.model import ( RestrictedReasons, WorkArea, ) -from aioautomower.utils import naive_to_aware from homeassistant.components.sensor import ( SensorDeviceClass, @@ -26,7 +25,6 @@ from homeassistant.const import PERCENTAGE, EntityCategory, UnitOfLength, UnitOf from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.entity_platform import AddEntitiesCallback from homeassistant.helpers.typing import StateType -from homeassistant.util import dt as dt_util from . import AutomowerConfigEntry from .coordinator import AutomowerDataUpdateCoordinator @@ -196,16 +194,16 @@ ERROR_STATES = { } RESTRICTED_REASONS: list = [ - RestrictedReasons.ALL_WORK_AREAS_COMPLETED.lower(), - RestrictedReasons.DAILY_LIMIT.lower(), - RestrictedReasons.EXTERNAL.lower(), - RestrictedReasons.FOTA.lower(), - RestrictedReasons.FROST.lower(), - RestrictedReasons.NONE.lower(), - RestrictedReasons.NOT_APPLICABLE.lower(), - RestrictedReasons.PARK_OVERRIDE.lower(), - RestrictedReasons.SENSOR.lower(), - RestrictedReasons.WEEK_SCHEDULE.lower(), + RestrictedReasons.ALL_WORK_AREAS_COMPLETED, + RestrictedReasons.DAILY_LIMIT, + RestrictedReasons.EXTERNAL, + RestrictedReasons.FOTA, + RestrictedReasons.FROST, + RestrictedReasons.NONE, + RestrictedReasons.NOT_APPLICABLE, + RestrictedReasons.PARK_OVERRIDE, + RestrictedReasons.SENSOR, + RestrictedReasons.WEEK_SCHEDULE, ] STATE_NO_WORK_AREA_ACTIVE = "no_work_area_active" @@ -272,15 +270,15 @@ MOWER_SENSOR_TYPES: tuple[AutomowerSensorEntityDescription, ...] = ( state_class=SensorStateClass.MEASUREMENT, device_class=SensorDeviceClass.BATTERY, native_unit_of_measurement=PERCENTAGE, - value_fn=lambda data: data.battery.battery_percent, + value_fn=attrgetter("battery.battery_percent"), ), AutomowerSensorEntityDescription( key="mode", translation_key="mode", device_class=SensorDeviceClass.ENUM, - option_fn=lambda data: [option.lower() for option in list(MowerModes)], + option_fn=lambda data: list(MowerModes), value_fn=( - lambda data: data.mower.mode.lower() + lambda data: data.mower.mode if data.mower.mode != MowerModes.UNKNOWN else None ), @@ -293,7 +291,7 @@ MOWER_SENSOR_TYPES: tuple[AutomowerSensorEntityDescription, ...] = ( native_unit_of_measurement=UnitOfTime.SECONDS, suggested_unit_of_measurement=UnitOfTime.HOURS, exists_fn=lambda data: data.statistics.cutting_blade_usage_time is not None, - value_fn=lambda data: data.statistics.cutting_blade_usage_time, + value_fn=attrgetter("statistics.cutting_blade_usage_time"), ), AutomowerSensorEntityDescription( key="total_charging_time", @@ -304,7 +302,7 @@ MOWER_SENSOR_TYPES: tuple[AutomowerSensorEntityDescription, ...] = ( native_unit_of_measurement=UnitOfTime.SECONDS, suggested_unit_of_measurement=UnitOfTime.HOURS, exists_fn=lambda data: data.statistics.total_charging_time is not None, - value_fn=lambda data: data.statistics.total_charging_time, + value_fn=attrgetter("statistics.total_charging_time"), ), AutomowerSensorEntityDescription( key="total_cutting_time", @@ -315,7 +313,7 @@ MOWER_SENSOR_TYPES: tuple[AutomowerSensorEntityDescription, ...] = ( native_unit_of_measurement=UnitOfTime.SECONDS, suggested_unit_of_measurement=UnitOfTime.HOURS, exists_fn=lambda data: data.statistics.total_cutting_time is not None, - value_fn=lambda data: data.statistics.total_cutting_time, + value_fn=attrgetter("statistics.total_cutting_time"), ), AutomowerSensorEntityDescription( key="total_running_time", @@ -326,7 +324,7 @@ MOWER_SENSOR_TYPES: tuple[AutomowerSensorEntityDescription, ...] = ( native_unit_of_measurement=UnitOfTime.SECONDS, suggested_unit_of_measurement=UnitOfTime.HOURS, exists_fn=lambda data: data.statistics.total_running_time is not None, - value_fn=lambda data: data.statistics.total_running_time, + value_fn=attrgetter("statistics.total_running_time"), ), AutomowerSensorEntityDescription( key="total_searching_time", @@ -337,7 +335,7 @@ MOWER_SENSOR_TYPES: tuple[AutomowerSensorEntityDescription, ...] = ( native_unit_of_measurement=UnitOfTime.SECONDS, suggested_unit_of_measurement=UnitOfTime.HOURS, exists_fn=lambda data: data.statistics.total_searching_time is not None, - value_fn=lambda data: data.statistics.total_searching_time, + value_fn=attrgetter("statistics.total_searching_time"), ), AutomowerSensorEntityDescription( key="number_of_charging_cycles", @@ -345,7 +343,7 @@ MOWER_SENSOR_TYPES: tuple[AutomowerSensorEntityDescription, ...] = ( entity_category=EntityCategory.DIAGNOSTIC, state_class=SensorStateClass.TOTAL, exists_fn=lambda data: data.statistics.number_of_charging_cycles is not None, - value_fn=lambda data: data.statistics.number_of_charging_cycles, + value_fn=attrgetter("statistics.number_of_charging_cycles"), ), AutomowerSensorEntityDescription( key="number_of_collisions", @@ -353,7 +351,7 @@ MOWER_SENSOR_TYPES: tuple[AutomowerSensorEntityDescription, ...] = ( entity_category=EntityCategory.DIAGNOSTIC, state_class=SensorStateClass.TOTAL, exists_fn=lambda data: data.statistics.number_of_collisions is not None, - value_fn=lambda data: data.statistics.number_of_collisions, + value_fn=attrgetter("statistics.number_of_collisions"), ), AutomowerSensorEntityDescription( key="total_drive_distance", @@ -364,16 +362,13 @@ MOWER_SENSOR_TYPES: tuple[AutomowerSensorEntityDescription, ...] = ( native_unit_of_measurement=UnitOfLength.METERS, suggested_unit_of_measurement=UnitOfLength.KILOMETERS, exists_fn=lambda data: data.statistics.total_drive_distance is not None, - value_fn=lambda data: data.statistics.total_drive_distance, + value_fn=attrgetter("statistics.total_drive_distance"), ), AutomowerSensorEntityDescription( key="next_start_timestamp", translation_key="next_start_timestamp", device_class=SensorDeviceClass.TIMESTAMP, - value_fn=lambda data: naive_to_aware( - data.planner.next_start_datetime_naive, - ZoneInfo(str(dt_util.DEFAULT_TIME_ZONE)), - ), + value_fn=attrgetter("planner.next_start_datetime"), ), AutomowerSensorEntityDescription( key="error", @@ -387,7 +382,7 @@ MOWER_SENSOR_TYPES: tuple[AutomowerSensorEntityDescription, ...] = ( translation_key="restricted_reason", device_class=SensorDeviceClass.ENUM, option_fn=lambda data: RESTRICTED_REASONS, - value_fn=lambda data: data.planner.restricted_reason.lower(), + value_fn=attrgetter("planner.restricted_reason"), ), AutomowerSensorEntityDescription( key="work_area", @@ -417,17 +412,14 @@ WORK_AREA_SENSOR_TYPES: tuple[WorkAreaSensorEntityDescription, ...] = ( exists_fn=lambda data: data.progress is not None, state_class=SensorStateClass.MEASUREMENT, native_unit_of_measurement=PERCENTAGE, - value_fn=lambda data: data.progress, + value_fn=attrgetter("progress"), ), WorkAreaSensorEntityDescription( key="last_time_completed", translation_key_fn=_work_area_translation_key, - exists_fn=lambda data: data.last_time_completed_naive is not None, + exists_fn=lambda data: data.last_time_completed is not None, device_class=SensorDeviceClass.TIMESTAMP, - value_fn=lambda data: naive_to_aware( - data.last_time_completed_naive, - ZoneInfo(str(dt_util.DEFAULT_TIME_ZONE)), - ), + value_fn=attrgetter("last_time_completed"), ), ) diff --git a/requirements_all.txt b/requirements_all.txt index 2d88b3c4f8733b7f5f7789b3a0f709d67c7ed5a5..1d4dc0476a577916a75ce9ca83a7a02ed5509040 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -198,7 +198,7 @@ aioaseko==1.0.0 aioasuswrt==1.4.0 # homeassistant.components.husqvarna_automower -aioautomower==2024.10.0 +aioautomower==2024.10.3 # homeassistant.components.azure_devops aioazuredevops==2.2.1 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index 883c64004671a903c59bad893e80e132b4ff6a15..e6bba8af2e397de7e335ad0ed6ab3a436b4a9ea4 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -186,7 +186,7 @@ aioaseko==1.0.0 aioasuswrt==1.4.0 # homeassistant.components.husqvarna_automower -aioautomower==2024.10.0 +aioautomower==2024.10.3 # homeassistant.components.azure_devops aioazuredevops==2.2.1 diff --git a/tests/components/husqvarna_automower/conftest.py b/tests/components/husqvarna_automower/conftest.py index dbb8f3b4c724b3cec09edf731d94e6fcadeeedd2..2814e1558d13749757adeaae31f67b4b5f985f14 100644 --- a/tests/components/husqvarna_automower/conftest.py +++ b/tests/components/husqvarna_automower/conftest.py @@ -4,6 +4,7 @@ from collections.abc import Generator import time from unittest.mock import AsyncMock, patch +from aioautomower.model import MowerAttributes from aioautomower.session import AutomowerSession, _MowerCommands from aioautomower.utils import mower_list_to_dictionary_dataclass from aiohttp import ClientWebSocketResponse @@ -16,6 +17,7 @@ from homeassistant.components.application_credentials import ( from homeassistant.components.husqvarna_automower.const import DOMAIN from homeassistant.core import HomeAssistant from homeassistant.setup import async_setup_component +from homeassistant.util import dt as dt_util from .const import CLIENT_ID, CLIENT_SECRET, USER_ID @@ -40,6 +42,21 @@ def mock_scope() -> str: return "iam:read amc:api" +@pytest.fixture(name="mower_time_zone") +async def mock_time_zone(hass: HomeAssistant) -> dict[str, MowerAttributes]: + """Fixture to set correct scope for the token.""" + return await dt_util.async_get_time_zone("Europe/Berlin") + + +@pytest.fixture(name="values") +def mock_values(mower_time_zone) -> dict[str, MowerAttributes]: + """Fixture to set correct scope for the token.""" + return mower_list_to_dictionary_dataclass( + load_json_value_fixture("mower.json", DOMAIN), + mower_time_zone, + ) + + @pytest.fixture def mock_config_entry(jwt: str, expires_at: int, scope: str) -> MockConfigEntry: """Return the default mocked config entry.""" @@ -81,17 +98,13 @@ async def setup_credentials(hass: HomeAssistant) -> None: @pytest.fixture -def mock_automower_client() -> Generator[AsyncMock]: +def mock_automower_client(values) -> Generator[AsyncMock]: """Mock a Husqvarna Automower client.""" - mower_dict = mower_list_to_dictionary_dataclass( - load_json_value_fixture("mower.json", DOMAIN) - ) - mock = AsyncMock(spec=AutomowerSession) mock.auth = AsyncMock(side_effect=ClientWebSocketResponse) mock.commands = AsyncMock(spec_set=_MowerCommands) - mock.get_status.return_value = mower_dict + mock.get_status.return_value = values with patch( "homeassistant.components.husqvarna_automower.AutomowerSession", diff --git a/tests/components/husqvarna_automower/snapshots/test_calendar.ambr b/tests/components/husqvarna_automower/snapshots/test_calendar.ambr index 1924b9ad42e39354041e04c01e76fad4b30a912d..7cd8c68b624d6c4e322e9b1f4a5bc4eec7020d22 100644 --- a/tests/components/husqvarna_automower/snapshots/test_calendar.ambr +++ b/tests/components/husqvarna_automower/snapshots/test_calendar.ambr @@ -68,6 +68,11 @@ 'start': '2023-06-10T01:00:00+02:00', 'summary': 'Back lawn schedule 2', }), + dict({ + 'end': '2023-06-12T09:00:00+02:00', + 'start': '2023-06-12T01:00:00+02:00', + 'summary': 'Back lawn schedule 2', + }), ]), }), 'calendar.test_mower_2': dict({ diff --git a/tests/components/husqvarna_automower/snapshots/test_diagnostics.ambr b/tests/components/husqvarna_automower/snapshots/test_diagnostics.ambr index ab9e81985c9c112ec117beda7de3e0086f3cc2d2..ee9b75107702e08b095c5f6c78fa01b54db4e8cf 100644 --- a/tests/components/husqvarna_automower/snapshots/test_diagnostics.ambr +++ b/tests/components/husqvarna_automower/snapshots/test_diagnostics.ambr @@ -68,31 +68,33 @@ 'status_dateteime': '2023-06-05T00:00:00+00:00', }), 'mower': dict({ - 'activity': 'PARKED_IN_CS', + 'activity': 'parked_in_cs', 'error_code': 0, + 'error_datetime': None, 'error_datetime_naive': None, 'error_key': None, 'error_timestamp': 0, - 'inactive_reason': 'NONE', + 'inactive_reason': 'none', 'is_error_confirmable': False, - 'mode': 'MAIN_AREA', - 'state': 'RESTRICTED', + 'mode': 'main_area', + 'state': 'restricted', 'work_area_id': 123456, 'work_area_name': 'Front lawn', }), 'planner': dict({ 'next_start': 1685991600000, + 'next_start_datetime': '2023-06-05T19:00:00+02:00', 'next_start_datetime_naive': '2023-06-05T19:00:00', 'override': dict({ - 'action': 'NOT_ACTIVE', + 'action': 'not_active', }), - 'restricted_reason': 'WEEK_SCHEDULE', + 'restricted_reason': 'week_schedule', }), 'positions': '**REDACTED**', 'settings': dict({ 'cutting_height': 4, 'headlight': dict({ - 'mode': 'EVENING_ONLY', + 'mode': 'evening_only', }), }), 'statistics': dict({ @@ -138,6 +140,7 @@ '0': dict({ 'cutting_height': 50, 'enabled': False, + 'last_time_completed': '2024-08-12T05:07:49+02:00', 'last_time_completed_naive': '2024-08-12T05:07:49', 'name': 'my_lawn', 'progress': 20, @@ -145,6 +148,7 @@ '123456': dict({ 'cutting_height': 50, 'enabled': True, + 'last_time_completed': '2024-08-12T07:54:29+02:00', 'last_time_completed_naive': '2024-08-12T07:54:29', 'name': 'Front lawn', 'progress': 40, @@ -152,6 +156,7 @@ '654321': dict({ 'cutting_height': 25, 'enabled': True, + 'last_time_completed': None, 'last_time_completed_naive': None, 'name': 'Back lawn', 'progress': None, @@ -165,7 +170,7 @@ 'auth_implementation': 'husqvarna_automower', 'token': dict({ 'access_token': '**REDACTED**', - 'expires_at': 1685926800.0, + 'expires_at': 1685919600.0, 'expires_in': 86399, 'provider': 'husqvarna', 'refresh_token': '**REDACTED**', diff --git a/tests/components/husqvarna_automower/snapshots/test_sensor.ambr b/tests/components/husqvarna_automower/snapshots/test_sensor.ambr index dfc1d41775fa178926aa9fb40141fe3cdb4b2316..d57a829a997007c58d21d7d52379d274a79e0523 100644 --- a/tests/components/husqvarna_automower/snapshots/test_sensor.ambr +++ b/tests/components/husqvarna_automower/snapshots/test_sensor.ambr @@ -552,11 +552,11 @@ 'area_id': None, 'capabilities': dict({ 'options': list([ - 'main_area', - 'demo', - 'secondary_area', - 'home', - 'unknown', + <MowerModes.MAIN_AREA: 'main_area'>, + <MowerModes.DEMO: 'demo'>, + <MowerModes.SECONDARY_AREA: 'secondary_area'>, + <MowerModes.HOME: 'home'>, + <MowerModes.UNKNOWN: 'unknown'>, ]), }), 'config_entry_id': <ANY>, @@ -592,11 +592,11 @@ 'device_class': 'enum', 'friendly_name': 'Test Mower 1 Mode', 'options': list([ - 'main_area', - 'demo', - 'secondary_area', - 'home', - 'unknown', + <MowerModes.MAIN_AREA: 'main_area'>, + <MowerModes.DEMO: 'demo'>, + <MowerModes.SECONDARY_AREA: 'secondary_area'>, + <MowerModes.HOME: 'home'>, + <MowerModes.UNKNOWN: 'unknown'>, ]), }), 'context': <ANY>, @@ -856,16 +856,16 @@ 'area_id': None, 'capabilities': dict({ 'options': list([ - 'all_work_areas_completed', - 'daily_limit', - 'external', - 'fota', - 'frost', - 'none', - 'not_applicable', - 'park_override', - 'sensor', - 'week_schedule', + <RestrictedReasons.ALL_WORK_AREAS_COMPLETED: 'all_work_areas_completed'>, + <RestrictedReasons.DAILY_LIMIT: 'daily_limit'>, + <RestrictedReasons.EXTERNAL: 'external'>, + <RestrictedReasons.FOTA: 'fota'>, + <RestrictedReasons.FROST: 'frost'>, + <RestrictedReasons.NONE: 'none'>, + <RestrictedReasons.NOT_APPLICABLE: 'not_applicable'>, + <RestrictedReasons.PARK_OVERRIDE: 'park_override'>, + <RestrictedReasons.SENSOR: 'sensor'>, + <RestrictedReasons.WEEK_SCHEDULE: 'week_schedule'>, ]), }), 'config_entry_id': <ANY>, @@ -901,16 +901,16 @@ 'device_class': 'enum', 'friendly_name': 'Test Mower 1 Restricted reason', 'options': list([ - 'all_work_areas_completed', - 'daily_limit', - 'external', - 'fota', - 'frost', - 'none', - 'not_applicable', - 'park_override', - 'sensor', - 'week_schedule', + <RestrictedReasons.ALL_WORK_AREAS_COMPLETED: 'all_work_areas_completed'>, + <RestrictedReasons.DAILY_LIMIT: 'daily_limit'>, + <RestrictedReasons.EXTERNAL: 'external'>, + <RestrictedReasons.FOTA: 'fota'>, + <RestrictedReasons.FROST: 'frost'>, + <RestrictedReasons.NONE: 'none'>, + <RestrictedReasons.NOT_APPLICABLE: 'not_applicable'>, + <RestrictedReasons.PARK_OVERRIDE: 'park_override'>, + <RestrictedReasons.SENSOR: 'sensor'>, + <RestrictedReasons.WEEK_SCHEDULE: 'week_schedule'>, ]), }), 'context': <ANY>, @@ -1658,11 +1658,11 @@ 'area_id': None, 'capabilities': dict({ 'options': list([ - 'main_area', - 'demo', - 'secondary_area', - 'home', - 'unknown', + <MowerModes.MAIN_AREA: 'main_area'>, + <MowerModes.DEMO: 'demo'>, + <MowerModes.SECONDARY_AREA: 'secondary_area'>, + <MowerModes.HOME: 'home'>, + <MowerModes.UNKNOWN: 'unknown'>, ]), }), 'config_entry_id': <ANY>, @@ -1698,11 +1698,11 @@ 'device_class': 'enum', 'friendly_name': 'Test Mower 2 Mode', 'options': list([ - 'main_area', - 'demo', - 'secondary_area', - 'home', - 'unknown', + <MowerModes.MAIN_AREA: 'main_area'>, + <MowerModes.DEMO: 'demo'>, + <MowerModes.SECONDARY_AREA: 'secondary_area'>, + <MowerModes.HOME: 'home'>, + <MowerModes.UNKNOWN: 'unknown'>, ]), }), 'context': <ANY>, @@ -1767,16 +1767,16 @@ 'area_id': None, 'capabilities': dict({ 'options': list([ - 'all_work_areas_completed', - 'daily_limit', - 'external', - 'fota', - 'frost', - 'none', - 'not_applicable', - 'park_override', - 'sensor', - 'week_schedule', + <RestrictedReasons.ALL_WORK_AREAS_COMPLETED: 'all_work_areas_completed'>, + <RestrictedReasons.DAILY_LIMIT: 'daily_limit'>, + <RestrictedReasons.EXTERNAL: 'external'>, + <RestrictedReasons.FOTA: 'fota'>, + <RestrictedReasons.FROST: 'frost'>, + <RestrictedReasons.NONE: 'none'>, + <RestrictedReasons.NOT_APPLICABLE: 'not_applicable'>, + <RestrictedReasons.PARK_OVERRIDE: 'park_override'>, + <RestrictedReasons.SENSOR: 'sensor'>, + <RestrictedReasons.WEEK_SCHEDULE: 'week_schedule'>, ]), }), 'config_entry_id': <ANY>, @@ -1812,16 +1812,16 @@ 'device_class': 'enum', 'friendly_name': 'Test Mower 2 Restricted reason', 'options': list([ - 'all_work_areas_completed', - 'daily_limit', - 'external', - 'fota', - 'frost', - 'none', - 'not_applicable', - 'park_override', - 'sensor', - 'week_schedule', + <RestrictedReasons.ALL_WORK_AREAS_COMPLETED: 'all_work_areas_completed'>, + <RestrictedReasons.DAILY_LIMIT: 'daily_limit'>, + <RestrictedReasons.EXTERNAL: 'external'>, + <RestrictedReasons.FOTA: 'fota'>, + <RestrictedReasons.FROST: 'frost'>, + <RestrictedReasons.NONE: 'none'>, + <RestrictedReasons.NOT_APPLICABLE: 'not_applicable'>, + <RestrictedReasons.PARK_OVERRIDE: 'park_override'>, + <RestrictedReasons.SENSOR: 'sensor'>, + <RestrictedReasons.WEEK_SCHEDULE: 'week_schedule'>, ]), }), 'context': <ANY>, diff --git a/tests/components/husqvarna_automower/test_binary_sensor.py b/tests/components/husqvarna_automower/test_binary_sensor.py index fceaeee2321044abb5df66c730621085acd4cb4a..858dc03b93f944b9b12d85bc21833de90008e2a5 100644 --- a/tests/components/husqvarna_automower/test_binary_sensor.py +++ b/tests/components/husqvarna_automower/test_binary_sensor.py @@ -2,12 +2,10 @@ from unittest.mock import AsyncMock, patch -from aioautomower.model import MowerActivities -from aioautomower.utils import mower_list_to_dictionary_dataclass +from aioautomower.model import MowerActivities, MowerAttributes from freezegun.api import FrozenDateTimeFactory from syrupy import SnapshotAssertion -from homeassistant.components.husqvarna_automower.const import DOMAIN from homeassistant.components.husqvarna_automower.coordinator import SCAN_INTERVAL from homeassistant.const import Platform from homeassistant.core import HomeAssistant @@ -16,12 +14,7 @@ from homeassistant.helpers import entity_registry as er from . import setup_integration from .const import TEST_MOWER_ID -from tests.common import ( - MockConfigEntry, - async_fire_time_changed, - load_json_value_fixture, - snapshot_platform, -) +from tests.common import MockConfigEntry, async_fire_time_changed, snapshot_platform async def test_binary_sensor_states( @@ -29,11 +22,9 @@ async def test_binary_sensor_states( mock_automower_client: AsyncMock, mock_config_entry: MockConfigEntry, freezer: FrozenDateTimeFactory, + values: dict[str, MowerAttributes], ) -> None: """Test binary sensor states.""" - values = mower_list_to_dictionary_dataclass( - load_json_value_fixture("mower.json", DOMAIN) - ) await setup_integration(hass, mock_config_entry) state = hass.states.get("binary_sensor.test_mower_1_charging") assert state is not None diff --git a/tests/components/husqvarna_automower/test_button.py b/tests/components/husqvarna_automower/test_button.py index bf76fcbb5988b2b9fa7d151f0f692792bf4b4edb..25fa64b531fce3b5546c60611fba1d263a1b1f5c 100644 --- a/tests/components/husqvarna_automower/test_button.py +++ b/tests/components/husqvarna_automower/test_button.py @@ -2,16 +2,14 @@ import datetime from unittest.mock import AsyncMock, patch -import zoneinfo from aioautomower.exceptions import ApiException -from aioautomower.utils import mower_list_to_dictionary_dataclass +from aioautomower.model import MowerAttributes from freezegun.api import FrozenDateTimeFactory import pytest from syrupy import SnapshotAssertion from homeassistant.components.button import DOMAIN as BUTTON_DOMAIN, SERVICE_PRESS -from homeassistant.components.husqvarna_automower.const import DOMAIN from homeassistant.components.husqvarna_automower.coordinator import SCAN_INTERVAL from homeassistant.const import ( ATTR_ENTITY_ID, @@ -26,12 +24,7 @@ from homeassistant.helpers import entity_registry as er from . import setup_integration from .const import TEST_MOWER_ID -from tests.common import ( - MockConfigEntry, - async_fire_time_changed, - load_json_value_fixture, - snapshot_platform, -) +from tests.common import MockConfigEntry, async_fire_time_changed, snapshot_platform @pytest.mark.freeze_time(datetime.datetime(2023, 6, 5, tzinfo=datetime.UTC)) @@ -40,6 +33,7 @@ async def test_button_states_and_commands( mock_automower_client: AsyncMock, mock_config_entry: MockConfigEntry, freezer: FrozenDateTimeFactory, + values: dict[str, MowerAttributes], ) -> None: """Test error confirm button command.""" entity_id = "button.test_mower_1_confirm_error" @@ -48,9 +42,6 @@ async def test_button_states_and_commands( assert state.name == "Test Mower 1 Confirm error" assert state.state == STATE_UNAVAILABLE - values = mower_list_to_dictionary_dataclass( - load_json_value_fixture("mower.json", DOMAIN) - ) values[TEST_MOWER_ID].mower.is_error_confirmable = None mock_automower_client.get_status.return_value = values freezer.tick(SCAN_INTERVAL) @@ -99,6 +90,7 @@ async def test_sync_clock( mock_automower_client: AsyncMock, mock_config_entry: MockConfigEntry, freezer: FrozenDateTimeFactory, + values: dict[str, MowerAttributes], ) -> None: """Test sync clock button command.""" entity_id = "button.test_mower_1_sync_clock" @@ -106,9 +98,6 @@ async def test_sync_clock( state = hass.states.get(entity_id) assert state.name == "Test Mower 1 Sync clock" - values = mower_list_to_dictionary_dataclass( - load_json_value_fixture("mower.json", DOMAIN) - ) mock_automower_client.get_status.return_value = values await hass.services.async_call( @@ -118,12 +107,7 @@ async def test_sync_clock( blocking=True, ) mocked_method = mock_automower_client.commands.set_datetime - # datetime(2024, 2, 29, 11, tzinfo=datetime.UTC) is in local time of the tests - # datetime(2024, 2, 29, 12, tzinfo=zoneinfo.ZoneInfo(key='Europe/Berlin')) - mocked_method.assert_called_once_with( - TEST_MOWER_ID, - datetime.datetime(2024, 2, 29, 12, tzinfo=zoneinfo.ZoneInfo("Europe/Berlin")), - ) + mocked_method.assert_called_once_with(TEST_MOWER_ID) await hass.async_block_till_done() state = hass.states.get(entity_id) assert state.state == "2024-02-29T11:00:00+00:00" diff --git a/tests/components/husqvarna_automower/test_calendar.py b/tests/components/husqvarna_automower/test_calendar.py index 0e914e272fb20019f110d2fb49537d6f86fe1523..8138b8c139b6b9a7d86d4bc522c8b29c1115c440 100644 --- a/tests/components/husqvarna_automower/test_calendar.py +++ b/tests/components/husqvarna_automower/test_calendar.py @@ -6,6 +6,7 @@ from http import HTTPStatus from typing import Any from unittest.mock import AsyncMock import urllib +import zoneinfo from aioautomower.utils import mower_list_to_dictionary_dataclass from freezegun.api import FrozenDateTimeFactory @@ -93,12 +94,16 @@ async def test_empty_calendar( mock_config_entry: MockConfigEntry, freezer: FrozenDateTimeFactory, get_events: GetEventsFn, + mower_time_zone: zoneinfo.ZoneInfo, ) -> None: """State if there is no schedule set.""" await setup_integration(hass, mock_config_entry) json_values = load_json_value_fixture("mower.json", DOMAIN) json_values["data"][0]["attributes"]["calendar"]["tasks"] = [] - values = mower_list_to_dictionary_dataclass(json_values) + values = mower_list_to_dictionary_dataclass( + json_values, + mower_time_zone, + ) mock_automower_client.get_status.return_value = values freezer.tick(SCAN_INTERVAL) async_fire_time_changed(hass) diff --git a/tests/components/husqvarna_automower/test_diagnostics.py b/tests/components/husqvarna_automower/test_diagnostics.py index f8dc89af6f0d1557a25cd7a0d85dc3bf952aeaf4..2b47bff25a43ebad414b8713b190505ca5e16f17 100644 --- a/tests/components/husqvarna_automower/test_diagnostics.py +++ b/tests/components/husqvarna_automower/test_diagnostics.py @@ -2,6 +2,7 @@ import datetime from unittest.mock import AsyncMock +import zoneinfo import pytest from syrupy.assertion import SnapshotAssertion @@ -21,7 +22,9 @@ from tests.components.diagnostics import ( from tests.typing import ClientSessionGenerator -@pytest.mark.freeze_time(datetime.datetime(2023, 6, 5, tzinfo=datetime.UTC)) +@pytest.mark.freeze_time( + datetime.datetime(2023, 6, 5, tzinfo=zoneinfo.ZoneInfo("Europe/Berlin")) +) async def test_entry_diagnostics( hass: HomeAssistant, hass_client: ClientSessionGenerator, @@ -40,7 +43,9 @@ async def test_entry_diagnostics( assert result == snapshot(exclude=props("created_at", "modified_at")) -@pytest.mark.freeze_time(datetime.datetime(2023, 6, 5, tzinfo=datetime.UTC)) +@pytest.mark.freeze_time( + datetime.datetime(2023, 6, 5, tzinfo=zoneinfo.ZoneInfo("Europe/Berlin")) +) async def test_device_diagnostics( hass: HomeAssistant, hass_client: ClientSessionGenerator, diff --git a/tests/components/husqvarna_automower/test_init.py b/tests/components/husqvarna_automower/test_init.py index b7cc6f883f4075495e1e753fcb56fb5f215f80c1..daebb743c2fbc1abaee6472239ca546bd9f8d7a2 100644 --- a/tests/components/husqvarna_automower/test_init.py +++ b/tests/components/husqvarna_automower/test_init.py @@ -10,7 +10,7 @@ from aioautomower.exceptions import ( AuthException, HusqvarnaWSServerHandshakeError, ) -from aioautomower.utils import mower_list_to_dictionary_dataclass +from aioautomower.model import MowerAttributes from freezegun.api import FrozenDateTimeFactory import pytest from syrupy.assertion import SnapshotAssertion @@ -23,11 +23,7 @@ from homeassistant.helpers import device_registry as dr, entity_registry as er from . import setup_integration from .const import TEST_MOWER_ID -from tests.common import ( - MockConfigEntry, - async_fire_time_changed, - load_json_value_fixture, -) +from tests.common import MockConfigEntry, async_fire_time_changed from tests.test_util.aiohttp import AiohttpClientMocker @@ -172,12 +168,10 @@ async def test_workarea_deleted( mock_automower_client: AsyncMock, mock_config_entry: MockConfigEntry, entity_registry: er.EntityRegistry, + values: dict[str, MowerAttributes], ) -> None: """Test if work area is deleted after removed.""" - values = mower_list_to_dictionary_dataclass( - load_json_value_fixture("mower.json", DOMAIN) - ) await setup_integration(hass, mock_config_entry) current_entries = len( er.async_entries_for_config_entry(entity_registry, mock_config_entry.entry_id) @@ -198,6 +192,7 @@ async def test_coordinator_automatic_registry_cleanup( mock_config_entry: MockConfigEntry, device_registry: dr.DeviceRegistry, entity_registry: er.EntityRegistry, + values: dict[str, MowerAttributes], ) -> None: """Test automatic registry cleanup.""" await setup_integration(hass, mock_config_entry) @@ -211,9 +206,6 @@ async def test_coordinator_automatic_registry_cleanup( dr.async_entries_for_config_entry(device_registry, entry.entry_id) ) - values = mower_list_to_dictionary_dataclass( - load_json_value_fixture("mower.json", DOMAIN) - ) values.pop(TEST_MOWER_ID) mock_automower_client.get_status.return_value = values await hass.config_entries.async_reload(mock_config_entry.entry_id) diff --git a/tests/components/husqvarna_automower/test_lawn_mower.py b/tests/components/husqvarna_automower/test_lawn_mower.py index 552a3a6a9cf176a33f977b1d8737df2eb00c0e43..3aca509e865048cb8e30b1a1a4adbca78b5a1678 100644 --- a/tests/components/husqvarna_automower/test_lawn_mower.py +++ b/tests/components/husqvarna_automower/test_lawn_mower.py @@ -4,7 +4,7 @@ from datetime import timedelta from unittest.mock import AsyncMock from aioautomower.exceptions import ApiException -from aioautomower.utils import mower_list_to_dictionary_dataclass +from aioautomower.model import MowerActivities, MowerAttributes, MowerStates from freezegun.api import FrozenDateTimeFactory import pytest from voluptuous.error import MultipleInvalid @@ -18,11 +18,7 @@ from homeassistant.exceptions import HomeAssistantError, ServiceValidationError from . import setup_integration from .const import TEST_MOWER_ID -from tests.common import ( - MockConfigEntry, - async_fire_time_changed, - load_json_value_fixture, -) +from tests.common import MockConfigEntry, async_fire_time_changed async def test_lawn_mower_states( @@ -30,21 +26,23 @@ async def test_lawn_mower_states( mock_automower_client: AsyncMock, mock_config_entry: MockConfigEntry, freezer: FrozenDateTimeFactory, + values: dict[str, MowerAttributes], ) -> None: """Test lawn_mower state.""" - values = mower_list_to_dictionary_dataclass( - load_json_value_fixture("mower.json", DOMAIN) - ) await setup_integration(hass, mock_config_entry) state = hass.states.get("lawn_mower.test_mower_1") assert state is not None assert state.state == LawnMowerActivity.DOCKED for activity, state, expected_state in ( - ("UNKNOWN", "PAUSED", LawnMowerActivity.PAUSED), - ("MOWING", "NOT_APPLICABLE", LawnMowerActivity.MOWING), - ("NOT_APPLICABLE", "ERROR", LawnMowerActivity.ERROR), - ("GOING_HOME", "IN_OPERATION", LawnMowerActivity.RETURNING), + (MowerActivities.UNKNOWN, MowerStates.PAUSED, LawnMowerActivity.PAUSED), + (MowerActivities.MOWING, MowerStates.NOT_APPLICABLE, LawnMowerActivity.MOWING), + (MowerActivities.NOT_APPLICABLE, MowerStates.ERROR, LawnMowerActivity.ERROR), + ( + MowerActivities.GOING_HOME, + MowerStates.IN_OPERATION, + LawnMowerActivity.RETURNING, + ), ): values[TEST_MOWER_ID].mower.activity = activity values[TEST_MOWER_ID].mower.state = state @@ -253,12 +251,10 @@ async def test_lawn_mower_wrong_service_commands( mock_automower_client: AsyncMock, mock_config_entry: MockConfigEntry, freezer: FrozenDateTimeFactory, + values: dict[str, MowerAttributes], ) -> None: """Test lawn_mower commands.""" await setup_integration(hass, mock_config_entry) - values = mower_list_to_dictionary_dataclass( - load_json_value_fixture("mower.json", DOMAIN) - ) values[TEST_MOWER_ID].capabilities.work_areas = mower_support_wa mock_automower_client.get_status.return_value = values freezer.tick(SCAN_INTERVAL) diff --git a/tests/components/husqvarna_automower/test_number.py b/tests/components/husqvarna_automower/test_number.py index b7ff84e14e6dacade7fa2fdda397acb4c6bdb3d4..e1f232e7b5ce530532cf7aebe1ff2030e8fd5a6e 100644 --- a/tests/components/husqvarna_automower/test_number.py +++ b/tests/components/husqvarna_automower/test_number.py @@ -4,15 +4,12 @@ from datetime import timedelta from unittest.mock import AsyncMock, patch from aioautomower.exceptions import ApiException -from aioautomower.utils import mower_list_to_dictionary_dataclass +from aioautomower.model import MowerAttributes from freezegun.api import FrozenDateTimeFactory import pytest from syrupy import SnapshotAssertion -from homeassistant.components.husqvarna_automower.const import ( - DOMAIN, - EXECUTION_TIME_DELAY, -) +from homeassistant.components.husqvarna_automower.const import EXECUTION_TIME_DELAY from homeassistant.const import Platform from homeassistant.core import HomeAssistant from homeassistant.exceptions import HomeAssistantError @@ -21,12 +18,7 @@ from homeassistant.helpers import entity_registry as er from . import setup_integration from .const import TEST_MOWER_ID -from tests.common import ( - MockConfigEntry, - async_fire_time_changed, - load_json_value_fixture, - snapshot_platform, -) +from tests.common import MockConfigEntry, async_fire_time_changed, snapshot_platform @pytest.mark.usefixtures("entity_registry_enabled_by_default") @@ -68,13 +60,11 @@ async def test_number_workarea_commands( mock_automower_client: AsyncMock, mock_config_entry: MockConfigEntry, freezer: FrozenDateTimeFactory, + values: dict[str, MowerAttributes], ) -> None: """Test number commands.""" entity_id = "number.test_mower_1_front_lawn_cutting_height" await setup_integration(hass, mock_config_entry) - values = mower_list_to_dictionary_dataclass( - load_json_value_fixture("mower.json", DOMAIN) - ) values[TEST_MOWER_ID].work_areas[123456].cutting_height = 75 mock_automower_client.get_status.return_value = values mocked_method = AsyncMock() diff --git a/tests/components/husqvarna_automower/test_select.py b/tests/components/husqvarna_automower/test_select.py index e885a4d3487927210cac15d89c84471275543060..18d1b0ed21ff619eee5b72603d3702f7215f8b50 100644 --- a/tests/components/husqvarna_automower/test_select.py +++ b/tests/components/husqvarna_automower/test_select.py @@ -3,12 +3,10 @@ from unittest.mock import AsyncMock from aioautomower.exceptions import ApiException -from aioautomower.model import HeadlightModes -from aioautomower.utils import mower_list_to_dictionary_dataclass +from aioautomower.model import HeadlightModes, MowerAttributes from freezegun.api import FrozenDateTimeFactory import pytest -from homeassistant.components.husqvarna_automower.const import DOMAIN from homeassistant.components.husqvarna_automower.coordinator import SCAN_INTERVAL from homeassistant.core import HomeAssistant from homeassistant.exceptions import HomeAssistantError @@ -16,11 +14,7 @@ from homeassistant.exceptions import HomeAssistantError from . import setup_integration from .const import TEST_MOWER_ID -from tests.common import ( - MockConfigEntry, - async_fire_time_changed, - load_json_value_fixture, -) +from tests.common import MockConfigEntry, async_fire_time_changed async def test_select_states( @@ -28,11 +22,9 @@ async def test_select_states( mock_automower_client: AsyncMock, mock_config_entry: MockConfigEntry, freezer: FrozenDateTimeFactory, + values: dict[str, MowerAttributes], ) -> None: """Test states of headlight mode select.""" - values = mower_list_to_dictionary_dataclass( - load_json_value_fixture("mower.json", DOMAIN) - ) await setup_integration(hass, mock_config_entry) state = hass.states.get("select.test_mower_1_headlight_mode") assert state is not None diff --git a/tests/components/husqvarna_automower/test_sensor.py b/tests/components/husqvarna_automower/test_sensor.py index 39bff398da67303899a69aea3a7cdbbbeb63aa4d..06fcc30e40c2bd63f82c0b7c84db06e8b0efbf94 100644 --- a/tests/components/husqvarna_automower/test_sensor.py +++ b/tests/components/husqvarna_automower/test_sensor.py @@ -1,14 +1,14 @@ """Tests for sensor platform.""" +import datetime from unittest.mock import AsyncMock, patch +import zoneinfo -from aioautomower.model import MowerModes, MowerStates -from aioautomower.utils import mower_list_to_dictionary_dataclass +from aioautomower.model import MowerAttributes, MowerModes, MowerStates from freezegun.api import FrozenDateTimeFactory import pytest from syrupy import SnapshotAssertion -from homeassistant.components.husqvarna_automower.const import DOMAIN from homeassistant.components.husqvarna_automower.coordinator import SCAN_INTERVAL from homeassistant.const import STATE_UNKNOWN, Platform from homeassistant.core import HomeAssistant @@ -17,12 +17,7 @@ from homeassistant.helpers import entity_registry as er from . import setup_integration from .const import TEST_MOWER_ID -from tests.common import ( - MockConfigEntry, - async_fire_time_changed, - load_json_value_fixture, - snapshot_platform, -) +from tests.common import MockConfigEntry, async_fire_time_changed, snapshot_platform async def test_sensor_unknown_states( @@ -30,11 +25,9 @@ async def test_sensor_unknown_states( mock_automower_client: AsyncMock, mock_config_entry: MockConfigEntry, freezer: FrozenDateTimeFactory, + values: dict[str, MowerAttributes], ) -> None: """Test a sensor which returns unknown.""" - values = mower_list_to_dictionary_dataclass( - load_json_value_fixture("mower.json", DOMAIN) - ) await setup_integration(hass, mock_config_entry) state = hass.states.get("sensor.test_mower_1_mode") assert state is not None @@ -63,11 +56,15 @@ async def test_cutting_blade_usage_time_sensor( assert state.state == "0.034" +@pytest.mark.freeze_time( + datetime.datetime(2023, 6, 5, tzinfo=zoneinfo.ZoneInfo("Europe/Berlin")) +) async def test_next_start_sensor( hass: HomeAssistant, mock_automower_client: AsyncMock, mock_config_entry: MockConfigEntry, freezer: FrozenDateTimeFactory, + values: dict[str, MowerAttributes], ) -> None: """Test if this sensor is only added, if data is available.""" await setup_integration(hass, mock_config_entry) @@ -75,10 +72,7 @@ async def test_next_start_sensor( assert state is not None assert state.state == "2023-06-05T17:00:00+00:00" - values = mower_list_to_dictionary_dataclass( - load_json_value_fixture("mower.json", DOMAIN) - ) - values[TEST_MOWER_ID].planner.next_start_datetime_naive = None + values[TEST_MOWER_ID].planner.next_start_datetime = None mock_automower_client.get_status.return_value = values freezer.tick(SCAN_INTERVAL) async_fire_time_changed(hass) @@ -92,6 +86,7 @@ async def test_work_area_sensor( mock_automower_client: AsyncMock, mock_config_entry: MockConfigEntry, freezer: FrozenDateTimeFactory, + values: dict[str, MowerAttributes], ) -> None: """Test the work area sensor.""" await setup_integration(hass, mock_config_entry) @@ -99,9 +94,6 @@ async def test_work_area_sensor( assert state is not None assert state.state == "Front lawn" - values = mower_list_to_dictionary_dataclass( - load_json_value_fixture("mower.json", DOMAIN) - ) values[TEST_MOWER_ID].mower.work_area_id = None mock_automower_client.get_status.return_value = values freezer.tick(SCAN_INTERVAL) @@ -137,13 +129,10 @@ async def test_statistics_not_available( mock_automower_client: AsyncMock, mock_config_entry: MockConfigEntry, sensor_to_test: str, + values: dict[str, MowerAttributes], ) -> None: """Test if this sensor is only added, if data is available.""" - values = mower_list_to_dictionary_dataclass( - load_json_value_fixture("mower.json", DOMAIN) - ) - delattr(values[TEST_MOWER_ID].statistics, sensor_to_test) mock_automower_client.get_status.return_value = values await setup_integration(hass, mock_config_entry) @@ -156,11 +145,9 @@ async def test_error_sensor( mock_automower_client: AsyncMock, mock_config_entry: MockConfigEntry, freezer: FrozenDateTimeFactory, + values: dict[str, MowerAttributes], ) -> None: """Test error sensor.""" - values = mower_list_to_dictionary_dataclass( - load_json_value_fixture("mower.json", DOMAIN) - ) await setup_integration(hass, mock_config_entry) for state, error_key, expected_state in ( diff --git a/tests/components/husqvarna_automower/test_switch.py b/tests/components/husqvarna_automower/test_switch.py index 8c62ff89154230e6323d8ed8dee0d8d0213e1c53..0dd5acfaf6b2524c0e58c50cb5e3b1e676587447 100644 --- a/tests/components/husqvarna_automower/test_switch.py +++ b/tests/components/husqvarna_automower/test_switch.py @@ -2,9 +2,10 @@ from datetime import timedelta from unittest.mock import AsyncMock, patch +import zoneinfo from aioautomower.exceptions import ApiException -from aioautomower.model import MowerModes +from aioautomower.model import MowerAttributes, MowerModes from aioautomower.utils import mower_list_to_dictionary_dataclass from freezegun.api import FrozenDateTimeFactory import pytest @@ -46,11 +47,9 @@ async def test_switch_states( mock_automower_client: AsyncMock, mock_config_entry: MockConfigEntry, freezer: FrozenDateTimeFactory, + values: dict[str, MowerAttributes], ) -> None: """Test switch state.""" - values = mower_list_to_dictionary_dataclass( - load_json_value_fixture("mower.json", DOMAIN) - ) await setup_integration(hass, mock_config_entry) for mode, expected_state in ( @@ -122,12 +121,14 @@ async def test_stay_out_zone_switch_commands( mock_automower_client: AsyncMock, mock_config_entry: MockConfigEntry, freezer: FrozenDateTimeFactory, + mower_time_zone: zoneinfo.ZoneInfo, ) -> None: """Test switch commands.""" entity_id = "switch.test_mower_1_avoid_danger_zone" await setup_integration(hass, mock_config_entry) values = mower_list_to_dictionary_dataclass( - load_json_value_fixture("mower.json", DOMAIN) + load_json_value_fixture("mower.json", DOMAIN), + mower_time_zone, ) values[TEST_MOWER_ID].stay_out_zones.zones[TEST_ZONE_ID].enabled = boolean mock_automower_client.get_status.return_value = values @@ -177,12 +178,14 @@ async def test_work_area_switch_commands( mock_automower_client: AsyncMock, mock_config_entry: MockConfigEntry, freezer: FrozenDateTimeFactory, + mower_time_zone: zoneinfo.ZoneInfo, ) -> None: """Test switch commands.""" entity_id = "switch.test_mower_1_my_lawn" await setup_integration(hass, mock_config_entry) values = mower_list_to_dictionary_dataclass( - load_json_value_fixture("mower.json", DOMAIN) + load_json_value_fixture("mower.json", DOMAIN), + mower_time_zone, ) values[TEST_MOWER_ID].work_areas[TEST_AREA_ID].enabled = boolean mock_automower_client.get_status.return_value = values @@ -221,12 +224,9 @@ async def test_zones_deleted( mock_automower_client: AsyncMock, mock_config_entry: MockConfigEntry, entity_registry: er.EntityRegistry, + values: dict[str, MowerAttributes], ) -> None: """Test if stay-out-zone is deleted after removed.""" - - values = mower_list_to_dictionary_dataclass( - load_json_value_fixture("mower.json", DOMAIN) - ) await setup_integration(hass, mock_config_entry) current_entries = len( er.async_entries_for_config_entry(entity_registry, mock_config_entry.entry_id)