Sensor device classes (#14282)

* Added light device class, moved device classes to const

* Removed unnecessary icons

* Replace 'lux' with 'lx'

* Fix comment

* Changed device_class name
This commit is contained in:
cdce8p 2018-05-05 15:37:40 +02:00 committed by Paulus Schoutsen
parent ec3ce4c80d
commit 95d27bd1fa
19 changed files with 92 additions and 79 deletions

View File

@ -14,7 +14,8 @@ from homeassistant.components.cover import (
from homeassistant.const import (
ATTR_SUPPORTED_FEATURES, ATTR_UNIT_OF_MEASUREMENT,
ATTR_DEVICE_CLASS, CONF_IP_ADDRESS, CONF_PORT, TEMP_CELSIUS,
TEMP_FAHRENHEIT, EVENT_HOMEASSISTANT_START, EVENT_HOMEASSISTANT_STOP)
TEMP_FAHRENHEIT, EVENT_HOMEASSISTANT_START, EVENT_HOMEASSISTANT_STOP,
DEVICE_CLASS_HUMIDITY, DEVICE_CLASS_ILLUMINANCE, DEVICE_CLASS_TEMPERATURE)
import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.entityfilter import FILTER_SCHEMA
from homeassistant.util import get_local_ip
@ -22,8 +23,7 @@ from homeassistant.util.decorator import Registry
from .const import (
DOMAIN, HOMEKIT_FILE, CONF_AUTO_START, CONF_ENTITY_CONFIG, CONF_FILTER,
DEFAULT_PORT, DEFAULT_AUTO_START, SERVICE_HOMEKIT_START,
DEVICE_CLASS_CO2, DEVICE_CLASS_LIGHT, DEVICE_CLASS_HUMIDITY,
DEVICE_CLASS_PM25, DEVICE_CLASS_TEMPERATURE)
DEVICE_CLASS_CO2, DEVICE_CLASS_PM25)
from .util import (
validate_entity_config, show_setup_message)
@ -137,8 +137,7 @@ def get_accessory(hass, state, aid, config):
elif device_class == DEVICE_CLASS_CO2 \
or DEVICE_CLASS_CO2 in state.entity_id:
a_type = 'CarbonDioxideSensor'
elif device_class == DEVICE_CLASS_LIGHT or unit == 'lm' or \
unit == 'lux' or unit == 'lx':
elif device_class == DEVICE_CLASS_ILLUMINANCE or unit in ('lm', 'lx'):
a_type = 'LightSensor'
elif state.domain in ('switch', 'remote', 'input_boolean', 'script'):

View File

@ -12,6 +12,9 @@ import voluptuous as vol
from homeassistant.helpers.entity_component import EntityComponent
from homeassistant.helpers.config_validation import PLATFORM_SCHEMA # noqa
from homeassistant.const import (
DEVICE_CLASS_BATTERY, DEVICE_CLASS_HUMIDITY, DEVICE_CLASS_ILLUMINANCE,
DEVICE_CLASS_TEMPERATURE)
_LOGGER = logging.getLogger(__name__)
@ -21,9 +24,10 @@ ENTITY_ID_FORMAT = DOMAIN + '.{}'
SCAN_INTERVAL = timedelta(seconds=30)
DEVICE_CLASSES = [
'battery', # % of battery that is left
'humidity', # % of humidity in the air
'temperature', # temperature (C/F)
DEVICE_CLASS_BATTERY, # % of battery that is left
DEVICE_CLASS_HUMIDITY, # % of humidity in the air
DEVICE_CLASS_ILLUMINANCE, # current light level (lx/lm)
DEVICE_CLASS_TEMPERATURE, # temperature (C/F)
]
DEVICE_CLASSES_SCHEMA = vol.All(vol.Lower, vol.In(DEVICE_CLASSES))

View File

@ -7,6 +7,8 @@ https://home-assistant.io/components/sensor.abode/
import logging
from homeassistant.components.abode import AbodeDevice, DOMAIN as ABODE_DOMAIN
from homeassistant.const import (
DEVICE_CLASS_HUMIDITY, DEVICE_CLASS_ILLUMINANCE, DEVICE_CLASS_TEMPERATURE)
_LOGGER = logging.getLogger(__name__)
@ -14,9 +16,9 @@ DEPENDENCIES = ['abode']
# Sensor types: Name, icon
SENSOR_TYPES = {
'temp': ['Temperature', 'thermometer'],
'humidity': ['Humidity', 'water-percent'],
'lux': ['Lux', 'lightbulb'],
'temp': ['Temperature', DEVICE_CLASS_TEMPERATURE],
'humidity': ['Humidity', DEVICE_CLASS_HUMIDITY],
'lux': ['Lux', DEVICE_CLASS_ILLUMINANCE],
}
@ -46,20 +48,20 @@ class AbodeSensor(AbodeDevice):
"""Initialize a sensor for an Abode device."""
super().__init__(data, device)
self._sensor_type = sensor_type
self._icon = 'mdi:{}'.format(SENSOR_TYPES[self._sensor_type][1])
self._name = '{0} {1}'.format(
self._device.name, SENSOR_TYPES[self._sensor_type][0])
@property
def icon(self):
"""Icon to use in the frontend, if any."""
return self._icon
self._device_class = SENSOR_TYPES[self._sensor_type][1]
@property
def name(self):
"""Return the name of the sensor."""
return self._name
@property
def device_class(self):
"""Return the device class."""
return self._device_class
@property
def state(self):
"""Return the state of the sensor."""

View File

@ -12,7 +12,7 @@ import voluptuous as vol
from homeassistant.components.sensor import PLATFORM_SCHEMA
import homeassistant.helpers.config_validation as cv
from homeassistant.const import CONF_NAME
from homeassistant.const import CONF_NAME, DEVICE_CLASS_ILLUMINANCE
from homeassistant.helpers.entity import Entity
REQUIREMENTS = ['i2csense==0.0.4',
@ -130,7 +130,7 @@ class BH1750Sensor(Entity):
@property
def device_class(self) -> str:
"""Return the class of this device, from component DEVICE_CLASSES."""
return 'light'
return DEVICE_CLASS_ILLUMINANCE
@asyncio.coroutine
def async_update(self):

View File

@ -6,10 +6,10 @@ https://home-assistant.io/components/sensor.deconz/
"""
from homeassistant.components.deconz import (
DOMAIN as DATA_DECONZ, DATA_DECONZ_ID)
from homeassistant.const import ATTR_BATTERY_LEVEL, ATTR_VOLTAGE
from homeassistant.const import (
ATTR_BATTERY_LEVEL, ATTR_VOLTAGE, DEVICE_CLASS_BATTERY)
from homeassistant.core import callback
from homeassistant.helpers.entity import Entity
from homeassistant.helpers.icon import icon_for_battery_level
from homeassistant.util import slugify
DEPENDENCIES = ['deconz']
@ -126,7 +126,6 @@ class DeconzBattery(Entity):
"""Register dispatcher callback for update of battery state."""
self._device = device
self._name = '{} {}'.format(self._device.name, 'Battery Level')
self._device_class = 'battery'
self._unit_of_measurement = "%"
async def async_added_to_hass(self):
@ -158,12 +157,7 @@ class DeconzBattery(Entity):
@property
def device_class(self):
"""Return the class of the sensor."""
return self._device_class
@property
def icon(self):
"""Return the icon to use in the frontend."""
return icon_for_battery_level(int(self.state))
return DEVICE_CLASS_BATTERY
@property
def unit_of_measurement(self):

View File

@ -4,7 +4,9 @@ Demo platform that has a couple of fake sensors.
For more details about this platform, please refer to the documentation
https://home-assistant.io/components/demo/
"""
from homeassistant.const import ATTR_BATTERY_LEVEL, TEMP_CELSIUS
from homeassistant.const import (
ATTR_BATTERY_LEVEL, TEMP_CELSIUS, DEVICE_CLASS_HUMIDITY,
DEVICE_CLASS_TEMPERATURE)
from homeassistant.helpers.entity import Entity
@ -12,9 +14,9 @@ from homeassistant.helpers.entity import Entity
def setup_platform(hass, config, add_devices, discovery_info=None):
"""Set up the Demo sensors."""
add_devices([
DemoSensor('Outside Temperature', 15.6, 'temperature',
DemoSensor('Outside Temperature', 15.6, DEVICE_CLASS_TEMPERATURE,
TEMP_CELSIUS, 12),
DemoSensor('Outside Humidity', 54, 'humidity', '%', None),
DemoSensor('Outside Humidity', 54, DEVICE_CLASS_HUMIDITY, '%', None),
])

View File

@ -5,7 +5,8 @@ For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/sensor.ecobee/
"""
from homeassistant.components import ecobee
from homeassistant.const import TEMP_FAHRENHEIT
from homeassistant.const import (
DEVICE_CLASS_HUMIDITY, DEVICE_CLASS_TEMPERATURE, TEMP_FAHRENHEIT)
from homeassistant.helpers.entity import Entity
DEPENDENCIES = ['ecobee']
@ -55,7 +56,7 @@ class EcobeeSensor(Entity):
@property
def device_class(self):
"""Return the device class of the sensor."""
if self.type in ('temperature', 'humidity'):
if self.type in (DEVICE_CLASS_HUMIDITY, DEVICE_CLASS_TEMPERATURE):
return self.type
return None

View File

@ -43,7 +43,7 @@ HM_UNIT_HA_CAST = {
'ENERGY_COUNTER': 'Wh',
'GAS_POWER': 'm3',
'GAS_ENERGY_COUNTER': 'm3',
'LUX': 'lux',
'LUX': 'lx',
'RAIN_COUNTER': 'mm',
'WIND_SPEED': 'km/h',
'WIND_DIRECTION': '°',

View File

@ -49,7 +49,7 @@ UOM_FRIENDLY_NAME = {
'33': 'kWH',
'34': 'liedu',
'35': 'l',
'36': 'lux',
'36': 'lx',
'37': 'mercalli',
'38': 'm',
'39': 'm³/hr',

View File

@ -10,7 +10,7 @@ import os
import voluptuous as vol
from homeassistant.components.sensor import PLATFORM_SCHEMA
from homeassistant.const import CONF_NAME
from homeassistant.const import CONF_NAME, DEVICE_CLASS_BATTERY
from homeassistant.helpers.entity import Entity
import homeassistant.helpers.config_validation as cv
@ -48,8 +48,6 @@ DEFAULT_SYSTEM = 'linux'
SYSTEMS = ['android', 'linux']
ICON = 'mdi:battery'
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
vol.Optional(CONF_BATTERY, default=DEFAULT_BATTERY): cv.positive_int,
vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
@ -97,7 +95,7 @@ class LinuxBatterySensor(Entity):
@property
def device_class(self):
"""Return the device class of the sensor."""
return 'battery'
return DEVICE_CLASS_BATTERY
@property
def state(self):
@ -109,11 +107,6 @@ class LinuxBatterySensor(Entity):
"""Return the unit the value is expressed in."""
return self._unit_of_measurement
@property
def icon(self):
"""Return the icon to use in the frontend, if any."""
return ICON
@property
def device_state_attributes(self):
"""Return the state attributes of the sensor."""

View File

@ -38,7 +38,7 @@ DEFAULT_TIMEOUT = 10
# Sensor types are defined like: Name, units
SENSOR_TYPES = {
'temperature': ['Temperature', '°C'],
'light': ['Light intensity', 'lux'],
'light': ['Light intensity', 'lx'],
'moisture': ['Moisture', '%'],
'conductivity': ['Conductivity', 'µS/cm'],
'battery': ['Battery', '%'],

View File

@ -26,7 +26,7 @@ SENSORS = {
'V_PERCENTAGE': ['%', 'mdi:percent'],
'V_LEVEL': {
'S_SOUND': ['dB', 'mdi:volume-high'], 'S_VIBRATION': ['Hz', None],
'S_LIGHT_LEVEL': ['lux', 'white-balance-sunny']},
'S_LIGHT_LEVEL': ['lx', 'white-balance-sunny']},
'V_ORP': ['mV', None],
'V_EC': ['μS/cm', None],
'V_VAR': ['var', None],

View File

@ -9,8 +9,9 @@ import logging
from homeassistant.components.nest import DATA_NEST
from homeassistant.helpers.entity import Entity
from homeassistant.const import (TEMP_CELSIUS, TEMP_FAHRENHEIT,
CONF_MONITORED_CONDITIONS)
from homeassistant.const import (
TEMP_CELSIUS, TEMP_FAHRENHEIT, CONF_MONITORED_CONDITIONS,
DEVICE_CLASS_TEMPERATURE)
DEPENDENCIES = ['nest']
SENSOR_TYPES = ['humidity',
@ -143,7 +144,7 @@ class NestTempSensor(NestSensor):
@property
def device_class(self):
"""Return the device class of the sensor."""
return 'temperature'
return DEVICE_CLASS_TEMPERATURE
def update(self):
"""Retrieve latest state."""

View File

@ -49,7 +49,7 @@ class TahomaSensor(TahomaDevice, Entity):
elif self.tahoma_device.type == 'io:SomfyContactIOSystemSensor':
return None
elif self.tahoma_device.type == 'io:LightIOSystemSensor':
return 'lux'
return 'lx'
elif self.tahoma_device.type == 'Humidity Sensor':
return '%'

View File

@ -7,7 +7,9 @@ https://home-assistant.io/components/sensor.tellduslive/
import logging
from homeassistant.components.tellduslive import TelldusLiveEntity
from homeassistant.const import TEMP_CELSIUS
from homeassistant.const import (
DEVICE_CLASS_HUMIDITY, DEVICE_CLASS_ILLUMINANCE, DEVICE_CLASS_TEMPERATURE,
TEMP_CELSIUS)
_LOGGER = logging.getLogger(__name__)
@ -25,18 +27,20 @@ SENSOR_TYPE_DEW_POINT = 'dewp'
SENSOR_TYPE_BAROMETRIC_PRESSURE = 'barpress'
SENSOR_TYPES = {
SENSOR_TYPE_TEMPERATURE: ['Temperature', TEMP_CELSIUS, 'mdi:thermometer'],
SENSOR_TYPE_HUMIDITY: ['Humidity', '%', 'mdi:water'],
SENSOR_TYPE_RAINRATE: ['Rain rate', 'mm/h', 'mdi:water'],
SENSOR_TYPE_RAINTOTAL: ['Rain total', 'mm', 'mdi:water'],
SENSOR_TYPE_WINDDIRECTION: ['Wind direction', '', ''],
SENSOR_TYPE_WINDAVERAGE: ['Wind average', 'm/s', ''],
SENSOR_TYPE_WINDGUST: ['Wind gust', 'm/s', ''],
SENSOR_TYPE_UV: ['UV', 'UV', ''],
SENSOR_TYPE_WATT: ['Power', 'W', ''],
SENSOR_TYPE_LUMINANCE: ['Luminance', 'lx', ''],
SENSOR_TYPE_DEW_POINT: ['Dew Point', TEMP_CELSIUS, 'mdi:thermometer'],
SENSOR_TYPE_BAROMETRIC_PRESSURE: ['Barometric Pressure', 'kPa', ''],
SENSOR_TYPE_TEMPERATURE: ['Temperature', TEMP_CELSIUS, None,
DEVICE_CLASS_TEMPERATURE],
SENSOR_TYPE_HUMIDITY: ['Humidity', '%', None, DEVICE_CLASS_HUMIDITY],
SENSOR_TYPE_RAINRATE: ['Rain rate', 'mm/h', 'mdi:water', None],
SENSOR_TYPE_RAINTOTAL: ['Rain total', 'mm', 'mdi:water', None],
SENSOR_TYPE_WINDDIRECTION: ['Wind direction', '', '', None],
SENSOR_TYPE_WINDAVERAGE: ['Wind average', 'm/s', '', None],
SENSOR_TYPE_WINDGUST: ['Wind gust', 'm/s', '', None],
SENSOR_TYPE_UV: ['UV', 'UV', '', None],
SENSOR_TYPE_WATT: ['Power', 'W', '', None],
SENSOR_TYPE_LUMINANCE: ['Luminance', 'lx', None, DEVICE_CLASS_ILLUMINANCE],
SENSOR_TYPE_DEW_POINT:
['Dew Point', TEMP_CELSIUS, None, DEVICE_CLASS_TEMPERATURE],
SENSOR_TYPE_BAROMETRIC_PRESSURE: ['Barometric Pressure', 'kPa', '', None],
}
@ -117,3 +121,9 @@ class TelldusLiveSensor(TelldusLiveEntity):
"""Return the icon."""
return SENSOR_TYPES[self._type][2] \
if self._type in SENSOR_TYPES else None
@property
def device_class(self):
"""Return the device class."""
return SENSOR_TYPES[self._type][3] \
if self._type in SENSOR_TYPES else None

View File

@ -52,7 +52,7 @@ class VeraSensor(VeraDevice, Entity):
if self.vera_device.category == veraApi.CATEGORY_TEMPERATURE_SENSOR:
return self._temperature_units
elif self.vera_device.category == veraApi.CATEGORY_LIGHT_SENSOR:
return 'lux'
return 'lx'
elif self.vera_device.category == veraApi.CATEGORY_UV_SENSOR:
return 'level'
elif self.vera_device.category == veraApi.CATEGORY_HUMIDITY_SENSOR:

View File

@ -3,16 +3,18 @@ import logging
from homeassistant.components.xiaomi_aqara import (PY_XIAOMI_GATEWAY,
XiaomiDevice)
from homeassistant.const import TEMP_CELSIUS
from homeassistant.const import (
DEVICE_CLASS_HUMIDITY, DEVICE_CLASS_ILLUMINANCE, DEVICE_CLASS_TEMPERATURE,
TEMP_CELSIUS)
_LOGGER = logging.getLogger(__name__)
SENSOR_TYPES = {
'temperature': [TEMP_CELSIUS, 'mdi:thermometer'],
'humidity': ['%', 'mdi:water-percent'],
'illumination': ['lm', 'mdi:weather-sunset'],
'lux': ['lx', 'mdi:weather-sunset'],
'pressure': ['hPa', 'mdi:gauge']
'temperature': [TEMP_CELSIUS, None, DEVICE_CLASS_TEMPERATURE],
'humidity': ['%', None, DEVICE_CLASS_HUMIDITY],
'illumination': ['lm', None, DEVICE_CLASS_ILLUMINANCE],
'lux': ['lx', None, DEVICE_CLASS_ILLUMINANCE],
'pressure': ['hPa', 'mdi:gauge', None]
}
@ -66,6 +68,12 @@ class XiaomiSensor(XiaomiDevice):
except TypeError:
return None
@property
def device_class(self):
"""Return the device class of this entity."""
return SENSOR_TYPES.get(self._data_key)[2] \
if self._data_key in SENSOR_TYPES else None
@property
def state(self):
"""Return the state of the sensor."""

View File

@ -166,6 +166,12 @@ EVENT_SERVICE_REMOVED = 'service_removed'
EVENT_LOGBOOK_ENTRY = 'logbook_entry'
EVENT_THEMES_UPDATED = 'themes_updated'
# #### DEVICE CLASSES ####
DEVICE_CLASS_BATTERY = 'battery'
DEVICE_CLASS_HUMIDITY = 'humidity'
DEVICE_CLASS_ILLUMINANCE = 'illuminance'
DEVICE_CLASS_TEMPERATURE = 'temperature'
# #### STATES ####
STATE_ON = 'on'
STATE_OFF = 'off'

View File

@ -99,10 +99,10 @@ class TestGetAccessories(unittest.TestCase):
get_accessory(None, state, 2, {})
def test_light_sensor(self):
"""Test light sensor with device class lux."""
"""Test light sensor with device class illuminance."""
with patch.dict(TYPES, {'LightSensor': self.mock_type}):
state = State('sensor.light', '900',
{ATTR_DEVICE_CLASS: 'light'})
{ATTR_DEVICE_CLASS: 'illuminance'})
get_accessory(None, state, 2, {})
def test_light_sensor_unit_lm(self):
@ -112,13 +112,6 @@ class TestGetAccessories(unittest.TestCase):
{ATTR_UNIT_OF_MEASUREMENT: 'lm'})
get_accessory(None, state, 2, {})
def test_light_sensor_unit_lux(self):
"""Test light sensor with lux as unit."""
with patch.dict(TYPES, {'LightSensor': self.mock_type}):
state = State('sensor.light', '900',
{ATTR_UNIT_OF_MEASUREMENT: 'lux'})
get_accessory(None, state, 2, {})
def test_light_sensor_unit_lx(self):
"""Test light sensor with lx as unit."""
with patch.dict(TYPES, {'LightSensor': self.mock_type}):