mirror of
https://github.com/home-assistant/core.git
synced 2025-07-27 15:17:35 +00:00
Add check that sensor state classes are used only with valid unit of measurements (#141444)
This commit is contained in:
parent
aa493ff97d
commit
f842640249
@ -44,6 +44,7 @@ from .const import ( # noqa: F401
|
|||||||
DEVICE_CLASSES_SCHEMA,
|
DEVICE_CLASSES_SCHEMA,
|
||||||
DOMAIN,
|
DOMAIN,
|
||||||
NON_NUMERIC_DEVICE_CLASSES,
|
NON_NUMERIC_DEVICE_CLASSES,
|
||||||
|
STATE_CLASS_UNITS,
|
||||||
STATE_CLASSES,
|
STATE_CLASSES,
|
||||||
STATE_CLASSES_SCHEMA,
|
STATE_CLASSES_SCHEMA,
|
||||||
UNIT_CONVERTERS,
|
UNIT_CONVERTERS,
|
||||||
@ -713,6 +714,18 @@ class SensorEntity(Entity, cached_properties=CACHED_PROPERTIES_WITH_ATTR_):
|
|||||||
report_issue,
|
report_issue,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Validate unit of measurement used for sensors with a state class
|
||||||
|
if (
|
||||||
|
state_class
|
||||||
|
and (units := STATE_CLASS_UNITS.get(state_class)) is not None
|
||||||
|
and native_unit_of_measurement not in units
|
||||||
|
):
|
||||||
|
raise ValueError(
|
||||||
|
f"Sensor {self.entity_id} ({type(self)}) is using native unit of "
|
||||||
|
f"measurement '{native_unit_of_measurement}' which is not a valid unit "
|
||||||
|
f"for the state class ('{state_class}') it is using; expected one of {units};"
|
||||||
|
)
|
||||||
|
|
||||||
return value
|
return value
|
||||||
|
|
||||||
def _display_precision_or_none(self) -> int | None:
|
def _display_precision_or_none(self) -> int | None:
|
||||||
|
@ -699,3 +699,8 @@ DEVICE_CLASS_STATE_CLASSES: dict[SensorDeviceClass, set[SensorStateClass]] = {
|
|||||||
SensorDeviceClass.WIND_DIRECTION: {SensorStateClass.MEASUREMENT_ANGLE},
|
SensorDeviceClass.WIND_DIRECTION: {SensorStateClass.MEASUREMENT_ANGLE},
|
||||||
SensorDeviceClass.WIND_SPEED: {SensorStateClass.MEASUREMENT},
|
SensorDeviceClass.WIND_SPEED: {SensorStateClass.MEASUREMENT},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
STATE_CLASS_UNITS: dict[SensorStateClass | str, set[type[StrEnum] | str | None]] = {
|
||||||
|
SensorStateClass.MEASUREMENT_ANGLE: {DEGREE},
|
||||||
|
}
|
||||||
|
@ -24,6 +24,7 @@ from homeassistant.components.sensor import (
|
|||||||
async_rounded_state,
|
async_rounded_state,
|
||||||
async_update_suggested_units,
|
async_update_suggested_units,
|
||||||
)
|
)
|
||||||
|
from homeassistant.components.sensor.const import STATE_CLASS_UNITS
|
||||||
from homeassistant.config_entries import ConfigEntry, ConfigFlow
|
from homeassistant.config_entries import ConfigEntry, ConfigFlow
|
||||||
from homeassistant.const import (
|
from homeassistant.const import (
|
||||||
ATTR_UNIT_OF_MEASUREMENT,
|
ATTR_UNIT_OF_MEASUREMENT,
|
||||||
@ -2005,6 +2006,7 @@ async def test_non_numeric_device_class_with_unit_of_measurement(
|
|||||||
SensorDeviceClass.VOLUME,
|
SensorDeviceClass.VOLUME,
|
||||||
SensorDeviceClass.WATER,
|
SensorDeviceClass.WATER,
|
||||||
SensorDeviceClass.WEIGHT,
|
SensorDeviceClass.WEIGHT,
|
||||||
|
SensorDeviceClass.WIND_DIRECTION,
|
||||||
SensorDeviceClass.WIND_SPEED,
|
SensorDeviceClass.WIND_SPEED,
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
@ -2035,6 +2037,37 @@ async def test_device_classes_with_invalid_unit_of_measurement(
|
|||||||
) in caplog.text
|
) in caplog.text
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
"state_class",
|
||||||
|
[SensorStateClass.MEASUREMENT_ANGLE],
|
||||||
|
)
|
||||||
|
async def test_state_classes_with_invalid_unit_of_measurement(
|
||||||
|
hass: HomeAssistant,
|
||||||
|
caplog: pytest.LogCaptureFixture,
|
||||||
|
state_class: SensorStateClass,
|
||||||
|
) -> None:
|
||||||
|
"""Test error when unit of measurement is not valid for used state class."""
|
||||||
|
entity0 = MockSensor(
|
||||||
|
name="Test",
|
||||||
|
native_value="1.0",
|
||||||
|
state_class=state_class,
|
||||||
|
native_unit_of_measurement="INVALID!",
|
||||||
|
)
|
||||||
|
setup_test_component_platform(hass, sensor.DOMAIN, [entity0])
|
||||||
|
units = {
|
||||||
|
str(unit) if unit else "no unit of measurement"
|
||||||
|
for unit in STATE_CLASS_UNITS.get(state_class, set())
|
||||||
|
}
|
||||||
|
assert await async_setup_component(hass, "sensor", {"sensor": {"platform": "test"}})
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
assert (
|
||||||
|
f"Sensor sensor.test ({entity0.__class__}) is using native unit of "
|
||||||
|
"measurement 'INVALID!' which is not a valid unit "
|
||||||
|
f"for the state class ('{state_class}') it is using; expected one of {units};"
|
||||||
|
) in caplog.text
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
("device_class", "state_class", "unit"),
|
("device_class", "state_class", "unit"),
|
||||||
[
|
[
|
||||||
|
Loading…
x
Reference in New Issue
Block a user