From a09c8eecb7b5ca2a2bace70c4d8460f3682c2d69 Mon Sep 17 00:00:00 2001 From: Erik Montnemery Date: Tue, 23 Mar 2021 15:56:33 +0100 Subject: [PATCH] Fix some sensor classes (#48254) * Fix some sensor classes * Tweak * Tweak --- .../components/aemet/abstract_aemet_sensor.py | 3 ++- homeassistant/components/hydrawise/__init__.py | 7 ------- homeassistant/components/hydrawise/sensor.py | 9 ++++++++- homeassistant/components/iqvia/__init__.py | 3 ++- homeassistant/components/iqvia/sensor.py | 5 ++--- .../components/nest/legacy/__init__.py | 5 ----- homeassistant/components/nest/legacy/sensor.py | 10 ++++++++++ homeassistant/components/nest/sensor_sdm.py | 4 ++-- .../components/onewire/onewire_entities.py | 5 ----- homeassistant/components/onewire/sensor.py | 17 ++++++++++++++--- homeassistant/components/raincloud/__init__.py | 5 ----- homeassistant/components/raincloud/sensor.py | 13 ++++++++++++- homeassistant/components/shelly/entity.py | 10 ---------- homeassistant/components/shelly/sensor.py | 15 +++++++++++++++ .../components/synology_dsm/__init__.py | 8 -------- homeassistant/components/synology_dsm/sensor.py | 17 ++++++++++++++--- homeassistant/components/withings/common.py | 5 ----- homeassistant/components/withings/sensor.py | 5 +++++ homeassistant/components/xbee/__init__.py | 3 ++- 19 files changed, 88 insertions(+), 61 deletions(-) diff --git a/homeassistant/components/aemet/abstract_aemet_sensor.py b/homeassistant/components/aemet/abstract_aemet_sensor.py index 7699a5f99a4..8847a5d094d 100644 --- a/homeassistant/components/aemet/abstract_aemet_sensor.py +++ b/homeassistant/components/aemet/abstract_aemet_sensor.py @@ -1,4 +1,5 @@ """Abstraction form AEMET OpenData sensors.""" +from homeassistant.components.sensor import SensorEntity from homeassistant.const import ATTR_ATTRIBUTION from homeassistant.helpers.update_coordinator import CoordinatorEntity @@ -6,7 +7,7 @@ from .const import ATTRIBUTION, SENSOR_DEVICE_CLASS, SENSOR_NAME, SENSOR_UNIT from .weather_update_coordinator import WeatherUpdateCoordinator -class AbstractAemetSensor(CoordinatorEntity): +class AbstractAemetSensor(CoordinatorEntity, SensorEntity): """Abstract class for an AEMET OpenData sensor.""" def __init__( diff --git a/homeassistant/components/hydrawise/__init__.py b/homeassistant/components/hydrawise/__init__.py index 6fa05ebef16..1f1b2c03157 100644 --- a/homeassistant/components/hydrawise/__init__.py +++ b/homeassistant/components/hydrawise/__init__.py @@ -143,13 +143,6 @@ class HydrawiseEntity(Entity): """Call update method.""" self.async_schedule_update_ha_state(True) - @property - def unit_of_measurement(self): - """Return the units of measurement.""" - return DEVICE_MAP[self._sensor_type][ - DEVICE_MAP_INDEX.index("UNIT_OF_MEASURE_INDEX") - ] - @property def extra_state_attributes(self): """Return the state attributes.""" diff --git a/homeassistant/components/hydrawise/sensor.py b/homeassistant/components/hydrawise/sensor.py index 7cd521296f6..62108afbded 100644 --- a/homeassistant/components/hydrawise/sensor.py +++ b/homeassistant/components/hydrawise/sensor.py @@ -8,7 +8,7 @@ from homeassistant.const import CONF_MONITORED_CONDITIONS import homeassistant.helpers.config_validation as cv from homeassistant.util import dt -from . import DATA_HYDRAWISE, SENSORS, HydrawiseEntity +from . import DATA_HYDRAWISE, DEVICE_MAP, DEVICE_MAP_INDEX, SENSORS, HydrawiseEntity _LOGGER = logging.getLogger(__name__) @@ -44,6 +44,13 @@ class HydrawiseSensor(HydrawiseEntity, SensorEntity): """Return the state of the sensor.""" return self._state + @property + def unit_of_measurement(self): + """Return the units of measurement.""" + return DEVICE_MAP[self._sensor_type][ + DEVICE_MAP_INDEX.index("UNIT_OF_MEASURE_INDEX") + ] + def update(self): """Get the latest data and updates the states.""" mydata = self.hass.data[DATA_HYDRAWISE].data diff --git a/homeassistant/components/iqvia/__init__.py b/homeassistant/components/iqvia/__init__.py index 962f13ca07e..c548a115e04 100644 --- a/homeassistant/components/iqvia/__init__.py +++ b/homeassistant/components/iqvia/__init__.py @@ -6,6 +6,7 @@ from functools import partial from pyiqvia import Client from pyiqvia.errors import IQVIAError +from homeassistant.components.sensor import SensorEntity from homeassistant.const import ATTR_ATTRIBUTION from homeassistant.core import callback from homeassistant.helpers import aiohttp_client @@ -109,7 +110,7 @@ async def async_unload_entry(hass, entry): return unload_ok -class IQVIAEntity(CoordinatorEntity): +class IQVIAEntity(CoordinatorEntity, SensorEntity): """Define a base IQVIA entity.""" def __init__(self, coordinator, entry, sensor_type, name, icon): diff --git a/homeassistant/components/iqvia/sensor.py b/homeassistant/components/iqvia/sensor.py index 169ff405d6d..48ec1cf97b1 100644 --- a/homeassistant/components/iqvia/sensor.py +++ b/homeassistant/components/iqvia/sensor.py @@ -3,7 +3,6 @@ from statistics import mean import numpy as np -from homeassistant.components.sensor import SensorEntity from homeassistant.const import ATTR_STATE from homeassistant.core import callback @@ -99,7 +98,7 @@ def calculate_trend(indices): return TREND_FLAT -class ForecastSensor(IQVIAEntity, SensorEntity): +class ForecastSensor(IQVIAEntity): """Define sensor related to forecast data.""" @callback @@ -138,7 +137,7 @@ class ForecastSensor(IQVIAEntity, SensorEntity): self._state = average -class IndexSensor(IQVIAEntity, SensorEntity): +class IndexSensor(IQVIAEntity): """Define sensor related to indices.""" @callback diff --git a/homeassistant/components/nest/legacy/__init__.py b/homeassistant/components/nest/legacy/__init__.py index 11bc1ab33ff..60faa90e8b4 100644 --- a/homeassistant/components/nest/legacy/__init__.py +++ b/homeassistant/components/nest/legacy/__init__.py @@ -363,11 +363,6 @@ class NestSensorDevice(Entity): """Return the name of the nest, if any.""" return self._name - @property - def unit_of_measurement(self): - """Return the unit the value is expressed in.""" - return self._unit - @property def should_poll(self): """Do not need poll thanks using Nest streaming API.""" diff --git a/homeassistant/components/nest/legacy/sensor.py b/homeassistant/components/nest/legacy/sensor.py index 9bea3b34ad4..53d9c824466 100644 --- a/homeassistant/components/nest/legacy/sensor.py +++ b/homeassistant/components/nest/legacy/sensor.py @@ -153,6 +153,11 @@ async def async_setup_legacy_entry(hass, entry, async_add_entities): class NestBasicSensor(NestSensorDevice, SensorEntity): """Representation a basic Nest sensor.""" + @property + def unit_of_measurement(self): + """Return the unit the value is expressed in.""" + return self._unit + @property def state(self): """Return the state of the sensor.""" @@ -188,6 +193,11 @@ class NestTempSensor(NestSensorDevice, SensorEntity): """Return the state of the sensor.""" return self._state + @property + def unit_of_measurement(self): + """Return the unit the value is expressed in.""" + return self._unit + @property def device_class(self): """Return the device class of the sensor.""" diff --git a/homeassistant/components/nest/sensor_sdm.py b/homeassistant/components/nest/sensor_sdm.py index 946be2e95b0..06e2b68d7cf 100644 --- a/homeassistant/components/nest/sensor_sdm.py +++ b/homeassistant/components/nest/sensor_sdm.py @@ -7,6 +7,7 @@ from google_nest_sdm.device import Device from google_nest_sdm.device_traits import HumidityTrait, TemperatureTrait from google_nest_sdm.exceptions import GoogleNestException +from homeassistant.components.sensor import SensorEntity from homeassistant.config_entries import ConfigEntry from homeassistant.const import ( DEVICE_CLASS_HUMIDITY, @@ -15,7 +16,6 @@ from homeassistant.const import ( TEMP_CELSIUS, ) from homeassistant.exceptions import PlatformNotReady -from homeassistant.helpers.entity import Entity from homeassistant.helpers.typing import HomeAssistantType from .const import DATA_SUBSCRIBER, DOMAIN @@ -53,7 +53,7 @@ async def async_setup_sdm_entry( async_add_entities(entities) -class SensorBase(Entity): +class SensorBase(SensorEntity): """Representation of a dynamically updated Sensor.""" def __init__(self, device: Device): diff --git a/homeassistant/components/onewire/onewire_entities.py b/homeassistant/components/onewire/onewire_entities.py index e8c013094f7..10c2b0c24a7 100644 --- a/homeassistant/components/onewire/onewire_entities.py +++ b/homeassistant/components/onewire/onewire_entities.py @@ -54,11 +54,6 @@ class OneWireBaseEntity(Entity): """Return the class of this device.""" return self._device_class - @property - def unit_of_measurement(self) -> str | None: - """Return the unit the value is expressed in.""" - return self._unit_of_measurement - @property def extra_state_attributes(self) -> dict[str, Any] | None: """Return the state attributes of the entity.""" diff --git a/homeassistant/components/onewire/sensor.py b/homeassistant/components/onewire/sensor.py index ba988aba226..3ea29a904db 100644 --- a/homeassistant/components/onewire/sensor.py +++ b/homeassistant/components/onewire/sensor.py @@ -1,4 +1,6 @@ """Support for 1-Wire environment sensors.""" +from __future__ import annotations + from glob import glob import logging import os @@ -394,7 +396,16 @@ def get_entities(onewirehub: OneWireHub, config): return entities -class OneWireProxySensor(OneWireProxyEntity, SensorEntity): +class OneWireSensor(OneWireBaseEntity, SensorEntity): + """Mixin for sensor specific attributes.""" + + @property + def unit_of_measurement(self) -> str | None: + """Return the unit the value is expressed in.""" + return self._unit_of_measurement + + +class OneWireProxySensor(OneWireProxyEntity, OneWireSensor): """Implementation of a 1-Wire sensor connected through owserver.""" @property @@ -403,7 +414,7 @@ class OneWireProxySensor(OneWireProxyEntity, SensorEntity): return self._state -class OneWireDirectSensor(OneWireBaseEntity, SensorEntity): +class OneWireDirectSensor(OneWireSensor): """Implementation of a 1-Wire sensor directly connected to RPI GPIO.""" def __init__(self, name, device_file, device_info, owsensor): @@ -431,7 +442,7 @@ class OneWireDirectSensor(OneWireBaseEntity, SensorEntity): self._state = value -class OneWireOWFSSensor(OneWireBaseEntity, SensorEntity): # pragma: no cover +class OneWireOWFSSensor(OneWireSensor): # pragma: no cover """Implementation of a 1-Wire sensor through owfs. This part of the implementation does not conform to policy regarding 3rd-party libraries, and will not longer be updated. diff --git a/homeassistant/components/raincloud/__init__.py b/homeassistant/components/raincloud/__init__.py index 6b0ca39df03..51e9f5de5ce 100644 --- a/homeassistant/components/raincloud/__init__.py +++ b/homeassistant/components/raincloud/__init__.py @@ -160,11 +160,6 @@ class RainCloudEntity(Entity): """Call update method.""" self.schedule_update_ha_state(True) - @property - def unit_of_measurement(self): - """Return the units of measurement.""" - return UNIT_OF_MEASUREMENT_MAP.get(self._sensor_type) - @property def extra_state_attributes(self): """Return the state attributes.""" diff --git a/homeassistant/components/raincloud/sensor.py b/homeassistant/components/raincloud/sensor.py index efff3677009..ee8f68734ad 100644 --- a/homeassistant/components/raincloud/sensor.py +++ b/homeassistant/components/raincloud/sensor.py @@ -8,7 +8,13 @@ from homeassistant.const import CONF_MONITORED_CONDITIONS import homeassistant.helpers.config_validation as cv from homeassistant.helpers.icon import icon_for_battery_level -from . import DATA_RAINCLOUD, ICON_MAP, SENSORS, RainCloudEntity +from . import ( + DATA_RAINCLOUD, + ICON_MAP, + SENSORS, + UNIT_OF_MEASUREMENT_MAP, + RainCloudEntity, +) _LOGGER = logging.getLogger(__name__) @@ -46,6 +52,11 @@ class RainCloudSensor(RainCloudEntity, SensorEntity): """Return the state of the sensor.""" return self._state + @property + def unit_of_measurement(self): + """Return the units of measurement.""" + return UNIT_OF_MEASUREMENT_MAP.get(self._sensor_type) + def update(self): """Get the latest data and updates the states.""" _LOGGER.debug("Updating RainCloud sensor: %s", self._name) diff --git a/homeassistant/components/shelly/entity.py b/homeassistant/components/shelly/entity.py index 292a6050f9a..48d37312225 100644 --- a/homeassistant/components/shelly/entity.py +++ b/homeassistant/components/shelly/entity.py @@ -267,11 +267,6 @@ class ShellyBlockAttributeEntity(ShellyBlockEntity, entity.Entity): return self.description.value(value) - @property - def unit_of_measurement(self): - """Return unit of sensor.""" - return self._unit - @property def device_class(self): """Device class of sensor.""" @@ -348,11 +343,6 @@ class ShellyRestAttributeEntity(update_coordinator.CoordinatorEntity): ) return self._last_value - @property - def unit_of_measurement(self): - """Return unit of sensor.""" - return self.description.unit - @property def device_class(self): """Device class of sensor.""" diff --git a/homeassistant/components/shelly/sensor.py b/homeassistant/components/shelly/sensor.py index ae9e2d740d3..9e24034bf83 100644 --- a/homeassistant/components/shelly/sensor.py +++ b/homeassistant/components/shelly/sensor.py @@ -212,6 +212,11 @@ class ShellySensor(ShellyBlockAttributeEntity, SensorEntity): """Return value of sensor.""" return self.attribute_value + @property + def unit_of_measurement(self): + """Return unit of sensor.""" + return self._unit + class ShellyRestSensor(ShellyRestAttributeEntity, SensorEntity): """Represent a shelly REST sensor.""" @@ -221,6 +226,11 @@ class ShellyRestSensor(ShellyRestAttributeEntity, SensorEntity): """Return value of sensor.""" return self.attribute_value + @property + def unit_of_measurement(self): + """Return unit of sensor.""" + return self.description.unit + class ShellySleepingSensor(ShellySleepingBlockAttributeEntity, SensorEntity): """Represent a shelly sleeping sensor.""" @@ -232,3 +242,8 @@ class ShellySleepingSensor(ShellySleepingBlockAttributeEntity, SensorEntity): return self.attribute_value return self.last_state + + @property + def unit_of_measurement(self): + """Return unit of sensor.""" + return self._unit diff --git a/homeassistant/components/synology_dsm/__init__.py b/homeassistant/components/synology_dsm/__init__.py index 673cb6717fc..960d6321c21 100644 --- a/homeassistant/components/synology_dsm/__init__.py +++ b/homeassistant/components/synology_dsm/__init__.py @@ -72,7 +72,6 @@ from .const import ( STORAGE_VOL_SENSORS, SYNO_API, SYSTEM_LOADED, - TEMP_SENSORS_KEYS, UNDO_UPDATE_LISTENER, UTILISATION_SENSORS, ) @@ -631,13 +630,6 @@ class SynologyDSMBaseEntity(CoordinatorEntity): """Return the icon.""" return self._icon - @property - def unit_of_measurement(self) -> str: - """Return the unit the value is expressed in.""" - if self.entity_type in TEMP_SENSORS_KEYS: - return self.hass.config.units.temperature_unit - return self._unit - @property def device_class(self) -> str: """Return the class of this device.""" diff --git a/homeassistant/components/synology_dsm/sensor.py b/homeassistant/components/synology_dsm/sensor.py index 56eb56df07d..22f41601e7b 100644 --- a/homeassistant/components/synology_dsm/sensor.py +++ b/homeassistant/components/synology_dsm/sensor.py @@ -87,7 +87,18 @@ async def async_setup_entry( async_add_entities(entities) -class SynoDSMUtilSensor(SynologyDSMBaseEntity, SensorEntity): +class SynoDSMSensor(SynologyDSMBaseEntity): + """Mixin for sensor specific attributes.""" + + @property + def unit_of_measurement(self) -> str: + """Return the unit the value is expressed in.""" + if self.entity_type in TEMP_SENSORS_KEYS: + return self.hass.config.units.temperature_unit + return self._unit + + +class SynoDSMUtilSensor(SynoDSMSensor, SensorEntity): """Representation a Synology Utilisation sensor.""" @property @@ -119,7 +130,7 @@ class SynoDSMUtilSensor(SynologyDSMBaseEntity, SensorEntity): return bool(self._api.utilisation) -class SynoDSMStorageSensor(SynologyDSMDeviceEntity, SensorEntity): +class SynoDSMStorageSensor(SynologyDSMDeviceEntity, SynoDSMSensor, SensorEntity): """Representation a Synology Storage sensor.""" @property @@ -140,7 +151,7 @@ class SynoDSMStorageSensor(SynologyDSMDeviceEntity, SensorEntity): return attr -class SynoDSMInfoSensor(SynologyDSMBaseEntity, SensorEntity): +class SynoDSMInfoSensor(SynoDSMSensor, SensorEntity): """Representation a Synology information sensor.""" def __init__( diff --git a/homeassistant/components/withings/common.py b/homeassistant/components/withings/common.py index 96be4fd3063..3ff869767a9 100644 --- a/homeassistant/components/withings/common.py +++ b/homeassistant/components/withings/common.py @@ -967,11 +967,6 @@ class BaseWithingsSensor(Entity): """Return a unique, Home Assistant friendly identifier for this entity.""" return self._unique_id - @property - def unit_of_measurement(self) -> str: - """Return the unit of measurement of this entity, if any.""" - return self._attribute.unit_of_measurement - @property def icon(self) -> str: """Icon to use in the frontend, if any.""" diff --git a/homeassistant/components/withings/sensor.py b/homeassistant/components/withings/sensor.py index 89bb81eb607..e26804f1f0a 100644 --- a/homeassistant/components/withings/sensor.py +++ b/homeassistant/components/withings/sensor.py @@ -35,3 +35,8 @@ class WithingsHealthSensor(BaseWithingsSensor, SensorEntity): def state(self) -> None | str | int | float: """Return the state of the entity.""" return self._state_data + + @property + def unit_of_measurement(self) -> str: + """Return the unit of measurement of this entity, if any.""" + return self._attribute.unit_of_measurement diff --git a/homeassistant/components/xbee/__init__.py b/homeassistant/components/xbee/__init__.py index 6373cfa7535..58ce7587070 100644 --- a/homeassistant/components/xbee/__init__.py +++ b/homeassistant/components/xbee/__init__.py @@ -9,6 +9,7 @@ import xbee_helper.const as xb_const from xbee_helper.device import convert_adc from xbee_helper.exceptions import ZigBeeException, ZigBeeTxFailure +from homeassistant.components.sensor import SensorEntity from homeassistant.const import ( CONF_ADDRESS, CONF_DEVICE, @@ -365,7 +366,7 @@ class XBeeDigitalOut(XBeeDigitalIn): self._state = self._config.state2bool[pin_state] -class XBeeAnalogIn(Entity): +class XBeeAnalogIn(SensorEntity): """Representation of a GPIO pin configured as an analog input.""" def __init__(self, config, device):