Store runtime data inside the config entry in Radarr (#119749)

* Store runtime data inside the config entry in Radarr

* move entry typing outside constructor
This commit is contained in:
Robert Hillis 2024-06-17 07:47:49 -04:00 committed by GitHub
parent 9f46b582d3
commit dcca749d50
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 49 additions and 43 deletions

View file

@ -2,7 +2,8 @@
from __future__ import annotations
from typing import Any, cast
from dataclasses import dataclass, fields
from typing import cast
from aiopyarr.models.host_configuration import PyArrHostConfiguration
from aiopyarr.radarr_client import RadarrClient
@ -34,9 +35,22 @@ from .coordinator import (
)
PLATFORMS = [Platform.BINARY_SENSOR, Platform.CALENDAR, Platform.SENSOR]
type RadarrConfigEntry = ConfigEntry[RadarrData]
async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
@dataclass(kw_only=True, slots=True)
class RadarrData:
"""Radarr data type."""
calendar: CalendarUpdateCoordinator
disk_space: DiskSpaceDataUpdateCoordinator
health: HealthDataUpdateCoordinator
movie: MoviesDataUpdateCoordinator
queue: QueueDataUpdateCoordinator
status: StatusDataUpdateCoordinator
async def async_setup_entry(hass: HomeAssistant, entry: RadarrConfigEntry) -> bool:
"""Set up Radarr from a config entry."""
host_configuration = PyArrHostConfiguration(
api_token=entry.data[CONF_API_KEY],
@ -47,27 +61,25 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
host_configuration=host_configuration,
session=async_get_clientsession(hass, entry.data[CONF_VERIFY_SSL]),
)
coordinators: dict[str, RadarrDataUpdateCoordinator[Any]] = {
"calendar": CalendarUpdateCoordinator(hass, host_configuration, radarr),
"disk_space": DiskSpaceDataUpdateCoordinator(hass, host_configuration, radarr),
"health": HealthDataUpdateCoordinator(hass, host_configuration, radarr),
"movie": MoviesDataUpdateCoordinator(hass, host_configuration, radarr),
"queue": QueueDataUpdateCoordinator(hass, host_configuration, radarr),
"status": StatusDataUpdateCoordinator(hass, host_configuration, radarr),
}
for coordinator in coordinators.values():
await coordinator.async_config_entry_first_refresh()
hass.data.setdefault(DOMAIN, {})[entry.entry_id] = coordinators
data = RadarrData(
calendar=CalendarUpdateCoordinator(hass, host_configuration, radarr),
disk_space=DiskSpaceDataUpdateCoordinator(hass, host_configuration, radarr),
health=HealthDataUpdateCoordinator(hass, host_configuration, radarr),
movie=MoviesDataUpdateCoordinator(hass, host_configuration, radarr),
queue=QueueDataUpdateCoordinator(hass, host_configuration, radarr),
status=StatusDataUpdateCoordinator(hass, host_configuration, radarr),
)
for field in fields(data):
await getattr(data, field.name).async_config_entry_first_refresh()
entry.runtime_data = data
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: RadarrConfigEntry) -> bool:
"""Unload a config entry."""
if unload_ok := await hass.config_entries.async_unload_platforms(entry, PLATFORMS):
hass.data[DOMAIN].pop(entry.entry_id)
return unload_ok
return await hass.config_entries.async_unload_platforms(entry, PLATFORMS)
class RadarrEntity(CoordinatorEntity[RadarrDataUpdateCoordinator[T]]):

View file

@ -9,13 +9,12 @@ from homeassistant.components.binary_sensor import (
BinarySensorEntity,
BinarySensorEntityDescription,
)
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import EntityCategory
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from . import RadarrEntity
from .const import DOMAIN, HEALTH_ISSUES
from . import RadarrConfigEntry, RadarrEntity
from .const import HEALTH_ISSUES
BINARY_SENSOR_TYPE = BinarySensorEntityDescription(
key="health",
@ -27,11 +26,11 @@ BINARY_SENSOR_TYPE = BinarySensorEntityDescription(
async def async_setup_entry(
hass: HomeAssistant,
entry: ConfigEntry,
entry: RadarrConfigEntry,
async_add_entities: AddEntitiesCallback,
) -> None:
"""Set up Radarr sensors based on a config entry."""
coordinator = hass.data[DOMAIN][entry.entry_id]["health"]
coordinator = entry.runtime_data.health
async_add_entities([RadarrBinarySensor(coordinator, BINARY_SENSOR_TYPE)])

View file

@ -5,13 +5,11 @@ from __future__ import annotations
from datetime import datetime
from homeassistant.components.calendar import CalendarEntity, CalendarEvent
from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers.entity import EntityDescription
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from . import RadarrEntity
from .const import DOMAIN
from . import RadarrConfigEntry, RadarrEntity
from .coordinator import CalendarUpdateCoordinator, RadarrEvent
CALENDAR_TYPE = EntityDescription(
@ -21,10 +19,12 @@ CALENDAR_TYPE = EntityDescription(
async def async_setup_entry(
hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback
hass: HomeAssistant,
entry: RadarrConfigEntry,
async_add_entities: AddEntitiesCallback,
) -> None:
"""Set up the Radarr calendar entity."""
coordinator = hass.data[DOMAIN][entry.entry_id]["calendar"]
coordinator = entry.runtime_data.calendar
async_add_entities([RadarrCalendarEntity(coordinator, CALENDAR_TYPE)])

View file

@ -11,11 +11,12 @@ from aiopyarr.models.host_configuration import PyArrHostConfiguration
from aiopyarr.radarr_client import RadarrClient
import voluptuous as vol
from homeassistant.config_entries import ConfigEntry, ConfigFlow, ConfigFlowResult
from homeassistant.config_entries import ConfigFlow, ConfigFlowResult
from homeassistant.const import CONF_API_KEY, CONF_URL, CONF_VERIFY_SSL
from homeassistant.core import HomeAssistant
from homeassistant.helpers.aiohttp_client import async_get_clientsession
from . import RadarrConfigEntry
from .const import DEFAULT_NAME, DEFAULT_URL, DOMAIN
@ -23,10 +24,7 @@ class RadarrConfigFlow(ConfigFlow, domain=DOMAIN):
"""Handle a config flow for Radarr."""
VERSION = 1
def __init__(self) -> None:
"""Initialize the flow."""
self.entry: ConfigEntry | None = None
entry: RadarrConfigEntry | None = None
async def async_step_reauth(self, _: Mapping[str, Any]) -> ConfigFlowResult:
"""Handle configuration by re-auth."""

View file

@ -6,7 +6,7 @@ from abc import ABC, abstractmethod
import asyncio
from dataclasses import dataclass
from datetime import date, datetime, timedelta
from typing import Generic, TypeVar, cast
from typing import TYPE_CHECKING, Generic, TypeVar, cast
from aiopyarr import (
Health,
@ -20,13 +20,15 @@ from aiopyarr.models.host_configuration import PyArrHostConfiguration
from aiopyarr.radarr_client import RadarrClient
from homeassistant.components.calendar import CalendarEvent
from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import ConfigEntryAuthFailed
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed
from .const import DEFAULT_MAX_RECORDS, DOMAIN, LOGGER
if TYPE_CHECKING:
from . import RadarrConfigEntry
T = TypeVar("T", bound=SystemStatus | list[RootFolder] | list[Health] | int | None)
@ -45,7 +47,7 @@ class RadarrEvent(CalendarEvent, RadarrEventMixIn):
class RadarrDataUpdateCoordinator(DataUpdateCoordinator[T], Generic[T], ABC):
"""Data update coordinator for the Radarr integration."""
config_entry: ConfigEntry
config_entry: RadarrConfigEntry
_update_interval = timedelta(seconds=30)
def __init__(

View file

@ -15,13 +15,11 @@ from homeassistant.components.sensor import (
SensorEntityDescription,
SensorStateClass,
)
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import EntityCategory, UnitOfInformation
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from . import RadarrEntity
from .const import DOMAIN
from . import RadarrConfigEntry, RadarrEntity
from .coordinator import RadarrDataUpdateCoordinator, T
@ -117,16 +115,13 @@ PARALLEL_UPDATES = 1
async def async_setup_entry(
hass: HomeAssistant,
entry: ConfigEntry,
entry: RadarrConfigEntry,
async_add_entities: AddEntitiesCallback,
) -> None:
"""Set up Radarr sensors based on a config entry."""
coordinators: dict[str, RadarrDataUpdateCoordinator[Any]] = hass.data[DOMAIN][
entry.entry_id
]
entities: list[RadarrSensor[Any]] = []
for coordinator_type, description in SENSOR_TYPES.items():
coordinator = coordinators[coordinator_type]
coordinator = getattr(entry.runtime_data, coordinator_type)
if coordinator_type != "disk_space":
entities.append(RadarrSensor(coordinator, description))
else: