mirror of
https://github.com/home-assistant/core.git
synced 2025-07-14 08:47:10 +00:00
Use EntityDescription - qnap (#55410)
* Use EntityDescription - qnap * Remove default values
This commit is contained in:
parent
3bd9be2f6d
commit
1c01ff401f
@ -1,11 +1,17 @@
|
|||||||
"""Support for QNAP NAS Sensors."""
|
"""Support for QNAP NAS Sensors."""
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
from datetime import timedelta
|
from datetime import timedelta
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
from qnapstats import QNAPStats
|
from qnapstats import QNAPStats
|
||||||
import voluptuous as vol
|
import voluptuous as vol
|
||||||
|
|
||||||
from homeassistant.components.sensor import PLATFORM_SCHEMA, SensorEntity
|
from homeassistant.components.sensor import (
|
||||||
|
PLATFORM_SCHEMA,
|
||||||
|
SensorEntity,
|
||||||
|
SensorEntityDescription,
|
||||||
|
)
|
||||||
from homeassistant.const import (
|
from homeassistant.const import (
|
||||||
ATTR_NAME,
|
ATTR_NAME,
|
||||||
CONF_HOST,
|
CONF_HOST,
|
||||||
@ -56,57 +62,117 @@ MIN_TIME_BETWEEN_UPDATES = timedelta(minutes=1)
|
|||||||
NOTIFICATION_ID = "qnap_notification"
|
NOTIFICATION_ID = "qnap_notification"
|
||||||
NOTIFICATION_TITLE = "QNAP Sensor Setup"
|
NOTIFICATION_TITLE = "QNAP Sensor Setup"
|
||||||
|
|
||||||
_SYSTEM_MON_COND = {
|
_SYSTEM_MON_COND: tuple[SensorEntityDescription, ...] = (
|
||||||
"status": ["Status", None, "mdi:checkbox-marked-circle-outline", None],
|
SensorEntityDescription(
|
||||||
"system_temp": ["System Temperature", TEMP_CELSIUS, None, DEVICE_CLASS_TEMPERATURE],
|
key="status",
|
||||||
}
|
name="Status",
|
||||||
_CPU_MON_COND = {
|
icon="mdi:checkbox-marked-circle-outline",
|
||||||
"cpu_temp": ["CPU Temperature", TEMP_CELSIUS, None, DEVICE_CLASS_TEMPERATURE],
|
),
|
||||||
"cpu_usage": ["CPU Usage", PERCENTAGE, "mdi:chip", None],
|
SensorEntityDescription(
|
||||||
}
|
key="system_temp",
|
||||||
_MEMORY_MON_COND = {
|
name="System Temperature",
|
||||||
"memory_free": ["Memory Available", DATA_GIBIBYTES, "mdi:memory", None],
|
native_unit_of_measurement=TEMP_CELSIUS,
|
||||||
"memory_used": ["Memory Used", DATA_GIBIBYTES, "mdi:memory", None],
|
device_class=DEVICE_CLASS_TEMPERATURE,
|
||||||
"memory_percent_used": ["Memory Usage", PERCENTAGE, "mdi:memory", None],
|
),
|
||||||
}
|
|
||||||
_NETWORK_MON_COND = {
|
|
||||||
"network_link_status": [
|
|
||||||
"Network Link",
|
|
||||||
None,
|
|
||||||
"mdi:checkbox-marked-circle-outline",
|
|
||||||
None,
|
|
||||||
],
|
|
||||||
"network_tx": ["Network Up", DATA_RATE_MEBIBYTES_PER_SECOND, "mdi:upload", None],
|
|
||||||
"network_rx": [
|
|
||||||
"Network Down",
|
|
||||||
DATA_RATE_MEBIBYTES_PER_SECOND,
|
|
||||||
"mdi:download",
|
|
||||||
None,
|
|
||||||
],
|
|
||||||
}
|
|
||||||
_DRIVE_MON_COND = {
|
|
||||||
"drive_smart_status": [
|
|
||||||
"SMART Status",
|
|
||||||
None,
|
|
||||||
"mdi:checkbox-marked-circle-outline",
|
|
||||||
None,
|
|
||||||
],
|
|
||||||
"drive_temp": ["Temperature", TEMP_CELSIUS, None, DEVICE_CLASS_TEMPERATURE],
|
|
||||||
}
|
|
||||||
_VOLUME_MON_COND = {
|
|
||||||
"volume_size_used": ["Used Space", DATA_GIBIBYTES, "mdi:chart-pie", None],
|
|
||||||
"volume_size_free": ["Free Space", DATA_GIBIBYTES, "mdi:chart-pie", None],
|
|
||||||
"volume_percentage_used": ["Volume Used", PERCENTAGE, "mdi:chart-pie", None],
|
|
||||||
}
|
|
||||||
|
|
||||||
_MONITORED_CONDITIONS = (
|
|
||||||
list(_SYSTEM_MON_COND)
|
|
||||||
+ list(_CPU_MON_COND)
|
|
||||||
+ list(_MEMORY_MON_COND)
|
|
||||||
+ list(_NETWORK_MON_COND)
|
|
||||||
+ list(_DRIVE_MON_COND)
|
|
||||||
+ list(_VOLUME_MON_COND)
|
|
||||||
)
|
)
|
||||||
|
_CPU_MON_COND: tuple[SensorEntityDescription, ...] = (
|
||||||
|
SensorEntityDescription(
|
||||||
|
key="cpu_temp",
|
||||||
|
name="CPU Temperature",
|
||||||
|
native_unit_of_measurement=TEMP_CELSIUS,
|
||||||
|
device_class=DEVICE_CLASS_TEMPERATURE,
|
||||||
|
),
|
||||||
|
SensorEntityDescription(
|
||||||
|
key="cpu_usage",
|
||||||
|
name="CPU Usage",
|
||||||
|
native_unit_of_measurement=PERCENTAGE,
|
||||||
|
icon="mdi:chip",
|
||||||
|
),
|
||||||
|
)
|
||||||
|
_MEMORY_MON_COND: tuple[SensorEntityDescription, ...] = (
|
||||||
|
SensorEntityDescription(
|
||||||
|
key="memory_free",
|
||||||
|
name="Memory Available",
|
||||||
|
native_unit_of_measurement=DATA_GIBIBYTES,
|
||||||
|
icon="mdi:memory",
|
||||||
|
),
|
||||||
|
SensorEntityDescription(
|
||||||
|
key="memory_used",
|
||||||
|
name="Memory Used",
|
||||||
|
native_unit_of_measurement=DATA_GIBIBYTES,
|
||||||
|
icon="mdi:memory",
|
||||||
|
),
|
||||||
|
SensorEntityDescription(
|
||||||
|
key="memory_percent_used",
|
||||||
|
name="Memory Usage",
|
||||||
|
native_unit_of_measurement=PERCENTAGE,
|
||||||
|
icon="mdi:memory",
|
||||||
|
),
|
||||||
|
)
|
||||||
|
_NETWORK_MON_COND: tuple[SensorEntityDescription, ...] = (
|
||||||
|
SensorEntityDescription(
|
||||||
|
key="network_link_status",
|
||||||
|
name="Network Link",
|
||||||
|
icon="mdi:checkbox-marked-circle-outline",
|
||||||
|
),
|
||||||
|
SensorEntityDescription(
|
||||||
|
key="network_tx",
|
||||||
|
name="Network Up",
|
||||||
|
native_unit_of_measurement=DATA_RATE_MEBIBYTES_PER_SECOND,
|
||||||
|
icon="mdi:upload",
|
||||||
|
),
|
||||||
|
SensorEntityDescription(
|
||||||
|
key="network_rx",
|
||||||
|
name="Network Down",
|
||||||
|
native_unit_of_measurement=DATA_RATE_MEBIBYTES_PER_SECOND,
|
||||||
|
icon="mdi:download",
|
||||||
|
),
|
||||||
|
)
|
||||||
|
_DRIVE_MON_COND: tuple[SensorEntityDescription, ...] = (
|
||||||
|
SensorEntityDescription(
|
||||||
|
key="drive_smart_status",
|
||||||
|
name="SMART Status",
|
||||||
|
icon="mdi:checkbox-marked-circle-outline",
|
||||||
|
),
|
||||||
|
SensorEntityDescription(
|
||||||
|
key="drive_temp",
|
||||||
|
name="Temperature",
|
||||||
|
native_unit_of_measurement=TEMP_CELSIUS,
|
||||||
|
device_class=DEVICE_CLASS_TEMPERATURE,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
_VOLUME_MON_COND: tuple[SensorEntityDescription, ...] = (
|
||||||
|
SensorEntityDescription(
|
||||||
|
key="volume_size_used",
|
||||||
|
name="Used Space",
|
||||||
|
native_unit_of_measurement=DATA_GIBIBYTES,
|
||||||
|
icon="mdi:chart-pie",
|
||||||
|
),
|
||||||
|
SensorEntityDescription(
|
||||||
|
key="volume_size_free",
|
||||||
|
name="Free Space",
|
||||||
|
native_unit_of_measurement=DATA_GIBIBYTES,
|
||||||
|
icon="mdi:chart-pie",
|
||||||
|
),
|
||||||
|
SensorEntityDescription(
|
||||||
|
key="volume_percentage_used",
|
||||||
|
name="Volume Used",
|
||||||
|
native_unit_of_measurement=PERCENTAGE,
|
||||||
|
icon="mdi:chart-pie",
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
SENSOR_KEYS: list[str] = [
|
||||||
|
desc.key
|
||||||
|
for desc in (
|
||||||
|
*_SYSTEM_MON_COND,
|
||||||
|
*_CPU_MON_COND,
|
||||||
|
*_MEMORY_MON_COND,
|
||||||
|
*_NETWORK_MON_COND,
|
||||||
|
*_DRIVE_MON_COND,
|
||||||
|
*_VOLUME_MON_COND,
|
||||||
|
)
|
||||||
|
]
|
||||||
|
|
||||||
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(
|
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(
|
||||||
{
|
{
|
||||||
@ -118,7 +184,7 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(
|
|||||||
vol.Required(CONF_USERNAME): cv.string,
|
vol.Required(CONF_USERNAME): cv.string,
|
||||||
vol.Required(CONF_PASSWORD): cv.string,
|
vol.Required(CONF_PASSWORD): cv.string,
|
||||||
vol.Optional(CONF_MONITORED_CONDITIONS): vol.All(
|
vol.Optional(CONF_MONITORED_CONDITIONS): vol.All(
|
||||||
cv.ensure_list, [vol.In(_MONITORED_CONDITIONS)]
|
cv.ensure_list, [vol.In(SENSOR_KEYS)]
|
||||||
),
|
),
|
||||||
vol.Optional(CONF_NICS): cv.ensure_list,
|
vol.Optional(CONF_NICS): cv.ensure_list,
|
||||||
vol.Optional(CONF_DRIVES): cv.ensure_list,
|
vol.Optional(CONF_DRIVES): cv.ensure_list,
|
||||||
@ -136,40 +202,61 @@ def setup_platform(hass, config, add_entities, discovery_info=None):
|
|||||||
if not api.data:
|
if not api.data:
|
||||||
raise PlatformNotReady
|
raise PlatformNotReady
|
||||||
|
|
||||||
|
monitored_conditions = config[CONF_MONITORED_CONDITIONS]
|
||||||
sensors = []
|
sensors = []
|
||||||
|
|
||||||
# Basic sensors
|
# Basic sensors
|
||||||
for variable in config[CONF_MONITORED_CONDITIONS]:
|
sensors.extend(
|
||||||
if variable in _SYSTEM_MON_COND:
|
[
|
||||||
sensors.append(QNAPSystemSensor(api, variable, _SYSTEM_MON_COND[variable]))
|
QNAPSystemSensor(api, description)
|
||||||
if variable in _CPU_MON_COND:
|
for description in _SYSTEM_MON_COND
|
||||||
sensors.append(QNAPCPUSensor(api, variable, _CPU_MON_COND[variable]))
|
if description.key in monitored_conditions
|
||||||
if variable in _MEMORY_MON_COND:
|
]
|
||||||
sensors.append(QNAPMemorySensor(api, variable, _MEMORY_MON_COND[variable]))
|
)
|
||||||
|
sensors.extend(
|
||||||
|
[
|
||||||
|
QNAPCPUSensor(api, description)
|
||||||
|
for description in _CPU_MON_COND
|
||||||
|
if description.key in monitored_conditions
|
||||||
|
]
|
||||||
|
)
|
||||||
|
sensors.extend(
|
||||||
|
[
|
||||||
|
QNAPMemorySensor(api, description)
|
||||||
|
for description in _MEMORY_MON_COND
|
||||||
|
if description.key in monitored_conditions
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
# Network sensors
|
# Network sensors
|
||||||
for nic in config.get(CONF_NICS, api.data["system_stats"]["nics"]):
|
sensors.extend(
|
||||||
sensors += [
|
[
|
||||||
QNAPNetworkSensor(api, variable, _NETWORK_MON_COND[variable], nic)
|
QNAPNetworkSensor(api, description, nic)
|
||||||
for variable in config[CONF_MONITORED_CONDITIONS]
|
for nic in config.get(CONF_NICS, api.data["system_stats"]["nics"])
|
||||||
if variable in _NETWORK_MON_COND
|
for description in _NETWORK_MON_COND
|
||||||
|
if description.key in monitored_conditions
|
||||||
]
|
]
|
||||||
|
)
|
||||||
|
|
||||||
# Drive sensors
|
# Drive sensors
|
||||||
for drive in config.get(CONF_DRIVES, api.data["smart_drive_health"]):
|
sensors.extend(
|
||||||
sensors += [
|
[
|
||||||
QNAPDriveSensor(api, variable, _DRIVE_MON_COND[variable], drive)
|
QNAPDriveSensor(api, description, drive)
|
||||||
for variable in config[CONF_MONITORED_CONDITIONS]
|
for drive in config.get(CONF_DRIVES, api.data["smart_drive_health"])
|
||||||
if variable in _DRIVE_MON_COND
|
for description in _DRIVE_MON_COND
|
||||||
|
if description.key in monitored_conditions
|
||||||
]
|
]
|
||||||
|
)
|
||||||
|
|
||||||
# Volume sensors
|
# Volume sensors
|
||||||
for volume in config.get(CONF_VOLUMES, api.data["volumes"]):
|
sensors.extend(
|
||||||
sensors += [
|
[
|
||||||
QNAPVolumeSensor(api, variable, _VOLUME_MON_COND[variable], volume)
|
QNAPVolumeSensor(api, description, volume)
|
||||||
for variable in config[CONF_MONITORED_CONDITIONS]
|
for volume in config.get(CONF_VOLUMES, api.data["volumes"])
|
||||||
if variable in _VOLUME_MON_COND
|
for description in _VOLUME_MON_COND
|
||||||
|
if description.key in monitored_conditions
|
||||||
]
|
]
|
||||||
|
)
|
||||||
|
|
||||||
add_entities(sensors)
|
add_entities(sensors)
|
||||||
|
|
||||||
@ -218,15 +305,11 @@ class QNAPStatsAPI:
|
|||||||
class QNAPSensor(SensorEntity):
|
class QNAPSensor(SensorEntity):
|
||||||
"""Base class for a QNAP sensor."""
|
"""Base class for a QNAP sensor."""
|
||||||
|
|
||||||
def __init__(self, api, variable, variable_info, monitor_device=None):
|
def __init__(self, api, description: SensorEntityDescription, monitor_device=None):
|
||||||
"""Initialize the sensor."""
|
"""Initialize the sensor."""
|
||||||
self.var_id = variable
|
self.entity_description = description
|
||||||
self.var_name = variable_info[0]
|
|
||||||
self.var_units = variable_info[1]
|
|
||||||
self.var_icon = variable_info[2]
|
|
||||||
self.monitor_device = monitor_device
|
self.monitor_device = monitor_device
|
||||||
self._api = api
|
self._api = api
|
||||||
self._attr_device_class = variable_info[3]
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def name(self):
|
def name(self):
|
||||||
@ -234,18 +317,10 @@ class QNAPSensor(SensorEntity):
|
|||||||
server_name = self._api.data["system_stats"]["system"]["name"]
|
server_name = self._api.data["system_stats"]["system"]["name"]
|
||||||
|
|
||||||
if self.monitor_device is not None:
|
if self.monitor_device is not None:
|
||||||
return f"{server_name} {self.var_name} ({self.monitor_device})"
|
return (
|
||||||
return f"{server_name} {self.var_name}"
|
f"{server_name} {self.entity_description.name} ({self.monitor_device})"
|
||||||
|
)
|
||||||
@property
|
return f"{server_name} {self.entity_description.name}"
|
||||||
def icon(self):
|
|
||||||
"""Return the icon to use in the frontend, if any."""
|
|
||||||
return self.var_icon
|
|
||||||
|
|
||||||
@property
|
|
||||||
def native_unit_of_measurement(self):
|
|
||||||
"""Return the unit the value is expressed in."""
|
|
||||||
return self.var_units
|
|
||||||
|
|
||||||
def update(self):
|
def update(self):
|
||||||
"""Get the latest data for the states."""
|
"""Get the latest data for the states."""
|
||||||
@ -258,9 +333,9 @@ class QNAPCPUSensor(QNAPSensor):
|
|||||||
@property
|
@property
|
||||||
def native_value(self):
|
def native_value(self):
|
||||||
"""Return the state of the sensor."""
|
"""Return the state of the sensor."""
|
||||||
if self.var_id == "cpu_temp":
|
if self.entity_description.key == "cpu_temp":
|
||||||
return self._api.data["system_stats"]["cpu"]["temp_c"]
|
return self._api.data["system_stats"]["cpu"]["temp_c"]
|
||||||
if self.var_id == "cpu_usage":
|
if self.entity_description.key == "cpu_usage":
|
||||||
return self._api.data["system_stats"]["cpu"]["usage_percent"]
|
return self._api.data["system_stats"]["cpu"]["usage_percent"]
|
||||||
|
|
||||||
|
|
||||||
@ -271,16 +346,16 @@ class QNAPMemorySensor(QNAPSensor):
|
|||||||
def native_value(self):
|
def native_value(self):
|
||||||
"""Return the state of the sensor."""
|
"""Return the state of the sensor."""
|
||||||
free = float(self._api.data["system_stats"]["memory"]["free"]) / 1024
|
free = float(self._api.data["system_stats"]["memory"]["free"]) / 1024
|
||||||
if self.var_id == "memory_free":
|
if self.entity_description.key == "memory_free":
|
||||||
return round_nicely(free)
|
return round_nicely(free)
|
||||||
|
|
||||||
total = float(self._api.data["system_stats"]["memory"]["total"]) / 1024
|
total = float(self._api.data["system_stats"]["memory"]["total"]) / 1024
|
||||||
|
|
||||||
used = total - free
|
used = total - free
|
||||||
if self.var_id == "memory_used":
|
if self.entity_description.key == "memory_used":
|
||||||
return round_nicely(used)
|
return round_nicely(used)
|
||||||
|
|
||||||
if self.var_id == "memory_percent_used":
|
if self.entity_description.key == "memory_percent_used":
|
||||||
return round(used / total * 100)
|
return round(used / total * 100)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@ -298,15 +373,15 @@ class QNAPNetworkSensor(QNAPSensor):
|
|||||||
@property
|
@property
|
||||||
def native_value(self):
|
def native_value(self):
|
||||||
"""Return the state of the sensor."""
|
"""Return the state of the sensor."""
|
||||||
if self.var_id == "network_link_status":
|
if self.entity_description.key == "network_link_status":
|
||||||
nic = self._api.data["system_stats"]["nics"][self.monitor_device]
|
nic = self._api.data["system_stats"]["nics"][self.monitor_device]
|
||||||
return nic["link_status"]
|
return nic["link_status"]
|
||||||
|
|
||||||
data = self._api.data["bandwidth"][self.monitor_device]
|
data = self._api.data["bandwidth"][self.monitor_device]
|
||||||
if self.var_id == "network_tx":
|
if self.entity_description.key == "network_tx":
|
||||||
return round_nicely(data["tx"] / 1024 / 1024)
|
return round_nicely(data["tx"] / 1024 / 1024)
|
||||||
|
|
||||||
if self.var_id == "network_rx":
|
if self.entity_description.key == "network_rx":
|
||||||
return round_nicely(data["rx"] / 1024 / 1024)
|
return round_nicely(data["rx"] / 1024 / 1024)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@ -331,10 +406,10 @@ class QNAPSystemSensor(QNAPSensor):
|
|||||||
@property
|
@property
|
||||||
def native_value(self):
|
def native_value(self):
|
||||||
"""Return the state of the sensor."""
|
"""Return the state of the sensor."""
|
||||||
if self.var_id == "status":
|
if self.entity_description.key == "status":
|
||||||
return self._api.data["system_health"]
|
return self._api.data["system_health"]
|
||||||
|
|
||||||
if self.var_id == "system_temp":
|
if self.entity_description.key == "system_temp":
|
||||||
return int(self._api.data["system_stats"]["system"]["temp_c"])
|
return int(self._api.data["system_stats"]["system"]["temp_c"])
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@ -362,10 +437,10 @@ class QNAPDriveSensor(QNAPSensor):
|
|||||||
"""Return the state of the sensor."""
|
"""Return the state of the sensor."""
|
||||||
data = self._api.data["smart_drive_health"][self.monitor_device]
|
data = self._api.data["smart_drive_health"][self.monitor_device]
|
||||||
|
|
||||||
if self.var_id == "drive_smart_status":
|
if self.entity_description.key == "drive_smart_status":
|
||||||
return data["health"]
|
return data["health"]
|
||||||
|
|
||||||
if self.var_id == "drive_temp":
|
if self.entity_description.key == "drive_temp":
|
||||||
return int(data["temp_c"]) if data["temp_c"] is not None else 0
|
return int(data["temp_c"]) if data["temp_c"] is not None else 0
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@ -373,7 +448,7 @@ class QNAPDriveSensor(QNAPSensor):
|
|||||||
"""Return the name of the sensor, if any."""
|
"""Return the name of the sensor, if any."""
|
||||||
server_name = self._api.data["system_stats"]["system"]["name"]
|
server_name = self._api.data["system_stats"]["system"]["name"]
|
||||||
|
|
||||||
return f"{server_name} {self.var_name} (Drive {self.monitor_device})"
|
return f"{server_name} {self.entity_description.name} (Drive {self.monitor_device})"
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def extra_state_attributes(self):
|
def extra_state_attributes(self):
|
||||||
@ -397,16 +472,16 @@ class QNAPVolumeSensor(QNAPSensor):
|
|||||||
data = self._api.data["volumes"][self.monitor_device]
|
data = self._api.data["volumes"][self.monitor_device]
|
||||||
|
|
||||||
free_gb = int(data["free_size"]) / 1024 / 1024 / 1024
|
free_gb = int(data["free_size"]) / 1024 / 1024 / 1024
|
||||||
if self.var_id == "volume_size_free":
|
if self.entity_description.key == "volume_size_free":
|
||||||
return round_nicely(free_gb)
|
return round_nicely(free_gb)
|
||||||
|
|
||||||
total_gb = int(data["total_size"]) / 1024 / 1024 / 1024
|
total_gb = int(data["total_size"]) / 1024 / 1024 / 1024
|
||||||
|
|
||||||
used_gb = total_gb - free_gb
|
used_gb = total_gb - free_gb
|
||||||
if self.var_id == "volume_size_used":
|
if self.entity_description.key == "volume_size_used":
|
||||||
return round_nicely(used_gb)
|
return round_nicely(used_gb)
|
||||||
|
|
||||||
if self.var_id == "volume_percentage_used":
|
if self.entity_description.key == "volume_percentage_used":
|
||||||
return round(used_gb / total_gb * 100)
|
return round(used_gb / total_gb * 100)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
Loading…
x
Reference in New Issue
Block a user