From 6f1208b07fdf41bcab550a4b7adb42a1909d7898 Mon Sep 17 00:00:00 2001 From: mbo18 Date: Sat, 26 Nov 2022 05:40:02 +0100 Subject: [PATCH] Add more sensors to SensorEntityDescription for RFLink (#82036) * Add more sensors to SensorEntityDescription * changes from comments * add device_class precipitation * fix test * change state_class for total_rain --- homeassistant/components/rflink/sensor.py | 207 ++++++++++++++++++---- tests/components/rflink/test_sensor.py | 49 +++-- 2 files changed, 209 insertions(+), 47 deletions(-) diff --git a/homeassistant/components/rflink/sensor.py b/homeassistant/components/rflink/sensor.py index d1c3682228c..38d2cd4dd09 100644 --- a/homeassistant/components/rflink/sensor.py +++ b/homeassistant/components/rflink/sensor.py @@ -18,8 +18,17 @@ from homeassistant.const import ( CONF_NAME, CONF_SENSOR_TYPE, CONF_UNIT_OF_MEASUREMENT, + DEGREE, + ELECTRIC_CURRENT_AMPERE, + ELECTRIC_POTENTIAL_VOLT, + LIGHT_LUX, + PERCENTAGE, + PRECIPITATION_MILLIMETERS, + UV_INDEX, + UnitOfPower, UnitOfSpeed, UnitOfTemperature, + UnitOfVolumetricFlux, ) from homeassistant.core import HomeAssistant import homeassistant.helpers.config_validation as cv @@ -41,18 +50,14 @@ from . import ( RflinkDevice, ) -SENSOR_ICONS = { - "humidity": "mdi:water-percent", - "battery": "mdi:battery", -} - SENSOR_TYPES = ( # check new descriptors against PACKET_FIELDS & UNITS from rflink.parser SensorEntityDescription( - key="distance", - name="Distance", - device_class=SensorDeviceClass.DISTANCE, + key="average_windspeed", + name="Average windspeed", + device_class=SensorDeviceClass.WIND_SPEED, state_class=SensorStateClass.MEASUREMENT, + native_unit_of_measurement=UnitOfSpeed.KILOMETERS_PER_HOUR, ), SensorEntityDescription( key="barometric_pressure", @@ -61,11 +66,169 @@ SENSOR_TYPES = ( state_class=SensorStateClass.MEASUREMENT, ), SensorEntityDescription( - key="average_windspeed", - name="Average windspeed", - device_class=SensorDeviceClass.WIND_SPEED, + key="battery", + name="Battery", + icon="mdi:battery", + ), + SensorEntityDescription( + key="co2_air_quality", + name="CO2 air quality", + device_class=SensorDeviceClass.CO2, state_class=SensorStateClass.MEASUREMENT, - native_unit_of_measurement=UnitOfSpeed.KILOMETERS_PER_HOUR, + ), + SensorEntityDescription( + key="command", + name="Command", + icon="mdi:text", + ), + SensorEntityDescription( + key="current_phase_1", + name="Current phase 1", + device_class=SensorDeviceClass.CURRENT, + state_class=SensorStateClass.MEASUREMENT, + native_unit_of_measurement=ELECTRIC_CURRENT_AMPERE, + ), + SensorEntityDescription( + key="current_phase_2", + name="Current phase 2", + device_class=SensorDeviceClass.CURRENT, + state_class=SensorStateClass.MEASUREMENT, + native_unit_of_measurement=ELECTRIC_CURRENT_AMPERE, + ), + SensorEntityDescription( + key="current_phase_3", + name="Current phase 3", + device_class=SensorDeviceClass.CURRENT, + state_class=SensorStateClass.MEASUREMENT, + native_unit_of_measurement=ELECTRIC_CURRENT_AMPERE, + ), + SensorEntityDescription( + key="distance", + name="Distance", + device_class=SensorDeviceClass.DISTANCE, + state_class=SensorStateClass.MEASUREMENT, + ), + SensorEntityDescription( + key="doorbell_melody", + name="Doorbell melody", + icon="mdi:bell", + ), + SensorEntityDescription( + key="firmware", + name="Firmware", + icon="mdi:information-outline", + ), + SensorEntityDescription( + key="hardware", + name="Hardware", + icon="mdi:chip", + ), + SensorEntityDescription( + key="humidity", + name="Humidity", + device_class=SensorDeviceClass.HUMIDITY, + state_class=SensorStateClass.MEASUREMENT, + native_unit_of_measurement=PERCENTAGE, + ), + SensorEntityDescription( + key="humidity_status", + name="Humidity status", + icon="mdi:water-percent", + ), + SensorEntityDescription( + key="kilowatt", + name="Kilowatt", + device_class=SensorDeviceClass.POWER, + state_class=SensorStateClass.MEASUREMENT, + native_unit_of_measurement=UnitOfPower.KILO_WATT, + ), + SensorEntityDescription( + key="light_intensity", + name="Light intensity", + device_class=SensorDeviceClass.ILLUMINANCE, + state_class=SensorStateClass.MEASUREMENT, + native_unit_of_measurement=LIGHT_LUX, + ), + SensorEntityDescription( + key="meter_value", + name="Meter value", + icon="mdi:counter", + ), + SensorEntityDescription( + key="noise_level", + name="Noise level", + icon="mdi:bell-alert", + ), + SensorEntityDescription( + key="rain_rate", + name="Rain rate", + device_class=SensorDeviceClass.PRECIPITATION_INTENSITY, + state_class=SensorStateClass.MEASUREMENT, + native_unit_of_measurement=UnitOfVolumetricFlux.MILLIMETERS_PER_HOUR, + ), + SensorEntityDescription( + key="revision", + name="Revision", + icon="mdi:information", + ), + SensorEntityDescription( + key="temperature", + name="Temperature", + device_class=SensorDeviceClass.TEMPERATURE, + state_class=SensorStateClass.MEASUREMENT, + native_unit_of_measurement=UnitOfTemperature.CELSIUS, + ), + SensorEntityDescription( + key="total_rain", + name="Total rain", + device_class=SensorDeviceClass.PRECIPITATION, + state_class=SensorStateClass.TOTAL_INCREASING, + native_unit_of_measurement=PRECIPITATION_MILLIMETERS, + ), + SensorEntityDescription( + key="uv_intensity", + name="UV intensity", + icon="mdi:sunglasses", + state_class=SensorStateClass.MEASUREMENT, + native_unit_of_measurement=UV_INDEX, + ), + SensorEntityDescription( + key="version", + name="Version", + icon="mdi:information", + ), + SensorEntityDescription( + key="voltage", + name="Voltage", + device_class=SensorDeviceClass.VOLTAGE, + state_class=SensorStateClass.MEASUREMENT, + native_unit_of_measurement=ELECTRIC_POTENTIAL_VOLT, + ), + SensorEntityDescription( + key="watt", + name="Watt", + device_class=SensorDeviceClass.POWER, + state_class=SensorStateClass.MEASUREMENT, + native_unit_of_measurement=UnitOfPower.WATT, + ), + SensorEntityDescription( + key="weather_forecast", + name="Weather forecast", + icon="mdi:weather-cloudy-clock", + ), + SensorEntityDescription( + key="windchill", + name="Wind chill", + device_class=SensorDeviceClass.TEMPERATURE, + state_class=SensorStateClass.MEASUREMENT, + native_unit_of_measurement=UnitOfTemperature.CELSIUS, + ), + SensorEntityDescription( + key="winddirection", + name="Wind direction", + icon="mdi:compass", + state_class=SensorStateClass.MEASUREMENT, + native_unit_of_measurement=DEGREE, ), SensorEntityDescription( key="windgusts", @@ -81,13 +244,6 @@ SENSOR_TYPES = ( state_class=SensorStateClass.MEASUREMENT, native_unit_of_measurement=UnitOfSpeed.KILOMETERS_PER_HOUR, ), - SensorEntityDescription( - key="temperature", - name="Temperature", - device_class=SensorDeviceClass.TEMPERATURE, - state_class=SensorStateClass.MEASUREMENT, - native_unit_of_measurement=UnitOfTemperature.CELSIUS, - ), SensorEntityDescription( key="windtemp", name="Wind temperature", @@ -95,13 +251,6 @@ SENSOR_TYPES = ( state_class=SensorStateClass.MEASUREMENT, native_unit_of_measurement=UnitOfTemperature.CELSIUS, ), - SensorEntityDescription( - key="windchill", - name="Wind chill", - device_class=SensorDeviceClass.TEMPERATURE, - state_class=SensorStateClass.MEASUREMENT, - native_unit_of_measurement=UnitOfTemperature.CELSIUS, - ), ) SENSOR_TYPES_DICT = {desc.key: desc for desc in SENSOR_TYPES} @@ -248,9 +397,3 @@ class RflinkSensor(RflinkDevice, SensorEntity): def native_value(self): """Return value.""" return self._state - - @property - def icon(self): - """Return possible sensor specific icon.""" - if self._sensor_type in SENSOR_ICONS: - return SENSOR_ICONS[self._sensor_type] diff --git a/tests/components/rflink/test_sensor.py b/tests/components/rflink/test_sensor.py index 4faa1eb6d07..0202894a41c 100644 --- a/tests/components/rflink/test_sensor.py +++ b/tests/components/rflink/test_sensor.py @@ -17,6 +17,7 @@ from homeassistant.const import ( ATTR_ICON, ATTR_UNIT_OF_MEASUREMENT, PERCENTAGE, + PRECIPITATION_MILLIMETERS, STATE_UNKNOWN, UnitOfTemperature, ) @@ -87,17 +88,15 @@ async def test_default_setup(hass, monkeypatch): ) # temperature uses SensorEntityDescription # test event for new unconfigured sensor - event_callback( - {"id": "test3", "sensor": "humidity", "value": 43, "unit": PERCENTAGE} - ) + event_callback({"id": "test3", "sensor": "battery", "value": "ok", "unit": None}) await hass.async_block_till_done() - # test state of hum sensor - hum_sensor = hass.states.get("sensor.test3") - assert hum_sensor - assert hum_sensor.state == "43" - assert hum_sensor.attributes[ATTR_UNIT_OF_MEASUREMENT] == PERCENTAGE - assert hum_sensor.attributes[ATTR_ICON] == "mdi:water-percent" + # test state of battery sensor + bat_sensor = hass.states.get("sensor.test3") + assert bat_sensor + assert bat_sensor.state == "ok" + assert ATTR_UNIT_OF_MEASUREMENT not in bat_sensor.attributes + assert bat_sensor.attributes[ATTR_ICON] == "mdi:battery" async def test_disable_automatic_add(hass, monkeypatch): @@ -195,7 +194,7 @@ async def test_aliases(hass, monkeypatch): ) await hass.async_block_till_done() - # test state of new sensor + # test state of new sensor updated_sensor = hass.states.get("sensor.test_02") assert updated_sensor assert updated_sensor.state == "65" @@ -221,11 +220,11 @@ async def test_race_condition(hass, monkeypatch): await hass.async_block_till_done() - # test state of new sensor + # test state of new sensor updated_sensor = hass.states.get("sensor.test3") assert updated_sensor - # test state of new sensor + # test state of new sensor new_sensor = hass.states.get(f"{DOMAIN}.test3") assert new_sensor assert new_sensor.state == "ok" @@ -235,7 +234,7 @@ async def test_race_condition(hass, monkeypatch): # tmp_entity must be deleted from EVENT_KEY_COMMAND assert tmp_entity not in hass.data[DATA_ENTITY_LOOKUP][EVENT_KEY_SENSOR]["test3"] - # test state of new sensor + # test state of new sensor new_sensor = hass.states.get(f"{DOMAIN}.test3") assert new_sensor assert new_sensor.state == "ko" @@ -249,6 +248,14 @@ async def test_sensor_attributes(hass, monkeypatch): DOMAIN: { "platform": "rflink", "devices": { + "my_meter_device_unique_id": { + "name": "meter_device", + "sensor_type": "meter_value", + }, + "my_rain_device_unique_id": { + "name": "rain_device", + "sensor_type": "total_rain", + }, "my_humidity_device_unique_id": { "name": "humidity_device", "sensor_type": "humidity", @@ -270,10 +277,22 @@ async def test_sensor_attributes(hass, monkeypatch): event_callback, _, _, _ = await mock_rflink(hass, config, DOMAIN, monkeypatch) # test sensor loaded from config + meter_state = hass.states.get("sensor.meter_device") + assert meter_state + assert "device_class" not in meter_state.attributes + assert "state_class" not in meter_state.attributes + assert "unit_of_measurement" not in meter_state.attributes + + rain_state = hass.states.get("sensor.rain_device") + assert rain_state + assert rain_state.attributes["device_class"] == SensorDeviceClass.PRECIPITATION + assert rain_state.attributes["state_class"] == SensorStateClass.TOTAL_INCREASING + assert rain_state.attributes["unit_of_measurement"] == PRECIPITATION_MILLIMETERS + humidity_state = hass.states.get("sensor.humidity_device") assert humidity_state - assert "device_class" not in humidity_state.attributes - assert "state_class" not in humidity_state.attributes + assert humidity_state.attributes["device_class"] == SensorDeviceClass.HUMIDITY + assert humidity_state.attributes["state_class"] == SensorStateClass.MEASUREMENT assert humidity_state.attributes["unit_of_measurement"] == PERCENTAGE temperature_state = hass.states.get("sensor.temperature_device")