Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Suez_water: fix yesterday sensor extra_state invalid typing #133425

Merged
merged 1 commit into from
Dec 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 16 additions & 14 deletions homeassistant/components/suez_water/coordinator.py
Original file line number Diff line number Diff line change
@@ -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

Expand All @@ -20,11 +18,11 @@
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


Expand All @@ -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


Expand Down Expand Up @@ -68,18 +66,22 @@ async def _async_setup(self) -> None:

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:
Expand Down
10 changes: 5 additions & 5 deletions homeassistant/components/suez_water/sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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, ...] = (
Expand All @@ -38,7 +38,7 @@ class SuezWaterSensorEntityDescription(SensorEntityDescription):
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",
Expand Down Expand Up @@ -93,6 +93,6 @@ def native_value(self) -> float | str | None:
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)
17 changes: 9 additions & 8 deletions tests/components/suez_water/conftest.py
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -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,
},
)

Expand Down
8 changes: 8 additions & 0 deletions tests/components/suez_water/test_sensor.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
"""Test Suez_water sensor platform."""

from datetime import date
from unittest.mock import AsyncMock, patch

from freezegun.api import FrozenDateTimeFactory
Expand Down Expand Up @@ -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(
Expand Down