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
This commit is contained in:
parent
fb132f8a26
commit
6f1208b07f
2 changed files with 209 additions and 47 deletions
|
@ -18,8 +18,17 @@ from homeassistant.const import (
|
||||||
CONF_NAME,
|
CONF_NAME,
|
||||||
CONF_SENSOR_TYPE,
|
CONF_SENSOR_TYPE,
|
||||||
CONF_UNIT_OF_MEASUREMENT,
|
CONF_UNIT_OF_MEASUREMENT,
|
||||||
|
DEGREE,
|
||||||
|
ELECTRIC_CURRENT_AMPERE,
|
||||||
|
ELECTRIC_POTENTIAL_VOLT,
|
||||||
|
LIGHT_LUX,
|
||||||
|
PERCENTAGE,
|
||||||
|
PRECIPITATION_MILLIMETERS,
|
||||||
|
UV_INDEX,
|
||||||
|
UnitOfPower,
|
||||||
UnitOfSpeed,
|
UnitOfSpeed,
|
||||||
UnitOfTemperature,
|
UnitOfTemperature,
|
||||||
|
UnitOfVolumetricFlux,
|
||||||
)
|
)
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
import homeassistant.helpers.config_validation as cv
|
import homeassistant.helpers.config_validation as cv
|
||||||
|
@ -41,18 +50,14 @@ from . import (
|
||||||
RflinkDevice,
|
RflinkDevice,
|
||||||
)
|
)
|
||||||
|
|
||||||
SENSOR_ICONS = {
|
|
||||||
"humidity": "mdi:water-percent",
|
|
||||||
"battery": "mdi:battery",
|
|
||||||
}
|
|
||||||
|
|
||||||
SENSOR_TYPES = (
|
SENSOR_TYPES = (
|
||||||
# check new descriptors against PACKET_FIELDS & UNITS from rflink.parser
|
# check new descriptors against PACKET_FIELDS & UNITS from rflink.parser
|
||||||
SensorEntityDescription(
|
SensorEntityDescription(
|
||||||
key="distance",
|
key="average_windspeed",
|
||||||
name="Distance",
|
name="Average windspeed",
|
||||||
device_class=SensorDeviceClass.DISTANCE,
|
device_class=SensorDeviceClass.WIND_SPEED,
|
||||||
state_class=SensorStateClass.MEASUREMENT,
|
state_class=SensorStateClass.MEASUREMENT,
|
||||||
|
native_unit_of_measurement=UnitOfSpeed.KILOMETERS_PER_HOUR,
|
||||||
),
|
),
|
||||||
SensorEntityDescription(
|
SensorEntityDescription(
|
||||||
key="barometric_pressure",
|
key="barometric_pressure",
|
||||||
|
@ -61,11 +66,169 @@ SENSOR_TYPES = (
|
||||||
state_class=SensorStateClass.MEASUREMENT,
|
state_class=SensorStateClass.MEASUREMENT,
|
||||||
),
|
),
|
||||||
SensorEntityDescription(
|
SensorEntityDescription(
|
||||||
key="average_windspeed",
|
key="battery",
|
||||||
name="Average windspeed",
|
name="Battery",
|
||||||
device_class=SensorDeviceClass.WIND_SPEED,
|
icon="mdi:battery",
|
||||||
|
),
|
||||||
|
SensorEntityDescription(
|
||||||
|
key="co2_air_quality",
|
||||||
|
name="CO2 air quality",
|
||||||
|
device_class=SensorDeviceClass.CO2,
|
||||||
state_class=SensorStateClass.MEASUREMENT,
|
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(
|
SensorEntityDescription(
|
||||||
key="windgusts",
|
key="windgusts",
|
||||||
|
@ -81,13 +244,6 @@ SENSOR_TYPES = (
|
||||||
state_class=SensorStateClass.MEASUREMENT,
|
state_class=SensorStateClass.MEASUREMENT,
|
||||||
native_unit_of_measurement=UnitOfSpeed.KILOMETERS_PER_HOUR,
|
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(
|
SensorEntityDescription(
|
||||||
key="windtemp",
|
key="windtemp",
|
||||||
name="Wind temperature",
|
name="Wind temperature",
|
||||||
|
@ -95,13 +251,6 @@ SENSOR_TYPES = (
|
||||||
state_class=SensorStateClass.MEASUREMENT,
|
state_class=SensorStateClass.MEASUREMENT,
|
||||||
native_unit_of_measurement=UnitOfTemperature.CELSIUS,
|
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}
|
SENSOR_TYPES_DICT = {desc.key: desc for desc in SENSOR_TYPES}
|
||||||
|
@ -248,9 +397,3 @@ class RflinkSensor(RflinkDevice, SensorEntity):
|
||||||
def native_value(self):
|
def native_value(self):
|
||||||
"""Return value."""
|
"""Return value."""
|
||||||
return self._state
|
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]
|
|
||||||
|
|
|
@ -17,6 +17,7 @@ from homeassistant.const import (
|
||||||
ATTR_ICON,
|
ATTR_ICON,
|
||||||
ATTR_UNIT_OF_MEASUREMENT,
|
ATTR_UNIT_OF_MEASUREMENT,
|
||||||
PERCENTAGE,
|
PERCENTAGE,
|
||||||
|
PRECIPITATION_MILLIMETERS,
|
||||||
STATE_UNKNOWN,
|
STATE_UNKNOWN,
|
||||||
UnitOfTemperature,
|
UnitOfTemperature,
|
||||||
)
|
)
|
||||||
|
@ -87,17 +88,15 @@ async def test_default_setup(hass, monkeypatch):
|
||||||
) # temperature uses SensorEntityDescription
|
) # temperature uses SensorEntityDescription
|
||||||
|
|
||||||
# test event for new unconfigured sensor
|
# test event for new unconfigured sensor
|
||||||
event_callback(
|
event_callback({"id": "test3", "sensor": "battery", "value": "ok", "unit": None})
|
||||||
{"id": "test3", "sensor": "humidity", "value": 43, "unit": PERCENTAGE}
|
|
||||||
)
|
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
# test state of hum sensor
|
# test state of battery sensor
|
||||||
hum_sensor = hass.states.get("sensor.test3")
|
bat_sensor = hass.states.get("sensor.test3")
|
||||||
assert hum_sensor
|
assert bat_sensor
|
||||||
assert hum_sensor.state == "43"
|
assert bat_sensor.state == "ok"
|
||||||
assert hum_sensor.attributes[ATTR_UNIT_OF_MEASUREMENT] == PERCENTAGE
|
assert ATTR_UNIT_OF_MEASUREMENT not in bat_sensor.attributes
|
||||||
assert hum_sensor.attributes[ATTR_ICON] == "mdi:water-percent"
|
assert bat_sensor.attributes[ATTR_ICON] == "mdi:battery"
|
||||||
|
|
||||||
|
|
||||||
async def test_disable_automatic_add(hass, monkeypatch):
|
async def test_disable_automatic_add(hass, monkeypatch):
|
||||||
|
@ -195,7 +194,7 @@ async def test_aliases(hass, monkeypatch):
|
||||||
)
|
)
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
# test state of new sensor
|
# test state of new sensor
|
||||||
updated_sensor = hass.states.get("sensor.test_02")
|
updated_sensor = hass.states.get("sensor.test_02")
|
||||||
assert updated_sensor
|
assert updated_sensor
|
||||||
assert updated_sensor.state == "65"
|
assert updated_sensor.state == "65"
|
||||||
|
@ -221,11 +220,11 @@ async def test_race_condition(hass, monkeypatch):
|
||||||
|
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
# test state of new sensor
|
# test state of new sensor
|
||||||
updated_sensor = hass.states.get("sensor.test3")
|
updated_sensor = hass.states.get("sensor.test3")
|
||||||
assert updated_sensor
|
assert updated_sensor
|
||||||
|
|
||||||
# test state of new sensor
|
# test state of new sensor
|
||||||
new_sensor = hass.states.get(f"{DOMAIN}.test3")
|
new_sensor = hass.states.get(f"{DOMAIN}.test3")
|
||||||
assert new_sensor
|
assert new_sensor
|
||||||
assert new_sensor.state == "ok"
|
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
|
# tmp_entity must be deleted from EVENT_KEY_COMMAND
|
||||||
assert tmp_entity not in hass.data[DATA_ENTITY_LOOKUP][EVENT_KEY_SENSOR]["test3"]
|
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")
|
new_sensor = hass.states.get(f"{DOMAIN}.test3")
|
||||||
assert new_sensor
|
assert new_sensor
|
||||||
assert new_sensor.state == "ko"
|
assert new_sensor.state == "ko"
|
||||||
|
@ -249,6 +248,14 @@ async def test_sensor_attributes(hass, monkeypatch):
|
||||||
DOMAIN: {
|
DOMAIN: {
|
||||||
"platform": "rflink",
|
"platform": "rflink",
|
||||||
"devices": {
|
"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": {
|
"my_humidity_device_unique_id": {
|
||||||
"name": "humidity_device",
|
"name": "humidity_device",
|
||||||
"sensor_type": "humidity",
|
"sensor_type": "humidity",
|
||||||
|
@ -270,10 +277,22 @@ async def test_sensor_attributes(hass, monkeypatch):
|
||||||
event_callback, _, _, _ = await mock_rflink(hass, config, DOMAIN, monkeypatch)
|
event_callback, _, _, _ = await mock_rflink(hass, config, DOMAIN, monkeypatch)
|
||||||
|
|
||||||
# test sensor loaded from config
|
# 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")
|
humidity_state = hass.states.get("sensor.humidity_device")
|
||||||
assert humidity_state
|
assert humidity_state
|
||||||
assert "device_class" not in humidity_state.attributes
|
assert humidity_state.attributes["device_class"] == SensorDeviceClass.HUMIDITY
|
||||||
assert "state_class" not in humidity_state.attributes
|
assert humidity_state.attributes["state_class"] == SensorStateClass.MEASUREMENT
|
||||||
assert humidity_state.attributes["unit_of_measurement"] == PERCENTAGE
|
assert humidity_state.attributes["unit_of_measurement"] == PERCENTAGE
|
||||||
|
|
||||||
temperature_state = hass.states.get("sensor.temperature_device")
|
temperature_state = hass.states.get("sensor.temperature_device")
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue