Use EntityDescription - qnap (#55410)

* Use EntityDescription - qnap

* Remove default values
This commit is contained in:
Marc Mueller 2021-08-30 21:59:50 +02:00 committed by GitHub
parent 3bd9be2f6d
commit 1c01ff401f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -1,11 +1,17 @@
"""Support for QNAP NAS Sensors."""
from __future__ import annotations
from datetime import timedelta
import logging
from qnapstats import QNAPStats
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 (
ATTR_NAME,
CONF_HOST,
@ -56,57 +62,117 @@ MIN_TIME_BETWEEN_UPDATES = timedelta(minutes=1)
NOTIFICATION_ID = "qnap_notification"
NOTIFICATION_TITLE = "QNAP Sensor Setup"
_SYSTEM_MON_COND = {
"status": ["Status", None, "mdi:checkbox-marked-circle-outline", None],
"system_temp": ["System Temperature", TEMP_CELSIUS, None, DEVICE_CLASS_TEMPERATURE],
}
_CPU_MON_COND = {
"cpu_temp": ["CPU Temperature", TEMP_CELSIUS, None, DEVICE_CLASS_TEMPERATURE],
"cpu_usage": ["CPU Usage", PERCENTAGE, "mdi:chip", None],
}
_MEMORY_MON_COND = {
"memory_free": ["Memory Available", DATA_GIBIBYTES, "mdi:memory", None],
"memory_used": ["Memory Used", DATA_GIBIBYTES, "mdi:memory", None],
"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)
_SYSTEM_MON_COND: tuple[SensorEntityDescription, ...] = (
SensorEntityDescription(
key="status",
name="Status",
icon="mdi:checkbox-marked-circle-outline",
),
SensorEntityDescription(
key="system_temp",
name="System Temperature",
native_unit_of_measurement=TEMP_CELSIUS,
device_class=DEVICE_CLASS_TEMPERATURE,
),
)
_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(
{
@ -118,7 +184,7 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(
vol.Required(CONF_USERNAME): cv.string,
vol.Required(CONF_PASSWORD): cv.string,
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_DRIVES): cv.ensure_list,
@ -136,40 +202,61 @@ def setup_platform(hass, config, add_entities, discovery_info=None):
if not api.data:
raise PlatformNotReady
monitored_conditions = config[CONF_MONITORED_CONDITIONS]
sensors = []
# Basic sensors
for variable in config[CONF_MONITORED_CONDITIONS]:
if variable in _SYSTEM_MON_COND:
sensors.append(QNAPSystemSensor(api, variable, _SYSTEM_MON_COND[variable]))
if variable in _CPU_MON_COND:
sensors.append(QNAPCPUSensor(api, variable, _CPU_MON_COND[variable]))
if variable in _MEMORY_MON_COND:
sensors.append(QNAPMemorySensor(api, variable, _MEMORY_MON_COND[variable]))
sensors.extend(
[
QNAPSystemSensor(api, description)
for description in _SYSTEM_MON_COND
if description.key in monitored_conditions
]
)
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
for nic in config.get(CONF_NICS, api.data["system_stats"]["nics"]):
sensors += [
QNAPNetworkSensor(api, variable, _NETWORK_MON_COND[variable], nic)
for variable in config[CONF_MONITORED_CONDITIONS]
if variable in _NETWORK_MON_COND
sensors.extend(
[
QNAPNetworkSensor(api, description, nic)
for nic in config.get(CONF_NICS, api.data["system_stats"]["nics"])
for description in _NETWORK_MON_COND
if description.key in monitored_conditions
]
)
# Drive sensors
for drive in config.get(CONF_DRIVES, api.data["smart_drive_health"]):
sensors += [
QNAPDriveSensor(api, variable, _DRIVE_MON_COND[variable], drive)
for variable in config[CONF_MONITORED_CONDITIONS]
if variable in _DRIVE_MON_COND
sensors.extend(
[
QNAPDriveSensor(api, description, drive)
for drive in config.get(CONF_DRIVES, api.data["smart_drive_health"])
for description in _DRIVE_MON_COND
if description.key in monitored_conditions
]
)
# Volume sensors
for volume in config.get(CONF_VOLUMES, api.data["volumes"]):
sensors += [
QNAPVolumeSensor(api, variable, _VOLUME_MON_COND[variable], volume)
for variable in config[CONF_MONITORED_CONDITIONS]
if variable in _VOLUME_MON_COND
sensors.extend(
[
QNAPVolumeSensor(api, description, volume)
for volume in config.get(CONF_VOLUMES, api.data["volumes"])
for description in _VOLUME_MON_COND
if description.key in monitored_conditions
]
)
add_entities(sensors)
@ -218,15 +305,11 @@ class QNAPStatsAPI:
class QNAPSensor(SensorEntity):
"""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."""
self.var_id = variable
self.var_name = variable_info[0]
self.var_units = variable_info[1]
self.var_icon = variable_info[2]
self.entity_description = description
self.monitor_device = monitor_device
self._api = api
self._attr_device_class = variable_info[3]
@property
def name(self):
@ -234,18 +317,10 @@ class QNAPSensor(SensorEntity):
server_name = self._api.data["system_stats"]["system"]["name"]
if self.monitor_device is not None:
return f"{server_name} {self.var_name} ({self.monitor_device})"
return f"{server_name} {self.var_name}"
@property
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
return (
f"{server_name} {self.entity_description.name} ({self.monitor_device})"
)
return f"{server_name} {self.entity_description.name}"
def update(self):
"""Get the latest data for the states."""
@ -258,9 +333,9 @@ class QNAPCPUSensor(QNAPSensor):
@property
def native_value(self):
"""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"]
if self.var_id == "cpu_usage":
if self.entity_description.key == "cpu_usage":
return self._api.data["system_stats"]["cpu"]["usage_percent"]
@ -271,16 +346,16 @@ class QNAPMemorySensor(QNAPSensor):
def native_value(self):
"""Return the state of the sensor."""
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)
total = float(self._api.data["system_stats"]["memory"]["total"]) / 1024
used = total - free
if self.var_id == "memory_used":
if self.entity_description.key == "memory_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)
@property
@ -298,15 +373,15 @@ class QNAPNetworkSensor(QNAPSensor):
@property
def native_value(self):
"""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]
return nic["link_status"]
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)
if self.var_id == "network_rx":
if self.entity_description.key == "network_rx":
return round_nicely(data["rx"] / 1024 / 1024)
@property
@ -331,10 +406,10 @@ class QNAPSystemSensor(QNAPSensor):
@property
def native_value(self):
"""Return the state of the sensor."""
if self.var_id == "status":
if self.entity_description.key == "status":
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"])
@property
@ -362,10 +437,10 @@ class QNAPDriveSensor(QNAPSensor):
"""Return the state of the sensor."""
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"]
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
@property
@ -373,7 +448,7 @@ class QNAPDriveSensor(QNAPSensor):
"""Return the name of the sensor, if any."""
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
def extra_state_attributes(self):
@ -397,16 +472,16 @@ class QNAPVolumeSensor(QNAPSensor):
data = self._api.data["volumes"][self.monitor_device]
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)
total_gb = int(data["total_size"]) / 1024 / 1024 / 1024
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)
if self.var_id == "volume_percentage_used":
if self.entity_description.key == "volume_percentage_used":
return round(used_gb / total_gb * 100)
@property