124 lines
4.3 KiB
Python
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,
|
|
)
|