mirror of
https://github.com/home-assistant/core.git
synced 2025-07-19 19:27:45 +00:00
Use EntityDescription - synology_dsm (#55407)
This commit is contained in:
parent
f5cd321185
commit
4eba2ccebc
@ -26,14 +26,9 @@ from synology_dsm.exceptions import (
|
|||||||
SynologyDSMRequestException,
|
SynologyDSMRequestException,
|
||||||
)
|
)
|
||||||
|
|
||||||
from homeassistant.components.sensor import ATTR_STATE_CLASS
|
|
||||||
from homeassistant.config_entries import SOURCE_REAUTH, ConfigEntry
|
from homeassistant.config_entries import SOURCE_REAUTH, ConfigEntry
|
||||||
from homeassistant.const import (
|
from homeassistant.const import (
|
||||||
ATTR_ATTRIBUTION,
|
ATTR_ATTRIBUTION,
|
||||||
ATTR_DEVICE_CLASS,
|
|
||||||
ATTR_ICON,
|
|
||||||
ATTR_NAME,
|
|
||||||
ATTR_UNIT_OF_MEASUREMENT,
|
|
||||||
CONF_HOST,
|
CONF_HOST,
|
||||||
CONF_MAC,
|
CONF_MAC,
|
||||||
CONF_PASSWORD,
|
CONF_PASSWORD,
|
||||||
@ -68,7 +63,6 @@ from .const import (
|
|||||||
DEFAULT_SCAN_INTERVAL,
|
DEFAULT_SCAN_INTERVAL,
|
||||||
DEFAULT_VERIFY_SSL,
|
DEFAULT_VERIFY_SSL,
|
||||||
DOMAIN,
|
DOMAIN,
|
||||||
ENTITY_ENABLE,
|
|
||||||
EXCEPTION_DETAILS,
|
EXCEPTION_DETAILS,
|
||||||
EXCEPTION_UNKNOWN,
|
EXCEPTION_UNKNOWN,
|
||||||
PLATFORMS,
|
PLATFORMS,
|
||||||
@ -82,7 +76,7 @@ from .const import (
|
|||||||
SYSTEM_LOADED,
|
SYSTEM_LOADED,
|
||||||
UNDO_UPDATE_LISTENER,
|
UNDO_UPDATE_LISTENER,
|
||||||
UTILISATION_SENSORS,
|
UTILISATION_SENSORS,
|
||||||
EntityInfo,
|
SynologyDSMEntityDescription,
|
||||||
)
|
)
|
||||||
|
|
||||||
CONFIG_SCHEMA = cv.deprecated(DOMAIN)
|
CONFIG_SCHEMA = cv.deprecated(DOMAIN)
|
||||||
@ -109,12 +103,12 @@ async def async_setup_entry( # noqa: C901
|
|||||||
if "SYNO." in entity_entry.unique_id:
|
if "SYNO." in entity_entry.unique_id:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
entries = {
|
entries = (
|
||||||
**STORAGE_DISK_BINARY_SENSORS,
|
*STORAGE_DISK_BINARY_SENSORS,
|
||||||
**STORAGE_DISK_SENSORS,
|
*STORAGE_DISK_SENSORS,
|
||||||
**STORAGE_VOL_SENSORS,
|
*STORAGE_VOL_SENSORS,
|
||||||
**UTILISATION_SENSORS,
|
*UTILISATION_SENSORS,
|
||||||
}
|
)
|
||||||
infos = entity_entry.unique_id.split("_")
|
infos = entity_entry.unique_id.split("_")
|
||||||
serial = infos.pop(0)
|
serial = infos.pop(0)
|
||||||
label = infos.pop(0)
|
label = infos.pop(0)
|
||||||
@ -129,22 +123,22 @@ async def async_setup_entry( # noqa: C901
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
entity_type: str | None = None
|
entity_type: str | None = None
|
||||||
for entity_key, entity_attrs in entries.items():
|
for description in entries:
|
||||||
if (
|
if (
|
||||||
device_id
|
device_id
|
||||||
and entity_attrs[ATTR_NAME] == "Status"
|
and description.name == "Status"
|
||||||
and "Status" in entity_entry.unique_id
|
and "Status" in entity_entry.unique_id
|
||||||
and "(Smart)" not in entity_entry.unique_id
|
and "(Smart)" not in entity_entry.unique_id
|
||||||
):
|
):
|
||||||
if "sd" in device_id and "disk" in entity_key:
|
if "sd" in device_id and "disk" in description.key:
|
||||||
entity_type = entity_key
|
entity_type = description.key
|
||||||
continue
|
continue
|
||||||
if "volume" in device_id and "volume" in entity_key:
|
if "volume" in device_id and "volume" in description.key:
|
||||||
entity_type = entity_key
|
entity_type = description.key
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if entity_attrs[ATTR_NAME] == label:
|
if description.name == label:
|
||||||
entity_type = entity_key
|
entity_type = description.key
|
||||||
|
|
||||||
if entity_type is None:
|
if entity_type is None:
|
||||||
return None
|
return None
|
||||||
@ -604,51 +598,25 @@ class SynoApi:
|
|||||||
class SynologyDSMBaseEntity(CoordinatorEntity):
|
class SynologyDSMBaseEntity(CoordinatorEntity):
|
||||||
"""Representation of a Synology NAS entry."""
|
"""Representation of a Synology NAS entry."""
|
||||||
|
|
||||||
|
entity_description: SynologyDSMEntityDescription
|
||||||
|
unique_id: str
|
||||||
|
_attr_extra_state_attributes = {ATTR_ATTRIBUTION: ATTRIBUTION}
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
api: SynoApi,
|
api: SynoApi,
|
||||||
entity_type: str,
|
|
||||||
entity_info: EntityInfo,
|
|
||||||
coordinator: DataUpdateCoordinator[dict[str, dict[str, Any]]],
|
coordinator: DataUpdateCoordinator[dict[str, dict[str, Any]]],
|
||||||
|
description: SynologyDSMEntityDescription,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Initialize the Synology DSM entity."""
|
"""Initialize the Synology DSM entity."""
|
||||||
super().__init__(coordinator)
|
super().__init__(coordinator)
|
||||||
|
self.entity_description = description
|
||||||
|
|
||||||
self._api = api
|
self._api = api
|
||||||
self._api_key = entity_type.split(":")[0]
|
self._attr_name = f"{api.network.hostname} {description.name}"
|
||||||
self.entity_type = entity_type.split(":")[-1]
|
self._attr_unique_id: str = (
|
||||||
self._name = f"{api.network.hostname} {entity_info[ATTR_NAME]}"
|
f"{api.information.serial}_{description.api_key}:{description.key}"
|
||||||
self._class = entity_info[ATTR_DEVICE_CLASS]
|
)
|
||||||
self._enable_default = entity_info[ENTITY_ENABLE]
|
|
||||||
self._icon = entity_info[ATTR_ICON]
|
|
||||||
self._unit = entity_info[ATTR_UNIT_OF_MEASUREMENT]
|
|
||||||
self._unique_id = f"{self._api.information.serial}_{entity_type}"
|
|
||||||
self._attr_state_class = entity_info[ATTR_STATE_CLASS]
|
|
||||||
|
|
||||||
@property
|
|
||||||
def unique_id(self) -> str:
|
|
||||||
"""Return a unique ID."""
|
|
||||||
return self._unique_id
|
|
||||||
|
|
||||||
@property
|
|
||||||
def name(self) -> str:
|
|
||||||
"""Return the name."""
|
|
||||||
return self._name
|
|
||||||
|
|
||||||
@property
|
|
||||||
def icon(self) -> str | None:
|
|
||||||
"""Return the icon."""
|
|
||||||
return self._icon
|
|
||||||
|
|
||||||
@property
|
|
||||||
def device_class(self) -> str | None:
|
|
||||||
"""Return the class of this device."""
|
|
||||||
return self._class
|
|
||||||
|
|
||||||
@property
|
|
||||||
def extra_state_attributes(self) -> dict[str, Any]:
|
|
||||||
"""Return the state attributes."""
|
|
||||||
return {ATTR_ATTRIBUTION: ATTRIBUTION}
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def device_info(self) -> DeviceInfo:
|
def device_info(self) -> DeviceInfo:
|
||||||
@ -661,14 +629,11 @@ class SynologyDSMBaseEntity(CoordinatorEntity):
|
|||||||
"sw_version": self._api.information.version_string,
|
"sw_version": self._api.information.version_string,
|
||||||
}
|
}
|
||||||
|
|
||||||
@property
|
|
||||||
def entity_registry_enabled_default(self) -> bool:
|
|
||||||
"""Return if the entity should be enabled when first added to the entity registry."""
|
|
||||||
return self._enable_default
|
|
||||||
|
|
||||||
async def async_added_to_hass(self) -> None:
|
async def async_added_to_hass(self) -> None:
|
||||||
"""Register entity for updates from API."""
|
"""Register entity for updates from API."""
|
||||||
self.async_on_remove(self._api.subscribe(self._api_key, self.unique_id))
|
self.async_on_remove(
|
||||||
|
self._api.subscribe(self.entity_description.api_key, self.unique_id)
|
||||||
|
)
|
||||||
await super().async_added_to_hass()
|
await super().async_added_to_hass()
|
||||||
|
|
||||||
|
|
||||||
@ -678,13 +643,12 @@ class SynologyDSMDeviceEntity(SynologyDSMBaseEntity):
|
|||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
api: SynoApi,
|
api: SynoApi,
|
||||||
entity_type: str,
|
|
||||||
entity_info: EntityInfo,
|
|
||||||
coordinator: DataUpdateCoordinator[dict[str, dict[str, Any]]],
|
coordinator: DataUpdateCoordinator[dict[str, dict[str, Any]]],
|
||||||
|
description: SynologyDSMEntityDescription,
|
||||||
device_id: str | None = None,
|
device_id: str | None = None,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Initialize the Synology DSM disk or volume entity."""
|
"""Initialize the Synology DSM disk or volume entity."""
|
||||||
super().__init__(api, entity_type, entity_info, coordinator)
|
super().__init__(api, coordinator, description)
|
||||||
self._device_id = device_id
|
self._device_id = device_id
|
||||||
self._device_name: str | None = None
|
self._device_name: str | None = None
|
||||||
self._device_manufacturer: str | None = None
|
self._device_manufacturer: str | None = None
|
||||||
@ -692,7 +656,7 @@ class SynologyDSMDeviceEntity(SynologyDSMBaseEntity):
|
|||||||
self._device_firmware: str | None = None
|
self._device_firmware: str | None = None
|
||||||
self._device_type = None
|
self._device_type = None
|
||||||
|
|
||||||
if "volume" in entity_type:
|
if "volume" in description.key:
|
||||||
volume = self._api.storage.get_volume(self._device_id)
|
volume = self._api.storage.get_volume(self._device_id)
|
||||||
# Volume does not have a name
|
# Volume does not have a name
|
||||||
self._device_name = volume["id"].replace("_", " ").capitalize()
|
self._device_name = volume["id"].replace("_", " ").capitalize()
|
||||||
@ -705,7 +669,7 @@ class SynologyDSMDeviceEntity(SynologyDSMBaseEntity):
|
|||||||
.replace("raid", "RAID")
|
.replace("raid", "RAID")
|
||||||
.replace("shr", "SHR")
|
.replace("shr", "SHR")
|
||||||
)
|
)
|
||||||
elif "disk" in entity_type:
|
elif "disk" in description.key:
|
||||||
disk = self._api.storage.get_disk(self._device_id)
|
disk = self._api.storage.get_disk(self._device_id)
|
||||||
self._device_name = disk["name"]
|
self._device_name = disk["name"]
|
||||||
self._device_manufacturer = disk["vendor"]
|
self._device_manufacturer = disk["vendor"]
|
||||||
@ -713,9 +677,9 @@ class SynologyDSMDeviceEntity(SynologyDSMBaseEntity):
|
|||||||
self._device_firmware = disk["firm"]
|
self._device_firmware = disk["firm"]
|
||||||
self._device_type = disk["diskType"]
|
self._device_type = disk["diskType"]
|
||||||
self._name = (
|
self._name = (
|
||||||
f"{self._api.network.hostname} {self._device_name} {entity_info[ATTR_NAME]}"
|
f"{self._api.network.hostname} {self._device_name} {description.name}"
|
||||||
)
|
)
|
||||||
self._unique_id += f"_{self._device_id}"
|
self._attr_unique_id += f"_{self._device_id}"
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def available(self) -> bool:
|
def available(self) -> bool:
|
||||||
|
@ -1,11 +1,14 @@
|
|||||||
"""Support for Synology DSM binary sensors."""
|
"""Support for Synology DSM binary sensors."""
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
from homeassistant.components.binary_sensor import BinarySensorEntity
|
from homeassistant.components.binary_sensor import BinarySensorEntity
|
||||||
from homeassistant.config_entries import ConfigEntry
|
from homeassistant.config_entries import ConfigEntry
|
||||||
from homeassistant.const import CONF_DISKS
|
from homeassistant.const import CONF_DISKS
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||||
|
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator
|
||||||
|
|
||||||
from . import SynoApi, SynologyDSMBaseEntity, SynologyDSMDeviceEntity
|
from . import SynoApi, SynologyDSMBaseEntity, SynologyDSMDeviceEntity
|
||||||
from .const import (
|
from .const import (
|
||||||
@ -15,6 +18,7 @@ from .const import (
|
|||||||
STORAGE_DISK_BINARY_SENSORS,
|
STORAGE_DISK_BINARY_SENSORS,
|
||||||
SYNO_API,
|
SYNO_API,
|
||||||
UPGRADE_BINARY_SENSORS,
|
UPGRADE_BINARY_SENSORS,
|
||||||
|
SynologyDSMBinarySensorEntityDescription,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@ -32,39 +36,52 @@ async def async_setup_entry(
|
|||||||
| SynoDSMUpgradeBinarySensor
|
| SynoDSMUpgradeBinarySensor
|
||||||
| SynoDSMStorageBinarySensor
|
| SynoDSMStorageBinarySensor
|
||||||
] = [
|
] = [
|
||||||
SynoDSMSecurityBinarySensor(api, sensor_type, sensor, coordinator)
|
SynoDSMSecurityBinarySensor(api, coordinator, description)
|
||||||
for sensor_type, sensor in SECURITY_BINARY_SENSORS.items()
|
for description in SECURITY_BINARY_SENSORS
|
||||||
]
|
]
|
||||||
|
|
||||||
entities += [
|
entities.extend(
|
||||||
SynoDSMUpgradeBinarySensor(api, sensor_type, sensor, coordinator)
|
[
|
||||||
for sensor_type, sensor in UPGRADE_BINARY_SENSORS.items()
|
SynoDSMUpgradeBinarySensor(api, coordinator, description)
|
||||||
|
for description in UPGRADE_BINARY_SENSORS
|
||||||
]
|
]
|
||||||
|
)
|
||||||
|
|
||||||
# Handle all disks
|
# Handle all disks
|
||||||
if api.storage.disks_ids:
|
if api.storage.disks_ids:
|
||||||
for disk in entry.data.get(CONF_DISKS, api.storage.disks_ids):
|
entities.extend(
|
||||||
entities += [
|
[
|
||||||
SynoDSMStorageBinarySensor(
|
SynoDSMStorageBinarySensor(api, coordinator, description, disk)
|
||||||
api,
|
for disk in entry.data.get(CONF_DISKS, api.storage.disks_ids)
|
||||||
sensor_type,
|
for description in STORAGE_DISK_BINARY_SENSORS
|
||||||
sensor,
|
|
||||||
coordinator,
|
|
||||||
disk,
|
|
||||||
)
|
|
||||||
for sensor_type, sensor in STORAGE_DISK_BINARY_SENSORS.items()
|
|
||||||
]
|
]
|
||||||
|
)
|
||||||
|
|
||||||
async_add_entities(entities)
|
async_add_entities(entities)
|
||||||
|
|
||||||
|
|
||||||
class SynoDSMSecurityBinarySensor(SynologyDSMBaseEntity, BinarySensorEntity):
|
class SynoDSMBinarySensor(SynologyDSMBaseEntity, BinarySensorEntity):
|
||||||
|
"""Mixin for binary sensor specific attributes."""
|
||||||
|
|
||||||
|
entity_description: SynologyDSMBinarySensorEntityDescription
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
api: SynoApi,
|
||||||
|
coordinator: DataUpdateCoordinator[dict[str, dict[str, Any]]],
|
||||||
|
description: SynologyDSMBinarySensorEntityDescription,
|
||||||
|
) -> None:
|
||||||
|
"""Initialize the Synology DSM binary_sensor entity."""
|
||||||
|
super().__init__(api, coordinator, description)
|
||||||
|
|
||||||
|
|
||||||
|
class SynoDSMSecurityBinarySensor(SynoDSMBinarySensor):
|
||||||
"""Representation a Synology Security binary sensor."""
|
"""Representation a Synology Security binary sensor."""
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def is_on(self) -> bool:
|
def is_on(self) -> bool:
|
||||||
"""Return the state."""
|
"""Return the state."""
|
||||||
return getattr(self._api.security, self.entity_type) != "safe" # type: ignore[no-any-return]
|
return getattr(self._api.security, self.entity_description.key) != "safe" # type: ignore[no-any-return]
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def available(self) -> bool:
|
def available(self) -> bool:
|
||||||
@ -77,22 +94,36 @@ class SynoDSMSecurityBinarySensor(SynologyDSMBaseEntity, BinarySensorEntity):
|
|||||||
return self._api.security.status_by_check # type: ignore[no-any-return]
|
return self._api.security.status_by_check # type: ignore[no-any-return]
|
||||||
|
|
||||||
|
|
||||||
class SynoDSMStorageBinarySensor(SynologyDSMDeviceEntity, BinarySensorEntity):
|
class SynoDSMStorageBinarySensor(SynologyDSMDeviceEntity, SynoDSMBinarySensor):
|
||||||
"""Representation a Synology Storage binary sensor."""
|
"""Representation a Synology Storage binary sensor."""
|
||||||
|
|
||||||
|
entity_description: SynologyDSMBinarySensorEntityDescription
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
api: SynoApi,
|
||||||
|
coordinator: DataUpdateCoordinator[dict[str, dict[str, Any]]],
|
||||||
|
description: SynologyDSMBinarySensorEntityDescription,
|
||||||
|
device_id: str | None = None,
|
||||||
|
) -> None:
|
||||||
|
"""Initialize the Synology DSM storage binary_sensor entity."""
|
||||||
|
super().__init__(api, coordinator, description, device_id)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def is_on(self) -> bool:
|
def is_on(self) -> bool:
|
||||||
"""Return the state."""
|
"""Return the state."""
|
||||||
return bool(getattr(self._api.storage, self.entity_type)(self._device_id))
|
return bool(
|
||||||
|
getattr(self._api.storage, self.entity_description.key)(self._device_id)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class SynoDSMUpgradeBinarySensor(SynologyDSMBaseEntity, BinarySensorEntity):
|
class SynoDSMUpgradeBinarySensor(SynoDSMBinarySensor):
|
||||||
"""Representation a Synology Upgrade binary sensor."""
|
"""Representation a Synology Upgrade binary sensor."""
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def is_on(self) -> bool:
|
def is_on(self) -> bool:
|
||||||
"""Return the state."""
|
"""Return the state."""
|
||||||
return bool(getattr(self._api.upgrade, self.entity_type))
|
return bool(getattr(self._api.upgrade, self.entity_description.key))
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def available(self) -> bool:
|
def available(self) -> bool:
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
"""Support for Synology DSM cameras."""
|
"""Support for Synology DSM cameras."""
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from dataclasses import dataclass
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
from synology_dsm.api.surveillance_station import SynoCamera, SynoSurveillanceStation
|
from synology_dsm.api.surveillance_station import SynoCamera, SynoSurveillanceStation
|
||||||
@ -9,26 +10,30 @@ from synology_dsm.exceptions import (
|
|||||||
SynologyDSMRequestException,
|
SynologyDSMRequestException,
|
||||||
)
|
)
|
||||||
|
|
||||||
from homeassistant.components.camera import SUPPORT_STREAM, Camera
|
from homeassistant.components.camera import (
|
||||||
from homeassistant.components.sensor import ATTR_STATE_CLASS
|
SUPPORT_STREAM,
|
||||||
from homeassistant.config_entries import ConfigEntry
|
Camera,
|
||||||
from homeassistant.const import (
|
CameraEntityDescription,
|
||||||
ATTR_DEVICE_CLASS,
|
|
||||||
ATTR_ICON,
|
|
||||||
ATTR_NAME,
|
|
||||||
ATTR_UNIT_OF_MEASUREMENT,
|
|
||||||
)
|
)
|
||||||
|
from homeassistant.config_entries import ConfigEntry
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
from homeassistant.helpers.entity import DeviceInfo
|
from homeassistant.helpers.entity import DeviceInfo
|
||||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||||
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator
|
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator
|
||||||
|
|
||||||
from . import SynoApi, SynologyDSMBaseEntity
|
from . import SynoApi, SynologyDSMBaseEntity
|
||||||
from .const import COORDINATOR_CAMERAS, DOMAIN, ENTITY_ENABLE, SYNO_API
|
from .const import COORDINATOR_CAMERAS, DOMAIN, SYNO_API, SynologyDSMEntityDescription
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class SynologyDSMCameraEntityDescription(
|
||||||
|
CameraEntityDescription, SynologyDSMEntityDescription
|
||||||
|
):
|
||||||
|
"""Describes Synology DSM camera entity."""
|
||||||
|
|
||||||
|
|
||||||
async def async_setup_entry(
|
async def async_setup_entry(
|
||||||
hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback
|
hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback
|
||||||
) -> None:
|
) -> None:
|
||||||
@ -56,6 +61,7 @@ class SynoDSMCamera(SynologyDSMBaseEntity, Camera):
|
|||||||
"""Representation a Synology camera."""
|
"""Representation a Synology camera."""
|
||||||
|
|
||||||
coordinator: DataUpdateCoordinator[dict[str, dict[str, SynoCamera]]]
|
coordinator: DataUpdateCoordinator[dict[str, dict[str, SynoCamera]]]
|
||||||
|
entity_description: SynologyDSMCameraEntityDescription
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
@ -64,26 +70,21 @@ class SynoDSMCamera(SynologyDSMBaseEntity, Camera):
|
|||||||
camera_id: str,
|
camera_id: str,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Initialize a Synology camera."""
|
"""Initialize a Synology camera."""
|
||||||
super().__init__(
|
description = SynologyDSMCameraEntityDescription(
|
||||||
api,
|
api_key=SynoSurveillanceStation.CAMERA_API_KEY,
|
||||||
f"{SynoSurveillanceStation.CAMERA_API_KEY}:{camera_id}",
|
key=camera_id,
|
||||||
{
|
name=coordinator.data["cameras"][camera_id].name,
|
||||||
ATTR_NAME: coordinator.data["cameras"][camera_id].name,
|
entity_registry_enabled_default=coordinator.data["cameras"][
|
||||||
ENTITY_ENABLE: coordinator.data["cameras"][camera_id].is_enabled,
|
camera_id
|
||||||
ATTR_DEVICE_CLASS: None,
|
].is_enabled,
|
||||||
ATTR_ICON: None,
|
|
||||||
ATTR_UNIT_OF_MEASUREMENT: None,
|
|
||||||
ATTR_STATE_CLASS: None,
|
|
||||||
},
|
|
||||||
coordinator,
|
|
||||||
)
|
)
|
||||||
|
super().__init__(api, coordinator, description)
|
||||||
Camera.__init__(self)
|
Camera.__init__(self)
|
||||||
self._camera_id = camera_id
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def camera_data(self) -> SynoCamera:
|
def camera_data(self) -> SynoCamera:
|
||||||
"""Camera data."""
|
"""Camera data."""
|
||||||
return self.coordinator.data["cameras"][self._camera_id]
|
return self.coordinator.data["cameras"][self.entity_description.key]
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def device_info(self) -> DeviceInfo:
|
def device_info(self) -> DeviceInfo:
|
||||||
@ -134,7 +135,7 @@ class SynoDSMCamera(SynologyDSMBaseEntity, Camera):
|
|||||||
if not self.available:
|
if not self.available:
|
||||||
return None
|
return None
|
||||||
try:
|
try:
|
||||||
return self._api.surveillance_station.get_camera_image(self._camera_id) # type: ignore[no-any-return]
|
return self._api.surveillance_station.get_camera_image(self.entity_description.key) # type: ignore[no-any-return]
|
||||||
except (
|
except (
|
||||||
SynologyDSMAPIErrorException,
|
SynologyDSMAPIErrorException,
|
||||||
SynologyDSMRequestException,
|
SynologyDSMRequestException,
|
||||||
@ -163,7 +164,9 @@ class SynoDSMCamera(SynologyDSMBaseEntity, Camera):
|
|||||||
"SynoDSMCamera.enable_motion_detection(%s)",
|
"SynoDSMCamera.enable_motion_detection(%s)",
|
||||||
self.camera_data.name,
|
self.camera_data.name,
|
||||||
)
|
)
|
||||||
self._api.surveillance_station.enable_motion_detection(self._camera_id)
|
self._api.surveillance_station.enable_motion_detection(
|
||||||
|
self.entity_description.key
|
||||||
|
)
|
||||||
|
|
||||||
def disable_motion_detection(self) -> None:
|
def disable_motion_detection(self) -> None:
|
||||||
"""Disable motion detection in camera."""
|
"""Disable motion detection in camera."""
|
||||||
@ -171,4 +174,6 @@ class SynoDSMCamera(SynologyDSMBaseEntity, Camera):
|
|||||||
"SynoDSMCamera.disable_motion_detection(%s)",
|
"SynoDSMCamera.disable_motion_detection(%s)",
|
||||||
self.camera_data.name,
|
self.camera_data.name,
|
||||||
)
|
)
|
||||||
self._api.surveillance_station.disable_motion_detection(self._camera_id)
|
self._api.surveillance_station.disable_motion_detection(
|
||||||
|
self.entity_description.key
|
||||||
|
)
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
"""Constants for Synology DSM."""
|
"""Constants for Synology DSM."""
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
from typing import Final, TypedDict
|
from dataclasses import dataclass
|
||||||
|
|
||||||
from synology_dsm.api.core.security import SynoCoreSecurity
|
from synology_dsm.api.core.security import SynoCoreSecurity
|
||||||
from synology_dsm.api.core.upgrade import SynoCoreUpgrade
|
from synology_dsm.api.core.upgrade import SynoCoreUpgrade
|
||||||
@ -13,13 +13,14 @@ from synology_dsm.api.surveillance_station import SynoSurveillanceStation
|
|||||||
from homeassistant.components.binary_sensor import (
|
from homeassistant.components.binary_sensor import (
|
||||||
DEVICE_CLASS_SAFETY,
|
DEVICE_CLASS_SAFETY,
|
||||||
DEVICE_CLASS_UPDATE,
|
DEVICE_CLASS_UPDATE,
|
||||||
|
BinarySensorEntityDescription,
|
||||||
)
|
)
|
||||||
from homeassistant.components.sensor import ATTR_STATE_CLASS, STATE_CLASS_MEASUREMENT
|
from homeassistant.components.sensor import (
|
||||||
|
STATE_CLASS_MEASUREMENT,
|
||||||
|
SensorEntityDescription,
|
||||||
|
)
|
||||||
|
from homeassistant.components.switch import SwitchEntityDescription
|
||||||
from homeassistant.const import (
|
from homeassistant.const import (
|
||||||
ATTR_DEVICE_CLASS,
|
|
||||||
ATTR_ICON,
|
|
||||||
ATTR_NAME,
|
|
||||||
ATTR_UNIT_OF_MEASUREMENT,
|
|
||||||
DATA_MEGABYTES,
|
DATA_MEGABYTES,
|
||||||
DATA_RATE_KILOBYTES_PER_SECOND,
|
DATA_RATE_KILOBYTES_PER_SECOND,
|
||||||
DATA_TERABYTES,
|
DATA_TERABYTES,
|
||||||
@ -28,18 +29,7 @@ from homeassistant.const import (
|
|||||||
PERCENTAGE,
|
PERCENTAGE,
|
||||||
TEMP_CELSIUS,
|
TEMP_CELSIUS,
|
||||||
)
|
)
|
||||||
|
from homeassistant.helpers.entity import EntityDescription
|
||||||
|
|
||||||
class EntityInfo(TypedDict):
|
|
||||||
"""TypedDict for EntityInfo."""
|
|
||||||
|
|
||||||
name: str
|
|
||||||
unit_of_measurement: str | None
|
|
||||||
icon: str | None
|
|
||||||
device_class: str | None
|
|
||||||
state_class: str | None
|
|
||||||
enable: bool
|
|
||||||
|
|
||||||
|
|
||||||
DOMAIN = "synology_dsm"
|
DOMAIN = "synology_dsm"
|
||||||
PLATFORMS = ["binary_sensor", "camera", "sensor", "switch"]
|
PLATFORMS = ["binary_sensor", "camera", "sensor", "switch"]
|
||||||
@ -68,7 +58,6 @@ DEFAULT_SCAN_INTERVAL = 15 # min
|
|||||||
DEFAULT_TIMEOUT = 10 # sec
|
DEFAULT_TIMEOUT = 10 # sec
|
||||||
|
|
||||||
ENTITY_UNIT_LOAD = "load"
|
ENTITY_UNIT_LOAD = "load"
|
||||||
ENTITY_ENABLE: Final = "enable"
|
|
||||||
|
|
||||||
# Services
|
# Services
|
||||||
SERVICE_REBOOT = "reboot"
|
SERVICE_REBOOT = "reboot"
|
||||||
@ -78,285 +67,302 @@ SERVICES = [
|
|||||||
SERVICE_SHUTDOWN,
|
SERVICE_SHUTDOWN,
|
||||||
]
|
]
|
||||||
|
|
||||||
# Entity keys should start with the API_KEY to fetch
|
|
||||||
|
@dataclass
|
||||||
|
class SynologyDSMRequiredKeysMixin:
|
||||||
|
"""Mixin for required keys."""
|
||||||
|
|
||||||
|
api_key: str
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class SynologyDSMEntityDescription(EntityDescription, SynologyDSMRequiredKeysMixin):
|
||||||
|
"""Generic Synology DSM entity description."""
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class SynologyDSMBinarySensorEntityDescription(
|
||||||
|
BinarySensorEntityDescription, SynologyDSMEntityDescription
|
||||||
|
):
|
||||||
|
"""Describes Synology DSM binary sensor entity."""
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class SynologyDSMSensorEntityDescription(
|
||||||
|
SensorEntityDescription, SynologyDSMEntityDescription
|
||||||
|
):
|
||||||
|
"""Describes Synology DSM sensor entity."""
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class SynologyDSMSwitchEntityDescription(
|
||||||
|
SwitchEntityDescription, SynologyDSMEntityDescription
|
||||||
|
):
|
||||||
|
"""Describes Synology DSM switch entity."""
|
||||||
|
|
||||||
|
|
||||||
# Binary sensors
|
# Binary sensors
|
||||||
UPGRADE_BINARY_SENSORS: dict[str, EntityInfo] = {
|
UPGRADE_BINARY_SENSORS: tuple[SynologyDSMBinarySensorEntityDescription, ...] = (
|
||||||
f"{SynoCoreUpgrade.API_KEY}:update_available": {
|
SynologyDSMBinarySensorEntityDescription(
|
||||||
ATTR_NAME: "Update available",
|
api_key=SynoCoreUpgrade.API_KEY,
|
||||||
ATTR_UNIT_OF_MEASUREMENT: None,
|
key="update_available",
|
||||||
ATTR_ICON: None,
|
name="Update available",
|
||||||
ATTR_DEVICE_CLASS: DEVICE_CLASS_UPDATE,
|
device_class=DEVICE_CLASS_UPDATE,
|
||||||
ENTITY_ENABLE: True,
|
),
|
||||||
ATTR_STATE_CLASS: None,
|
)
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
SECURITY_BINARY_SENSORS: dict[str, EntityInfo] = {
|
SECURITY_BINARY_SENSORS: tuple[SynologyDSMBinarySensorEntityDescription, ...] = (
|
||||||
f"{SynoCoreSecurity.API_KEY}:status": {
|
SynologyDSMBinarySensorEntityDescription(
|
||||||
ATTR_NAME: "Security status",
|
api_key=SynoCoreSecurity.API_KEY,
|
||||||
ATTR_UNIT_OF_MEASUREMENT: None,
|
key="status",
|
||||||
ATTR_ICON: None,
|
name="Security status",
|
||||||
ATTR_DEVICE_CLASS: DEVICE_CLASS_SAFETY,
|
device_class=DEVICE_CLASS_SAFETY,
|
||||||
ENTITY_ENABLE: True,
|
),
|
||||||
ATTR_STATE_CLASS: None,
|
)
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
STORAGE_DISK_BINARY_SENSORS: dict[str, EntityInfo] = {
|
STORAGE_DISK_BINARY_SENSORS: tuple[SynologyDSMBinarySensorEntityDescription, ...] = (
|
||||||
f"{SynoStorage.API_KEY}:disk_exceed_bad_sector_thr": {
|
SynologyDSMBinarySensorEntityDescription(
|
||||||
ATTR_NAME: "Exceeded Max Bad Sectors",
|
api_key=SynoStorage.API_KEY,
|
||||||
ATTR_UNIT_OF_MEASUREMENT: None,
|
key="disk_exceed_bad_sector_thr",
|
||||||
ATTR_ICON: None,
|
name="Exceeded Max Bad Sectors",
|
||||||
ATTR_DEVICE_CLASS: DEVICE_CLASS_SAFETY,
|
device_class=DEVICE_CLASS_SAFETY,
|
||||||
ENTITY_ENABLE: True,
|
),
|
||||||
ATTR_STATE_CLASS: None,
|
SynologyDSMBinarySensorEntityDescription(
|
||||||
},
|
api_key=SynoStorage.API_KEY,
|
||||||
f"{SynoStorage.API_KEY}:disk_below_remain_life_thr": {
|
key="disk_below_remain_life_thr",
|
||||||
ATTR_NAME: "Below Min Remaining Life",
|
name="Below Min Remaining Life",
|
||||||
ATTR_UNIT_OF_MEASUREMENT: None,
|
device_class=DEVICE_CLASS_SAFETY,
|
||||||
ATTR_ICON: None,
|
),
|
||||||
ATTR_DEVICE_CLASS: DEVICE_CLASS_SAFETY,
|
)
|
||||||
ENTITY_ENABLE: True,
|
|
||||||
ATTR_STATE_CLASS: None,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
# Sensors
|
# Sensors
|
||||||
UTILISATION_SENSORS: dict[str, EntityInfo] = {
|
UTILISATION_SENSORS: tuple[SynologyDSMSensorEntityDescription, ...] = (
|
||||||
f"{SynoCoreUtilization.API_KEY}:cpu_other_load": {
|
SynologyDSMSensorEntityDescription(
|
||||||
ATTR_NAME: "CPU Utilization (Other)",
|
api_key=SynoCoreUtilization.API_KEY,
|
||||||
ATTR_UNIT_OF_MEASUREMENT: PERCENTAGE,
|
key="cpu_other_load",
|
||||||
ATTR_ICON: "mdi:chip",
|
name="CPU Utilization (Other)",
|
||||||
ATTR_DEVICE_CLASS: None,
|
native_unit_of_measurement=PERCENTAGE,
|
||||||
ENTITY_ENABLE: False,
|
icon="mdi:chip",
|
||||||
ATTR_STATE_CLASS: STATE_CLASS_MEASUREMENT,
|
entity_registry_enabled_default=False,
|
||||||
},
|
state_class=STATE_CLASS_MEASUREMENT,
|
||||||
f"{SynoCoreUtilization.API_KEY}:cpu_user_load": {
|
),
|
||||||
ATTR_NAME: "CPU Utilization (User)",
|
SynologyDSMSensorEntityDescription(
|
||||||
ATTR_UNIT_OF_MEASUREMENT: PERCENTAGE,
|
api_key=SynoCoreUtilization.API_KEY,
|
||||||
ATTR_ICON: "mdi:chip",
|
key="cpu_user_load",
|
||||||
ATTR_DEVICE_CLASS: None,
|
name="CPU Utilization (User)",
|
||||||
ENTITY_ENABLE: True,
|
native_unit_of_measurement=PERCENTAGE,
|
||||||
ATTR_STATE_CLASS: STATE_CLASS_MEASUREMENT,
|
icon="mdi:chip",
|
||||||
},
|
state_class=STATE_CLASS_MEASUREMENT,
|
||||||
f"{SynoCoreUtilization.API_KEY}:cpu_system_load": {
|
),
|
||||||
ATTR_NAME: "CPU Utilization (System)",
|
SynologyDSMSensorEntityDescription(
|
||||||
ATTR_UNIT_OF_MEASUREMENT: PERCENTAGE,
|
api_key=SynoCoreUtilization.API_KEY,
|
||||||
ATTR_ICON: "mdi:chip",
|
key="cpu_system_load",
|
||||||
ATTR_DEVICE_CLASS: None,
|
name="CPU Utilization (System)",
|
||||||
ENTITY_ENABLE: False,
|
native_unit_of_measurement=PERCENTAGE,
|
||||||
ATTR_STATE_CLASS: STATE_CLASS_MEASUREMENT,
|
icon="mdi:chip",
|
||||||
},
|
entity_registry_enabled_default=False,
|
||||||
f"{SynoCoreUtilization.API_KEY}:cpu_total_load": {
|
state_class=STATE_CLASS_MEASUREMENT,
|
||||||
ATTR_NAME: "CPU Utilization (Total)",
|
),
|
||||||
ATTR_UNIT_OF_MEASUREMENT: PERCENTAGE,
|
SynologyDSMSensorEntityDescription(
|
||||||
ATTR_ICON: "mdi:chip",
|
api_key=SynoCoreUtilization.API_KEY,
|
||||||
ATTR_DEVICE_CLASS: None,
|
key="cpu_total_load",
|
||||||
ENTITY_ENABLE: True,
|
name="CPU Utilization (Total)",
|
||||||
ATTR_STATE_CLASS: STATE_CLASS_MEASUREMENT,
|
native_unit_of_measurement=PERCENTAGE,
|
||||||
},
|
icon="mdi:chip",
|
||||||
f"{SynoCoreUtilization.API_KEY}:cpu_1min_load": {
|
state_class=STATE_CLASS_MEASUREMENT,
|
||||||
ATTR_NAME: "CPU Load Average (1 min)",
|
),
|
||||||
ATTR_UNIT_OF_MEASUREMENT: ENTITY_UNIT_LOAD,
|
SynologyDSMSensorEntityDescription(
|
||||||
ATTR_ICON: "mdi:chip",
|
api_key=SynoCoreUtilization.API_KEY,
|
||||||
ATTR_DEVICE_CLASS: None,
|
key="cpu_1min_load",
|
||||||
ENTITY_ENABLE: False,
|
name="CPU Load Average (1 min)",
|
||||||
ATTR_STATE_CLASS: None,
|
native_unit_of_measurement=ENTITY_UNIT_LOAD,
|
||||||
},
|
icon="mdi:chip",
|
||||||
f"{SynoCoreUtilization.API_KEY}:cpu_5min_load": {
|
entity_registry_enabled_default=False,
|
||||||
ATTR_NAME: "CPU Load Average (5 min)",
|
),
|
||||||
ATTR_UNIT_OF_MEASUREMENT: ENTITY_UNIT_LOAD,
|
SynologyDSMSensorEntityDescription(
|
||||||
ATTR_ICON: "mdi:chip",
|
api_key=SynoCoreUtilization.API_KEY,
|
||||||
ATTR_DEVICE_CLASS: None,
|
key="cpu_5min_load",
|
||||||
ENTITY_ENABLE: True,
|
name="CPU Load Average (5 min)",
|
||||||
ATTR_STATE_CLASS: None,
|
native_unit_of_measurement=ENTITY_UNIT_LOAD,
|
||||||
},
|
icon="mdi:chip",
|
||||||
f"{SynoCoreUtilization.API_KEY}:cpu_15min_load": {
|
),
|
||||||
ATTR_NAME: "CPU Load Average (15 min)",
|
SynologyDSMSensorEntityDescription(
|
||||||
ATTR_UNIT_OF_MEASUREMENT: ENTITY_UNIT_LOAD,
|
api_key=SynoCoreUtilization.API_KEY,
|
||||||
ATTR_ICON: "mdi:chip",
|
key="cpu_15min_load",
|
||||||
ATTR_DEVICE_CLASS: None,
|
name="CPU Load Average (15 min)",
|
||||||
ENTITY_ENABLE: True,
|
native_unit_of_measurement=ENTITY_UNIT_LOAD,
|
||||||
ATTR_STATE_CLASS: None,
|
icon="mdi:chip",
|
||||||
},
|
),
|
||||||
f"{SynoCoreUtilization.API_KEY}:memory_real_usage": {
|
SynologyDSMSensorEntityDescription(
|
||||||
ATTR_NAME: "Memory Usage (Real)",
|
api_key=SynoCoreUtilization.API_KEY,
|
||||||
ATTR_UNIT_OF_MEASUREMENT: PERCENTAGE,
|
key="memory_real_usage",
|
||||||
ATTR_ICON: "mdi:memory",
|
name="Memory Usage (Real)",
|
||||||
ATTR_DEVICE_CLASS: None,
|
native_unit_of_measurement=PERCENTAGE,
|
||||||
ENTITY_ENABLE: True,
|
icon="mdi:memory",
|
||||||
ATTR_STATE_CLASS: STATE_CLASS_MEASUREMENT,
|
state_class=STATE_CLASS_MEASUREMENT,
|
||||||
},
|
),
|
||||||
f"{SynoCoreUtilization.API_KEY}:memory_size": {
|
SynologyDSMSensorEntityDescription(
|
||||||
ATTR_NAME: "Memory Size",
|
api_key=SynoCoreUtilization.API_KEY,
|
||||||
ATTR_UNIT_OF_MEASUREMENT: DATA_MEGABYTES,
|
key="memory_size",
|
||||||
ATTR_ICON: "mdi:memory",
|
name="Memory Size",
|
||||||
ATTR_DEVICE_CLASS: None,
|
native_unit_of_measurement=DATA_MEGABYTES,
|
||||||
ENTITY_ENABLE: False,
|
icon="mdi:memory",
|
||||||
ATTR_STATE_CLASS: STATE_CLASS_MEASUREMENT,
|
entity_registry_enabled_default=False,
|
||||||
},
|
state_class=STATE_CLASS_MEASUREMENT,
|
||||||
f"{SynoCoreUtilization.API_KEY}:memory_cached": {
|
),
|
||||||
ATTR_NAME: "Memory Cached",
|
SynologyDSMSensorEntityDescription(
|
||||||
ATTR_UNIT_OF_MEASUREMENT: DATA_MEGABYTES,
|
api_key=SynoCoreUtilization.API_KEY,
|
||||||
ATTR_ICON: "mdi:memory",
|
key="memory_cached",
|
||||||
ATTR_DEVICE_CLASS: None,
|
name="Memory Cached",
|
||||||
ENTITY_ENABLE: False,
|
native_unit_of_measurement=DATA_MEGABYTES,
|
||||||
ATTR_STATE_CLASS: STATE_CLASS_MEASUREMENT,
|
icon="mdi:memory",
|
||||||
},
|
entity_registry_enabled_default=False,
|
||||||
f"{SynoCoreUtilization.API_KEY}:memory_available_swap": {
|
state_class=STATE_CLASS_MEASUREMENT,
|
||||||
ATTR_NAME: "Memory Available (Swap)",
|
),
|
||||||
ATTR_UNIT_OF_MEASUREMENT: DATA_MEGABYTES,
|
SynologyDSMSensorEntityDescription(
|
||||||
ATTR_ICON: "mdi:memory",
|
api_key=SynoCoreUtilization.API_KEY,
|
||||||
ATTR_DEVICE_CLASS: None,
|
key="memory_available_swap",
|
||||||
ENTITY_ENABLE: True,
|
name="Memory Available (Swap)",
|
||||||
ATTR_STATE_CLASS: STATE_CLASS_MEASUREMENT,
|
native_unit_of_measurement=DATA_MEGABYTES,
|
||||||
},
|
icon="mdi:memory",
|
||||||
f"{SynoCoreUtilization.API_KEY}:memory_available_real": {
|
state_class=STATE_CLASS_MEASUREMENT,
|
||||||
ATTR_NAME: "Memory Available (Real)",
|
),
|
||||||
ATTR_UNIT_OF_MEASUREMENT: DATA_MEGABYTES,
|
SynologyDSMSensorEntityDescription(
|
||||||
ATTR_ICON: "mdi:memory",
|
api_key=SynoCoreUtilization.API_KEY,
|
||||||
ATTR_DEVICE_CLASS: None,
|
key="memory_available_real",
|
||||||
ENTITY_ENABLE: True,
|
name="Memory Available (Real)",
|
||||||
ATTR_STATE_CLASS: STATE_CLASS_MEASUREMENT,
|
native_unit_of_measurement=DATA_MEGABYTES,
|
||||||
},
|
icon="mdi:memory",
|
||||||
f"{SynoCoreUtilization.API_KEY}:memory_total_swap": {
|
state_class=STATE_CLASS_MEASUREMENT,
|
||||||
ATTR_NAME: "Memory Total (Swap)",
|
),
|
||||||
ATTR_UNIT_OF_MEASUREMENT: DATA_MEGABYTES,
|
SynologyDSMSensorEntityDescription(
|
||||||
ATTR_ICON: "mdi:memory",
|
api_key=SynoCoreUtilization.API_KEY,
|
||||||
ATTR_DEVICE_CLASS: None,
|
key="memory_total_swap",
|
||||||
ENTITY_ENABLE: True,
|
name="Memory Total (Swap)",
|
||||||
ATTR_STATE_CLASS: STATE_CLASS_MEASUREMENT,
|
native_unit_of_measurement=DATA_MEGABYTES,
|
||||||
},
|
icon="mdi:memory",
|
||||||
f"{SynoCoreUtilization.API_KEY}:memory_total_real": {
|
state_class=STATE_CLASS_MEASUREMENT,
|
||||||
ATTR_NAME: "Memory Total (Real)",
|
),
|
||||||
ATTR_UNIT_OF_MEASUREMENT: DATA_MEGABYTES,
|
SynologyDSMSensorEntityDescription(
|
||||||
ATTR_ICON: "mdi:memory",
|
api_key=SynoCoreUtilization.API_KEY,
|
||||||
ATTR_DEVICE_CLASS: None,
|
key="memory_total_real",
|
||||||
ENTITY_ENABLE: True,
|
name="Memory Total (Real)",
|
||||||
ATTR_STATE_CLASS: STATE_CLASS_MEASUREMENT,
|
native_unit_of_measurement=DATA_MEGABYTES,
|
||||||
},
|
icon="mdi:memory",
|
||||||
f"{SynoCoreUtilization.API_KEY}:network_up": {
|
state_class=STATE_CLASS_MEASUREMENT,
|
||||||
ATTR_NAME: "Upload Throughput",
|
),
|
||||||
ATTR_UNIT_OF_MEASUREMENT: DATA_RATE_KILOBYTES_PER_SECOND,
|
SynologyDSMSensorEntityDescription(
|
||||||
ATTR_ICON: "mdi:upload",
|
api_key=SynoCoreUtilization.API_KEY,
|
||||||
ATTR_DEVICE_CLASS: None,
|
key="network_up",
|
||||||
ENTITY_ENABLE: True,
|
name="Upload Throughput",
|
||||||
ATTR_STATE_CLASS: STATE_CLASS_MEASUREMENT,
|
native_unit_of_measurement=DATA_RATE_KILOBYTES_PER_SECOND,
|
||||||
},
|
icon="mdi:upload",
|
||||||
f"{SynoCoreUtilization.API_KEY}:network_down": {
|
state_class=STATE_CLASS_MEASUREMENT,
|
||||||
ATTR_NAME: "Download Throughput",
|
),
|
||||||
ATTR_UNIT_OF_MEASUREMENT: DATA_RATE_KILOBYTES_PER_SECOND,
|
SynologyDSMSensorEntityDescription(
|
||||||
ATTR_ICON: "mdi:download",
|
api_key=SynoCoreUtilization.API_KEY,
|
||||||
ATTR_DEVICE_CLASS: None,
|
key="network_down",
|
||||||
ENTITY_ENABLE: True,
|
name="Download Throughput",
|
||||||
ATTR_STATE_CLASS: STATE_CLASS_MEASUREMENT,
|
native_unit_of_measurement=DATA_RATE_KILOBYTES_PER_SECOND,
|
||||||
},
|
icon="mdi:download",
|
||||||
}
|
state_class=STATE_CLASS_MEASUREMENT,
|
||||||
STORAGE_VOL_SENSORS: dict[str, EntityInfo] = {
|
),
|
||||||
f"{SynoStorage.API_KEY}:volume_status": {
|
)
|
||||||
ATTR_NAME: "Status",
|
STORAGE_VOL_SENSORS: tuple[SynologyDSMSensorEntityDescription, ...] = (
|
||||||
ATTR_UNIT_OF_MEASUREMENT: None,
|
SynologyDSMSensorEntityDescription(
|
||||||
ATTR_ICON: "mdi:checkbox-marked-circle-outline",
|
api_key=SynoStorage.API_KEY,
|
||||||
ATTR_DEVICE_CLASS: None,
|
key="volume_status",
|
||||||
ENTITY_ENABLE: True,
|
name="Status",
|
||||||
ATTR_STATE_CLASS: None,
|
icon="mdi:checkbox-marked-circle-outline",
|
||||||
},
|
),
|
||||||
f"{SynoStorage.API_KEY}:volume_size_total": {
|
SynologyDSMSensorEntityDescription(
|
||||||
ATTR_NAME: "Total Size",
|
api_key=SynoStorage.API_KEY,
|
||||||
ATTR_UNIT_OF_MEASUREMENT: DATA_TERABYTES,
|
key="volume_size_total",
|
||||||
ATTR_ICON: "mdi:chart-pie",
|
name="Total Size",
|
||||||
ATTR_DEVICE_CLASS: None,
|
native_unit_of_measurement=DATA_TERABYTES,
|
||||||
ENTITY_ENABLE: False,
|
icon="mdi:chart-pie",
|
||||||
ATTR_STATE_CLASS: STATE_CLASS_MEASUREMENT,
|
entity_registry_enabled_default=False,
|
||||||
},
|
state_class=STATE_CLASS_MEASUREMENT,
|
||||||
f"{SynoStorage.API_KEY}:volume_size_used": {
|
),
|
||||||
ATTR_NAME: "Used Space",
|
SynologyDSMSensorEntityDescription(
|
||||||
ATTR_UNIT_OF_MEASUREMENT: DATA_TERABYTES,
|
api_key=SynoStorage.API_KEY,
|
||||||
ATTR_ICON: "mdi:chart-pie",
|
key="volume_size_used",
|
||||||
ATTR_DEVICE_CLASS: None,
|
name="Used Space",
|
||||||
ENTITY_ENABLE: True,
|
native_unit_of_measurement=DATA_TERABYTES,
|
||||||
ATTR_STATE_CLASS: STATE_CLASS_MEASUREMENT,
|
icon="mdi:chart-pie",
|
||||||
},
|
state_class=STATE_CLASS_MEASUREMENT,
|
||||||
f"{SynoStorage.API_KEY}:volume_percentage_used": {
|
),
|
||||||
ATTR_NAME: "Volume Used",
|
SynologyDSMSensorEntityDescription(
|
||||||
ATTR_UNIT_OF_MEASUREMENT: PERCENTAGE,
|
api_key=SynoStorage.API_KEY,
|
||||||
ATTR_ICON: "mdi:chart-pie",
|
key="volume_percentage_used",
|
||||||
ATTR_DEVICE_CLASS: None,
|
name="Volume Used",
|
||||||
ENTITY_ENABLE: True,
|
native_unit_of_measurement=PERCENTAGE,
|
||||||
ATTR_STATE_CLASS: None,
|
icon="mdi:chart-pie",
|
||||||
},
|
),
|
||||||
f"{SynoStorage.API_KEY}:volume_disk_temp_avg": {
|
SynologyDSMSensorEntityDescription(
|
||||||
ATTR_NAME: "Average Disk Temp",
|
api_key=SynoStorage.API_KEY,
|
||||||
ATTR_UNIT_OF_MEASUREMENT: TEMP_CELSIUS,
|
key="volume_disk_temp_avg",
|
||||||
ATTR_ICON: None,
|
name="Average Disk Temp",
|
||||||
ATTR_DEVICE_CLASS: DEVICE_CLASS_TEMPERATURE,
|
native_unit_of_measurement=TEMP_CELSIUS,
|
||||||
ENTITY_ENABLE: True,
|
device_class=DEVICE_CLASS_TEMPERATURE,
|
||||||
ATTR_STATE_CLASS: None,
|
),
|
||||||
},
|
SynologyDSMSensorEntityDescription(
|
||||||
f"{SynoStorage.API_KEY}:volume_disk_temp_max": {
|
api_key=SynoStorage.API_KEY,
|
||||||
ATTR_NAME: "Maximum Disk Temp",
|
key="volume_disk_temp_max",
|
||||||
ATTR_UNIT_OF_MEASUREMENT: TEMP_CELSIUS,
|
name="Maximum Disk Temp",
|
||||||
ATTR_ICON: None,
|
native_unit_of_measurement=TEMP_CELSIUS,
|
||||||
ATTR_DEVICE_CLASS: DEVICE_CLASS_TEMPERATURE,
|
device_class=DEVICE_CLASS_TEMPERATURE,
|
||||||
ENTITY_ENABLE: False,
|
entity_registry_enabled_default=False,
|
||||||
ATTR_STATE_CLASS: None,
|
),
|
||||||
},
|
)
|
||||||
}
|
STORAGE_DISK_SENSORS: tuple[SynologyDSMSensorEntityDescription, ...] = (
|
||||||
STORAGE_DISK_SENSORS: dict[str, EntityInfo] = {
|
SynologyDSMSensorEntityDescription(
|
||||||
f"{SynoStorage.API_KEY}:disk_smart_status": {
|
api_key=SynoStorage.API_KEY,
|
||||||
ATTR_NAME: "Status (Smart)",
|
key="disk_smart_status",
|
||||||
ATTR_UNIT_OF_MEASUREMENT: None,
|
name="Status (Smart)",
|
||||||
ATTR_ICON: "mdi:checkbox-marked-circle-outline",
|
icon="mdi:checkbox-marked-circle-outline",
|
||||||
ATTR_DEVICE_CLASS: None,
|
entity_registry_enabled_default=False,
|
||||||
ENTITY_ENABLE: False,
|
),
|
||||||
ATTR_STATE_CLASS: None,
|
SynologyDSMSensorEntityDescription(
|
||||||
},
|
api_key=SynoStorage.API_KEY,
|
||||||
f"{SynoStorage.API_KEY}:disk_status": {
|
key="disk_status",
|
||||||
ATTR_NAME: "Status",
|
name="Status",
|
||||||
ATTR_UNIT_OF_MEASUREMENT: None,
|
icon="mdi:checkbox-marked-circle-outline",
|
||||||
ATTR_ICON: "mdi:checkbox-marked-circle-outline",
|
),
|
||||||
ATTR_DEVICE_CLASS: None,
|
SynologyDSMSensorEntityDescription(
|
||||||
ENTITY_ENABLE: True,
|
api_key=SynoStorage.API_KEY,
|
||||||
ATTR_STATE_CLASS: None,
|
key="disk_temp",
|
||||||
},
|
name="Temperature",
|
||||||
f"{SynoStorage.API_KEY}:disk_temp": {
|
native_unit_of_measurement=TEMP_CELSIUS,
|
||||||
ATTR_NAME: "Temperature",
|
device_class=DEVICE_CLASS_TEMPERATURE,
|
||||||
ATTR_UNIT_OF_MEASUREMENT: TEMP_CELSIUS,
|
state_class=STATE_CLASS_MEASUREMENT,
|
||||||
ATTR_ICON: None,
|
),
|
||||||
ATTR_DEVICE_CLASS: DEVICE_CLASS_TEMPERATURE,
|
)
|
||||||
ENTITY_ENABLE: True,
|
|
||||||
ATTR_STATE_CLASS: STATE_CLASS_MEASUREMENT,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
INFORMATION_SENSORS: dict[str, EntityInfo] = {
|
INFORMATION_SENSORS: tuple[SynologyDSMSensorEntityDescription, ...] = (
|
||||||
f"{SynoDSMInformation.API_KEY}:temperature": {
|
SynologyDSMSensorEntityDescription(
|
||||||
ATTR_NAME: "temperature",
|
api_key=SynoDSMInformation.API_KEY,
|
||||||
ATTR_UNIT_OF_MEASUREMENT: TEMP_CELSIUS,
|
key="temperature",
|
||||||
ATTR_ICON: None,
|
name="temperature",
|
||||||
ATTR_DEVICE_CLASS: DEVICE_CLASS_TEMPERATURE,
|
native_unit_of_measurement=TEMP_CELSIUS,
|
||||||
ENTITY_ENABLE: True,
|
device_class=DEVICE_CLASS_TEMPERATURE,
|
||||||
ATTR_STATE_CLASS: STATE_CLASS_MEASUREMENT,
|
state_class=STATE_CLASS_MEASUREMENT,
|
||||||
},
|
),
|
||||||
f"{SynoDSMInformation.API_KEY}:uptime": {
|
SynologyDSMSensorEntityDescription(
|
||||||
ATTR_NAME: "last boot",
|
api_key=SynoDSMInformation.API_KEY,
|
||||||
ATTR_UNIT_OF_MEASUREMENT: None,
|
key="uptime",
|
||||||
ATTR_ICON: None,
|
name="last boot",
|
||||||
ATTR_DEVICE_CLASS: DEVICE_CLASS_TIMESTAMP,
|
device_class=DEVICE_CLASS_TIMESTAMP,
|
||||||
ENTITY_ENABLE: False,
|
entity_registry_enabled_default=False,
|
||||||
ATTR_STATE_CLASS: None,
|
),
|
||||||
},
|
)
|
||||||
}
|
|
||||||
|
|
||||||
# Switch
|
# Switch
|
||||||
SURVEILLANCE_SWITCH: dict[str, EntityInfo] = {
|
SURVEILLANCE_SWITCH: tuple[SynologyDSMSwitchEntityDescription, ...] = (
|
||||||
f"{SynoSurveillanceStation.HOME_MODE_API_KEY}:home_mode": {
|
SynologyDSMSwitchEntityDescription(
|
||||||
ATTR_NAME: "home mode",
|
api_key=SynoSurveillanceStation.HOME_MODE_API_KEY,
|
||||||
ATTR_UNIT_OF_MEASUREMENT: None,
|
key="home_mode",
|
||||||
ATTR_ICON: "mdi:home-account",
|
name="home mode",
|
||||||
ATTR_DEVICE_CLASS: None,
|
icon="mdi:home-account",
|
||||||
ENTITY_ENABLE: True,
|
),
|
||||||
ATTR_STATE_CLASS: None,
|
)
|
||||||
},
|
|
||||||
}
|
|
||||||
|
@ -28,7 +28,7 @@ from .const import (
|
|||||||
STORAGE_VOL_SENSORS,
|
STORAGE_VOL_SENSORS,
|
||||||
SYNO_API,
|
SYNO_API,
|
||||||
UTILISATION_SENSORS,
|
UTILISATION_SENSORS,
|
||||||
EntityInfo,
|
SynologyDSMSensorEntityDescription,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@ -42,77 +42,77 @@ async def async_setup_entry(
|
|||||||
coordinator = data[COORDINATOR_CENTRAL]
|
coordinator = data[COORDINATOR_CENTRAL]
|
||||||
|
|
||||||
entities: list[SynoDSMUtilSensor | SynoDSMStorageSensor | SynoDSMInfoSensor] = [
|
entities: list[SynoDSMUtilSensor | SynoDSMStorageSensor | SynoDSMInfoSensor] = [
|
||||||
SynoDSMUtilSensor(api, sensor_type, sensor, coordinator)
|
SynoDSMUtilSensor(api, coordinator, description)
|
||||||
for sensor_type, sensor in UTILISATION_SENSORS.items()
|
for description in UTILISATION_SENSORS
|
||||||
]
|
]
|
||||||
|
|
||||||
# Handle all volumes
|
# Handle all volumes
|
||||||
if api.storage.volumes_ids:
|
if api.storage.volumes_ids:
|
||||||
for volume in entry.data.get(CONF_VOLUMES, api.storage.volumes_ids):
|
entities.extend(
|
||||||
entities += [
|
[
|
||||||
SynoDSMStorageSensor(
|
SynoDSMStorageSensor(api, coordinator, description, volume)
|
||||||
api,
|
for volume in entry.data.get(CONF_VOLUMES, api.storage.volumes_ids)
|
||||||
sensor_type,
|
for description in STORAGE_VOL_SENSORS
|
||||||
sensor,
|
|
||||||
coordinator,
|
|
||||||
volume,
|
|
||||||
)
|
|
||||||
for sensor_type, sensor in STORAGE_VOL_SENSORS.items()
|
|
||||||
]
|
]
|
||||||
|
)
|
||||||
|
|
||||||
# Handle all disks
|
# Handle all disks
|
||||||
if api.storage.disks_ids:
|
if api.storage.disks_ids:
|
||||||
for disk in entry.data.get(CONF_DISKS, api.storage.disks_ids):
|
entities.extend(
|
||||||
entities += [
|
[
|
||||||
SynoDSMStorageSensor(
|
SynoDSMStorageSensor(api, coordinator, description, disk)
|
||||||
api,
|
for disk in entry.data.get(CONF_DISKS, api.storage.disks_ids)
|
||||||
sensor_type,
|
for description in STORAGE_DISK_SENSORS
|
||||||
sensor,
|
]
|
||||||
coordinator,
|
|
||||||
disk,
|
|
||||||
)
|
)
|
||||||
for sensor_type, sensor in STORAGE_DISK_SENSORS.items()
|
|
||||||
]
|
|
||||||
|
|
||||||
entities += [
|
entities.extend(
|
||||||
SynoDSMInfoSensor(api, sensor_type, sensor, coordinator)
|
[
|
||||||
for sensor_type, sensor in INFORMATION_SENSORS.items()
|
SynoDSMInfoSensor(api, coordinator, description)
|
||||||
|
for description in INFORMATION_SENSORS
|
||||||
]
|
]
|
||||||
|
)
|
||||||
|
|
||||||
async_add_entities(entities)
|
async_add_entities(entities)
|
||||||
|
|
||||||
|
|
||||||
class SynoDSMSensor(SynologyDSMBaseEntity):
|
class SynoDSMSensor(SynologyDSMBaseEntity, SensorEntity):
|
||||||
"""Mixin for sensor specific attributes."""
|
"""Mixin for sensor specific attributes."""
|
||||||
|
|
||||||
@property
|
entity_description: SynologyDSMSensorEntityDescription
|
||||||
def native_unit_of_measurement(self) -> str | None:
|
|
||||||
"""Return the unit the value is expressed in."""
|
def __init__(
|
||||||
return self._unit
|
self,
|
||||||
|
api: SynoApi,
|
||||||
|
coordinator: DataUpdateCoordinator[dict[str, dict[str, Any]]],
|
||||||
|
description: SynologyDSMSensorEntityDescription,
|
||||||
|
) -> None:
|
||||||
|
"""Initialize the Synology DSM sensor entity."""
|
||||||
|
super().__init__(api, coordinator, description)
|
||||||
|
|
||||||
|
|
||||||
class SynoDSMUtilSensor(SynoDSMSensor, SensorEntity):
|
class SynoDSMUtilSensor(SynoDSMSensor):
|
||||||
"""Representation a Synology Utilisation sensor."""
|
"""Representation a Synology Utilisation sensor."""
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def native_value(self) -> Any | None:
|
def native_value(self) -> Any | None:
|
||||||
"""Return the state."""
|
"""Return the state."""
|
||||||
attr = getattr(self._api.utilisation, self.entity_type)
|
attr = getattr(self._api.utilisation, self.entity_description.key)
|
||||||
if callable(attr):
|
if callable(attr):
|
||||||
attr = attr()
|
attr = attr()
|
||||||
if attr is None:
|
if attr is None:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
# Data (RAM)
|
# Data (RAM)
|
||||||
if self._unit == DATA_MEGABYTES:
|
if self.native_unit_of_measurement == DATA_MEGABYTES:
|
||||||
return round(attr / 1024.0 ** 2, 1)
|
return round(attr / 1024.0 ** 2, 1)
|
||||||
|
|
||||||
# Network
|
# Network
|
||||||
if self._unit == DATA_RATE_KILOBYTES_PER_SECOND:
|
if self.native_unit_of_measurement == DATA_RATE_KILOBYTES_PER_SECOND:
|
||||||
return round(attr / 1024.0, 1)
|
return round(attr / 1024.0, 1)
|
||||||
|
|
||||||
# CPU load average
|
# CPU load average
|
||||||
if self._unit == ENTITY_UNIT_LOAD:
|
if self.native_unit_of_measurement == ENTITY_UNIT_LOAD:
|
||||||
return round(attr / 100, 2)
|
return round(attr / 100, 2)
|
||||||
|
|
||||||
return attr
|
return attr
|
||||||
@ -123,46 +123,57 @@ class SynoDSMUtilSensor(SynoDSMSensor, SensorEntity):
|
|||||||
return bool(self._api.utilisation)
|
return bool(self._api.utilisation)
|
||||||
|
|
||||||
|
|
||||||
class SynoDSMStorageSensor(SynologyDSMDeviceEntity, SynoDSMSensor, SensorEntity):
|
class SynoDSMStorageSensor(SynologyDSMDeviceEntity, SynoDSMSensor):
|
||||||
"""Representation a Synology Storage sensor."""
|
"""Representation a Synology Storage sensor."""
|
||||||
|
|
||||||
|
entity_description: SynologyDSMSensorEntityDescription
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
api: SynoApi,
|
||||||
|
coordinator: DataUpdateCoordinator[dict[str, dict[str, Any]]],
|
||||||
|
description: SynologyDSMSensorEntityDescription,
|
||||||
|
device_id: str | None = None,
|
||||||
|
) -> None:
|
||||||
|
"""Initialize the Synology DSM storage sensor entity."""
|
||||||
|
super().__init__(api, coordinator, description, device_id)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def native_value(self) -> Any | None:
|
def native_value(self) -> Any | None:
|
||||||
"""Return the state."""
|
"""Return the state."""
|
||||||
attr = getattr(self._api.storage, self.entity_type)(self._device_id)
|
attr = getattr(self._api.storage, self.entity_description.key)(self._device_id)
|
||||||
if attr is None:
|
if attr is None:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
# Data (disk space)
|
# Data (disk space)
|
||||||
if self._unit == DATA_TERABYTES:
|
if self.native_unit_of_measurement == DATA_TERABYTES:
|
||||||
return round(attr / 1024.0 ** 4, 2)
|
return round(attr / 1024.0 ** 4, 2)
|
||||||
|
|
||||||
return attr
|
return attr
|
||||||
|
|
||||||
|
|
||||||
class SynoDSMInfoSensor(SynoDSMSensor, SensorEntity):
|
class SynoDSMInfoSensor(SynoDSMSensor):
|
||||||
"""Representation a Synology information sensor."""
|
"""Representation a Synology information sensor."""
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
api: SynoApi,
|
api: SynoApi,
|
||||||
entity_type: str,
|
|
||||||
entity_info: EntityInfo,
|
|
||||||
coordinator: DataUpdateCoordinator[dict[str, dict[str, Any]]],
|
coordinator: DataUpdateCoordinator[dict[str, dict[str, Any]]],
|
||||||
|
description: SynologyDSMSensorEntityDescription,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Initialize the Synology SynoDSMInfoSensor entity."""
|
"""Initialize the Synology SynoDSMInfoSensor entity."""
|
||||||
super().__init__(api, entity_type, entity_info, coordinator)
|
super().__init__(api, coordinator, description)
|
||||||
self._previous_uptime: str | None = None
|
self._previous_uptime: str | None = None
|
||||||
self._last_boot: str | None = None
|
self._last_boot: str | None = None
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def native_value(self) -> Any | None:
|
def native_value(self) -> Any | None:
|
||||||
"""Return the state."""
|
"""Return the state."""
|
||||||
attr = getattr(self._api.information, self.entity_type)
|
attr = getattr(self._api.information, self.entity_description.key)
|
||||||
if attr is None:
|
if attr is None:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
if self.entity_type == "uptime":
|
if self.entity_description.key == "uptime":
|
||||||
# reboot happened or entity creation
|
# reboot happened or entity creation
|
||||||
if self._previous_uptime is None or self._previous_uptime > attr:
|
if self._previous_uptime is None or self._previous_uptime > attr:
|
||||||
last_boot = utcnow() - timedelta(seconds=attr)
|
last_boot = utcnow() - timedelta(seconds=attr)
|
||||||
|
@ -19,7 +19,7 @@ from .const import (
|
|||||||
DOMAIN,
|
DOMAIN,
|
||||||
SURVEILLANCE_SWITCH,
|
SURVEILLANCE_SWITCH,
|
||||||
SYNO_API,
|
SYNO_API,
|
||||||
EntityInfo,
|
SynologyDSMSwitchEntityDescription,
|
||||||
)
|
)
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
@ -42,12 +42,14 @@ async def async_setup_entry(
|
|||||||
# initial data fetch
|
# initial data fetch
|
||||||
coordinator: DataUpdateCoordinator = data[COORDINATOR_SWITCHES]
|
coordinator: DataUpdateCoordinator = data[COORDINATOR_SWITCHES]
|
||||||
await coordinator.async_refresh()
|
await coordinator.async_refresh()
|
||||||
entities += [
|
entities.extend(
|
||||||
|
[
|
||||||
SynoDSMSurveillanceHomeModeToggle(
|
SynoDSMSurveillanceHomeModeToggle(
|
||||||
api, sensor_type, switch, version, coordinator
|
api, version, coordinator, description
|
||||||
)
|
)
|
||||||
for sensor_type, switch in SURVEILLANCE_SWITCH.items()
|
for description in SURVEILLANCE_SWITCH
|
||||||
]
|
]
|
||||||
|
)
|
||||||
|
|
||||||
async_add_entities(entities, True)
|
async_add_entities(entities, True)
|
||||||
|
|
||||||
@ -56,28 +58,23 @@ class SynoDSMSurveillanceHomeModeToggle(SynologyDSMBaseEntity, ToggleEntity):
|
|||||||
"""Representation a Synology Surveillance Station Home Mode toggle."""
|
"""Representation a Synology Surveillance Station Home Mode toggle."""
|
||||||
|
|
||||||
coordinator: DataUpdateCoordinator[dict[str, dict[str, bool]]]
|
coordinator: DataUpdateCoordinator[dict[str, dict[str, bool]]]
|
||||||
|
entity_description: SynologyDSMSwitchEntityDescription
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
api: SynoApi,
|
api: SynoApi,
|
||||||
entity_type: str,
|
|
||||||
entity_info: EntityInfo,
|
|
||||||
version: str,
|
version: str,
|
||||||
coordinator: DataUpdateCoordinator[dict[str, dict[str, bool]]],
|
coordinator: DataUpdateCoordinator[dict[str, dict[str, bool]]],
|
||||||
|
description: SynologyDSMSwitchEntityDescription,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Initialize a Synology Surveillance Station Home Mode."""
|
"""Initialize a Synology Surveillance Station Home Mode."""
|
||||||
super().__init__(
|
super().__init__(api, coordinator, description)
|
||||||
api,
|
|
||||||
entity_type,
|
|
||||||
entity_info,
|
|
||||||
coordinator,
|
|
||||||
)
|
|
||||||
self._version = version
|
self._version = version
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def is_on(self) -> bool:
|
def is_on(self) -> bool:
|
||||||
"""Return the state."""
|
"""Return the state."""
|
||||||
return self.coordinator.data["switches"][self.entity_type]
|
return self.coordinator.data["switches"][self.entity_description.key]
|
||||||
|
|
||||||
async def async_turn_on(self, **kwargs: Any) -> None:
|
async def async_turn_on(self, **kwargs: Any) -> None:
|
||||||
"""Turn on Home mode."""
|
"""Turn on Home mode."""
|
||||||
|
Loading…
x
Reference in New Issue
Block a user