Rework Synology DSM to use config entry runtime_data (#141084)

rework to use config entry runtime_data
This commit is contained in:
Michael 2025-03-23 12:05:40 +01:00 committed by GitHub
parent d8a5881eaa
commit 489c486278
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
15 changed files with 110 additions and 106 deletions

View File

@ -9,7 +9,6 @@ from synology_dsm.api.surveillance_station import SynoSurveillanceStation
from synology_dsm.api.surveillance_station.camera import SynoCamera
from synology_dsm.exceptions import SynologyDSMNotLoggedInException
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import CONF_MAC, CONF_SCAN_INTERVAL, CONF_VERIFY_SSL
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import ConfigEntryNotReady
@ -31,15 +30,16 @@ from .const import (
from .coordinator import (
SynologyDSMCameraUpdateCoordinator,
SynologyDSMCentralUpdateCoordinator,
SynologyDSMConfigEntry,
SynologyDSMData,
SynologyDSMSwitchUpdateCoordinator,
)
from .models import SynologyDSMData
from .service import async_setup_services
_LOGGER = logging.getLogger(__name__)
async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
async def async_setup_entry(hass: HomeAssistant, entry: SynologyDSMConfigEntry) -> bool:
"""Set up Synology DSM sensors."""
# Migrate device identifiers
@ -120,13 +120,12 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
except SYNOLOGY_CONNECTION_EXCEPTIONS as ex:
raise ConfigEntryNotReady from ex
synology_data = SynologyDSMData(
entry.runtime_data = SynologyDSMData(
api=api,
coordinator_central=coordinator_central,
coordinator_cameras=coordinator_cameras,
coordinator_switches=coordinator_switches,
)
hass.data.setdefault(DOMAIN, {})[entry.unique_id] = synology_data
await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS)
entry.async_on_unload(entry.add_update_listener(_async_update_listener))
@ -143,25 +142,28 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
return True
async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
async def async_unload_entry(
hass: HomeAssistant, entry: SynologyDSMConfigEntry
) -> bool:
"""Unload Synology DSM sensors."""
if unload_ok := await hass.config_entries.async_unload_platforms(entry, PLATFORMS):
entry_data: SynologyDSMData = hass.data[DOMAIN][entry.unique_id]
entry_data = entry.runtime_data
await entry_data.api.async_unload()
hass.data[DOMAIN].pop(entry.unique_id)
return unload_ok
async def _async_update_listener(hass: HomeAssistant, entry: ConfigEntry) -> None:
async def _async_update_listener(
hass: HomeAssistant, entry: SynologyDSMConfigEntry
) -> None:
"""Handle options update."""
await hass.config_entries.async_reload(entry.entry_id)
async def async_remove_config_entry_device(
hass: HomeAssistant, entry: ConfigEntry, device_entry: dr.DeviceEntry
hass: HomeAssistant, entry: SynologyDSMConfigEntry, device_entry: dr.DeviceEntry
) -> bool:
"""Remove synology_dsm config entry from a device."""
data: SynologyDSMData = hass.data[DOMAIN][entry.unique_id]
data = entry.runtime_data
api = data.api
assert api.information is not None
serial = api.information.serial

View File

@ -17,7 +17,6 @@ from homeassistant.components.backup import (
BackupNotFound,
suggested_filename,
)
from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers.aiohttp_client import ChunkAsyncStreamIterator
from homeassistant.helpers.json import json_dumps
@ -29,7 +28,7 @@ from .const import (
DATA_BACKUP_AGENT_LISTENERS,
DOMAIN,
)
from .models import SynologyDSMData
from .coordinator import SynologyDSMConfigEntry
LOGGER = logging.getLogger(__name__)
@ -47,18 +46,17 @@ async def async_get_backup_agents(
hass: HomeAssistant,
) -> list[BackupAgent]:
"""Return a list of backup agents."""
if not (
entries := hass.config_entries.async_loaded_entries(DOMAIN)
) or not hass.data.get(DOMAIN):
entries: list[SynologyDSMConfigEntry] = hass.config_entries.async_loaded_entries(
DOMAIN
)
if not entries:
LOGGER.debug("No proper config entry found")
return []
syno_datas: dict[str, SynologyDSMData] = hass.data[DOMAIN]
return [
SynologyDSMBackupAgent(hass, entry, entry.unique_id)
for entry in entries
if entry.unique_id is not None
and (syno_data := syno_datas.get(entry.unique_id))
and syno_data.api.file_station
and entry.runtime_data.api.file_station
and entry.options.get(CONF_BACKUP_PATH)
]
@ -91,7 +89,9 @@ class SynologyDSMBackupAgent(BackupAgent):
domain = DOMAIN
def __init__(self, hass: HomeAssistant, entry: ConfigEntry, unique_id: str) -> None:
def __init__(
self, hass: HomeAssistant, entry: SynologyDSMConfigEntry, unique_id: str
) -> None:
"""Initialize the Synology DSM backup agent."""
super().__init__()
LOGGER.debug("Initializing Synology DSM backup agent for %s", entry.unique_id)
@ -100,7 +100,7 @@ class SynologyDSMBackupAgent(BackupAgent):
self.path = (
f"{entry.options[CONF_BACKUP_SHARE]}/{entry.options[CONF_BACKUP_PATH]}"
)
syno_data: SynologyDSMData = hass.data[DOMAIN][entry.unique_id]
syno_data = entry.runtime_data
self.api = syno_data.api
self.backup_base_names: dict[str, str] = {}

View File

@ -12,20 +12,17 @@ from homeassistant.components.binary_sensor import (
BinarySensorEntity,
BinarySensorEntityDescription,
)
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import CONF_DISKS, EntityCategory
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
from . import SynoApi
from .const import DOMAIN
from .coordinator import SynologyDSMCentralUpdateCoordinator
from .coordinator import SynologyDSMCentralUpdateCoordinator, SynologyDSMConfigEntry
from .entity import (
SynologyDSMBaseEntity,
SynologyDSMDeviceEntity,
SynologyDSMEntityDescription,
)
from .models import SynologyDSMData
@dataclass(frozen=True, kw_only=True)
@ -64,11 +61,11 @@ STORAGE_DISK_BINARY_SENSORS: tuple[SynologyDSMBinarySensorEntityDescription, ...
async def async_setup_entry(
hass: HomeAssistant,
entry: ConfigEntry,
entry: SynologyDSMConfigEntry,
async_add_entities: AddConfigEntryEntitiesCallback,
) -> None:
"""Set up the Synology NAS binary sensor."""
data: SynologyDSMData = hass.data[DOMAIN][entry.unique_id]
data = entry.runtime_data
api = data.api
coordinator = data.coordinator_central
assert api.storage is not None

View File

@ -12,7 +12,6 @@ from homeassistant.components.button import (
ButtonEntity,
ButtonEntityDescription,
)
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import EntityCategory
from homeassistant.core import HomeAssistant
from homeassistant.helpers.device_registry import DeviceInfo
@ -20,7 +19,7 @@ from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
from . import SynoApi
from .const import DOMAIN
from .models import SynologyDSMData
from .coordinator import SynologyDSMConfigEntry
LOGGER = logging.getLogger(__name__)
@ -52,11 +51,11 @@ BUTTONS: Final = [
async def async_setup_entry(
hass: HomeAssistant,
entry: ConfigEntry,
entry: SynologyDSMConfigEntry,
async_add_entities: AddConfigEntryEntitiesCallback,
) -> None:
"""Set buttons for device."""
data: SynologyDSMData = hass.data[DOMAIN][entry.unique_id]
data = entry.runtime_data
async_add_entities(SynologyDSMButton(data.api, button) for button in BUTTONS)

View File

@ -16,7 +16,6 @@ from homeassistant.components.camera import (
CameraEntityDescription,
CameraEntityFeature,
)
from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers.device_registry import DeviceInfo
from homeassistant.helpers.dispatcher import async_dispatcher_connect
@ -29,9 +28,8 @@ from .const import (
DOMAIN,
SIGNAL_CAMERA_SOURCE_CHANGED,
)
from .coordinator import SynologyDSMCameraUpdateCoordinator
from .coordinator import SynologyDSMCameraUpdateCoordinator, SynologyDSMConfigEntry
from .entity import SynologyDSMBaseEntity, SynologyDSMEntityDescription
from .models import SynologyDSMData
_LOGGER = logging.getLogger(__name__)
@ -47,11 +45,11 @@ class SynologyDSMCameraEntityDescription(
async def async_setup_entry(
hass: HomeAssistant,
entry: ConfigEntry,
entry: SynologyDSMConfigEntry,
async_add_entities: AddConfigEntryEntitiesCallback,
) -> None:
"""Set up the Synology NAS cameras."""
data: SynologyDSMData = hass.data[DOMAIN][entry.unique_id]
data = entry.runtime_data
if coordinator := data.coordinator_cameras:
async_add_entities(
SynoDSMCamera(data.api, coordinator, camera_id)

View File

@ -72,7 +72,7 @@ from .const import (
DOMAIN,
SYNOLOGY_CONNECTION_EXCEPTIONS,
)
from .models import SynologyDSMData
from .coordinator import SynologyDSMConfigEntry
_LOGGER = logging.getLogger(__name__)
@ -131,7 +131,7 @@ class SynologyDSMFlowHandler(ConfigFlow, domain=DOMAIN):
@staticmethod
@callback
def async_get_options_flow(
config_entry: ConfigEntry,
config_entry: SynologyDSMConfigEntry,
) -> SynologyDSMOptionsFlowHandler:
"""Get the options flow for this handler."""
return SynologyDSMOptionsFlowHandler()
@ -444,6 +444,8 @@ class SynologyDSMFlowHandler(ConfigFlow, domain=DOMAIN):
class SynologyDSMOptionsFlowHandler(OptionsFlow):
"""Handle a option flow."""
config_entry: SynologyDSMConfigEntry
async def async_step_init(
self, user_input: dict[str, Any] | None = None
) -> ConfigFlowResult:
@ -451,7 +453,7 @@ class SynologyDSMOptionsFlowHandler(OptionsFlow):
if user_input is not None:
return self.async_create_entry(title="", data=user_input)
syno_data: SynologyDSMData = self.hass.data[DOMAIN][self.config_entry.unique_id]
syno_data = self.config_entry.runtime_data
data_schema = vol.Schema(
{

View File

@ -3,6 +3,7 @@
from __future__ import annotations
from collections.abc import Awaitable, Callable, Coroutine
from dataclasses import dataclass
from datetime import timedelta
import logging
from typing import Any, Concatenate
@ -28,6 +29,19 @@ from .const import (
_LOGGER = logging.getLogger(__name__)
@dataclass
class SynologyDSMData:
"""Data for the synology_dsm integration."""
api: SynoApi
coordinator_central: SynologyDSMCentralUpdateCoordinator
coordinator_cameras: SynologyDSMCameraUpdateCoordinator | None
coordinator_switches: SynologyDSMSwitchUpdateCoordinator | None
type SynologyDSMConfigEntry = ConfigEntry[SynologyDSMData]
def async_re_login_on_expired[_T: SynologyDSMUpdateCoordinator[Any], **_P, _R](
func: Callable[Concatenate[_T, _P], Awaitable[_R]],
) -> Callable[Concatenate[_T, _P], Coroutine[Any, Any, _R]]:
@ -57,12 +71,12 @@ def async_re_login_on_expired[_T: SynologyDSMUpdateCoordinator[Any], **_P, _R](
class SynologyDSMUpdateCoordinator[_DataT](DataUpdateCoordinator[_DataT]):
"""DataUpdateCoordinator base class for synology_dsm."""
config_entry: ConfigEntry
config_entry: SynologyDSMConfigEntry
def __init__(
self,
hass: HomeAssistant,
entry: ConfigEntry,
entry: SynologyDSMConfigEntry,
api: SynoApi,
update_interval: timedelta,
) -> None:
@ -85,7 +99,7 @@ class SynologyDSMSwitchUpdateCoordinator(
def __init__(
self,
hass: HomeAssistant,
entry: ConfigEntry,
entry: SynologyDSMConfigEntry,
api: SynoApi,
) -> None:
"""Initialize DataUpdateCoordinator for switch devices."""
@ -116,7 +130,7 @@ class SynologyDSMCentralUpdateCoordinator(SynologyDSMUpdateCoordinator[None]):
def __init__(
self,
hass: HomeAssistant,
entry: ConfigEntry,
entry: SynologyDSMConfigEntry,
api: SynoApi,
) -> None:
"""Initialize DataUpdateCoordinator for central device."""
@ -136,7 +150,7 @@ class SynologyDSMCameraUpdateCoordinator(
def __init__(
self,
hass: HomeAssistant,
entry: ConfigEntry,
entry: SynologyDSMConfigEntry,
api: SynoApi,
) -> None:
"""Initialize DataUpdateCoordinator for cameras."""

View File

@ -6,21 +6,20 @@ from typing import Any
from homeassistant.components.camera import diagnostics as camera_diagnostics
from homeassistant.components.diagnostics import async_redact_data
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import CONF_PASSWORD, CONF_USERNAME
from homeassistant.core import HomeAssistant
from .const import CONF_DEVICE_TOKEN, DOMAIN
from .models import SynologyDSMData
from .const import CONF_DEVICE_TOKEN
from .coordinator import SynologyDSMConfigEntry
TO_REDACT = {CONF_USERNAME, CONF_PASSWORD, CONF_DEVICE_TOKEN}
async def async_get_config_entry_diagnostics(
hass: HomeAssistant, entry: ConfigEntry
hass: HomeAssistant, entry: SynologyDSMConfigEntry
) -> dict[str, Any]:
"""Return diagnostics for a config entry."""
data: SynologyDSMData = hass.data[DOMAIN][entry.unique_id]
data = entry.runtime_data
syno_api = data.api
dsm_info = syno_api.dsm.information

View File

@ -2,6 +2,7 @@
from __future__ import annotations
from logging import getLogger
import mimetypes
from aiohttp import web
@ -22,7 +23,9 @@ from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant
from .const import DOMAIN, SHARED_SUFFIX
from .models import SynologyDSMData
from .coordinator import SynologyDSMConfigEntry, SynologyDSMData
LOGGER = getLogger(__name__)
async def async_get_media_source(hass: HomeAssistant) -> MediaSource:
@ -41,15 +44,13 @@ class SynologyPhotosMediaSourceIdentifier:
"""Split identifier into parts."""
parts = identifier.split("/")
self.unique_id = None
self.unique_id = parts[0]
self.album_id = None
self.cache_key = None
self.file_name = None
self.is_shared = False
self.passphrase = ""
self.unique_id = parts[0]
if len(parts) > 1:
album_parts = parts[1].split("_")
self.album_id = album_parts[0]
@ -82,7 +83,7 @@ class SynologyPhotosMediaSource(MediaSource):
item: MediaSourceItem,
) -> BrowseMediaSource:
"""Return media."""
if not self.hass.data.get(DOMAIN):
if not self.hass.config_entries.async_loaded_entries(DOMAIN):
raise BrowseError("Diskstation not initialized")
return BrowseMediaSource(
domain=DOMAIN,
@ -116,7 +117,13 @@ class SynologyPhotosMediaSource(MediaSource):
for entry in self.entries
]
identifier = SynologyPhotosMediaSourceIdentifier(item.identifier)
diskstation: SynologyDSMData = self.hass.data[DOMAIN][identifier.unique_id]
entry: SynologyDSMConfigEntry | None = (
self.hass.config_entries.async_entry_for_domain_unique_id(
DOMAIN, identifier.unique_id
)
)
assert entry
diskstation = entry.runtime_data
assert diskstation.api.photos is not None
if identifier.album_id is None:
@ -244,7 +251,7 @@ class SynologyDsmMediaView(http.HomeAssistantView):
self, request: web.Request, source_dir_id: str, location: str
) -> web.Response:
"""Start a GET request."""
if not self.hass.data.get(DOMAIN):
if not self.hass.config_entries.async_loaded_entries(DOMAIN):
raise web.HTTPNotFound
# location: {cache_key}/{filename}
cache_key, file_name, passphrase = location.split("/")
@ -257,7 +264,13 @@ class SynologyDsmMediaView(http.HomeAssistantView):
if not isinstance(mime_type, str):
raise web.HTTPNotFound
diskstation: SynologyDSMData = self.hass.data[DOMAIN][source_dir_id]
entry: SynologyDSMConfigEntry | None = (
self.hass.config_entries.async_entry_for_domain_unique_id(
DOMAIN, source_dir_id
)
)
assert entry
diskstation = entry.runtime_data
assert diskstation.api.photos is not None
item = SynoPhotosItem(image_id, "", "", "", cache_key, "xl", shared, passphrase)
try:

View File

@ -1,22 +0,0 @@
"""The synology_dsm integration models."""
from __future__ import annotations
from dataclasses import dataclass
from .common import SynoApi
from .coordinator import (
SynologyDSMCameraUpdateCoordinator,
SynologyDSMCentralUpdateCoordinator,
SynologyDSMSwitchUpdateCoordinator,
)
@dataclass
class SynologyDSMData:
"""Data for the synology_dsm integration."""
api: SynoApi
coordinator_central: SynologyDSMCentralUpdateCoordinator
coordinator_cameras: SynologyDSMCameraUpdateCoordinator | None
coordinator_switches: SynologyDSMSwitchUpdateCoordinator | None

View File

@ -11,7 +11,6 @@ import voluptuous as vol
from homeassistant import data_entry_flow
from homeassistant.components.repairs import ConfirmRepairFlow, RepairsFlow
from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant
from homeassistant.helpers import issue_registry as ir
from homeassistant.helpers.selector import (
@ -28,7 +27,7 @@ from .const import (
ISSUE_MISSING_BACKUP_SETUP,
SYNOLOGY_CONNECTION_EXCEPTIONS,
)
from .models import SynologyDSMData
from .coordinator import SynologyDSMConfigEntry
LOGGER = logging.getLogger(__name__)
@ -36,7 +35,7 @@ LOGGER = logging.getLogger(__name__)
class MissingBackupSetupRepairFlow(RepairsFlow):
"""Handler for an issue fixing flow."""
def __init__(self, entry: ConfigEntry, issue_id: str) -> None:
def __init__(self, entry: SynologyDSMConfigEntry, issue_id: str) -> None:
"""Create flow."""
self.entry = entry
self.issue_id = issue_id
@ -59,7 +58,7 @@ class MissingBackupSetupRepairFlow(RepairsFlow):
) -> data_entry_flow.FlowResult:
"""Handle the confirm step of a fix flow."""
syno_data: SynologyDSMData = self.hass.data[DOMAIN][self.entry.unique_id]
syno_data = self.entry.runtime_data
if user_input is not None:
self.hass.config_entries.async_update_entry(

View File

@ -16,7 +16,6 @@ from homeassistant.components.sensor import (
SensorEntityDescription,
SensorStateClass,
)
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import (
CONF_DISKS,
PERCENTAGE,
@ -31,14 +30,13 @@ from homeassistant.helpers.typing import StateType
from homeassistant.util.dt import utcnow
from . import SynoApi
from .const import CONF_VOLUMES, DOMAIN, ENTITY_UNIT_LOAD
from .coordinator import SynologyDSMCentralUpdateCoordinator
from .const import CONF_VOLUMES, ENTITY_UNIT_LOAD
from .coordinator import SynologyDSMCentralUpdateCoordinator, SynologyDSMConfigEntry
from .entity import (
SynologyDSMBaseEntity,
SynologyDSMDeviceEntity,
SynologyDSMEntityDescription,
)
from .models import SynologyDSMData
@dataclass(frozen=True, kw_only=True)
@ -287,11 +285,11 @@ INFORMATION_SENSORS: tuple[SynologyDSMSensorEntityDescription, ...] = (
async def async_setup_entry(
hass: HomeAssistant,
entry: ConfigEntry,
entry: SynologyDSMConfigEntry,
async_add_entities: AddConfigEntryEntitiesCallback,
) -> None:
"""Set up the Synology NAS Sensor."""
data: SynologyDSMData = hass.data[DOMAIN][entry.unique_id]
data = entry.runtime_data
api = data.api
coordinator = data.coordinator_central
storage = api.storage

View File

@ -3,13 +3,14 @@
from __future__ import annotations
import logging
from typing import cast
from synology_dsm.exceptions import SynologyDSMException
from homeassistant.core import HomeAssistant, ServiceCall
from .const import CONF_SERIAL, DOMAIN, SERVICE_REBOOT, SERVICE_SHUTDOWN, SERVICES
from .models import SynologyDSMData
from .coordinator import SynologyDSMConfigEntry
LOGGER = logging.getLogger(__name__)
@ -19,11 +20,20 @@ async def async_setup_services(hass: HomeAssistant) -> None:
async def service_handler(call: ServiceCall) -> None:
"""Handle service call."""
serial = call.data.get(CONF_SERIAL)
dsm_devices = hass.data[DOMAIN]
serial: str | None = call.data.get(CONF_SERIAL)
entries: list[SynologyDSMConfigEntry] = (
hass.config_entries.async_loaded_entries(DOMAIN)
)
dsm_devices = {
cast(str, entry.unique_id): entry.runtime_data for entry in entries
}
if serial:
dsm_device: SynologyDSMData = hass.data[DOMAIN][serial]
entry: SynologyDSMConfigEntry | None = (
hass.config_entries.async_entry_for_domain_unique_id(DOMAIN, serial)
)
assert entry
dsm_device = entry.runtime_data
elif len(dsm_devices) == 1:
dsm_device = next(iter(dsm_devices.values()))
serial = next(iter(dsm_devices))
@ -39,7 +49,7 @@ async def async_setup_services(hass: HomeAssistant) -> None:
return
if call.service in [SERVICE_REBOOT, SERVICE_SHUTDOWN]:
if serial not in hass.data[DOMAIN]:
if serial not in dsm_devices:
LOGGER.error("DSM with specified serial %s not found", serial)
return
LOGGER.debug("%s DSM with serial %s", call.service, serial)
@ -50,7 +60,7 @@ async def async_setup_services(hass: HomeAssistant) -> None:
),
call.service,
)
dsm_device = hass.data[DOMAIN][serial]
dsm_device = dsm_devices[serial]
dsm_api = dsm_device.api
try:
await getattr(dsm_api, f"async_{call.service}")()

View File

@ -9,16 +9,14 @@ from typing import Any
from synology_dsm.api.surveillance_station import SynoSurveillanceStation
from homeassistant.components.switch import SwitchEntity, SwitchEntityDescription
from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant
from homeassistant.helpers.device_registry import DeviceInfo
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
from . import SynoApi
from .const import DOMAIN
from .coordinator import SynologyDSMSwitchUpdateCoordinator
from .coordinator import SynologyDSMConfigEntry, SynologyDSMSwitchUpdateCoordinator
from .entity import SynologyDSMBaseEntity, SynologyDSMEntityDescription
from .models import SynologyDSMData
_LOGGER = logging.getLogger(__name__)
@ -41,11 +39,11 @@ SURVEILLANCE_SWITCH: tuple[SynologyDSMSwitchEntityDescription, ...] = (
async def async_setup_entry(
hass: HomeAssistant,
entry: ConfigEntry,
entry: SynologyDSMConfigEntry,
async_add_entities: AddConfigEntryEntitiesCallback,
) -> None:
"""Set up the Synology NAS switch."""
data: SynologyDSMData = hass.data[DOMAIN][entry.unique_id]
data = entry.runtime_data
if coordinator := data.coordinator_switches:
assert coordinator.version is not None
async_add_entities(

View File

@ -9,15 +9,12 @@ from synology_dsm.api.core.upgrade import SynoCoreUpgrade
from yarl import URL
from homeassistant.components.update import UpdateEntity, UpdateEntityDescription
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import EntityCategory
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
from .const import DOMAIN
from .coordinator import SynologyDSMCentralUpdateCoordinator
from .coordinator import SynologyDSMCentralUpdateCoordinator, SynologyDSMConfigEntry
from .entity import SynologyDSMBaseEntity, SynologyDSMEntityDescription
from .models import SynologyDSMData
@dataclass(frozen=True, kw_only=True)
@ -39,11 +36,11 @@ UPDATE_ENTITIES: Final = [
async def async_setup_entry(
hass: HomeAssistant,
entry: ConfigEntry,
entry: SynologyDSMConfigEntry,
async_add_entities: AddConfigEntryEntitiesCallback,
) -> None:
"""Set up Synology DSM update entities."""
data: SynologyDSMData = hass.data[DOMAIN][entry.unique_id]
data = entry.runtime_data
async_add_entities(
SynoDSMUpdateEntity(data.api, data.coordinator_central, description)
for description in UPDATE_ENTITIES