diff --git a/homeassistant/components/suez_water/coordinator.py b/homeassistant/components/suez_water/coordinator.py index 72da68c0f5d..aab1ba110b7 100644 --- a/homeassistant/components/suez_water/coordinator.py +++ b/homeassistant/components/suez_water/coordinator.py @@ -1,9 +1,7 @@ """Suez water update coordinator.""" -from collections.abc import Mapping from dataclasses import dataclass from datetime import date -from typing import Any from pysuez import PySuezError, SuezClient @@ -20,11 +18,11 @@ from .const import CONF_COUNTER_ID, DATA_REFRESH_INTERVAL, DOMAIN class SuezWaterAggregatedAttributes: """Class containing aggregated sensor extra attributes.""" - this_month_consumption: dict[date, float] - previous_month_consumption: dict[date, float] + this_month_consumption: dict[str, float] + previous_month_consumption: dict[str, float] last_year_overall: dict[str, float] this_year_overall: dict[str, float] - history: dict[date, float] + history: dict[str, float] highest_monthly_consumption: float @@ -33,7 +31,7 @@ class SuezWaterData: """Class used to hold all fetch data from suez api.""" aggregated_value: float - aggregated_attr: Mapping[str, Any] + aggregated_attr: SuezWaterAggregatedAttributes price: float @@ -68,18 +66,22 @@ class SuezWaterCoordinator(DataUpdateCoordinator[SuezWaterData]): async def _async_update_data(self) -> SuezWaterData: """Fetch data from API endpoint.""" + + def map_dict(param: dict[date, float]) -> dict[str, float]: + return {str(key): value for key, value in param.items()} + try: aggregated = await self._suez_client.fetch_aggregated_data() data = SuezWaterData( aggregated_value=aggregated.value, - aggregated_attr={ - "this_month_consumption": aggregated.current_month, - "previous_month_consumption": aggregated.previous_month, - "highest_monthly_consumption": aggregated.highest_monthly_consumption, - "last_year_overall": aggregated.previous_year, - "this_year_overall": aggregated.current_year, - "history": aggregated.history, - }, + aggregated_attr=SuezWaterAggregatedAttributes( + this_month_consumption=map_dict(aggregated.current_month), + previous_month_consumption=map_dict(aggregated.previous_month), + highest_monthly_consumption=aggregated.highest_monthly_consumption, + last_year_overall=aggregated.previous_year, + this_year_overall=aggregated.current_year, + history=map_dict(aggregated.history), + ), price=(await self._suez_client.get_price()).price, ) except PySuezError as err: diff --git a/homeassistant/components/suez_water/sensor.py b/homeassistant/components/suez_water/sensor.py index e4e53dd7f6d..1152ebd551b 100644 --- a/homeassistant/components/suez_water/sensor.py +++ b/homeassistant/components/suez_water/sensor.py @@ -2,8 +2,8 @@ from __future__ import annotations -from collections.abc import Callable, Mapping -from dataclasses import dataclass +from collections.abc import Callable +from dataclasses import asdict, dataclass from typing import Any from pysuez.const import ATTRIBUTION @@ -28,7 +28,7 @@ class SuezWaterSensorEntityDescription(SensorEntityDescription): """Describes Suez water sensor entity.""" value_fn: Callable[[SuezWaterData], float | str | None] - attr_fn: Callable[[SuezWaterData], Mapping[str, Any] | None] = lambda _: None + attr_fn: Callable[[SuezWaterData], dict[str, Any] | None] = lambda _: None SENSORS: tuple[SuezWaterSensorEntityDescription, ...] = ( @@ -38,7 +38,7 @@ SENSORS: tuple[SuezWaterSensorEntityDescription, ...] = ( native_unit_of_measurement=UnitOfVolume.LITERS, device_class=SensorDeviceClass.WATER, value_fn=lambda suez_data: suez_data.aggregated_value, - attr_fn=lambda suez_data: suez_data.aggregated_attr, + attr_fn=lambda suez_data: asdict(suez_data.aggregated_attr), ), SuezWaterSensorEntityDescription( key="water_price", @@ -93,6 +93,6 @@ class SuezWaterSensor(CoordinatorEntity[SuezWaterCoordinator], SensorEntity): return self.entity_description.value_fn(self.coordinator.data) @property - def extra_state_attributes(self) -> Mapping[str, Any] | None: + def extra_state_attributes(self) -> dict[str, Any] | None: """Return extra state of the sensor.""" return self.entity_description.attr_fn(self.coordinator.data) diff --git a/tests/components/suez_water/conftest.py b/tests/components/suez_water/conftest.py index f634a053c65..b034d9b00fa 100644 --- a/tests/components/suez_water/conftest.py +++ b/tests/components/suez_water/conftest.py @@ -1,6 +1,7 @@ """Common fixtures for the Suez Water tests.""" from collections.abc import Generator +from datetime import date from unittest.mock import AsyncMock, patch from pysuez import AggregatedData, PriceResult @@ -56,22 +57,22 @@ def mock_suez_client() -> Generator[AsyncMock]: result = AggregatedData( value=160, current_month={ - "2024-01-01": 130, - "2024-01-02": 145, + date.fromisoformat("2024-01-01"): 130, + date.fromisoformat("2024-01-02"): 145, }, previous_month={ - "2024-12-01": 154, - "2024-12-02": 166, + date.fromisoformat("2024-12-01"): 154, + date.fromisoformat("2024-12-02"): 166, }, current_year=1500, previous_year=1000, attribution=ATTRIBUTION, highest_monthly_consumption=2558, history={ - "2024-01-01": 130, - "2024-01-02": 145, - "2024-12-01": 154, - "2024-12-02": 166, + date.fromisoformat("2024-01-01"): 130, + date.fromisoformat("2024-01-02"): 145, + date.fromisoformat("2024-12-01"): 154, + date.fromisoformat("2024-12-02"): 166, }, ) diff --git a/tests/components/suez_water/test_sensor.py b/tests/components/suez_water/test_sensor.py index cb578432f62..950d5d8393d 100644 --- a/tests/components/suez_water/test_sensor.py +++ b/tests/components/suez_water/test_sensor.py @@ -1,5 +1,6 @@ """Test Suez_water sensor platform.""" +from datetime import date from unittest.mock import AsyncMock, patch from freezegun.api import FrozenDateTimeFactory @@ -32,6 +33,13 @@ async def test_sensors_valid_state( assert mock_config_entry.state is ConfigEntryState.LOADED await snapshot_platform(hass, entity_registry, snapshot, mock_config_entry.entry_id) + state = hass.states.get("sensor.suez_mock_device_water_usage_yesterday") + assert state + previous: dict = state.attributes["previous_month_consumption"] + assert previous + assert previous.get(date.fromisoformat("2024-12-01")) is None + assert previous.get(str(date.fromisoformat("2024-12-01"))) == 154 + @pytest.mark.parametrize("method", [("fetch_aggregated_data"), ("get_price")]) async def test_sensors_failed_update(