diff --git a/homeassistant/components/glances/const.py b/homeassistant/components/glances/const.py index 56d55931cdb..b74662db22b 100644 --- a/homeassistant/components/glances/const.py +++ b/homeassistant/components/glances/const.py @@ -1,9 +1,10 @@ """Constants for Glances component.""" from __future__ import annotations +from dataclasses import dataclass import sys -from typing import NamedTuple +from homeassistant.components.sensor import SensorEntityDescription from homeassistant.const import ( DATA_GIBIBYTES, DATA_MEBIBYTES, @@ -30,147 +31,167 @@ else: CPU_ICON = "mdi:cpu-32-bit" -class GlancesSensorMetadata(NamedTuple): - """Sensor metadata for an individual Glances sensor.""" +@dataclass +class GlancesSensorEntityDescription(SensorEntityDescription): + """Describe Glances sensor entity.""" - type: str - name_suffix: str - unit_of_measurement: str - icon: str | None = None - device_class: str | None = None + type: str | None = None + name_suffix: str | None = None -SENSOR_TYPES: dict[str, GlancesSensorMetadata] = { - "disk_use_percent": GlancesSensorMetadata( +SENSOR_TYPES: tuple[GlancesSensorEntityDescription, ...] = ( + GlancesSensorEntityDescription( + key="disk_use_percent", type="fs", name_suffix="used percent", unit_of_measurement=PERCENTAGE, icon="mdi:harddisk", ), - "disk_use": GlancesSensorMetadata( + GlancesSensorEntityDescription( + key="disk_use", type="fs", name_suffix="used", unit_of_measurement=DATA_GIBIBYTES, icon="mdi:harddisk", ), - "disk_free": GlancesSensorMetadata( + GlancesSensorEntityDescription( + key="disk_free", type="fs", name_suffix="free", unit_of_measurement=DATA_GIBIBYTES, icon="mdi:harddisk", ), - "memory_use_percent": GlancesSensorMetadata( + GlancesSensorEntityDescription( + key="memory_use_percent", type="mem", name_suffix="RAM used percent", unit_of_measurement=PERCENTAGE, icon="mdi:memory", ), - "memory_use": GlancesSensorMetadata( + GlancesSensorEntityDescription( + key="memory_use", type="mem", name_suffix="RAM used", unit_of_measurement=DATA_MEBIBYTES, icon="mdi:memory", ), - "memory_free": GlancesSensorMetadata( + GlancesSensorEntityDescription( + key="memory_free", type="mem", name_suffix="RAM free", unit_of_measurement=DATA_MEBIBYTES, icon="mdi:memory", ), - "swap_use_percent": GlancesSensorMetadata( + GlancesSensorEntityDescription( + key="swap_use_percent", type="memswap", name_suffix="Swap used percent", unit_of_measurement=PERCENTAGE, icon="mdi:memory", ), - "swap_use": GlancesSensorMetadata( + GlancesSensorEntityDescription( + key="swap_use", type="memswap", name_suffix="Swap used", unit_of_measurement=DATA_GIBIBYTES, icon="mdi:memory", ), - "swap_free": GlancesSensorMetadata( + GlancesSensorEntityDescription( + key="swap_free", type="memswap", name_suffix="Swap free", unit_of_measurement=DATA_GIBIBYTES, icon="mdi:memory", ), - "processor_load": GlancesSensorMetadata( + GlancesSensorEntityDescription( + key="processor_load", type="load", name_suffix="CPU load", unit_of_measurement="15 min", icon=CPU_ICON, ), - "process_running": GlancesSensorMetadata( + GlancesSensorEntityDescription( + key="process_running", type="processcount", name_suffix="Running", unit_of_measurement="Count", icon=CPU_ICON, ), - "process_total": GlancesSensorMetadata( + GlancesSensorEntityDescription( + key="process_total", type="processcount", name_suffix="Total", unit_of_measurement="Count", icon=CPU_ICON, ), - "process_thread": GlancesSensorMetadata( + GlancesSensorEntityDescription( + key="process_thread", type="processcount", name_suffix="Thread", unit_of_measurement="Count", icon=CPU_ICON, ), - "process_sleeping": GlancesSensorMetadata( + GlancesSensorEntityDescription( + key="process_sleeping", type="processcount", name_suffix="Sleeping", unit_of_measurement="Count", icon=CPU_ICON, ), - "cpu_use_percent": GlancesSensorMetadata( + GlancesSensorEntityDescription( + key="cpu_use_percent", type="cpu", name_suffix="CPU used", unit_of_measurement=PERCENTAGE, icon=CPU_ICON, ), - "temperature_core": GlancesSensorMetadata( + GlancesSensorEntityDescription( + key="temperature_core", type="sensors", name_suffix="Temperature", unit_of_measurement=TEMP_CELSIUS, device_class=DEVICE_CLASS_TEMPERATURE, ), - "temperature_hdd": GlancesSensorMetadata( + GlancesSensorEntityDescription( + key="temperature_hdd", type="sensors", name_suffix="Temperature", unit_of_measurement=TEMP_CELSIUS, device_class=DEVICE_CLASS_TEMPERATURE, ), - "fan_speed": GlancesSensorMetadata( + GlancesSensorEntityDescription( + key="fan_speed", type="sensors", name_suffix="Fan speed", unit_of_measurement="RPM", icon="mdi:fan", ), - "battery": GlancesSensorMetadata( + GlancesSensorEntityDescription( + key="battery", type="sensors", name_suffix="Charge", unit_of_measurement=PERCENTAGE, icon="mdi:battery", ), - "docker_active": GlancesSensorMetadata( + GlancesSensorEntityDescription( + key="docker_active", type="docker", name_suffix="Containers active", unit_of_measurement="", icon="mdi:docker", ), - "docker_cpu_use": GlancesSensorMetadata( + GlancesSensorEntityDescription( + key="docker_cpu_use", type="docker", name_suffix="Containers CPU used", unit_of_measurement=PERCENTAGE, icon="mdi:docker", ), - "docker_memory_use": GlancesSensorMetadata( + GlancesSensorEntityDescription( + key="docker_memory_use", type="docker", name_suffix="Containers RAM used", unit_of_measurement=DATA_MEBIBYTES, icon="mdi:docker", ), -} +) diff --git a/homeassistant/components/glances/sensor.py b/homeassistant/components/glances/sensor.py index e33fd121200..fd31ee37faf 100644 --- a/homeassistant/components/glances/sensor.py +++ b/homeassistant/components/glances/sensor.py @@ -4,7 +4,7 @@ from homeassistant.const import CONF_NAME, STATE_UNAVAILABLE from homeassistant.core import callback from homeassistant.helpers.dispatcher import async_dispatcher_connect -from .const import DATA_UPDATED, DOMAIN, SENSOR_TYPES, GlancesSensorMetadata +from .const import DATA_UPDATED, DOMAIN, SENSOR_TYPES, GlancesSensorEntityDescription async def async_setup_entry(hass, config_entry, async_add_entities): @@ -14,42 +14,37 @@ async def async_setup_entry(hass, config_entry, async_add_entities): name = config_entry.data[CONF_NAME] dev = [] - for sensor_type, metadata in SENSOR_TYPES.items(): - if metadata.type not in client.api.data: - continue - if metadata.type == "fs": + for description in SENSOR_TYPES: + if description.type == "fs": # fs will provide a list of disks attached - for disk in client.api.data[metadata.type]: + for disk in client.api.data[description.type]: dev.append( GlancesSensor( client, name, disk["mnt_point"], - sensor_type, - metadata, + description, ) ) - elif metadata.type == "sensors": + elif description.type == "sensors": # sensors will provide temp for different devices - for sensor in client.api.data[metadata.type]: - if sensor["type"] == sensor_type: + for sensor in client.api.data[description.type]: + if sensor["type"] == description.key: dev.append( GlancesSensor( client, name, sensor["label"], - sensor_type, - metadata, + description, ) ) - elif client.api.data[metadata.type]: + elif client.api.data[description.type]: dev.append( GlancesSensor( client, name, "", - sensor_type, - metadata, + description, ) ) @@ -59,26 +54,23 @@ async def async_setup_entry(hass, config_entry, async_add_entities): class GlancesSensor(SensorEntity): """Implementation of a Glances sensor.""" + entity_description: GlancesSensorEntityDescription + def __init__( self, glances_data, name, sensor_name_prefix, - sensor_type, - metadata: GlancesSensorMetadata, + description: GlancesSensorEntityDescription, ): """Initialize the sensor.""" self.glances_data = glances_data self._sensor_name_prefix = sensor_name_prefix - self.type = sensor_type self._state = None - self._metadata = metadata self.unsub_update = None - self._attr_name = f"{name} {sensor_name_prefix} {metadata.name_suffix}" - self._attr_icon = metadata.icon - self._attr_unit_of_measurement = metadata.unit_of_measurement - self._attr_device_class = metadata.device_class + self.entity_description = description + self._attr_name = f"{name} {sensor_name_prefix} {description.name_suffix}" @property def unique_id(self): @@ -122,12 +114,12 @@ class GlancesSensor(SensorEntity): if value is None: return - if self._metadata.type == "fs": + if self.entity_description.type == "fs": for var in value["fs"]: if var["mnt_point"] == self._sensor_name_prefix: disk = var break - if self.type == "disk_free": + if self.entity_description.key == "disk_free": try: self._state = round(disk["free"] / 1024 ** 3, 1) except KeyError: @@ -135,67 +127,67 @@ class GlancesSensor(SensorEntity): (disk["size"] - disk["used"]) / 1024 ** 3, 1, ) - elif self.type == "disk_use": + elif self.entity_description.key == "disk_use": self._state = round(disk["used"] / 1024 ** 3, 1) - elif self.type == "disk_use_percent": + elif self.entity_description.key == "disk_use_percent": self._state = disk["percent"] - elif self.type == "battery": + elif self.entity_description.key == "battery": for sensor in value["sensors"]: if ( sensor["type"] == "battery" and sensor["label"] == self._sensor_name_prefix ): self._state = sensor["value"] - elif self.type == "fan_speed": + elif self.entity_description.key == "fan_speed": for sensor in value["sensors"]: if ( sensor["type"] == "fan_speed" and sensor["label"] == self._sensor_name_prefix ): self._state = sensor["value"] - elif self.type == "temperature_core": + elif self.entity_description.key == "temperature_core": for sensor in value["sensors"]: if ( sensor["type"] == "temperature_core" and sensor["label"] == self._sensor_name_prefix ): self._state = sensor["value"] - elif self.type == "temperature_hdd": + elif self.entity_description.key == "temperature_hdd": for sensor in value["sensors"]: if ( sensor["type"] == "temperature_hdd" and sensor["label"] == self._sensor_name_prefix ): self._state = sensor["value"] - elif self.type == "memory_use_percent": + elif self.entity_description.key == "memory_use_percent": self._state = value["mem"]["percent"] - elif self.type == "memory_use": + elif self.entity_description.key == "memory_use": self._state = round(value["mem"]["used"] / 1024 ** 2, 1) - elif self.type == "memory_free": + elif self.entity_description.key == "memory_free": self._state = round(value["mem"]["free"] / 1024 ** 2, 1) - elif self.type == "swap_use_percent": + elif self.entity_description.key == "swap_use_percent": self._state = value["memswap"]["percent"] - elif self.type == "swap_use": + elif self.entity_description.key == "swap_use": self._state = round(value["memswap"]["used"] / 1024 ** 3, 1) - elif self.type == "swap_free": + elif self.entity_description.key == "swap_free": self._state = round(value["memswap"]["free"] / 1024 ** 3, 1) - elif self.type == "processor_load": + elif self.entity_description.key == "processor_load": # Windows systems don't provide load details try: self._state = value["load"]["min15"] except KeyError: self._state = value["cpu"]["total"] - elif self.type == "process_running": + elif self.entity_description.key == "process_running": self._state = value["processcount"]["running"] - elif self.type == "process_total": + elif self.entity_description.key == "process_total": self._state = value["processcount"]["total"] - elif self.type == "process_thread": + elif self.entity_description.key == "process_thread": self._state = value["processcount"]["thread"] - elif self.type == "process_sleeping": + elif self.entity_description.key == "process_sleeping": self._state = value["processcount"]["sleeping"] - elif self.type == "cpu_use_percent": + elif self.entity_description.key == "cpu_use_percent": self._state = value["quicklook"]["cpu"] - elif self.type == "docker_active": + elif self.entity_description.key == "docker_active": count = 0 try: for container in value["docker"]["containers"]: @@ -204,7 +196,7 @@ class GlancesSensor(SensorEntity): self._state = count except KeyError: self._state = count - elif self.type == "docker_cpu_use": + elif self.entity_description.key == "docker_cpu_use": cpu_use = 0.0 try: for container in value["docker"]["containers"]: @@ -213,7 +205,7 @@ class GlancesSensor(SensorEntity): self._state = round(cpu_use, 1) except KeyError: self._state = STATE_UNAVAILABLE - elif self.type == "docker_memory_use": + elif self.entity_description.key == "docker_memory_use": mem_use = 0.0 try: for container in value["docker"]["containers"]: