Address late feedback in SFR Box coordinator (#85039)

* Address late feedback in SFR Box coordinator

* One more
This commit is contained in:
epenet 2023-01-03 13:54:15 +01:00 committed by GitHub
parent 4cea5420b3
commit 58b36514ad
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 61 additions and 32 deletions

View File

@ -1,31 +1,39 @@
"""SFR Box.""" """SFR Box."""
from __future__ import annotations from __future__ import annotations
import asyncio
from sfrbox_api.bridge import SFRBox from sfrbox_api.bridge import SFRBox
from sfrbox_api.exceptions import SFRBoxError
from homeassistant.config_entries import ConfigEntry from homeassistant.config_entries import ConfigEntry
from homeassistant.const import CONF_HOST from homeassistant.const import CONF_HOST
from homeassistant.core import HomeAssistant from homeassistant.core import HomeAssistant
from homeassistant.exceptions import ConfigEntryNotReady
from homeassistant.helpers import device_registry as dr from homeassistant.helpers import device_registry as dr
from homeassistant.helpers.httpx_client import get_async_client from homeassistant.helpers.httpx_client import get_async_client
from .const import DOMAIN, PLATFORMS from .const import DOMAIN, PLATFORMS
from .coordinator import DslDataUpdateCoordinator from .coordinator import SFRDataUpdateCoordinator
from .models import DomainData
async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
"""Set up SFR box as config entry.""" """Set up SFR box as config entry."""
box = SFRBox(ip=entry.data[CONF_HOST], client=get_async_client(hass)) box = SFRBox(ip=entry.data[CONF_HOST], client=get_async_client(hass))
try: data = DomainData(
system_info = await box.system_get_info() dsl=SFRDataUpdateCoordinator(hass, box, "dsl", lambda b: b.dsl_get_info()),
except SFRBoxError as err: system=SFRDataUpdateCoordinator(
raise ConfigEntryNotReady( hass, box, "system", lambda b: b.system_get_info()
f"Unable to connect to {entry.data[CONF_HOST]}" ),
) from err )
hass.data.setdefault(DOMAIN, {}) tasks = [
data.dsl.async_config_entry_first_refresh(),
data.system.async_config_entry_first_refresh(),
]
await asyncio.gather(*tasks)
hass.data.setdefault(DOMAIN, {})[entry.entry_id] = data
system_info = data.system.data
device_registry = dr.async_get(hass) device_registry = dr.async_get(hass)
device_registry.async_get_or_create( device_registry.async_get_or_create(
config_entry_id=entry.entry_id, config_entry_id=entry.entry_id,
@ -36,11 +44,6 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
configuration_url=f"http://{entry.data[CONF_HOST]}", configuration_url=f"http://{entry.data[CONF_HOST]}",
) )
hass.data[DOMAIN][entry.entry_id] = {
"box": box,
"dsl_coordinator": DslDataUpdateCoordinator(hass, box),
}
await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS) await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS)
return True return True

View File

@ -1,25 +1,39 @@
"""SFR Box coordinator.""" """SFR Box coordinator."""
from collections.abc import Callable, Coroutine
from datetime import timedelta from datetime import timedelta
import logging import logging
from typing import Any, TypeVar
from sfrbox_api.bridge import SFRBox from sfrbox_api.bridge import SFRBox
from sfrbox_api.models import DslInfo from sfrbox_api.exceptions import SFRBoxError
from homeassistant.core import HomeAssistant from homeassistant.core import HomeAssistant
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
_SCAN_INTERVAL = timedelta(minutes=1) _SCAN_INTERVAL = timedelta(minutes=1)
_T = TypeVar("_T")
class DslDataUpdateCoordinator(DataUpdateCoordinator[DslInfo]):
class SFRDataUpdateCoordinator(DataUpdateCoordinator[_T]):
"""Coordinator to manage data updates.""" """Coordinator to manage data updates."""
def __init__(self, hass: HomeAssistant, box: SFRBox) -> None: def __init__(
self,
hass: HomeAssistant,
box: SFRBox,
name: str,
method: Callable[[SFRBox], Coroutine[Any, Any, _T]],
) -> None:
"""Initialize coordinator.""" """Initialize coordinator."""
self._box = box self.box = box
super().__init__(hass, _LOGGER, name="dsl", update_interval=_SCAN_INTERVAL) self._method = method
super().__init__(hass, _LOGGER, name=name, update_interval=_SCAN_INTERVAL)
async def _async_update_data(self) -> DslInfo: async def _async_update_data(self) -> _T:
"""Update data.""" """Update data."""
return await self._box.dsl_get_info() try:
return await self._method(self.box)
except SFRBoxError as err:
raise UpdateFailed() from err

View File

@ -0,0 +1,14 @@
"""SFR Box models."""
from dataclasses import dataclass
from sfrbox_api.models import DslInfo, SystemInfo
from .coordinator import SFRDataUpdateCoordinator
@dataclass
class DomainData:
"""Domain data for SFR Box."""
dsl: SFRDataUpdateCoordinator[DslInfo]
system: SFRDataUpdateCoordinator[SystemInfo]

View File

@ -2,7 +2,6 @@
from collections.abc import Callable from collections.abc import Callable
from dataclasses import dataclass from dataclasses import dataclass
from sfrbox_api.bridge import SFRBox
from sfrbox_api.models import DslInfo, SystemInfo from sfrbox_api.models import DslInfo, SystemInfo
from homeassistant.components.sensor import ( from homeassistant.components.sensor import (
@ -20,7 +19,8 @@ from homeassistant.helpers.typing import StateType
from homeassistant.helpers.update_coordinator import CoordinatorEntity from homeassistant.helpers.update_coordinator import CoordinatorEntity
from .const import DOMAIN from .const import DOMAIN
from .coordinator import DslDataUpdateCoordinator from .coordinator import SFRDataUpdateCoordinator
from .models import DomainData
@dataclass @dataclass
@ -156,18 +156,16 @@ async def async_setup_entry(
hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback
) -> None: ) -> None:
"""Set up the sensors.""" """Set up the sensors."""
data = hass.data[DOMAIN][entry.entry_id] data: DomainData = hass.data[DOMAIN][entry.entry_id]
box: SFRBox = data["box"]
system_info = await box.system_get_info()
entities = [ entities = [
SFRBoxSensor(data["dsl_coordinator"], description, system_info) SFRBoxSensor(data.dsl, description, data.system.data)
for description in SENSOR_TYPES for description in SENSOR_TYPES
] ]
async_add_entities(entities, True) async_add_entities(entities)
class SFRBoxSensor(CoordinatorEntity[DslDataUpdateCoordinator], SensorEntity): class SFRBoxSensor(CoordinatorEntity[SFRDataUpdateCoordinator[DslInfo]], SensorEntity):
"""SFR Box sensor.""" """SFR Box sensor."""
entity_description: SFRBoxSensorEntityDescription entity_description: SFRBoxSensorEntityDescription
@ -175,7 +173,7 @@ class SFRBoxSensor(CoordinatorEntity[DslDataUpdateCoordinator], SensorEntity):
def __init__( def __init__(
self, self,
coordinator: DslDataUpdateCoordinator, coordinator: SFRDataUpdateCoordinator[DslInfo],
description: SFRBoxSensorEntityDescription, description: SFRBoxSensorEntityDescription,
system_info: SystemInfo, system_info: SystemInfo,
) -> None: ) -> None: