Allow customizing sensor state precision (#86074)
* Allow customizing sensor precision * Don't convert integer strings to floats * Tweak converting sensor state to number * Drop default rounding to 2 decimals * Adjust test * Tweak rounding, improve test coverage * Don't convert to a number if not necessary * Raise if native_precision is set and state is not numeric * Address review comments * Address comments, simplify * Don't call property twice * Make exception more helpful
This commit is contained in:
parent
ba63a9600e
commit
086a6460ef
4 changed files with 445 additions and 94 deletions
|
@ -41,23 +41,29 @@ from tests.common import mock_restore_cache_with_extra_data
|
|||
UnitOfTemperature.FAHRENHEIT,
|
||||
UnitOfTemperature.FAHRENHEIT,
|
||||
100,
|
||||
100,
|
||||
"100",
|
||||
),
|
||||
(
|
||||
US_CUSTOMARY_SYSTEM,
|
||||
UnitOfTemperature.CELSIUS,
|
||||
UnitOfTemperature.FAHRENHEIT,
|
||||
38,
|
||||
100,
|
||||
"100",
|
||||
),
|
||||
(
|
||||
METRIC_SYSTEM,
|
||||
UnitOfTemperature.FAHRENHEIT,
|
||||
UnitOfTemperature.CELSIUS,
|
||||
100,
|
||||
38,
|
||||
"38",
|
||||
),
|
||||
(
|
||||
METRIC_SYSTEM,
|
||||
UnitOfTemperature.CELSIUS,
|
||||
UnitOfTemperature.CELSIUS,
|
||||
38,
|
||||
"38",
|
||||
),
|
||||
(METRIC_SYSTEM, UnitOfTemperature.CELSIUS, UnitOfTemperature.CELSIUS, 38, 38),
|
||||
],
|
||||
)
|
||||
async def test_temperature_conversion(
|
||||
|
@ -85,7 +91,7 @@ async def test_temperature_conversion(
|
|||
await hass.async_block_till_done()
|
||||
|
||||
state = hass.states.get(entity0.entity_id)
|
||||
assert float(state.state) == approx(float(state_value))
|
||||
assert state.state == state_value
|
||||
assert state.attributes[ATTR_UNIT_OF_MEASUREMENT] == state_unit
|
||||
|
||||
|
||||
|
@ -407,7 +413,7 @@ async def test_restore_sensor_restore_state(
|
|||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"device_class,native_unit,custom_unit,state_unit,native_value,custom_value",
|
||||
"device_class, native_unit, custom_unit, state_unit, native_value, custom_state",
|
||||
[
|
||||
# Smaller to larger unit, InHg is ~33x larger than hPa -> 1 more decimal
|
||||
(
|
||||
|
@ -416,7 +422,7 @@ async def test_restore_sensor_restore_state(
|
|||
UnitOfPressure.INHG,
|
||||
UnitOfPressure.INHG,
|
||||
1000.0,
|
||||
29.53,
|
||||
"29.53",
|
||||
),
|
||||
(
|
||||
SensorDeviceClass.PRESSURE,
|
||||
|
@ -424,7 +430,15 @@ async def test_restore_sensor_restore_state(
|
|||
UnitOfPressure.HPA,
|
||||
UnitOfPressure.HPA,
|
||||
1.234,
|
||||
12.34,
|
||||
"12.340",
|
||||
),
|
||||
(
|
||||
SensorDeviceClass.ATMOSPHERIC_PRESSURE,
|
||||
UnitOfPressure.HPA,
|
||||
UnitOfPressure.MMHG,
|
||||
UnitOfPressure.MMHG,
|
||||
1000,
|
||||
"750",
|
||||
),
|
||||
(
|
||||
SensorDeviceClass.PRESSURE,
|
||||
|
@ -432,7 +446,7 @@ async def test_restore_sensor_restore_state(
|
|||
UnitOfPressure.MMHG,
|
||||
UnitOfPressure.MMHG,
|
||||
1000,
|
||||
750,
|
||||
"750",
|
||||
),
|
||||
# Not a supported pressure unit
|
||||
(
|
||||
|
@ -441,7 +455,7 @@ async def test_restore_sensor_restore_state(
|
|||
"peer_pressure",
|
||||
UnitOfPressure.HPA,
|
||||
1000,
|
||||
1000,
|
||||
"1000",
|
||||
),
|
||||
(
|
||||
SensorDeviceClass.TEMPERATURE,
|
||||
|
@ -449,7 +463,7 @@ async def test_restore_sensor_restore_state(
|
|||
UnitOfTemperature.FAHRENHEIT,
|
||||
UnitOfTemperature.FAHRENHEIT,
|
||||
37.5,
|
||||
99.5,
|
||||
"99.5",
|
||||
),
|
||||
(
|
||||
SensorDeviceClass.TEMPERATURE,
|
||||
|
@ -457,7 +471,7 @@ async def test_restore_sensor_restore_state(
|
|||
UnitOfTemperature.CELSIUS,
|
||||
UnitOfTemperature.CELSIUS,
|
||||
100,
|
||||
38.0,
|
||||
"38",
|
||||
),
|
||||
],
|
||||
)
|
||||
|
@ -469,7 +483,7 @@ async def test_custom_unit(
|
|||
custom_unit,
|
||||
state_unit,
|
||||
native_value,
|
||||
custom_value,
|
||||
custom_state,
|
||||
):
|
||||
"""Test custom unit."""
|
||||
entity_registry = er.async_get(hass)
|
||||
|
@ -495,12 +509,184 @@ async def test_custom_unit(
|
|||
await hass.async_block_till_done()
|
||||
|
||||
state = hass.states.get(entity0.entity_id)
|
||||
assert float(state.state) == approx(float(custom_value))
|
||||
assert state.state == custom_state
|
||||
assert state.attributes[ATTR_UNIT_OF_MEASUREMENT] == state_unit
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"native_unit,custom_unit,state_unit,native_value,custom_value,device_class",
|
||||
"device_class,native_unit,custom_unit,native_value,native_precision,default_state,custom_state",
|
||||
[
|
||||
(
|
||||
SensorDeviceClass.ATMOSPHERIC_PRESSURE,
|
||||
UnitOfPressure.HPA,
|
||||
UnitOfPressure.INHG,
|
||||
1000.0,
|
||||
2,
|
||||
"1000.00", # Native precision is 2
|
||||
"29.530", # One digit of precision added when converting
|
||||
),
|
||||
(
|
||||
SensorDeviceClass.ATMOSPHERIC_PRESSURE,
|
||||
UnitOfPressure.INHG,
|
||||
UnitOfPressure.HPA,
|
||||
29.9211,
|
||||
3,
|
||||
"29.921", # Native precision is 3
|
||||
"1013.24", # One digit of precision removed when converting
|
||||
),
|
||||
],
|
||||
)
|
||||
async def test_native_precision_scaling(
|
||||
hass,
|
||||
enable_custom_integrations,
|
||||
device_class,
|
||||
native_unit,
|
||||
custom_unit,
|
||||
native_value,
|
||||
native_precision,
|
||||
default_state,
|
||||
custom_state,
|
||||
):
|
||||
"""Test native precision is influenced by unit conversion."""
|
||||
entity_registry = er.async_get(hass)
|
||||
|
||||
entry = entity_registry.async_get_or_create("sensor", "test", "very_unique")
|
||||
platform = getattr(hass.components, "test.sensor")
|
||||
platform.init(empty=True)
|
||||
platform.ENTITIES["0"] = platform.MockSensor(
|
||||
name="Test",
|
||||
native_value=str(native_value),
|
||||
native_precision=native_precision,
|
||||
native_unit_of_measurement=native_unit,
|
||||
device_class=device_class,
|
||||
unique_id="very_unique",
|
||||
)
|
||||
|
||||
entity0 = platform.ENTITIES["0"]
|
||||
assert await async_setup_component(hass, "sensor", {"sensor": {"platform": "test"}})
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state = hass.states.get(entity0.entity_id)
|
||||
assert state.state == default_state
|
||||
assert state.attributes[ATTR_UNIT_OF_MEASUREMENT] == native_unit
|
||||
|
||||
entity_registry.async_update_entity_options(
|
||||
entry.entity_id, "sensor", {"unit_of_measurement": custom_unit}
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state = hass.states.get(entity0.entity_id)
|
||||
assert state.state == custom_state
|
||||
assert state.attributes[ATTR_UNIT_OF_MEASUREMENT] == custom_unit
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"device_class,native_unit,custom_precision,native_value,default_state,custom_state",
|
||||
[
|
||||
(
|
||||
SensorDeviceClass.ATMOSPHERIC_PRESSURE,
|
||||
UnitOfPressure.HPA,
|
||||
4,
|
||||
1000.0,
|
||||
"1000.000",
|
||||
"1000.0000",
|
||||
),
|
||||
],
|
||||
)
|
||||
async def test_custom_precision_native_precision(
|
||||
hass,
|
||||
enable_custom_integrations,
|
||||
device_class,
|
||||
native_unit,
|
||||
custom_precision,
|
||||
native_value,
|
||||
default_state,
|
||||
custom_state,
|
||||
):
|
||||
"""Test custom precision."""
|
||||
entity_registry = er.async_get(hass)
|
||||
|
||||
entry = entity_registry.async_get_or_create("sensor", "test", "very_unique")
|
||||
platform = getattr(hass.components, "test.sensor")
|
||||
platform.init(empty=True)
|
||||
platform.ENTITIES["0"] = platform.MockSensor(
|
||||
name="Test",
|
||||
native_value=str(native_value),
|
||||
native_precision=3,
|
||||
native_unit_of_measurement=native_unit,
|
||||
device_class=device_class,
|
||||
unique_id="very_unique",
|
||||
)
|
||||
|
||||
entity0 = platform.ENTITIES["0"]
|
||||
assert await async_setup_component(hass, "sensor", {"sensor": {"platform": "test"}})
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state = hass.states.get(entity0.entity_id)
|
||||
assert state.state == default_state
|
||||
assert state.attributes[ATTR_UNIT_OF_MEASUREMENT] == native_unit
|
||||
|
||||
entity_registry.async_update_entity_options(
|
||||
entry.entity_id, "sensor", {"precision": custom_precision}
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state = hass.states.get(entity0.entity_id)
|
||||
assert state.state == custom_state
|
||||
assert state.attributes[ATTR_UNIT_OF_MEASUREMENT] == native_unit
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"device_class,native_unit,custom_precision,native_value,custom_state",
|
||||
[
|
||||
(
|
||||
SensorDeviceClass.ATMOSPHERIC_PRESSURE,
|
||||
UnitOfPressure.HPA,
|
||||
4,
|
||||
1000.0,
|
||||
"1000.0000",
|
||||
),
|
||||
],
|
||||
)
|
||||
async def test_custom_precision_no_native_precision(
|
||||
hass,
|
||||
enable_custom_integrations,
|
||||
device_class,
|
||||
native_unit,
|
||||
custom_precision,
|
||||
native_value,
|
||||
custom_state,
|
||||
):
|
||||
"""Test custom precision."""
|
||||
entity_registry = er.async_get(hass)
|
||||
|
||||
entry = entity_registry.async_get_or_create("sensor", "test", "very_unique")
|
||||
entity_registry.async_update_entity_options(
|
||||
entry.entity_id, "sensor", {"precision": custom_precision}
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
platform = getattr(hass.components, "test.sensor")
|
||||
platform.init(empty=True)
|
||||
platform.ENTITIES["0"] = platform.MockSensor(
|
||||
name="Test",
|
||||
native_value=str(native_value),
|
||||
native_unit_of_measurement=native_unit,
|
||||
device_class=device_class,
|
||||
unique_id="very_unique",
|
||||
)
|
||||
|
||||
entity0 = platform.ENTITIES["0"]
|
||||
assert await async_setup_component(hass, "sensor", {"sensor": {"platform": "test"}})
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state = hass.states.get(entity0.entity_id)
|
||||
assert state.state == custom_state
|
||||
assert state.attributes[ATTR_UNIT_OF_MEASUREMENT] == native_unit
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"native_unit, custom_unit, state_unit, native_value, native_state, custom_state, device_class",
|
||||
[
|
||||
# Distance
|
||||
(
|
||||
|
@ -508,7 +694,8 @@ async def test_custom_unit(
|
|||
UnitOfLength.MILES,
|
||||
UnitOfLength.MILES,
|
||||
1000,
|
||||
621,
|
||||
"1000",
|
||||
"621",
|
||||
SensorDeviceClass.DISTANCE,
|
||||
),
|
||||
(
|
||||
|
@ -516,7 +703,8 @@ async def test_custom_unit(
|
|||
UnitOfLength.INCHES,
|
||||
UnitOfLength.INCHES,
|
||||
7.24,
|
||||
2.85,
|
||||
"7.24",
|
||||
"2.85",
|
||||
SensorDeviceClass.DISTANCE,
|
||||
),
|
||||
(
|
||||
|
@ -524,7 +712,8 @@ async def test_custom_unit(
|
|||
"peer_distance",
|
||||
UnitOfLength.KILOMETERS,
|
||||
1000,
|
||||
1000,
|
||||
"1000",
|
||||
"1000",
|
||||
SensorDeviceClass.DISTANCE,
|
||||
),
|
||||
# Energy
|
||||
|
@ -533,7 +722,8 @@ async def test_custom_unit(
|
|||
UnitOfEnergy.MEGA_WATT_HOUR,
|
||||
UnitOfEnergy.MEGA_WATT_HOUR,
|
||||
1000,
|
||||
1.0,
|
||||
"1000",
|
||||
"1.000",
|
||||
SensorDeviceClass.ENERGY,
|
||||
),
|
||||
(
|
||||
|
@ -541,7 +731,8 @@ async def test_custom_unit(
|
|||
UnitOfEnergy.MEGA_WATT_HOUR,
|
||||
UnitOfEnergy.MEGA_WATT_HOUR,
|
||||
1000,
|
||||
278,
|
||||
"1000",
|
||||
"278",
|
||||
SensorDeviceClass.ENERGY,
|
||||
),
|
||||
(
|
||||
|
@ -549,7 +740,8 @@ async def test_custom_unit(
|
|||
"BTU",
|
||||
UnitOfEnergy.KILO_WATT_HOUR,
|
||||
1000,
|
||||
1000,
|
||||
"1000",
|
||||
"1000",
|
||||
SensorDeviceClass.ENERGY,
|
||||
),
|
||||
# Power factor
|
||||
|
@ -558,7 +750,8 @@ async def test_custom_unit(
|
|||
PERCENTAGE,
|
||||
PERCENTAGE,
|
||||
1.0,
|
||||
100,
|
||||
"1.0",
|
||||
"100.0",
|
||||
SensorDeviceClass.POWER_FACTOR,
|
||||
),
|
||||
(
|
||||
|
@ -566,7 +759,8 @@ async def test_custom_unit(
|
|||
None,
|
||||
None,
|
||||
100,
|
||||
1,
|
||||
"100",
|
||||
"1.00",
|
||||
SensorDeviceClass.POWER_FACTOR,
|
||||
),
|
||||
(
|
||||
|
@ -574,7 +768,8 @@ async def test_custom_unit(
|
|||
None,
|
||||
"Cos φ",
|
||||
1.0,
|
||||
1.0,
|
||||
"1.0",
|
||||
"1.0",
|
||||
SensorDeviceClass.POWER_FACTOR,
|
||||
),
|
||||
# Pressure
|
||||
|
@ -584,7 +779,8 @@ async def test_custom_unit(
|
|||
UnitOfPressure.INHG,
|
||||
UnitOfPressure.INHG,
|
||||
1000.0,
|
||||
29.53,
|
||||
"1000.0",
|
||||
"29.53",
|
||||
SensorDeviceClass.PRESSURE,
|
||||
),
|
||||
(
|
||||
|
@ -592,7 +788,8 @@ async def test_custom_unit(
|
|||
UnitOfPressure.HPA,
|
||||
UnitOfPressure.HPA,
|
||||
1.234,
|
||||
12.34,
|
||||
"1.234",
|
||||
"12.340",
|
||||
SensorDeviceClass.PRESSURE,
|
||||
),
|
||||
(
|
||||
|
@ -600,7 +797,8 @@ async def test_custom_unit(
|
|||
UnitOfPressure.MMHG,
|
||||
UnitOfPressure.MMHG,
|
||||
1000,
|
||||
750,
|
||||
"1000",
|
||||
"750",
|
||||
SensorDeviceClass.PRESSURE,
|
||||
),
|
||||
# Not a supported pressure unit
|
||||
|
@ -609,7 +807,8 @@ async def test_custom_unit(
|
|||
"peer_pressure",
|
||||
UnitOfPressure.HPA,
|
||||
1000,
|
||||
1000,
|
||||
"1000",
|
||||
"1000",
|
||||
SensorDeviceClass.PRESSURE,
|
||||
),
|
||||
# Speed
|
||||
|
@ -618,7 +817,8 @@ async def test_custom_unit(
|
|||
UnitOfSpeed.MILES_PER_HOUR,
|
||||
UnitOfSpeed.MILES_PER_HOUR,
|
||||
100,
|
||||
62,
|
||||
"100",
|
||||
"62",
|
||||
SensorDeviceClass.SPEED,
|
||||
),
|
||||
(
|
||||
|
@ -626,7 +826,8 @@ async def test_custom_unit(
|
|||
UnitOfVolumetricFlux.INCHES_PER_HOUR,
|
||||
UnitOfVolumetricFlux.INCHES_PER_HOUR,
|
||||
78,
|
||||
0.13,
|
||||
"78",
|
||||
"0.13",
|
||||
SensorDeviceClass.SPEED,
|
||||
),
|
||||
(
|
||||
|
@ -634,7 +835,8 @@ async def test_custom_unit(
|
|||
"peer_distance",
|
||||
UnitOfSpeed.KILOMETERS_PER_HOUR,
|
||||
100,
|
||||
100,
|
||||
"100",
|
||||
"100",
|
||||
SensorDeviceClass.SPEED,
|
||||
),
|
||||
# Volume
|
||||
|
@ -643,7 +845,8 @@ async def test_custom_unit(
|
|||
UnitOfVolume.CUBIC_FEET,
|
||||
UnitOfVolume.CUBIC_FEET,
|
||||
100,
|
||||
3531,
|
||||
"100",
|
||||
"3531",
|
||||
SensorDeviceClass.VOLUME,
|
||||
),
|
||||
(
|
||||
|
@ -651,7 +854,8 @@ async def test_custom_unit(
|
|||
UnitOfVolume.FLUID_OUNCES,
|
||||
UnitOfVolume.FLUID_OUNCES,
|
||||
2.3,
|
||||
77.8,
|
||||
"2.3",
|
||||
"77.8",
|
||||
SensorDeviceClass.VOLUME,
|
||||
),
|
||||
(
|
||||
|
@ -659,7 +863,8 @@ async def test_custom_unit(
|
|||
"peer_distance",
|
||||
UnitOfVolume.CUBIC_METERS,
|
||||
100,
|
||||
100,
|
||||
"100",
|
||||
"100",
|
||||
SensorDeviceClass.VOLUME,
|
||||
),
|
||||
# Weight
|
||||
|
@ -668,7 +873,8 @@ async def test_custom_unit(
|
|||
UnitOfMass.OUNCES,
|
||||
UnitOfMass.OUNCES,
|
||||
100,
|
||||
3.5,
|
||||
"100",
|
||||
"3.5",
|
||||
SensorDeviceClass.WEIGHT,
|
||||
),
|
||||
(
|
||||
|
@ -676,7 +882,8 @@ async def test_custom_unit(
|
|||
UnitOfMass.GRAMS,
|
||||
UnitOfMass.GRAMS,
|
||||
78,
|
||||
2211,
|
||||
"78",
|
||||
"2211",
|
||||
SensorDeviceClass.WEIGHT,
|
||||
),
|
||||
(
|
||||
|
@ -684,7 +891,8 @@ async def test_custom_unit(
|
|||
"peer_distance",
|
||||
UnitOfMass.GRAMS,
|
||||
100,
|
||||
100,
|
||||
"100",
|
||||
"100",
|
||||
SensorDeviceClass.WEIGHT,
|
||||
),
|
||||
],
|
||||
|
@ -696,7 +904,8 @@ async def test_custom_unit_change(
|
|||
custom_unit,
|
||||
state_unit,
|
||||
native_value,
|
||||
custom_value,
|
||||
native_state,
|
||||
custom_state,
|
||||
device_class,
|
||||
):
|
||||
"""Test custom unit changes are picked up."""
|
||||
|
@ -716,7 +925,7 @@ async def test_custom_unit_change(
|
|||
await hass.async_block_till_done()
|
||||
|
||||
state = hass.states.get(entity0.entity_id)
|
||||
assert float(state.state) == approx(float(native_value))
|
||||
assert state.state == native_state
|
||||
assert state.attributes.get(ATTR_UNIT_OF_MEASUREMENT) == native_unit
|
||||
|
||||
entity_registry.async_update_entity_options(
|
||||
|
@ -725,7 +934,7 @@ async def test_custom_unit_change(
|
|||
await hass.async_block_till_done()
|
||||
|
||||
state = hass.states.get(entity0.entity_id)
|
||||
assert float(state.state) == approx(float(custom_value))
|
||||
assert state.state == custom_state
|
||||
assert state.attributes.get(ATTR_UNIT_OF_MEASUREMENT) == state_unit
|
||||
|
||||
entity_registry.async_update_entity_options(
|
||||
|
@ -734,19 +943,19 @@ async def test_custom_unit_change(
|
|||
await hass.async_block_till_done()
|
||||
|
||||
state = hass.states.get(entity0.entity_id)
|
||||
assert float(state.state) == approx(float(native_value))
|
||||
assert state.state == native_state
|
||||
assert state.attributes.get(ATTR_UNIT_OF_MEASUREMENT) == native_unit
|
||||
|
||||
entity_registry.async_update_entity_options("sensor.test", "sensor", None)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state = hass.states.get(entity0.entity_id)
|
||||
assert float(state.state) == approx(float(native_value))
|
||||
assert state.state == native_state
|
||||
assert state.attributes.get(ATTR_UNIT_OF_MEASUREMENT) == native_unit
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"unit_system, native_unit, automatic_unit, suggested_unit, custom_unit, native_value, automatic_value, suggested_value, custom_value, device_class",
|
||||
"unit_system, native_unit, automatic_unit, suggested_unit, custom_unit, native_value, native_state, automatic_state, suggested_state, custom_state, device_class",
|
||||
[
|
||||
# Distance
|
||||
(
|
||||
|
@ -756,9 +965,10 @@ async def test_custom_unit_change(
|
|||
UnitOfLength.METERS,
|
||||
UnitOfLength.YARDS,
|
||||
1000,
|
||||
621,
|
||||
1000000,
|
||||
1093613,
|
||||
"1000",
|
||||
"621",
|
||||
"1000000",
|
||||
"1093613",
|
||||
SensorDeviceClass.DISTANCE,
|
||||
),
|
||||
],
|
||||
|
@ -772,9 +982,10 @@ async def test_unit_conversion_priority(
|
|||
suggested_unit,
|
||||
custom_unit,
|
||||
native_value,
|
||||
automatic_value,
|
||||
suggested_value,
|
||||
custom_value,
|
||||
native_state,
|
||||
automatic_state,
|
||||
suggested_state,
|
||||
custom_state,
|
||||
device_class,
|
||||
):
|
||||
"""Test priority of unit conversion."""
|
||||
|
@ -826,7 +1037,7 @@ async def test_unit_conversion_priority(
|
|||
|
||||
# Registered entity -> Follow automatic unit conversion
|
||||
state = hass.states.get(entity0.entity_id)
|
||||
assert float(state.state) == approx(float(automatic_value))
|
||||
assert state.state == automatic_state
|
||||
assert state.attributes[ATTR_UNIT_OF_MEASUREMENT] == automatic_unit
|
||||
# Assert the automatic unit conversion is stored in the registry
|
||||
entry = entity_registry.async_get(entity0.entity_id)
|
||||
|
@ -836,12 +1047,12 @@ async def test_unit_conversion_priority(
|
|||
|
||||
# Unregistered entity -> Follow native unit
|
||||
state = hass.states.get(entity1.entity_id)
|
||||
assert float(state.state) == approx(float(native_value))
|
||||
assert state.state == native_state
|
||||
assert state.attributes[ATTR_UNIT_OF_MEASUREMENT] == native_unit
|
||||
|
||||
# Registered entity with suggested unit
|
||||
state = hass.states.get(entity2.entity_id)
|
||||
assert float(state.state) == approx(float(suggested_value))
|
||||
assert state.state == suggested_state
|
||||
assert state.attributes[ATTR_UNIT_OF_MEASUREMENT] == suggested_unit
|
||||
# Assert the suggested unit is stored in the registry
|
||||
entry = entity_registry.async_get(entity2.entity_id)
|
||||
|
@ -851,7 +1062,7 @@ async def test_unit_conversion_priority(
|
|||
|
||||
# Unregistered entity with suggested unit
|
||||
state = hass.states.get(entity3.entity_id)
|
||||
assert float(state.state) == approx(float(suggested_value))
|
||||
assert state.state == suggested_state
|
||||
assert state.attributes[ATTR_UNIT_OF_MEASUREMENT] == suggested_unit
|
||||
|
||||
# Set a custom unit, this should have priority over the automatic unit conversion
|
||||
|
@ -861,7 +1072,7 @@ async def test_unit_conversion_priority(
|
|||
await hass.async_block_till_done()
|
||||
|
||||
state = hass.states.get(entity0.entity_id)
|
||||
assert float(state.state) == approx(float(custom_value))
|
||||
assert state.state == custom_state
|
||||
assert state.attributes[ATTR_UNIT_OF_MEASUREMENT] == custom_unit
|
||||
|
||||
entity_registry.async_update_entity_options(
|
||||
|
@ -870,7 +1081,7 @@ async def test_unit_conversion_priority(
|
|||
await hass.async_block_till_done()
|
||||
|
||||
state = hass.states.get(entity2.entity_id)
|
||||
assert float(state.state) == approx(float(custom_value))
|
||||
assert state.state == custom_state
|
||||
assert state.attributes[ATTR_UNIT_OF_MEASUREMENT] == custom_unit
|
||||
|
||||
|
||||
|
@ -964,7 +1175,7 @@ async def test_unit_conversion_priority_suggested_unit_change(
|
|||
UnitOfLength.KILOMETERS,
|
||||
UnitOfLength.MILES,
|
||||
1000,
|
||||
621,
|
||||
621.0,
|
||||
SensorDeviceClass.DISTANCE,
|
||||
),
|
||||
(
|
||||
|
@ -1219,7 +1430,7 @@ async def test_device_classes_with_invalid_unit_of_measurement(
|
|||
(date(2012, 11, 10), "2012-11-10"),
|
||||
],
|
||||
)
|
||||
async def test_non_numeric_validation(
|
||||
async def test_non_numeric_validation_warn(
|
||||
hass: HomeAssistant,
|
||||
caplog: pytest.LogCaptureFixture,
|
||||
enable_custom_integrations: None,
|
||||
|
@ -1253,6 +1464,51 @@ async def test_non_numeric_validation(
|
|||
) in caplog.text
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"device_class,state_class,unit,precision", ((None, None, None, 1),)
|
||||
)
|
||||
@pytest.mark.parametrize(
|
||||
"native_value,expected",
|
||||
[
|
||||
("abc", "abc"),
|
||||
("13.7.1", "13.7.1"),
|
||||
(datetime(2012, 11, 10, 7, 35, 1), "2012-11-10 07:35:01"),
|
||||
(date(2012, 11, 10), "2012-11-10"),
|
||||
],
|
||||
)
|
||||
async def test_non_numeric_validation_raise(
|
||||
hass: HomeAssistant,
|
||||
caplog: pytest.LogCaptureFixture,
|
||||
enable_custom_integrations: None,
|
||||
native_value: Any,
|
||||
expected: str,
|
||||
device_class: SensorDeviceClass | None,
|
||||
state_class: SensorStateClass | None,
|
||||
unit: str | None,
|
||||
precision,
|
||||
) -> None:
|
||||
"""Test error on expected numeric entities."""
|
||||
platform = getattr(hass.components, "test.sensor")
|
||||
platform.init(empty=True)
|
||||
platform.ENTITIES["0"] = platform.MockSensor(
|
||||
name="Test",
|
||||
device_class=device_class,
|
||||
native_precision=precision,
|
||||
native_unit_of_measurement=unit,
|
||||
native_value=native_value,
|
||||
state_class=state_class,
|
||||
)
|
||||
entity0 = platform.ENTITIES["0"]
|
||||
|
||||
assert await async_setup_component(hass, "sensor", {"sensor": {"platform": "test"}})
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state = hass.states.get(entity0.entity_id)
|
||||
assert state is None
|
||||
|
||||
assert ("Error adding entities for domain sensor with platform test") in caplog.text
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"device_class,state_class,unit",
|
||||
[
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue