Test all device classes in Sensor device condition/trigger tests (#146366)

This commit is contained in:
Abílio Costa 2025-06-09 14:22:58 +01:00 committed by GitHub
parent 46dcc91510
commit 0cce4d1b81
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 104 additions and 32 deletions

View File

@ -5,52 +5,104 @@ from homeassistant.components.sensor import (
SensorDeviceClass,
SensorEntity,
)
from homeassistant.components.sensor.const import DEVICE_CLASS_STATE_CLASSES
from homeassistant.const import (
CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
CONCENTRATION_PARTS_PER_MILLION,
DEGREE,
LIGHT_LUX,
PERCENTAGE,
SIGNAL_STRENGTH_DECIBELS,
UnitOfApparentPower,
UnitOfArea,
UnitOfBloodGlucoseConcentration,
UnitOfConductivity,
UnitOfDataRate,
UnitOfElectricCurrent,
UnitOfElectricPotential,
UnitOfEnergy,
UnitOfEnergyDistance,
UnitOfFrequency,
UnitOfInformation,
UnitOfIrradiance,
UnitOfLength,
UnitOfMass,
UnitOfPower,
UnitOfPrecipitationDepth,
UnitOfPressure,
UnitOfReactiveEnergy,
UnitOfReactivePower,
UnitOfSoundPressure,
UnitOfSpeed,
UnitOfTemperature,
UnitOfTime,
UnitOfVolume,
UnitOfVolumeFlowRate,
UnitOfVolumetricFlux,
)
from tests.common import MockEntity
UNITS_OF_MEASUREMENT = {
SensorDeviceClass.APPARENT_POWER: UnitOfApparentPower.VOLT_AMPERE, # apparent power (VA)
SensorDeviceClass.BATTERY: PERCENTAGE, # % of battery that is left
SensorDeviceClass.CO: CONCENTRATION_PARTS_PER_MILLION, # ppm of CO concentration
SensorDeviceClass.CO2: CONCENTRATION_PARTS_PER_MILLION, # ppm of CO2 concentration
SensorDeviceClass.HUMIDITY: PERCENTAGE, # % of humidity in the air
SensorDeviceClass.ILLUMINANCE: LIGHT_LUX, # current light level lx
SensorDeviceClass.MOISTURE: PERCENTAGE, # % of water in a substance
SensorDeviceClass.NITROGEN_DIOXIDE: CONCENTRATION_MICROGRAMS_PER_CUBIC_METER, # µg/m³ of nitrogen dioxide
SensorDeviceClass.NITROGEN_MONOXIDE: CONCENTRATION_MICROGRAMS_PER_CUBIC_METER, # µg/m³ of nitrogen monoxide
SensorDeviceClass.NITROUS_OXIDE: CONCENTRATION_MICROGRAMS_PER_CUBIC_METER, # µg/m³ of nitrogen oxide
SensorDeviceClass.OZONE: CONCENTRATION_MICROGRAMS_PER_CUBIC_METER, # µg/m³ of ozone
SensorDeviceClass.PM1: CONCENTRATION_MICROGRAMS_PER_CUBIC_METER, # µg/m³ of PM1
SensorDeviceClass.PM10: CONCENTRATION_MICROGRAMS_PER_CUBIC_METER, # µg/m³ of PM10
SensorDeviceClass.PM25: CONCENTRATION_MICROGRAMS_PER_CUBIC_METER, # µg/m³ of PM2.5
SensorDeviceClass.SIGNAL_STRENGTH: SIGNAL_STRENGTH_DECIBELS, # signal strength (dB/dBm)
SensorDeviceClass.SULPHUR_DIOXIDE: CONCENTRATION_MICROGRAMS_PER_CUBIC_METER, # µg/m³ of sulphur dioxide
SensorDeviceClass.TEMPERATURE: "C", # temperature (C/F)
SensorDeviceClass.PRESSURE: UnitOfPressure.HPA, # pressure (hPa/mbar)
SensorDeviceClass.POWER: "kW", # power (W/kW)
SensorDeviceClass.CURRENT: "A", # current (A)
SensorDeviceClass.ENERGY: "kWh", # energy (Wh/kWh/MWh)
SensorDeviceClass.FREQUENCY: UnitOfFrequency.GIGAHERTZ, # energy (Hz/kHz/MHz/GHz)
SensorDeviceClass.POWER_FACTOR: PERCENTAGE, # power factor (no unit, min: -1.0, max: 1.0)
SensorDeviceClass.REACTIVE_ENERGY: UnitOfReactiveEnergy.VOLT_AMPERE_REACTIVE_HOUR, # reactive energy (varh)
SensorDeviceClass.REACTIVE_POWER: UnitOfReactivePower.VOLT_AMPERE_REACTIVE, # reactive power (var)
SensorDeviceClass.VOLATILE_ORGANIC_COMPOUNDS: CONCENTRATION_MICROGRAMS_PER_CUBIC_METER, # µg/m³ of vocs
SensorDeviceClass.VOLTAGE: "V", # voltage (V)
SensorDeviceClass.GAS: UnitOfVolume.CUBIC_METERS, # gas (m³)
SensorDeviceClass.APPARENT_POWER: UnitOfApparentPower.VOLT_AMPERE,
SensorDeviceClass.AQI: None,
SensorDeviceClass.AREA: UnitOfArea.SQUARE_METERS,
SensorDeviceClass.ATMOSPHERIC_PRESSURE: UnitOfPressure.HPA,
SensorDeviceClass.BATTERY: PERCENTAGE,
SensorDeviceClass.BLOOD_GLUCOSE_CONCENTRATION: UnitOfBloodGlucoseConcentration.MILLIGRAMS_PER_DECILITER,
SensorDeviceClass.CO2: CONCENTRATION_PARTS_PER_MILLION,
SensorDeviceClass.CO: CONCENTRATION_PARTS_PER_MILLION,
SensorDeviceClass.CONDUCTIVITY: UnitOfConductivity.SIEMENS_PER_CM,
SensorDeviceClass.CURRENT: UnitOfElectricCurrent.AMPERE,
SensorDeviceClass.DATA_RATE: UnitOfDataRate.BITS_PER_SECOND,
SensorDeviceClass.DATA_SIZE: UnitOfInformation.BYTES,
SensorDeviceClass.DATE: None,
SensorDeviceClass.DISTANCE: UnitOfLength.METERS,
SensorDeviceClass.DURATION: UnitOfTime.SECONDS,
SensorDeviceClass.ENERGY: UnitOfEnergy.KILO_WATT_HOUR,
SensorDeviceClass.ENERGY_DISTANCE: UnitOfEnergyDistance.KILO_WATT_HOUR_PER_100_KM,
SensorDeviceClass.ENERGY_STORAGE: UnitOfEnergy.KILO_WATT_HOUR,
SensorDeviceClass.ENUM: None,
SensorDeviceClass.FREQUENCY: UnitOfFrequency.GIGAHERTZ,
SensorDeviceClass.GAS: UnitOfVolume.CUBIC_METERS,
SensorDeviceClass.HUMIDITY: PERCENTAGE,
SensorDeviceClass.ILLUMINANCE: LIGHT_LUX,
SensorDeviceClass.IRRADIANCE: UnitOfIrradiance.WATTS_PER_SQUARE_METER,
SensorDeviceClass.MOISTURE: PERCENTAGE,
SensorDeviceClass.MONETARY: None,
SensorDeviceClass.NITROGEN_DIOXIDE: CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
SensorDeviceClass.NITROGEN_MONOXIDE: CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
SensorDeviceClass.NITROUS_OXIDE: CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
SensorDeviceClass.OZONE: CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
SensorDeviceClass.PH: None,
SensorDeviceClass.PM10: CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
SensorDeviceClass.PM1: CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
SensorDeviceClass.PM25: CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
SensorDeviceClass.POWER: UnitOfPower.KILO_WATT,
SensorDeviceClass.POWER_FACTOR: PERCENTAGE,
SensorDeviceClass.PRECIPITATION: UnitOfPrecipitationDepth.MILLIMETERS,
SensorDeviceClass.PRECIPITATION_INTENSITY: UnitOfVolumetricFlux.MILLIMETERS_PER_HOUR,
SensorDeviceClass.PRESSURE: UnitOfPressure.HPA,
SensorDeviceClass.REACTIVE_ENERGY: UnitOfReactiveEnergy.VOLT_AMPERE_REACTIVE_HOUR,
SensorDeviceClass.REACTIVE_POWER: UnitOfReactivePower.VOLT_AMPERE_REACTIVE,
SensorDeviceClass.SIGNAL_STRENGTH: SIGNAL_STRENGTH_DECIBELS,
SensorDeviceClass.SOUND_PRESSURE: UnitOfSoundPressure.DECIBEL,
SensorDeviceClass.SPEED: UnitOfSpeed.METERS_PER_SECOND,
SensorDeviceClass.SULPHUR_DIOXIDE: CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
SensorDeviceClass.TEMPERATURE: UnitOfTemperature.CELSIUS,
SensorDeviceClass.TIMESTAMP: None,
SensorDeviceClass.VOLATILE_ORGANIC_COMPOUNDS: CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
SensorDeviceClass.VOLATILE_ORGANIC_COMPOUNDS_PARTS: CONCENTRATION_PARTS_PER_MILLION,
SensorDeviceClass.VOLTAGE: UnitOfElectricPotential.VOLT,
SensorDeviceClass.VOLUME: UnitOfVolume.LITERS,
SensorDeviceClass.VOLUME_FLOW_RATE: UnitOfVolumeFlowRate.LITERS_PER_MINUTE,
SensorDeviceClass.VOLUME_STORAGE: UnitOfVolume.LITERS,
SensorDeviceClass.WATER: UnitOfVolume.LITERS,
SensorDeviceClass.WEIGHT: UnitOfMass.KILOGRAMS,
SensorDeviceClass.WIND_DIRECTION: DEGREE,
SensorDeviceClass.WIND_SPEED: UnitOfSpeed.METERS_PER_SECOND,
}
assert UNITS_OF_MEASUREMENT.keys() == {cls.value for cls in SensorDeviceClass}
class MockSensor(MockEntity, SensorEntity):
@ -118,6 +170,7 @@ def get_mock_sensor_entities() -> dict[str, MockSensor]:
name=f"{device_class} sensor",
unique_id=f"unique_{device_class}",
device_class=device_class,
state_class=DEVICE_CLASS_STATE_CLASSES.get(device_class),
native_unit_of_measurement=UNITS_OF_MEASUREMENT.get(device_class),
)
for device_class in SensorDeviceClass

View File

@ -102,6 +102,11 @@ async def test_get_conditions(
device_id=device_entry.id,
)
DEVICE_CLASSES_WITHOUT_CONDITION = {
SensorDeviceClass.DATE,
SensorDeviceClass.ENUM,
SensorDeviceClass.TIMESTAMP,
}
expected_conditions = [
{
"condition": "device",
@ -113,13 +118,14 @@ async def test_get_conditions(
}
for device_class in SensorDeviceClass
if device_class in UNITS_OF_MEASUREMENT
and device_class not in DEVICE_CLASSES_WITHOUT_CONDITION
for condition in ENTITY_CONDITIONS[device_class]
if device_class != "none"
]
conditions = await async_get_device_automations(
hass, DeviceAutomationType.CONDITION, device_entry.id
)
assert len(conditions) == 28
assert len(conditions) == 54
assert conditions == unordered(expected_conditions)
@ -197,6 +203,14 @@ async def test_get_conditions_no_state(
await hass.async_block_till_done()
IGNORED_DEVICE_CLASSES = {
SensorDeviceClass.DATE, # No condition
SensorDeviceClass.ENUM, # No condition
SensorDeviceClass.TIMESTAMP, # No condition
SensorDeviceClass.AQI, # No unit of measurement
SensorDeviceClass.PH, # No unit of measurement
SensorDeviceClass.MONETARY, # No unit of measurement
}
expected_conditions = [
{
"condition": "device",
@ -208,8 +222,8 @@ async def test_get_conditions_no_state(
}
for device_class in SensorDeviceClass
if device_class in UNITS_OF_MEASUREMENT
and device_class not in IGNORED_DEVICE_CLASSES
for condition in ENTITY_CONDITIONS[device_class]
if device_class != "none"
]
conditions = await async_get_device_automations(
hass, DeviceAutomationType.CONDITION, device_entry.id

View File

@ -104,6 +104,11 @@ async def test_get_triggers(
device_id=device_entry.id,
)
DEVICE_CLASSES_WITHOUT_TRIGGER = {
SensorDeviceClass.DATE,
SensorDeviceClass.ENUM,
SensorDeviceClass.TIMESTAMP,
}
expected_triggers = [
{
"platform": "device",
@ -115,13 +120,13 @@ async def test_get_triggers(
}
for device_class in SensorDeviceClass
if device_class in UNITS_OF_MEASUREMENT
and device_class not in DEVICE_CLASSES_WITHOUT_TRIGGER
for trigger in ENTITY_TRIGGERS[device_class]
if device_class != "none"
]
triggers = await async_get_device_automations(
hass, DeviceAutomationType.TRIGGER, device_entry.id
)
assert len(triggers) == 28
assert len(triggers) == 54
assert triggers == unordered(expected_triggers)