core/homeassistant/components/synology_dsm/entity.py

124 lines
4.3 KiB
Python

"""Entities for Synology DSM."""
from __future__ import annotations
from dataclasses import dataclass
from typing import Any, TypeVar
from homeassistant.helpers.device_registry import DeviceInfo
from homeassistant.helpers.entity import EntityDescription
from homeassistant.helpers.update_coordinator import CoordinatorEntity
from .common import SynoApi
from .const import ATTRIBUTION, DOMAIN
from .coordinator import (
SynologyDSMCentralUpdateCoordinator,
SynologyDSMUpdateCoordinator,
)
_CoordinatorT = TypeVar("_CoordinatorT", bound=SynologyDSMUpdateCoordinator[Any])
@dataclass
class SynologyDSMRequiredKeysMixin:
"""Mixin for required keys."""
api_key: str
@dataclass
class SynologyDSMEntityDescription(EntityDescription, SynologyDSMRequiredKeysMixin):
"""Generic Synology DSM entity description."""
class SynologyDSMBaseEntity(CoordinatorEntity[_CoordinatorT]):
"""Representation of a Synology NAS entry."""
entity_description: SynologyDSMEntityDescription
unique_id: str
_attr_attribution = ATTRIBUTION
_attr_has_entity_name = True
def __init__(
self,
api: SynoApi,
coordinator: _CoordinatorT,
description: SynologyDSMEntityDescription,
) -> None:
"""Initialize the Synology DSM entity."""
super().__init__(coordinator)
self.entity_description = description
self._api = api
self._attr_unique_id: str = (
f"{api.information.serial}_{description.api_key}:{description.key}"
)
self._attr_device_info = DeviceInfo(
identifiers={(DOMAIN, self._api.information.serial)},
name=self._api.network.hostname,
manufacturer="Synology",
model=self._api.information.model,
sw_version=self._api.information.version_string,
configuration_url=self._api.config_url,
)
async def async_added_to_hass(self) -> None:
"""Register entity for updates from API."""
self.async_on_remove(
self._api.subscribe(self.entity_description.api_key, self.unique_id)
)
await super().async_added_to_hass()
class SynologyDSMDeviceEntity(
SynologyDSMBaseEntity[SynologyDSMCentralUpdateCoordinator]
):
"""Representation of a Synology NAS disk or volume entry."""
def __init__(
self,
api: SynoApi,
coordinator: SynologyDSMCentralUpdateCoordinator,
description: SynologyDSMEntityDescription,
device_id: str | None = None,
) -> None:
"""Initialize the Synology DSM disk or volume entity."""
super().__init__(api, coordinator, description)
self._device_id = device_id
self._device_name: str | None = None
self._device_manufacturer: str | None = None
self._device_model: str | None = None
self._device_firmware: str | None = None
self._device_type = None
if "volume" in description.key:
volume = self._api.storage.get_volume(self._device_id)
# Volume does not have a name
self._device_name = volume["id"].replace("_", " ").capitalize()
self._device_manufacturer = "Synology"
self._device_model = self._api.information.model
self._device_firmware = self._api.information.version_string
self._device_type = (
volume["device_type"]
.replace("_", " ")
.replace("raid", "RAID")
.replace("shr", "SHR")
)
elif "disk" in description.key:
disk = self._api.storage.get_disk(self._device_id)
self._device_name = disk["name"]
self._device_manufacturer = disk["vendor"]
self._device_model = disk["model"].strip()
self._device_firmware = disk["firm"]
self._device_type = disk["diskType"]
self._attr_unique_id += f"_{self._device_id}"
self._attr_device_info = DeviceInfo(
identifiers={(DOMAIN, f"{self._api.information.serial}_{self._device_id}")},
name=f"{self._api.network.hostname} ({self._device_name})",
manufacturer=self._device_manufacturer,
model=self._device_model,
sw_version=self._device_firmware,
via_device=(DOMAIN, self._api.information.serial),
configuration_url=self._api.config_url,
)