diff --git a/homeassistant/components/husqvarna_automower/device_tracker.py b/homeassistant/components/husqvarna_automower/device_tracker.py index a32fd8758bd..780d1da76fb 100644 --- a/homeassistant/components/husqvarna_automower/device_tracker.py +++ b/homeassistant/components/husqvarna_automower/device_tracker.py @@ -1,5 +1,7 @@ """Creates the device tracker entity for the mower.""" +from typing import TYPE_CHECKING + from homeassistant.components.device_tracker import SourceType, TrackerEntity from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant @@ -44,9 +46,13 @@ class AutomowerDeviceTrackerEntity(AutomowerBaseEntity, TrackerEntity): @property def latitude(self) -> float: """Return latitude value of the device.""" + if TYPE_CHECKING: + assert self.mower_attributes.positions is not None return self.mower_attributes.positions[0].latitude @property def longitude(self) -> float: """Return longitude value of the device.""" + if TYPE_CHECKING: + assert self.mower_attributes.positions is not None return self.mower_attributes.positions[0].longitude diff --git a/homeassistant/components/husqvarna_automower/manifest.json b/homeassistant/components/husqvarna_automower/manifest.json index e4536ee594d..147c6dfb6d5 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.3.4"] + "requirements": ["aioautomower==2024.4.3"] } diff --git a/homeassistant/components/husqvarna_automower/select.py b/homeassistant/components/husqvarna_automower/select.py index e4376a1bca5..67aac4a2046 100644 --- a/homeassistant/components/husqvarna_automower/select.py +++ b/homeassistant/components/husqvarna_automower/select.py @@ -1,6 +1,7 @@ """Creates a select entity for the headlight of the mower.""" import logging +from typing import cast from aioautomower.exceptions import ApiException from aioautomower.model import HeadlightModes @@ -58,12 +59,14 @@ class AutomowerSelectEntity(AutomowerControlEntity, SelectEntity): @property def current_option(self) -> str: """Return the current option for the entity.""" - return self.mower_attributes.headlight.mode.lower() + return cast(HeadlightModes, self.mower_attributes.headlight.mode).lower() async def async_select_option(self, option: str) -> None: """Change the selected option.""" try: - await self.coordinator.api.set_headlight_mode(self.mower_id, option.upper()) + await self.coordinator.api.set_headlight_mode( + self.mower_id, cast(HeadlightModes, option.upper()) + ) except ApiException as exception: raise HomeAssistantError( f"Command couldn't be sent to the command queue: {exception}" diff --git a/homeassistant/components/husqvarna_automower/sensor.py b/homeassistant/components/husqvarna_automower/sensor.py index 10aec9b1536..6840708ed42 100644 --- a/homeassistant/components/husqvarna_automower/sensor.py +++ b/homeassistant/components/husqvarna_automower/sensor.py @@ -18,7 +18,6 @@ from homeassistant.const import PERCENTAGE, EntityCategory, UnitOfLength, UnitOf from homeassistant.core import HomeAssistant from homeassistant.helpers.entity_platform import AddEntitiesCallback from homeassistant.helpers.typing import StateType -from homeassistant.util import dt as dt_util from .const import DOMAIN from .coordinator import AutomowerDataUpdateCoordinator @@ -298,7 +297,7 @@ SENSOR_TYPES: tuple[AutomowerSensorEntityDescription, ...] = ( key="next_start_timestamp", translation_key="next_start_timestamp", device_class=SensorDeviceClass.TIMESTAMP, - value_fn=lambda data: dt_util.as_local(data.planner.next_start_datetime), + value_fn=lambda data: data.planner.next_start_datetime, ), AutomowerSensorEntityDescription( key="error", diff --git a/requirements_all.txt b/requirements_all.txt index b2c21c1239d..df688e6e00f 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -204,7 +204,7 @@ aioaseko==0.1.1 aioasuswrt==1.4.0 # homeassistant.components.husqvarna_automower -aioautomower==2024.3.4 +aioautomower==2024.4.3 # homeassistant.components.azure_devops aioazuredevops==2.0.0 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index 664467ea0a5..60e54a81780 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -183,7 +183,7 @@ aioaseko==0.1.1 aioasuswrt==1.4.0 # homeassistant.components.husqvarna_automower -aioautomower==2024.3.4 +aioautomower==2024.4.3 # homeassistant.components.azure_devops aioazuredevops==2.0.0 diff --git a/tests/components/husqvarna_automower/snapshots/test_diagnostics.ambr b/tests/components/husqvarna_automower/snapshots/test_diagnostics.ambr index aea65005fc4..ee951986062 100644 --- a/tests/components/husqvarna_automower/snapshots/test_diagnostics.ambr +++ b/tests/components/husqvarna_automower/snapshots/test_diagnostics.ambr @@ -50,12 +50,14 @@ 'activity': 'PARKED_IN_CS', 'error_code': 0, 'error_datetime': None, + 'error_datetime_naive': None, 'error_key': None, 'mode': 'MAIN_AREA', 'state': 'RESTRICTED', }), 'planner': dict({ - 'next_start_datetime': '2023-06-05T19:00:00', + 'next_start_datetime': '2023-06-05T19:00:00+00:00', + 'next_start_datetime_naive': '2023-06-05T19:00:00', 'override': dict({ 'action': 'NOT_ACTIVE', }), diff --git a/tests/components/husqvarna_automower/snapshots/test_sensor.ambr b/tests/components/husqvarna_automower/snapshots/test_sensor.ambr index fda9c900240..7d4533afe72 100644 --- a/tests/components/husqvarna_automower/snapshots/test_sensor.ambr +++ b/tests/components/husqvarna_automower/snapshots/test_sensor.ambr @@ -548,7 +548,7 @@ 'last_changed': , 'last_reported': , 'last_updated': , - 'state': '2023-06-06T02:00:00+00:00', + 'state': '2023-06-05T19:00:00+00:00', }) # --- # name: test_sensor[sensor.test_mower_1_number_of_charging_cycles-entry] diff --git a/tests/components/husqvarna_automower/test_sensor.py b/tests/components/husqvarna_automower/test_sensor.py index f54ce9c6275..2c0661f82cb 100644 --- a/tests/components/husqvarna_automower/test_sensor.py +++ b/tests/components/husqvarna_automower/test_sensor.py @@ -10,7 +10,7 @@ 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.const import STATE_UNKNOWN, Platform from homeassistant.core import HomeAssistant from homeassistant.helpers import entity_registry as er @@ -46,7 +46,7 @@ async def test_sensor_unknown_states( async_fire_time_changed(hass) await hass.async_block_till_done() state = hass.states.get("sensor.test_mower_1_mode") - assert state.state == "unknown" + assert state.state == STATE_UNKNOWN async def test_cutting_blade_usage_time_sensor( @@ -63,6 +63,30 @@ async def test_cutting_blade_usage_time_sensor( assert state.state == "0.034" +async def test_next_start_sensor( + hass: HomeAssistant, + mock_automower_client: AsyncMock, + mock_config_entry: MockConfigEntry, + freezer: FrozenDateTimeFactory, +) -> None: + """Test if this sensor is only added, if data is available.""" + await setup_integration(hass, mock_config_entry) + state = hass.states.get("sensor.test_mower_1_next_start") + assert state is not None + assert state.state == "2023-06-05T19: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 = None + mock_automower_client.get_status.return_value = values + freezer.tick(SCAN_INTERVAL) + async_fire_time_changed(hass) + await hass.async_block_till_done() + state = hass.states.get("sensor.test_mower_1_next_start") + assert state.state == STATE_UNKNOWN + + @pytest.mark.parametrize( ("sensor_to_test"), [