Add names, units and icons to APCUPSd Sensor (#2443)

* Add names, units and icons to APCUPSd Sensor

* Fix farcy errors

* Attempt fix of errors

* Remove "type:" from configuration

* Remove duplicate "mdi:" prefix
This commit is contained in:
Dale Higgs 2016-07-06 20:25:57 -05:00 committed by Paulus Schoutsen
parent c634cbf866
commit db23320659

View File

@ -11,33 +11,109 @@ from homeassistant.const import TEMP_CELSIUS
from homeassistant.helpers.entity import Entity
DEPENDENCIES = [apcupsd.DOMAIN]
DEFAULT_NAME = "UPS Status"
SENSOR_PREFIX = 'UPS '
SENSOR_TYPES = {
'alarmdel': ['Alarm Delay', '', 'mdi:alarm'],
'ambtemp': ['Ambient Temperature', '', 'mdi:thermometer'],
'apc': ['Status Data', '', 'mdi:information-outline'],
'apcmodel': ['Model', '', 'mdi:information-outline'],
'badbatts': ['Bad Batteries', '', 'mdi:information-outline'],
'battdate': ['Battery Replaced', '', 'mdi:calendar-clock'],
'battstat': ['Battery Status', '', 'mdi:information-outline'],
'battv': ['Battery Voltage', 'V', 'mdi:flash'],
'bcharge': ['Battery', '%', 'mdi:battery'],
'cable': ['Cable Type', '', 'mdi:ethernet-cable'],
'cumonbatt': ['Total Time on Battery', '', 'mdi:timer'],
'date': ['Status Date', '', 'mdi:calendar-clock'],
'dipsw': ['Dip Switch Settings', '', 'mdi:information-outline'],
'dlowbatt': ['Low Battery Signal', '', 'mdi:clock-alert'],
'driver': ['Driver', '', 'mdi:information-outline'],
'dshutd': ['Shutdown Delay', '', 'mdi:timer'],
'dwake': ['Wake Delay', '', 'mdi:timer'],
'endapc': ['Date and Time', '', 'mdi:calendar-clock'],
'extbatts': ['External Batteries', '', 'mdi:information-outline'],
'firmware': ['Firmware Version', '', 'mdi:information-outline'],
'hitrans': ['Transfer High', 'V', 'mdi:flash'],
'hostname': ['Hostname', '', 'mdi:information-outline'],
'humidity': ['Ambient Humidity', '%', 'mdi:water-percent'],
'itemp': ['Internal Temperature', TEMP_CELSIUS, 'mdi:thermometer'],
'lastxfer': ['Last Transfer', '', 'mdi:transfer'],
'linefail': ['Input Voltage Status', '', 'mdi:information-outline'],
'linefreq': ['Line Frequency', 'Hz', 'mdi:information-outline'],
'linev': ['Input Voltage', 'V', 'mdi:flash'],
'loadpct': ['Load', '%', 'mdi:gauge'],
'lotrans': ['Transfer Low', 'V', 'mdi:flash'],
'mandate': ['Manufacture Date', '', 'mdi:calendar'],
'masterupd': ['Master Update', '', 'mdi:information-outline'],
'maxlinev': ['Input Voltage High', 'V', 'mdi:flash'],
'maxtime': ['Battery Timeout', '', 'mdi:timer-off'],
'mbattchg': ['Battery Shutdown', '%', 'mdi:battery-alert'],
'minlinev': ['Input Voltage Low', 'V', 'mdi:flash'],
'mintimel': ['Shutdown Time', '', 'mdi:timer'],
'model': ['Model', '', 'mdi:information-outline'],
'nombattv': ['Battery Nominal Voltage', 'V', 'mdi:flash'],
'nominv': ['Nominal Input Voltage', 'V', 'mdi:flash'],
'nomoutv': ['Nominal Output Voltage', 'V', 'mdi:flash'],
'nompower': ['Nominal Output Power', 'W', 'mdi:flash'],
'numxfers': ['Transfer Count', '', 'mdi:counter'],
'outputv': ['Output Voltage', 'V', 'mdi:flash'],
'reg1': ['Register 1 Fault', '', 'mdi:information-outline'],
'reg2': ['Register 2 Fault', '', 'mdi:information-outline'],
'reg3': ['Register 3 Fault', '', 'mdi:information-outline'],
'retpct': ['Restore Requirement', '%', 'mdi:battery-alert'],
'selftest': ['Last Self Test', '', 'mdi:calendar-clock'],
'sense': ['Sensitivity', '', 'mdi:information-outline'],
'serialno': ['Serial Number', '', 'mdi:information-outline'],
'starttime': ['Startup Time', '', 'mdi:calendar-clock'],
'statflag': ['Status Flag', '', 'mdi:information-outline'],
'status': ['Status', '', 'mdi:information-outline'],
'stesti': ['Self Test Interval', '', 'mdi:information-outline'],
'timeleft': ['Time Left', '', 'mdi:clock-alert'],
'tonbatt': ['Time on Battery', '', 'mdi:timer'],
'upsmode': ['Mode', '', 'mdi:information-outline'],
'upsname': ['Name', '', 'mdi:information-outline'],
'version': ['Daemon Info', '', 'mdi:information-outline'],
'xoffbat': ['Transfer from Battery', '', 'mdi:transfer'],
'xoffbatt': ['Transfer from Battery', '', 'mdi:transfer'],
'xonbatt': ['Transfer to Battery', '', 'mdi:transfer'],
}
SPECIFIC_UNITS = {
"ITEMP": TEMP_CELSIUS
'ITEMP': TEMP_CELSIUS
}
INFERRED_UNITS = {
' Minutes': 'min',
' Seconds': 'sec',
' Percent': '%',
' Volts': 'V',
' Watts': 'W',
' Hz': 'Hz',
' C': TEMP_CELSIUS,
}
_LOGGER = logging.getLogger(__name__)
def setup_platform(hass, config, add_entities, discovery_info=None):
"""Setup the APCUPSd sensor."""
typ = config.get(apcupsd.CONF_TYPE)
if typ is None:
_LOGGER.error(
"You must include a '%s' when configuring an APCUPSd sensor.",
apcupsd.CONF_TYPE)
return False
typ = typ.upper()
"""Setup the APCUPSd sensors."""
entities = []
if typ not in apcupsd.DATA.status:
_LOGGER.error(
"Specified '%s' of '%s' does not appear in the APCUPSd status "
"output.", apcupsd.CONF_TYPE, typ)
return False
for resource in config['resources']:
sensor_type = resource.lower()
add_entities((
Sensor(config, apcupsd.DATA, unit=SPECIFIC_UNITS.get(typ)),
))
if sensor_type not in SENSOR_TYPES:
SENSOR_TYPES[sensor_type] = [
sensor_type.title(), '', 'mdi:information-outline']
if sensor_type.upper() not in apcupsd.DATA.status:
_LOGGER.warning(
'Sensor type: "%s" does not appear in the APCUPSd status '
'output.', sensor_type)
entities.append(APCUPSdSensor(apcupsd.DATA, sensor_type))
add_entities(entities)
def infer_unit(value):
@ -49,25 +125,31 @@ def infer_unit(value):
from apcaccess.status import ALL_UNITS
for unit in ALL_UNITS:
if value.endswith(unit):
return value[:-len(unit)], unit
return value[:-len(unit)], INFERRED_UNITS.get(unit, unit.strip())
return value, None
class Sensor(Entity):
class APCUPSdSensor(Entity):
"""Representation of a sensor entity for APCUPSd status values."""
def __init__(self, config, data, unit=None):
def __init__(self, data, sensor_type):
"""Initialize the sensor."""
self._config = config
self._unit = unit
self._data = data
self.type = sensor_type
self._name = SENSOR_PREFIX + SENSOR_TYPES[sensor_type][0]
self._unit = SENSOR_TYPES[sensor_type][1]
self._inferred_unit = None
self.update()
@property
def name(self):
"""Return the name of the UPS sensor."""
return self._config.get("name", DEFAULT_NAME)
return self._name
@property
def icon(self):
"""Icon to use in the frontend, if any."""
return SENSOR_TYPES[self.type][2]
@property
def state(self):
@ -77,11 +159,15 @@ class Sensor(Entity):
@property
def unit_of_measurement(self):
"""Return the unit of measurement of this entity, if any."""
if self._unit is None:
if not self._unit:
return self._inferred_unit
return self._unit
def update(self):
"""Get the latest status and use it to update our sensor state."""
key = self._config[apcupsd.CONF_TYPE].upper()
self._state, self._inferred_unit = infer_unit(self._data.status[key])
if self.type.upper() not in self._data.status:
self._state = None
self._inferred_unit = None
else:
self._state, self._inferred_unit = infer_unit(
self._data.status[self.type.upper()])