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

Add data coordinator to Stookwijzer #131574

Merged
merged 2 commits into from
Nov 25, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
25 changes: 13 additions & 12 deletions homeassistant/components/stookwijzer/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,36 +4,37 @@

from stookwijzer import Stookwijzer

from homeassistant.config_entries import ConfigEntry
from homeassistant.const import CONF_LATITUDE, CONF_LOCATION, CONF_LONGITUDE, Platform
from homeassistant.core import HomeAssistant
from homeassistant.helpers import issue_registry as ir
from homeassistant.helpers.aiohttp_client import async_get_clientsession

from .const import DOMAIN, LOGGER
from .coordinator import StookwijzerConfigEntry, StookwijzerCoordinator

PLATFORMS = [Platform.SENSOR]


async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
async def async_setup_entry(hass: HomeAssistant, entry: StookwijzerConfigEntry) -> bool:
"""Set up Stookwijzer from a config entry."""
hass.data.setdefault(DOMAIN, {})[entry.entry_id] = Stookwijzer(
async_get_clientsession(hass),
entry.data[CONF_LATITUDE],
entry.data[CONF_LONGITUDE],
)
coordinator = StookwijzerCoordinator(hass, entry)
await coordinator.async_config_entry_first_refresh()

entry.runtime_data = coordinator
await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS)
return True


async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
async def async_unload_entry(
hass: HomeAssistant, entry: StookwijzerConfigEntry
) -> bool:
"""Unload Stookwijzer config entry."""
if unload_ok := await hass.config_entries.async_unload_platforms(entry, PLATFORMS):
del hass.data[DOMAIN][entry.entry_id]
return unload_ok
return await hass.config_entries.async_unload_platforms(entry, PLATFORMS)


async def async_migrate_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
async def async_migrate_entry(
hass: HomeAssistant, entry: StookwijzerConfigEntry
) -> bool:
"""Migrate old entry."""
LOGGER.debug("Migrating from version %s", entry.version)

Expand Down
44 changes: 44 additions & 0 deletions homeassistant/components/stookwijzer/coordinator.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
"""Class representing a Stookwijzer update coordinator."""

from datetime import timedelta

from stookwijzer import Stookwijzer

from homeassistant.config_entries import ConfigEntry
from homeassistant.const import CONF_LATITUDE, CONF_LONGITUDE
from homeassistant.core import HomeAssistant
from homeassistant.helpers.aiohttp_client import async_get_clientsession
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed

from .const import DOMAIN, LOGGER

SCAN_INTERVAL = timedelta(minutes=60)

type StookwijzerConfigEntry = ConfigEntry[StookwijzerCoordinator]


class StookwijzerCoordinator(DataUpdateCoordinator[None]):
"""Stookwijzer update coordinator."""

def __init__(self, hass: HomeAssistant, entry: StookwijzerConfigEntry) -> None:
"""Initialize the coordinator."""
super().__init__(
hass,
LOGGER,
name=DOMAIN,
update_interval=SCAN_INTERVAL,
)
self.client = Stookwijzer(
async_get_clientsession(hass),
entry.data[CONF_LATITUDE],
entry.data[CONF_LONGITUDE],
)

async def _async_update_data(self) -> None:
"""Fetch data from API endpoint."""
await self.client.async_update()
if self.client.advice is None:
raise UpdateFailed(
translation_domain=DOMAIN,
translation_key="no_data_received",
)
9 changes: 3 additions & 6 deletions homeassistant/components/stookwijzer/diagnostics.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,16 @@

from typing import Any

from stookwijzer import Stookwijzer

from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant

from .const import DOMAIN
from .coordinator import StookwijzerConfigEntry


async def async_get_config_entry_diagnostics(
hass: HomeAssistant, entry: ConfigEntry
hass: HomeAssistant, entry: StookwijzerConfigEntry
) -> dict[str, Any]:
"""Return diagnostics for a config entry."""
client: Stookwijzer = hass.data[DOMAIN][entry.entry_id]
client = entry.runtime_data.client
return {
"advice": client.advice,
}
26 changes: 8 additions & 18 deletions homeassistant/components/stookwijzer/sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,40 +4,39 @@

from datetime import timedelta

from stookwijzer import Stookwijzer

from homeassistant.components.sensor import SensorDeviceClass, SensorEntity
from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant
from homeassistant.helpers.device_registry import DeviceEntryType, DeviceInfo
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.helpers.update_coordinator import CoordinatorEntity

from .const import DOMAIN
from .coordinator import StookwijzerConfigEntry, StookwijzerCoordinator

SCAN_INTERVAL = timedelta(minutes=60)
frenck marked this conversation as resolved.
Show resolved Hide resolved


async def async_setup_entry(
hass: HomeAssistant,
entry: ConfigEntry,
entry: StookwijzerConfigEntry,
async_add_entities: AddEntitiesCallback,
) -> None:
"""Set up Stookwijzer sensor from a config entry."""
client = hass.data[DOMAIN][entry.entry_id]
async_add_entities([StookwijzerSensor(client, entry)], update_before_add=True)
async_add_entities([StookwijzerSensor(entry)])


class StookwijzerSensor(SensorEntity):
class StookwijzerSensor(CoordinatorEntity[StookwijzerCoordinator], SensorEntity):
"""Defines a Stookwijzer binary sensor."""

_attr_attribution = "Data provided by atlasleefomgeving.nl"
_attr_device_class = SensorDeviceClass.ENUM
_attr_has_entity_name = True
_attr_translation_key = "advice"

def __init__(self, client: Stookwijzer, entry: ConfigEntry) -> None:
def __init__(self, entry: StookwijzerConfigEntry) -> None:
"""Initialize a Stookwijzer device."""
self._client = client
super().__init__(entry.runtime_data)
self._client = entry.runtime_data.client
self._attr_options = ["code_yellow", "code_orange", "code_red"]
self._attr_unique_id = entry.entry_id
self._attr_device_info = DeviceInfo(
Expand All @@ -47,15 +46,6 @@ def __init__(self, client: Stookwijzer, entry: ConfigEntry) -> None:
configuration_url="https://www.atlasleefomgeving.nl/stookwijzer",
)

async def async_update(self) -> None:
"""Update the data from the Stookwijzer handler."""
await self._client.async_update()

@property
def available(self) -> bool:
"""Return if entity is available."""
return self._client.advice is not None

@property
def native_value(self) -> str | None:
"""Return the state of the device."""
Expand Down
5 changes: 5 additions & 0 deletions homeassistant/components/stookwijzer/strings.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,5 +29,10 @@
"description": "The Stookwijzer integration was unable to automatically migrate your location to a new format the updated integrations uses.\n\nMake sure you are connected to the internet and restart Home Assistant to try again.\n\nIf this doesn't resolve the error, remove and re-add the integration.",
"title": "Migration of your location failed"
}
},
"exceptions": {
"no_data_received": {
"message": "No data received from Stookwijzer."
}
}
}
4 changes: 4 additions & 0 deletions tests/components/stookwijzer/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,10 @@ def mock_stookwijzer() -> Generator[MagicMock]:
"homeassistant.components.stookwijzer.Stookwijzer",
frenck marked this conversation as resolved.
Show resolved Hide resolved
autospec=True,
) as stookwijzer_mock,
patch(
"homeassistant.components.stookwijzer.coordinator.Stookwijzer",
new=stookwijzer_mock,
),
patch(
"homeassistant.components.stookwijzer.config_flow.Stookwijzer",
new=stookwijzer_mock,
Expand Down
Loading