diff --git a/homeassistant/components/letpot/__init__.py b/homeassistant/components/letpot/__init__.py index f5153b6d05dd4..e48e1c9ced0a5 100644 --- a/homeassistant/components/letpot/__init__.py +++ b/homeassistant/components/letpot/__init__.py @@ -3,10 +3,10 @@ import asyncio from letpot.client import LetPotClient -from letpot.converters import CONVERTERS +from letpot.converters import GARDEN_CONVERTERS from letpot.deviceclient import LetPotDeviceClient from letpot.exceptions import LetPotAuthenticationException, LetPotException -from letpot.models import AuthenticationInfo +from letpot.models import AuthenticationInfo, LetPotGardenStatus from homeassistant.const import CONF_ACCESS_TOKEN, CONF_EMAIL, Platform from homeassistant.core import HomeAssistant @@ -71,10 +71,13 @@ async def async_setup_entry(hass: HomeAssistant, entry: LetPotConfigEntry) -> bo device_client = LetPotDeviceClient(auth) - coordinators: list[LetPotDeviceCoordinator] = [ - LetPotDeviceCoordinator(hass, entry, device, device_client) + coordinators: list[LetPotDeviceCoordinator[LetPotGardenStatus]] = [ + LetPotDeviceCoordinator[LetPotGardenStatus](hass, entry, device, device_client) for device in devices - if any(converter.supports_type(device.device_type) for converter in CONVERTERS) + if any( + converter.supports_type(device.device_type) + for converter in GARDEN_CONVERTERS + ) ] await asyncio.gather( diff --git a/homeassistant/components/letpot/binary_sensor.py b/homeassistant/components/letpot/binary_sensor.py index 54b1499118a1f..7819a62373287 100644 --- a/homeassistant/components/letpot/binary_sensor.py +++ b/homeassistant/components/letpot/binary_sensor.py @@ -14,7 +14,7 @@ from homeassistant.core import HomeAssistant from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback -from .coordinator import LetPotConfigEntry, LetPotDeviceCoordinator +from .coordinator import LetPotConfigEntry, LetPotDeviceCoordinator, LetPotGardenStatus from .entity import LetPotEntity, LetPotEntityDescription # Coordinator is used to centralize the data updates @@ -22,16 +22,16 @@ @dataclass(frozen=True, kw_only=True) -class LetPotBinarySensorEntityDescription( +class LetPotBinarySensorEntityDescription[_DataT: LetPotDeviceStatus]( LetPotEntityDescription, BinarySensorEntityDescription ): """Describes a LetPot binary sensor entity.""" - is_on_fn: Callable[[LetPotDeviceStatus], bool] + is_on_fn: Callable[[_DataT], bool] -BINARY_SENSORS: tuple[LetPotBinarySensorEntityDescription, ...] = ( - LetPotBinarySensorEntityDescription( +BINARY_SENSORS: tuple[LetPotBinarySensorEntityDescription[LetPotGardenStatus], ...] = ( + LetPotBinarySensorEntityDescription[LetPotGardenStatus]( key="low_nutrients", translation_key="low_nutrients", is_on_fn=lambda status: bool(status.errors.low_nutrients), @@ -42,7 +42,7 @@ class LetPotBinarySensorEntityDescription( lambda coordinator: coordinator.data.errors.low_nutrients is not None ), ), - LetPotBinarySensorEntityDescription( + LetPotBinarySensorEntityDescription[LetPotGardenStatus]( key="low_water", translation_key="low_water", is_on_fn=lambda status: bool(status.errors.low_water), @@ -51,7 +51,7 @@ class LetPotBinarySensorEntityDescription( device_class=BinarySensorDeviceClass.PROBLEM, supported_fn=lambda coordinator: coordinator.data.errors.low_water is not None, ), - LetPotBinarySensorEntityDescription( + LetPotBinarySensorEntityDescription[LetPotGardenStatus]( key="pump", translation_key="pump", is_on_fn=lambda status: status.pump_status == 1, @@ -65,7 +65,7 @@ class LetPotBinarySensorEntityDescription( ) ), ), - LetPotBinarySensorEntityDescription( + LetPotBinarySensorEntityDescription[LetPotGardenStatus]( key="pump_error", translation_key="pump_error", is_on_fn=lambda status: bool(status.errors.pump_malfunction), @@ -76,7 +76,7 @@ class LetPotBinarySensorEntityDescription( lambda coordinator: coordinator.data.errors.pump_malfunction is not None ), ), - LetPotBinarySensorEntityDescription( + LetPotBinarySensorEntityDescription[LetPotGardenStatus]( key="refill_error", translation_key="refill_error", is_on_fn=lambda status: bool(status.errors.refill_error), @@ -98,22 +98,24 @@ async def async_setup_entry( """Set up LetPot binary sensor entities based on a config entry and device status/features.""" coordinators = entry.runtime_data async_add_entities( - LetPotBinarySensorEntity(coordinator, description) + LetPotBinarySensorEntity[LetPotGardenStatus](coordinator, description) for description in BINARY_SENSORS for coordinator in coordinators if description.supported_fn(coordinator) ) -class LetPotBinarySensorEntity(LetPotEntity, BinarySensorEntity): +class LetPotBinarySensorEntity[_DataT: LetPotDeviceStatus]( + LetPotEntity[_DataT], BinarySensorEntity +): """Defines a LetPot binary sensor entity.""" - entity_description: LetPotBinarySensorEntityDescription + entity_description: LetPotBinarySensorEntityDescription[_DataT] def __init__( self, - coordinator: LetPotDeviceCoordinator, - description: LetPotBinarySensorEntityDescription, + coordinator: LetPotDeviceCoordinator[_DataT], + description: LetPotBinarySensorEntityDescription[_DataT], ) -> None: """Initialize LetPot binary sensor entity.""" super().__init__(coordinator) diff --git a/homeassistant/components/letpot/coordinator.py b/homeassistant/components/letpot/coordinator.py index 4852b340952e5..1d588523e4676 100644 --- a/homeassistant/components/letpot/coordinator.py +++ b/homeassistant/components/letpot/coordinator.py @@ -1,12 +1,14 @@ """Coordinator for the LetPot integration.""" import asyncio +from collections.abc import Callable from datetime import timedelta import logging +from typing import cast from letpot.deviceclient import LetPotDeviceClient from letpot.exceptions import LetPotAuthenticationException, LetPotException -from letpot.models import LetPotDevice, LetPotDeviceStatus +from letpot.models import LetPotDevice, LetPotDeviceStatus, LetPotGardenStatus from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant @@ -17,11 +19,13 @@ _LOGGER = logging.getLogger(__name__) -type LetPotConfigEntry = ConfigEntry[list[LetPotDeviceCoordinator]] +type LetPotConfigEntry = ConfigEntry[list[LetPotDeviceCoordinator[LetPotGardenStatus]]] -class LetPotDeviceCoordinator(DataUpdateCoordinator[LetPotDeviceStatus]): - """Class to handle data updates for a specific garden.""" +class LetPotDeviceCoordinator[_DataT: LetPotDeviceStatus]( + DataUpdateCoordinator[_DataT] +): + """Class to handle data updates for a specific device.""" config_entry: LetPotConfigEntry @@ -46,7 +50,7 @@ def __init__( self.device = device self.device_client = device_client - def _handle_status_update(self, status: LetPotDeviceStatus) -> None: + def _handle_status_update(self, status: _DataT) -> None: """Distribute status update to entities.""" self.async_set_updated_data(data=status) @@ -54,12 +58,13 @@ async def _async_setup(self) -> None: """Set up subscription for coordinator.""" try: await self.device_client.subscribe( - self.device.serial_number, self._handle_status_update + self.device.serial_number, + cast(Callable[[LetPotDeviceStatus], None], self._handle_status_update), ) except LetPotAuthenticationException as exc: raise ConfigEntryAuthFailed from exc - async def _async_update_data(self) -> LetPotDeviceStatus: + async def _async_update_data(self) -> _DataT: """Request an update from the device and wait for a status update or timeout.""" try: async with asyncio.timeout(REQUEST_UPDATE_TIMEOUT): diff --git a/homeassistant/components/letpot/entity.py b/homeassistant/components/letpot/entity.py index 11d6a132a18c8..02c6233e6750c 100644 --- a/homeassistant/components/letpot/entity.py +++ b/homeassistant/components/letpot/entity.py @@ -5,6 +5,7 @@ from typing import Any, Concatenate from letpot.exceptions import LetPotConnectionException, LetPotException +from letpot.models import LetPotDeviceStatus from homeassistant.exceptions import HomeAssistantError from homeassistant.helpers.device_registry import DeviceInfo @@ -22,12 +23,14 @@ class LetPotEntityDescription(EntityDescription): supported_fn: Callable[[LetPotDeviceCoordinator], bool] = lambda _: True -class LetPotEntity(CoordinatorEntity[LetPotDeviceCoordinator]): +class LetPotEntity[_DataT: LetPotDeviceStatus]( + CoordinatorEntity[LetPotDeviceCoordinator[_DataT]] +): """Defines a base LetPot entity.""" _attr_has_entity_name = True - def __init__(self, coordinator: LetPotDeviceCoordinator) -> None: + def __init__(self, coordinator: LetPotDeviceCoordinator[_DataT]) -> None: """Initialize a LetPot entity.""" super().__init__(coordinator) info = coordinator.device_client.device_info(coordinator.device.serial_number) diff --git a/homeassistant/components/letpot/manifest.json b/homeassistant/components/letpot/manifest.json index 5400814a47f9b..64477f08a6d42 100644 --- a/homeassistant/components/letpot/manifest.json +++ b/homeassistant/components/letpot/manifest.json @@ -8,5 +8,5 @@ "iot_class": "cloud_push", "loggers": ["letpot"], "quality_scale": "silver", - "requirements": ["letpot==0.6.4"] + "requirements": ["letpot==0.7.0"] } diff --git a/homeassistant/components/letpot/number.py b/homeassistant/components/letpot/number.py index 1ab632e067e00..998935f0532af 100644 --- a/homeassistant/components/letpot/number.py +++ b/homeassistant/components/letpot/number.py @@ -5,7 +5,7 @@ from typing import Any from letpot.deviceclient import LetPotDeviceClient -from letpot.models import DeviceFeature +from letpot.models import DeviceFeature, LetPotDeviceStatus, LetPotGardenStatus from homeassistant.components.number import ( NumberEntity, @@ -25,16 +25,18 @@ @dataclass(frozen=True, kw_only=True) -class LetPotNumberEntityDescription(LetPotEntityDescription, NumberEntityDescription): +class LetPotNumberEntityDescription[_DataT: LetPotDeviceStatus]( + LetPotEntityDescription, NumberEntityDescription +): """Describes a LetPot number entity.""" - max_value_fn: Callable[[LetPotDeviceCoordinator], float] - value_fn: Callable[[LetPotDeviceCoordinator], float | None] + max_value_fn: Callable[[LetPotDeviceCoordinator[_DataT]], float] + value_fn: Callable[[LetPotDeviceCoordinator[_DataT]], float | None] set_value_fn: Callable[[LetPotDeviceClient, str, float], Coroutine[Any, Any, None]] -NUMBERS: tuple[LetPotNumberEntityDescription, ...] = ( - LetPotNumberEntityDescription( +NUMBERS: tuple[LetPotNumberEntityDescription[LetPotGardenStatus], ...] = ( + LetPotNumberEntityDescription[LetPotGardenStatus]( key="light_brightness_levels", translation_key="light_brightness", value_fn=( @@ -73,7 +75,7 @@ class LetPotNumberEntityDescription(LetPotEntityDescription, NumberEntityDescrip mode=NumberMode.SLIDER, entity_category=EntityCategory.CONFIG, ), - LetPotNumberEntityDescription( + LetPotNumberEntityDescription[LetPotGardenStatus]( key="plant_days", translation_key="plant_days", native_unit_of_measurement=UnitOfTime.DAYS, @@ -99,22 +101,24 @@ async def async_setup_entry( """Set up LetPot number entities based on a config entry and device status/features.""" coordinators = entry.runtime_data async_add_entities( - LetPotNumberEntity(coordinator, description) + LetPotNumberEntity[LetPotGardenStatus](coordinator, description) for description in NUMBERS for coordinator in coordinators if description.supported_fn(coordinator) ) -class LetPotNumberEntity(LetPotEntity, NumberEntity): +class LetPotNumberEntity[_DataT: LetPotDeviceStatus]( + LetPotEntity[_DataT], NumberEntity +): """Defines a LetPot number entity.""" - entity_description: LetPotNumberEntityDescription + entity_description: LetPotNumberEntityDescription[_DataT] def __init__( self, - coordinator: LetPotDeviceCoordinator, - description: LetPotNumberEntityDescription, + coordinator: LetPotDeviceCoordinator[_DataT], + description: LetPotNumberEntityDescription[_DataT], ) -> None: """Initialize LetPot number entity.""" super().__init__(coordinator) diff --git a/homeassistant/components/letpot/select.py b/homeassistant/components/letpot/select.py index 7508e80329e2e..81cf9bba5a52d 100644 --- a/homeassistant/components/letpot/select.py +++ b/homeassistant/components/letpot/select.py @@ -6,7 +6,13 @@ from typing import Any from letpot.deviceclient import LetPotDeviceClient -from letpot.models import DeviceFeature, LightMode, TemperatureUnit +from letpot.models import ( + DeviceFeature, + LetPotDeviceStatus, + LetPotGardenStatus, + LightMode, + TemperatureUnit, +) from homeassistant.components.select import SelectEntity, SelectEntityDescription from homeassistant.const import EntityCategory @@ -52,15 +58,17 @@ async def _set_brightness_low_high_value( @dataclass(frozen=True, kw_only=True) -class LetPotSelectEntityDescription(LetPotEntityDescription, SelectEntityDescription): +class LetPotSelectEntityDescription[_DataT: LetPotDeviceStatus]( + LetPotEntityDescription, SelectEntityDescription +): """Describes a LetPot select entity.""" - value_fn: Callable[[LetPotDeviceCoordinator], str | None] + value_fn: Callable[[LetPotDeviceCoordinator[_DataT]], str | None] set_value_fn: Callable[[LetPotDeviceClient, str, str], Coroutine[Any, Any, None]] -SELECTORS: tuple[LetPotSelectEntityDescription, ...] = ( - LetPotSelectEntityDescription( +SELECTORS: tuple[LetPotSelectEntityDescription[LetPotGardenStatus], ...] = ( + LetPotSelectEntityDescription[LetPotGardenStatus]( key="display_temperature_unit", translation_key="display_temperature_unit", options=[x.name.lower() for x in TemperatureUnit], @@ -86,7 +94,7 @@ class LetPotSelectEntityDescription(LetPotEntityDescription, SelectEntityDescrip ), entity_category=EntityCategory.CONFIG, ), - LetPotSelectEntityDescription( + LetPotSelectEntityDescription[LetPotGardenStatus]( key="light_brightness_low_high", translation_key="light_brightness", options=[ @@ -105,7 +113,7 @@ class LetPotSelectEntityDescription(LetPotEntityDescription, SelectEntityDescrip ), entity_category=EntityCategory.CONFIG, ), - LetPotSelectEntityDescription( + LetPotSelectEntityDescription[LetPotGardenStatus]( key="light_mode", translation_key="light_mode", options=[x.name.lower() for x in LightMode], @@ -134,22 +142,24 @@ async def async_setup_entry( """Set up LetPot select entities based on a config entry and device status/features.""" coordinators = entry.runtime_data async_add_entities( - LetPotSelectEntity(coordinator, description) + LetPotSelectEntity[LetPotGardenStatus](coordinator, description) for description in SELECTORS for coordinator in coordinators if description.supported_fn(coordinator) ) -class LetPotSelectEntity(LetPotEntity, SelectEntity): +class LetPotSelectEntity[_DataT: LetPotDeviceStatus]( + LetPotEntity[_DataT], SelectEntity +): """Defines a LetPot select entity.""" - entity_description: LetPotSelectEntityDescription + entity_description: LetPotSelectEntityDescription[_DataT] def __init__( self, - coordinator: LetPotDeviceCoordinator, - description: LetPotSelectEntityDescription, + coordinator: LetPotDeviceCoordinator[_DataT], + description: LetPotSelectEntityDescription[_DataT], ) -> None: """Initialize LetPot select entity.""" super().__init__(coordinator) diff --git a/homeassistant/components/letpot/sensor.py b/homeassistant/components/letpot/sensor.py index 4391a6d8b0e87..418bdccf071ea 100644 --- a/homeassistant/components/letpot/sensor.py +++ b/homeassistant/components/letpot/sensor.py @@ -3,7 +3,12 @@ from collections.abc import Callable from dataclasses import dataclass -from letpot.models import DeviceFeature, LetPotDeviceStatus, TemperatureUnit +from letpot.models import ( + DeviceFeature, + LetPotDeviceStatus, + LetPotGardenStatus, + TemperatureUnit, +) from homeassistant.components.sensor import ( SensorDeviceClass, @@ -30,15 +35,17 @@ @dataclass(frozen=True, kw_only=True) -class LetPotSensorEntityDescription(LetPotEntityDescription, SensorEntityDescription): +class LetPotSensorEntityDescription[_DataT: LetPotDeviceStatus]( + LetPotEntityDescription, SensorEntityDescription +): """Describes a LetPot sensor entity.""" - native_unit_of_measurement_fn: Callable[[LetPotDeviceStatus], str | None] - value_fn: Callable[[LetPotDeviceStatus], StateType] + native_unit_of_measurement_fn: Callable[[_DataT], str | None] + value_fn: Callable[[_DataT], StateType] -SENSORS: tuple[LetPotSensorEntityDescription, ...] = ( - LetPotSensorEntityDescription( +SENSORS: tuple[LetPotSensorEntityDescription[LetPotGardenStatus], ...] = ( + LetPotSensorEntityDescription[LetPotGardenStatus]( key="temperature", value_fn=lambda status: status.temperature_value, native_unit_of_measurement_fn=( @@ -57,7 +64,7 @@ class LetPotSensorEntityDescription(LetPotEntityDescription, SensorEntityDescrip ) ), ), - LetPotSensorEntityDescription( + LetPotSensorEntityDescription[LetPotGardenStatus]( key="water_level", translation_key="water_level", value_fn=lambda status: status.water_level, @@ -83,22 +90,24 @@ async def async_setup_entry( """Set up LetPot sensor entities based on a device features.""" coordinators = entry.runtime_data async_add_entities( - LetPotSensorEntity(coordinator, description) + LetPotSensorEntity[LetPotGardenStatus](coordinator, description) for description in SENSORS for coordinator in coordinators if description.supported_fn(coordinator) ) -class LetPotSensorEntity(LetPotEntity, SensorEntity): +class LetPotSensorEntity[_DataT: LetPotDeviceStatus]( + LetPotEntity[_DataT], SensorEntity +): """Defines a LetPot sensor entity.""" - entity_description: LetPotSensorEntityDescription + entity_description: LetPotSensorEntityDescription[_DataT] def __init__( self, - coordinator: LetPotDeviceCoordinator, - description: LetPotSensorEntityDescription, + coordinator: LetPotDeviceCoordinator[_DataT], + description: LetPotSensorEntityDescription[_DataT], ) -> None: """Initialize LetPot sensor entity.""" super().__init__(coordinator) diff --git a/homeassistant/components/letpot/switch.py b/homeassistant/components/letpot/switch.py index 119635b513c9c..ac1e644f993c8 100644 --- a/homeassistant/components/letpot/switch.py +++ b/homeassistant/components/letpot/switch.py @@ -5,7 +5,7 @@ from typing import Any from letpot.deviceclient import LetPotDeviceClient -from letpot.models import DeviceFeature, LetPotDeviceStatus +from letpot.models import DeviceFeature, LetPotDeviceStatus, LetPotGardenStatus from homeassistant.components.switch import SwitchEntity, SwitchEntityDescription from homeassistant.const import EntityCategory @@ -21,15 +21,17 @@ @dataclass(frozen=True, kw_only=True) -class LetPotSwitchEntityDescription(LetPotEntityDescription, SwitchEntityDescription): +class LetPotSwitchEntityDescription[_DataT: LetPotDeviceStatus]( + LetPotEntityDescription, SwitchEntityDescription +): """Describes a LetPot switch entity.""" - value_fn: Callable[[LetPotDeviceStatus], bool | None] + value_fn: Callable[[_DataT], bool | None] set_value_fn: Callable[[LetPotDeviceClient, str, bool], Coroutine[Any, Any, None]] -SWITCHES: tuple[LetPotSwitchEntityDescription, ...] = ( - LetPotSwitchEntityDescription( +SWITCHES: tuple[LetPotSwitchEntityDescription[LetPotGardenStatus], ...] = ( + LetPotSwitchEntityDescription[LetPotGardenStatus]( key="alarm_sound", translation_key="alarm_sound", value_fn=lambda status: status.system_sound, @@ -39,7 +41,7 @@ class LetPotSwitchEntityDescription(LetPotEntityDescription, SwitchEntityDescrip entity_category=EntityCategory.CONFIG, supported_fn=lambda coordinator: coordinator.data.system_sound is not None, ), - LetPotSwitchEntityDescription( + LetPotSwitchEntityDescription[LetPotGardenStatus]( key="auto_mode", translation_key="auto_mode", value_fn=lambda status: status.water_mode == 1, @@ -58,7 +60,7 @@ class LetPotSwitchEntityDescription(LetPotEntityDescription, SwitchEntityDescrip ) ), ), - LetPotSwitchEntityDescription( + LetPotSwitchEntityDescription[LetPotGardenStatus]( key="power", translation_key="power", value_fn=lambda status: status.system_on, @@ -67,7 +69,7 @@ class LetPotSwitchEntityDescription(LetPotEntityDescription, SwitchEntityDescrip ), entity_category=EntityCategory.CONFIG, ), - LetPotSwitchEntityDescription( + LetPotSwitchEntityDescription[LetPotGardenStatus]( key="pump_cycling", translation_key="pump_cycling", value_fn=lambda status: status.pump_mode == 1, @@ -87,7 +89,7 @@ async def async_setup_entry( """Set up LetPot switch entities based on a config entry and device status/features.""" coordinators = entry.runtime_data entities: list[SwitchEntity] = [ - LetPotSwitchEntity(coordinator, description) + LetPotSwitchEntity[LetPotGardenStatus](coordinator, description) for description in SWITCHES for coordinator in coordinators if description.supported_fn(coordinator) @@ -95,15 +97,17 @@ async def async_setup_entry( async_add_entities(entities) -class LetPotSwitchEntity(LetPotEntity, SwitchEntity): +class LetPotSwitchEntity[_DataT: LetPotDeviceStatus]( + LetPotEntity[_DataT], SwitchEntity +): """Defines a LetPot switch entity.""" - entity_description: LetPotSwitchEntityDescription + entity_description: LetPotSwitchEntityDescription[_DataT] def __init__( self, - coordinator: LetPotDeviceCoordinator, - description: LetPotSwitchEntityDescription, + coordinator: LetPotDeviceCoordinator[_DataT], + description: LetPotSwitchEntityDescription[_DataT], ) -> None: """Initialize LetPot switch entity.""" super().__init__(coordinator) diff --git a/homeassistant/components/letpot/time.py b/homeassistant/components/letpot/time.py index 87ce35f828db6..ff3b1b7e9d547 100644 --- a/homeassistant/components/letpot/time.py +++ b/homeassistant/components/letpot/time.py @@ -13,7 +13,7 @@ from homeassistant.core import HomeAssistant from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback -from .coordinator import LetPotConfigEntry, LetPotDeviceCoordinator +from .coordinator import LetPotConfigEntry, LetPotDeviceCoordinator, LetPotGardenStatus from .entity import LetPotEntity, exception_handler # Each change pushes a 'full' device status with the change. The library will cache @@ -22,15 +22,15 @@ @dataclass(frozen=True, kw_only=True) -class LetPotTimeEntityDescription(TimeEntityDescription): +class LetPotTimeEntityDescription[_DataT: LetPotDeviceStatus](TimeEntityDescription): """Describes a LetPot time entity.""" - value_fn: Callable[[LetPotDeviceStatus], time | None] + value_fn: Callable[[_DataT], time | None] set_value_fn: Callable[[LetPotDeviceClient, str, time], Coroutine[Any, Any, None]] -TIME_SENSORS: tuple[LetPotTimeEntityDescription, ...] = ( - LetPotTimeEntityDescription( +TIME_SENSORS: tuple[LetPotTimeEntityDescription[LetPotGardenStatus], ...] = ( + LetPotTimeEntityDescription[LetPotGardenStatus]( key="light_schedule_end", translation_key="light_schedule_end", value_fn=lambda status: None if status is None else status.light_schedule_end, @@ -41,7 +41,7 @@ class LetPotTimeEntityDescription(TimeEntityDescription): ), entity_category=EntityCategory.CONFIG, ), - LetPotTimeEntityDescription( + LetPotTimeEntityDescription[LetPotGardenStatus]( key="light_schedule_start", translation_key="light_schedule_start", value_fn=lambda status: None if status is None else status.light_schedule_start, @@ -63,21 +63,21 @@ async def async_setup_entry( """Set up LetPot time entities based on a config entry.""" coordinators = entry.runtime_data async_add_entities( - LetPotTimeEntity(coordinator, description) + LetPotTimeEntity[LetPotGardenStatus](coordinator, description) for description in TIME_SENSORS for coordinator in coordinators ) -class LetPotTimeEntity(LetPotEntity, TimeEntity): +class LetPotTimeEntity[_DataT: LetPotDeviceStatus](LetPotEntity[_DataT], TimeEntity): """Defines a LetPot time entity.""" - entity_description: LetPotTimeEntityDescription + entity_description: LetPotTimeEntityDescription[_DataT] def __init__( self, - coordinator: LetPotDeviceCoordinator, - description: LetPotTimeEntityDescription, + coordinator: LetPotDeviceCoordinator[_DataT], + description: LetPotTimeEntityDescription[_DataT], ) -> None: """Initialize LetPot time entity.""" super().__init__(coordinator) diff --git a/requirements_all.txt b/requirements_all.txt index 2a2b19ac296c3..9eb4a2f1a4aea 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -1444,7 +1444,7 @@ led-ble==1.1.8 lektricowifi==0.1 # homeassistant.components.letpot -letpot==0.6.4 +letpot==0.7.0 # homeassistant.components.foscam libpyfoscamcgi==0.0.9 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index 2f5c0eae69cd0..eb2a9a57d554b 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -1281,7 +1281,7 @@ led-ble==1.1.8 lektricowifi==0.1 # homeassistant.components.letpot -letpot==0.6.4 +letpot==0.7.0 # homeassistant.components.foscam libpyfoscamcgi==0.0.9 diff --git a/tests/components/letpot/__init__.py b/tests/components/letpot/__init__.py index 644b8e1580f14..d3c33160218ec 100644 --- a/tests/components/letpot/__init__.py +++ b/tests/components/letpot/__init__.py @@ -5,7 +5,7 @@ from letpot.models import ( AuthenticationInfo, LetPotDeviceErrors, - LetPotDeviceStatus, + LetPotGardenStatus, LightMode, TemperatureUnit, ) @@ -31,7 +31,7 @@ async def setup_integration(hass: HomeAssistant, config_entry: MockConfigEntry) email="email@example.com", ) -MAX_STATUS = LetPotDeviceStatus( +MAX_STATUS = LetPotGardenStatus( errors=LetPotDeviceErrors(low_water=True, low_nutrients=False, refill_error=False), light_brightness=750, light_mode=LightMode.VEGETABLE, @@ -51,7 +51,7 @@ async def setup_integration(hass: HomeAssistant, config_entry: MockConfigEntry) water_level=100, ) -SE_STATUS = LetPotDeviceStatus( +SE_STATUS = LetPotGardenStatus( errors=LetPotDeviceErrors(low_water=True, pump_malfunction=True), light_brightness=500, light_mode=LightMode.VEGETABLE,