Use EntityDescription - apcupsd (#55790)

This commit is contained in:
Marc Mueller 2021-09-06 10:19:31 +02:00 committed by GitHub
parent 655399eb7b
commit a4e4ffef0a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -1,10 +1,16 @@
"""Support for APCUPSd sensors."""
from __future__ import annotations
import logging
from apcaccess.status import ALL_UNITS
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 (
CONF_RESOURCES,
DEVICE_CLASS_TEMPERATURE,
@ -25,74 +31,360 @@ from . import DOMAIN
_LOGGER = logging.getLogger(__name__)
SENSOR_PREFIX = "UPS "
SENSOR_TYPES = {
"alarmdel": ["Alarm Delay", None, "mdi:alarm", None],
"ambtemp": ["Ambient Temperature", None, "mdi:thermometer", None],
"apc": ["Status Data", None, "mdi:information-outline", None],
"apcmodel": ["Model", None, "mdi:information-outline", None],
"badbatts": ["Bad Batteries", None, "mdi:information-outline", None],
"battdate": ["Battery Replaced", None, "mdi:calendar-clock", None],
"battstat": ["Battery Status", None, "mdi:information-outline", None],
"battv": ["Battery Voltage", ELECTRIC_POTENTIAL_VOLT, "mdi:flash", None],
"bcharge": ["Battery", PERCENTAGE, "mdi:battery", None],
"cable": ["Cable Type", None, "mdi:ethernet-cable", None],
"cumonbatt": ["Total Time on Battery", None, "mdi:timer-outline", None],
"date": ["Status Date", None, "mdi:calendar-clock", None],
"dipsw": ["Dip Switch Settings", None, "mdi:information-outline", None],
"dlowbatt": ["Low Battery Signal", None, "mdi:clock-alert", None],
"driver": ["Driver", None, "mdi:information-outline", None],
"dshutd": ["Shutdown Delay", None, "mdi:timer-outline", None],
"dwake": ["Wake Delay", None, "mdi:timer-outline", None],
"endapc": ["Date and Time", None, "mdi:calendar-clock", None],
"extbatts": ["External Batteries", None, "mdi:information-outline", None],
"firmware": ["Firmware Version", None, "mdi:information-outline", None],
"hitrans": ["Transfer High", ELECTRIC_POTENTIAL_VOLT, "mdi:flash", None],
"hostname": ["Hostname", None, "mdi:information-outline", None],
"humidity": ["Ambient Humidity", PERCENTAGE, "mdi:water-percent", None],
"itemp": ["Internal Temperature", TEMP_CELSIUS, None, DEVICE_CLASS_TEMPERATURE],
"lastxfer": ["Last Transfer", None, "mdi:transfer", None],
"linefail": ["Input Voltage Status", None, "mdi:information-outline", None],
"linefreq": ["Line Frequency", FREQUENCY_HERTZ, "mdi:information-outline", None],
"linev": ["Input Voltage", ELECTRIC_POTENTIAL_VOLT, "mdi:flash", None],
"loadpct": ["Load", PERCENTAGE, "mdi:gauge", None],
"loadapnt": ["Load Apparent Power", PERCENTAGE, "mdi:gauge", None],
"lotrans": ["Transfer Low", ELECTRIC_POTENTIAL_VOLT, "mdi:flash", None],
"mandate": ["Manufacture Date", None, "mdi:calendar", None],
"masterupd": ["Master Update", None, "mdi:information-outline", None],
"maxlinev": ["Input Voltage High", ELECTRIC_POTENTIAL_VOLT, "mdi:flash", None],
"maxtime": ["Battery Timeout", None, "mdi:timer-off-outline", None],
"mbattchg": ["Battery Shutdown", PERCENTAGE, "mdi:battery-alert", None],
"minlinev": ["Input Voltage Low", ELECTRIC_POTENTIAL_VOLT, "mdi:flash", None],
"mintimel": ["Shutdown Time", None, "mdi:timer-outline", None],
"model": ["Model", None, "mdi:information-outline", None],
"nombattv": ["Battery Nominal Voltage", ELECTRIC_POTENTIAL_VOLT, "mdi:flash", None],
"nominv": ["Nominal Input Voltage", ELECTRIC_POTENTIAL_VOLT, "mdi:flash", None],
"nomoutv": ["Nominal Output Voltage", ELECTRIC_POTENTIAL_VOLT, "mdi:flash", None],
"nompower": ["Nominal Output Power", POWER_WATT, "mdi:flash", None],
"nomapnt": ["Nominal Apparent Power", POWER_VOLT_AMPERE, "mdi:flash", None],
"numxfers": ["Transfer Count", None, "mdi:counter", None],
"outcurnt": ["Output Current", ELECTRIC_CURRENT_AMPERE, "mdi:flash", None],
"outputv": ["Output Voltage", ELECTRIC_POTENTIAL_VOLT, "mdi:flash", None],
"reg1": ["Register 1 Fault", None, "mdi:information-outline", None],
"reg2": ["Register 2 Fault", None, "mdi:information-outline", None],
"reg3": ["Register 3 Fault", None, "mdi:information-outline", None],
"retpct": ["Restore Requirement", PERCENTAGE, "mdi:battery-alert", None],
"selftest": ["Last Self Test", None, "mdi:calendar-clock", None],
"sense": ["Sensitivity", None, "mdi:information-outline", None],
"serialno": ["Serial Number", None, "mdi:information-outline", None],
"starttime": ["Startup Time", None, "mdi:calendar-clock", None],
"statflag": ["Status Flag", None, "mdi:information-outline", None],
"status": ["Status", None, "mdi:information-outline", None],
"stesti": ["Self Test Interval", None, "mdi:information-outline", None],
"timeleft": ["Time Left", None, "mdi:clock-alert", None],
"tonbatt": ["Time on Battery", None, "mdi:timer-outline", None],
"upsmode": ["Mode", None, "mdi:information-outline", None],
"upsname": ["Name", None, "mdi:information-outline", None],
"version": ["Daemon Info", None, "mdi:information-outline", None],
"xoffbat": ["Transfer from Battery", None, "mdi:transfer", None],
"xoffbatt": ["Transfer from Battery", None, "mdi:transfer", None],
"xonbatt": ["Transfer to Battery", None, "mdi:transfer", None],
}
SENSOR_TYPES: tuple[SensorEntityDescription, ...] = (
SensorEntityDescription(
key="alarmdel",
name="Alarm Delay",
icon="mdi:alarm",
),
SensorEntityDescription(
key="ambtemp",
name="Ambient Temperature",
icon="mdi:thermometer",
),
SensorEntityDescription(
key="apc",
name="Status Data",
icon="mdi:information-outline",
),
SensorEntityDescription(
key="apcmodel",
name="Model",
icon="mdi:information-outline",
),
SensorEntityDescription(
key="badbatts",
name="Bad Batteries",
icon="mdi:information-outline",
),
SensorEntityDescription(
key="battdate",
name="Battery Replaced",
icon="mdi:calendar-clock",
),
SensorEntityDescription(
key="battstat",
name="Battery Status",
icon="mdi:information-outline",
),
SensorEntityDescription(
key="battv",
name="Battery Voltage",
native_unit_of_measurement=ELECTRIC_POTENTIAL_VOLT,
icon="mdi:flash",
),
SensorEntityDescription(
key="bcharge",
name="Battery",
native_unit_of_measurement=PERCENTAGE,
icon="mdi:battery",
),
SensorEntityDescription(
key="cable",
name="Cable Type",
icon="mdi:ethernet-cable",
),
SensorEntityDescription(
key="cumonbatt",
name="Total Time on Battery",
icon="mdi:timer-outline",
),
SensorEntityDescription(
key="date",
name="Status Date",
icon="mdi:calendar-clock",
),
SensorEntityDescription(
key="dipsw",
name="Dip Switch Settings",
icon="mdi:information-outline",
),
SensorEntityDescription(
key="dlowbatt",
name="Low Battery Signal",
icon="mdi:clock-alert",
),
SensorEntityDescription(
key="driver",
name="Driver",
icon="mdi:information-outline",
),
SensorEntityDescription(
key="dshutd",
name="Shutdown Delay",
icon="mdi:timer-outline",
),
SensorEntityDescription(
key="dwake",
name="Wake Delay",
icon="mdi:timer-outline",
),
SensorEntityDescription(
key="endapc",
name="Date and Time",
icon="mdi:calendar-clock",
),
SensorEntityDescription(
key="extbatts",
name="External Batteries",
icon="mdi:information-outline",
),
SensorEntityDescription(
key="firmware",
name="Firmware Version",
icon="mdi:information-outline",
),
SensorEntityDescription(
key="hitrans",
name="Transfer High",
native_unit_of_measurement=ELECTRIC_POTENTIAL_VOLT,
icon="mdi:flash",
),
SensorEntityDescription(
key="hostname",
name="Hostname",
icon="mdi:information-outline",
),
SensorEntityDescription(
key="humidity",
name="Ambient Humidity",
native_unit_of_measurement=PERCENTAGE,
icon="mdi:water-percent",
),
SensorEntityDescription(
key="itemp",
name="Internal Temperature",
native_unit_of_measurement=TEMP_CELSIUS,
device_class=DEVICE_CLASS_TEMPERATURE,
),
SensorEntityDescription(
key="lastxfer",
name="Last Transfer",
icon="mdi:transfer",
),
SensorEntityDescription(
key="linefail",
name="Input Voltage Status",
icon="mdi:information-outline",
),
SensorEntityDescription(
key="linefreq",
name="Line Frequency",
native_unit_of_measurement=FREQUENCY_HERTZ,
icon="mdi:information-outline",
),
SensorEntityDescription(
key="linev",
name="Input Voltage",
native_unit_of_measurement=ELECTRIC_POTENTIAL_VOLT,
icon="mdi:flash",
),
SensorEntityDescription(
key="loadpct",
name="Load",
native_unit_of_measurement=PERCENTAGE,
icon="mdi:gauge",
),
SensorEntityDescription(
key="loadapnt",
name="Load Apparent Power",
native_unit_of_measurement=PERCENTAGE,
icon="mdi:gauge",
),
SensorEntityDescription(
key="lotrans",
name="Transfer Low",
native_unit_of_measurement=ELECTRIC_POTENTIAL_VOLT,
icon="mdi:flash",
),
SensorEntityDescription(
key="mandate",
name="Manufacture Date",
icon="mdi:calendar",
),
SensorEntityDescription(
key="masterupd",
name="Master Update",
icon="mdi:information-outline",
),
SensorEntityDescription(
key="maxlinev",
name="Input Voltage High",
native_unit_of_measurement=ELECTRIC_POTENTIAL_VOLT,
icon="mdi:flash",
),
SensorEntityDescription(
key="maxtime",
name="Battery Timeout",
icon="mdi:timer-off-outline",
),
SensorEntityDescription(
key="mbattchg",
name="Battery Shutdown",
native_unit_of_measurement=PERCENTAGE,
icon="mdi:battery-alert",
),
SensorEntityDescription(
key="minlinev",
name="Input Voltage Low",
native_unit_of_measurement=ELECTRIC_POTENTIAL_VOLT,
icon="mdi:flash",
),
SensorEntityDescription(
key="mintimel",
name="Shutdown Time",
icon="mdi:timer-outline",
),
SensorEntityDescription(
key="model",
name="Model",
icon="mdi:information-outline",
),
SensorEntityDescription(
key="nombattv",
name="Battery Nominal Voltage",
native_unit_of_measurement=ELECTRIC_POTENTIAL_VOLT,
icon="mdi:flash",
),
SensorEntityDescription(
key="nominv",
name="Nominal Input Voltage",
native_unit_of_measurement=ELECTRIC_POTENTIAL_VOLT,
icon="mdi:flash",
),
SensorEntityDescription(
key="nomoutv",
name="Nominal Output Voltage",
native_unit_of_measurement=ELECTRIC_POTENTIAL_VOLT,
icon="mdi:flash",
),
SensorEntityDescription(
key="nompower",
name="Nominal Output Power",
native_unit_of_measurement=POWER_WATT,
icon="mdi:flash",
),
SensorEntityDescription(
key="nomapnt",
name="Nominal Apparent Power",
native_unit_of_measurement=POWER_VOLT_AMPERE,
icon="mdi:flash",
),
SensorEntityDescription(
key="numxfers",
name="Transfer Count",
icon="mdi:counter",
),
SensorEntityDescription(
key="outcurnt",
name="Output Current",
native_unit_of_measurement=ELECTRIC_CURRENT_AMPERE,
icon="mdi:flash",
),
SensorEntityDescription(
key="outputv",
name="Output Voltage",
native_unit_of_measurement=ELECTRIC_POTENTIAL_VOLT,
icon="mdi:flash",
),
SensorEntityDescription(
key="reg1",
name="Register 1 Fault",
icon="mdi:information-outline",
),
SensorEntityDescription(
key="reg2",
name="Register 2 Fault",
icon="mdi:information-outline",
),
SensorEntityDescription(
key="reg3",
name="Register 3 Fault",
icon="mdi:information-outline",
),
SensorEntityDescription(
key="retpct",
name="Restore Requirement",
native_unit_of_measurement=PERCENTAGE,
icon="mdi:battery-alert",
),
SensorEntityDescription(
key="selftest",
name="Last Self Test",
icon="mdi:calendar-clock",
),
SensorEntityDescription(
key="sense",
name="Sensitivity",
icon="mdi:information-outline",
),
SensorEntityDescription(
key="serialno",
name="Serial Number",
icon="mdi:information-outline",
),
SensorEntityDescription(
key="starttime",
name="Startup Time",
icon="mdi:calendar-clock",
),
SensorEntityDescription(
key="statflag",
name="Status Flag",
icon="mdi:information-outline",
),
SensorEntityDescription(
key="status",
name="Status",
icon="mdi:information-outline",
),
SensorEntityDescription(
key="stesti",
name="Self Test Interval",
icon="mdi:information-outline",
),
SensorEntityDescription(
key="timeleft",
name="Time Left",
icon="mdi:clock-alert",
),
SensorEntityDescription(
key="tonbatt",
name="Time on Battery",
icon="mdi:timer-outline",
),
SensorEntityDescription(
key="upsmode",
name="Mode",
icon="mdi:information-outline",
),
SensorEntityDescription(
key="upsname",
name="Name",
icon="mdi:information-outline",
),
SensorEntityDescription(
key="version",
name="Daemon Info",
icon="mdi:information-outline",
),
SensorEntityDescription(
key="xoffbat",
name="Transfer from Battery",
icon="mdi:transfer",
),
SensorEntityDescription(
key="xoffbatt",
name="Transfer from Battery",
icon="mdi:transfer",
),
SensorEntityDescription(
key="xonbatt",
name="Transfer to Battery",
icon="mdi:transfer",
),
)
SENSOR_KEYS: list[str] = [desc.key for desc in SENSOR_TYPES]
SPECIFIC_UNITS = {"ITEMP": TEMP_CELSIUS}
INFERRED_UNITS = {
@ -111,7 +403,7 @@ INFERRED_UNITS = {
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(
{
vol.Required(CONF_RESOURCES, default=[]): vol.All(
cv.ensure_list, [vol.In(SENSOR_TYPES)]
cv.ensure_list, [vol.In(SENSOR_KEYS)]
)
}
)
@ -120,25 +412,20 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(
def setup_platform(hass, config, add_entities, discovery_info=None):
"""Set up the APCUPSd sensors."""
apcups_data = hass.data[DOMAIN]
entities = []
resources = config[CONF_RESOURCES]
for resource in config[CONF_RESOURCES]:
sensor_type = resource.lower()
if sensor_type not in SENSOR_TYPES:
SENSOR_TYPES[sensor_type] = [
sensor_type.title(),
"",
"mdi:information-outline",
]
if sensor_type.upper() not in apcups_data.status:
for resource in resources:
if resource.upper() not in apcups_data.status:
_LOGGER.warning(
"Sensor type: %s does not appear in the APCUPSd status output",
sensor_type,
resource,
)
entities.append(APCUPSdSensor(apcups_data, sensor_type))
entities = [
APCUPSdSensor(apcups_data, description)
for description in SENSOR_TYPES
if description.key in resources
]
add_entities(entities, True)
@ -159,22 +446,18 @@ def infer_unit(value):
class APCUPSdSensor(SensorEntity):
"""Representation of a sensor entity for APCUPSd status values."""
def __init__(self, data, sensor_type):
def __init__(self, data, description: SensorEntityDescription):
"""Initialize the sensor."""
self.entity_description = description
self._data = data
self.type = sensor_type
self._attr_name = SENSOR_PREFIX + SENSOR_TYPES[sensor_type][0]
self._attr_icon = SENSOR_TYPES[self.type][2]
self._attr_native_unit_of_measurement = SENSOR_TYPES[sensor_type][1]
self._attr_device_class = SENSOR_TYPES[sensor_type][3]
self._attr_name = f"{SENSOR_PREFIX}{description.name}"
def update(self):
"""Get the latest status and use it to update our sensor state."""
if self.type.upper() not in self._data.status:
key = self.entity_description.key.upper()
if key not in self._data.status:
self._attr_native_value = None
else:
self._attr_native_value, inferred_unit = infer_unit(
self._data.status[self.type.upper()]
)
if not self._attr_native_unit_of_measurement:
self._attr_native_value, inferred_unit = infer_unit(self._data.status[key])
if not self.native_unit_of_measurement:
self._attr_native_unit_of_measurement = inferred_unit