Suez_water: fix yesterday sensor extra_state invalid typing (#133425)

This commit is contained in:
jb101010-2 2024-12-22 23:21:52 +01:00 committed by GitHub
parent 74b425a06e
commit a3657a0fef
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 38 additions and 27 deletions

View File

@ -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:

View File

@ -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)

View File

@ -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,
},
)

View File

@ -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(