Skip to content
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
33 changes: 18 additions & 15 deletions homeassistant/components/sfr_box/__init__.py
Original file line number Diff line number Diff line change
@@ -1,31 +1,39 @@
"""SFR Box."""
from __future__ import annotations

import asyncio

from sfrbox_api.bridge import SFRBox
from sfrbox_api.exceptions import SFRBoxError

from homeassistant.config_entries import ConfigEntry
from homeassistant.const import CONF_HOST
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import ConfigEntryNotReady
from homeassistant.helpers import device_registry as dr
from homeassistant.helpers.httpx_client import get_async_client

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:
"""Set up SFR box as config entry."""
box = SFRBox(ip=entry.data[CONF_HOST], client=get_async_client(hass))
try:
system_info = await box.system_get_info()
except SFRBoxError as err:
raise ConfigEntryNotReady(
f"Unable to connect to {entry.data[CONF_HOST]}"
) from err
hass.data.setdefault(DOMAIN, {})
data = DomainData(
dsl=SFRDataUpdateCoordinator(hass, box, "dsl", lambda b: b.dsl_get_info()),
system=SFRDataUpdateCoordinator(
hass, box, "system", lambda b: b.system_get_info()
),
)
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.async_get_or_create(
config_entry_id=entry.entry_id,
Expand All @@ -36,11 +44,6 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
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)

return True
Expand Down
30 changes: 22 additions & 8 deletions homeassistant/components/sfr_box/coordinator.py
Original file line number Diff line number Diff line change
@@ -1,25 +1,39 @@
"""SFR Box coordinator."""
from collections.abc import Callable, Coroutine
from datetime import timedelta
import logging
from typing import Any, TypeVar

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.helpers.update_coordinator import DataUpdateCoordinator
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed

_LOGGER = logging.getLogger(__name__)
_SCAN_INTERVAL = timedelta(minutes=1)

_T = TypeVar("_T")

class DslDataUpdateCoordinator(DataUpdateCoordinator[DslInfo]):

class SFRDataUpdateCoordinator(DataUpdateCoordinator[_T]):
"""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."""
self._box = box
super().__init__(hass, _LOGGER, name="dsl", update_interval=_SCAN_INTERVAL)
self.box = box
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."""
return await self._box.dsl_get_info()
try:
return await self._method(self.box)
except SFRBoxError as err:
raise UpdateFailed() from err
14 changes: 14 additions & 0 deletions homeassistant/components/sfr_box/models.py
Original file line number Diff line number Diff line change
@@ -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]
16 changes: 7 additions & 9 deletions homeassistant/components/sfr_box/sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
from collections.abc import Callable
from dataclasses import dataclass

from sfrbox_api.bridge import SFRBox
from sfrbox_api.models import DslInfo, SystemInfo

from homeassistant.components.sensor import (
Expand All @@ -19,7 +18,8 @@
from homeassistant.helpers.update_coordinator import CoordinatorEntity

from .const import DOMAIN
from .coordinator import DslDataUpdateCoordinator
from .coordinator import SFRDataUpdateCoordinator
from .models import DomainData


@dataclass
Expand Down Expand Up @@ -148,25 +148,23 @@ async def async_setup_entry(
hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback
) -> None:
"""Set up the sensors."""
data = hass.data[DOMAIN][entry.entry_id]
box: SFRBox = data["box"]
system_info = await box.system_get_info()
data: DomainData = hass.data[DOMAIN][entry.entry_id]

entities = [
SFRBoxSensor(data["dsl_coordinator"], description, system_info)
SFRBoxSensor(data.dsl, description, data.system.data)
Comment thread
MartinHjelmare marked this conversation as resolved.
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."""

entity_description: SFRBoxSensorEntityDescription

def __init__(
self,
coordinator: DslDataUpdateCoordinator,
coordinator: SFRDataUpdateCoordinator[DslInfo],
description: SFRBoxSensorEntityDescription,
system_info: SystemInfo,
) -> None:
Expand Down