mirror of
https://github.com/home-assistant/core.git
synced 2025-07-19 11:17:21 +00:00
Suez_water: fix yesterday sensor extra_state invalid typing (#133425)
This commit is contained in:
parent
74b425a06e
commit
a3657a0fef
@ -1,9 +1,7 @@
|
|||||||
"""Suez water update coordinator."""
|
"""Suez water update coordinator."""
|
||||||
|
|
||||||
from collections.abc import Mapping
|
|
||||||
from dataclasses import dataclass
|
from dataclasses import dataclass
|
||||||
from datetime import date
|
from datetime import date
|
||||||
from typing import Any
|
|
||||||
|
|
||||||
from pysuez import PySuezError, SuezClient
|
from pysuez import PySuezError, SuezClient
|
||||||
|
|
||||||
@ -20,11 +18,11 @@ from .const import CONF_COUNTER_ID, DATA_REFRESH_INTERVAL, DOMAIN
|
|||||||
class SuezWaterAggregatedAttributes:
|
class SuezWaterAggregatedAttributes:
|
||||||
"""Class containing aggregated sensor extra attributes."""
|
"""Class containing aggregated sensor extra attributes."""
|
||||||
|
|
||||||
this_month_consumption: dict[date, float]
|
this_month_consumption: dict[str, float]
|
||||||
previous_month_consumption: dict[date, float]
|
previous_month_consumption: dict[str, float]
|
||||||
last_year_overall: dict[str, float]
|
last_year_overall: dict[str, float]
|
||||||
this_year_overall: dict[str, float]
|
this_year_overall: dict[str, float]
|
||||||
history: dict[date, float]
|
history: dict[str, float]
|
||||||
highest_monthly_consumption: float
|
highest_monthly_consumption: float
|
||||||
|
|
||||||
|
|
||||||
@ -33,7 +31,7 @@ class SuezWaterData:
|
|||||||
"""Class used to hold all fetch data from suez api."""
|
"""Class used to hold all fetch data from suez api."""
|
||||||
|
|
||||||
aggregated_value: float
|
aggregated_value: float
|
||||||
aggregated_attr: Mapping[str, Any]
|
aggregated_attr: SuezWaterAggregatedAttributes
|
||||||
price: float
|
price: float
|
||||||
|
|
||||||
|
|
||||||
@ -68,18 +66,22 @@ class SuezWaterCoordinator(DataUpdateCoordinator[SuezWaterData]):
|
|||||||
|
|
||||||
async def _async_update_data(self) -> SuezWaterData:
|
async def _async_update_data(self) -> SuezWaterData:
|
||||||
"""Fetch data from API endpoint."""
|
"""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:
|
try:
|
||||||
aggregated = await self._suez_client.fetch_aggregated_data()
|
aggregated = await self._suez_client.fetch_aggregated_data()
|
||||||
data = SuezWaterData(
|
data = SuezWaterData(
|
||||||
aggregated_value=aggregated.value,
|
aggregated_value=aggregated.value,
|
||||||
aggregated_attr={
|
aggregated_attr=SuezWaterAggregatedAttributes(
|
||||||
"this_month_consumption": aggregated.current_month,
|
this_month_consumption=map_dict(aggregated.current_month),
|
||||||
"previous_month_consumption": aggregated.previous_month,
|
previous_month_consumption=map_dict(aggregated.previous_month),
|
||||||
"highest_monthly_consumption": aggregated.highest_monthly_consumption,
|
highest_monthly_consumption=aggregated.highest_monthly_consumption,
|
||||||
"last_year_overall": aggregated.previous_year,
|
last_year_overall=aggregated.previous_year,
|
||||||
"this_year_overall": aggregated.current_year,
|
this_year_overall=aggregated.current_year,
|
||||||
"history": aggregated.history,
|
history=map_dict(aggregated.history),
|
||||||
},
|
),
|
||||||
price=(await self._suez_client.get_price()).price,
|
price=(await self._suez_client.get_price()).price,
|
||||||
)
|
)
|
||||||
except PySuezError as err:
|
except PySuezError as err:
|
||||||
|
@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
from collections.abc import Callable, Mapping
|
from collections.abc import Callable
|
||||||
from dataclasses import dataclass
|
from dataclasses import asdict, dataclass
|
||||||
from typing import Any
|
from typing import Any
|
||||||
|
|
||||||
from pysuez.const import ATTRIBUTION
|
from pysuez.const import ATTRIBUTION
|
||||||
@ -28,7 +28,7 @@ class SuezWaterSensorEntityDescription(SensorEntityDescription):
|
|||||||
"""Describes Suez water sensor entity."""
|
"""Describes Suez water sensor entity."""
|
||||||
|
|
||||||
value_fn: Callable[[SuezWaterData], float | str | None]
|
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, ...] = (
|
SENSORS: tuple[SuezWaterSensorEntityDescription, ...] = (
|
||||||
@ -38,7 +38,7 @@ SENSORS: tuple[SuezWaterSensorEntityDescription, ...] = (
|
|||||||
native_unit_of_measurement=UnitOfVolume.LITERS,
|
native_unit_of_measurement=UnitOfVolume.LITERS,
|
||||||
device_class=SensorDeviceClass.WATER,
|
device_class=SensorDeviceClass.WATER,
|
||||||
value_fn=lambda suez_data: suez_data.aggregated_value,
|
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(
|
SuezWaterSensorEntityDescription(
|
||||||
key="water_price",
|
key="water_price",
|
||||||
@ -93,6 +93,6 @@ class SuezWaterSensor(CoordinatorEntity[SuezWaterCoordinator], SensorEntity):
|
|||||||
return self.entity_description.value_fn(self.coordinator.data)
|
return self.entity_description.value_fn(self.coordinator.data)
|
||||||
|
|
||||||
@property
|
@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 extra state of the sensor."""
|
||||||
return self.entity_description.attr_fn(self.coordinator.data)
|
return self.entity_description.attr_fn(self.coordinator.data)
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
"""Common fixtures for the Suez Water tests."""
|
"""Common fixtures for the Suez Water tests."""
|
||||||
|
|
||||||
from collections.abc import Generator
|
from collections.abc import Generator
|
||||||
|
from datetime import date
|
||||||
from unittest.mock import AsyncMock, patch
|
from unittest.mock import AsyncMock, patch
|
||||||
|
|
||||||
from pysuez import AggregatedData, PriceResult
|
from pysuez import AggregatedData, PriceResult
|
||||||
@ -56,22 +57,22 @@ def mock_suez_client() -> Generator[AsyncMock]:
|
|||||||
result = AggregatedData(
|
result = AggregatedData(
|
||||||
value=160,
|
value=160,
|
||||||
current_month={
|
current_month={
|
||||||
"2024-01-01": 130,
|
date.fromisoformat("2024-01-01"): 130,
|
||||||
"2024-01-02": 145,
|
date.fromisoformat("2024-01-02"): 145,
|
||||||
},
|
},
|
||||||
previous_month={
|
previous_month={
|
||||||
"2024-12-01": 154,
|
date.fromisoformat("2024-12-01"): 154,
|
||||||
"2024-12-02": 166,
|
date.fromisoformat("2024-12-02"): 166,
|
||||||
},
|
},
|
||||||
current_year=1500,
|
current_year=1500,
|
||||||
previous_year=1000,
|
previous_year=1000,
|
||||||
attribution=ATTRIBUTION,
|
attribution=ATTRIBUTION,
|
||||||
highest_monthly_consumption=2558,
|
highest_monthly_consumption=2558,
|
||||||
history={
|
history={
|
||||||
"2024-01-01": 130,
|
date.fromisoformat("2024-01-01"): 130,
|
||||||
"2024-01-02": 145,
|
date.fromisoformat("2024-01-02"): 145,
|
||||||
"2024-12-01": 154,
|
date.fromisoformat("2024-12-01"): 154,
|
||||||
"2024-12-02": 166,
|
date.fromisoformat("2024-12-02"): 166,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
"""Test Suez_water sensor platform."""
|
"""Test Suez_water sensor platform."""
|
||||||
|
|
||||||
|
from datetime import date
|
||||||
from unittest.mock import AsyncMock, patch
|
from unittest.mock import AsyncMock, patch
|
||||||
|
|
||||||
from freezegun.api import FrozenDateTimeFactory
|
from freezegun.api import FrozenDateTimeFactory
|
||||||
@ -32,6 +33,13 @@ async def test_sensors_valid_state(
|
|||||||
assert mock_config_entry.state is ConfigEntryState.LOADED
|
assert mock_config_entry.state is ConfigEntryState.LOADED
|
||||||
await snapshot_platform(hass, entity_registry, snapshot, mock_config_entry.entry_id)
|
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")])
|
@pytest.mark.parametrize("method", [("fetch_aggregated_data"), ("get_price")])
|
||||||
async def test_sensors_failed_update(
|
async def test_sensors_failed_update(
|
||||||
|
Loading…
x
Reference in New Issue
Block a user