Avoid more device_class lookups for number entities when writing state (#102381)

This commit is contained in:
J. Nick Koston 2023-10-22 11:55:13 -10:00 committed by GitHub
parent a97e34f28e
commit b980ed3eac
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 44 additions and 7 deletions

View File

@ -218,8 +218,13 @@ class NumberEntity(Entity):
@property
def capability_attributes(self) -> dict[str, Any]:
"""Return capability attributes."""
min_value = self.min_value
max_value = self.max_value
device_class = self.device_class
min_value = self._convert_to_state_value(
self.native_min_value, floor_decimal, device_class
)
max_value = self._convert_to_state_value(
self.native_max_value, ceil_decimal, device_class
)
return {
ATTR_MIN: min_value,
ATTR_MAX: max_value,
@ -259,7 +264,9 @@ class NumberEntity(Entity):
@final
def min_value(self) -> float:
"""Return the minimum value."""
return self._convert_to_state_value(self.native_min_value, floor_decimal)
return self._convert_to_state_value(
self.native_min_value, floor_decimal, self.device_class
)
@property
def native_max_value(self) -> float:
@ -277,7 +284,9 @@ class NumberEntity(Entity):
@final
def max_value(self) -> float:
"""Return the maximum value."""
return self._convert_to_state_value(self.native_max_value, ceil_decimal)
return self._convert_to_state_value(
self.native_max_value, ceil_decimal, self.device_class
)
@property
def native_step(self) -> float | None:
@ -365,7 +374,7 @@ class NumberEntity(Entity):
"""Return the entity value to represent the entity state."""
if (native_value := self.native_value) is None:
return native_value
return self._convert_to_state_value(native_value, round)
return self._convert_to_state_value(native_value, round, self.device_class)
def set_native_value(self, value: float) -> None:
"""Set new value."""
@ -386,12 +395,15 @@ class NumberEntity(Entity):
await self.hass.async_add_executor_job(self.set_value, value)
def _convert_to_state_value(
self, value: float, method: Callable[[float, int], float]
self,
value: float,
method: Callable[[float, int], float],
device_class: NumberDeviceClass | None,
) -> float:
"""Convert a value in the number's native unit to the configured unit."""
# device_class is checked first since most of the time we can avoid
# the unit conversion
if (device_class := self.device_class) not in UNIT_CONVERTERS:
if device_class not in UNIT_CONVERTERS:
return value
native_unit_of_measurement = self.native_unit_of_measurement

View File

@ -8,6 +8,7 @@ import pytest
from homeassistant.components.number import (
ATTR_MAX,
ATTR_MIN,
ATTR_MODE,
ATTR_STEP,
ATTR_VALUE,
DOMAIN,
@ -227,6 +228,12 @@ async def test_attributes(hass: HomeAssistant) -> None:
assert number.step == 1.0
assert number.unit_of_measurement is None
assert number.value == 0.5
assert number.capability_attributes == {
ATTR_MAX: 100.0,
ATTR_MIN: 0.0,
ATTR_MODE: NumberMode.AUTO,
ATTR_STEP: 1.0,
}
number_2 = MockNumberEntity()
number_2.hass = hass
@ -235,6 +242,12 @@ async def test_attributes(hass: HomeAssistant) -> None:
assert number_2.step == 0.1
assert number_2.unit_of_measurement == "native_cats"
assert number_2.value == 0.5
assert number_2.capability_attributes == {
ATTR_MAX: 0.5,
ATTR_MIN: -0.5,
ATTR_MODE: NumberMode.AUTO,
ATTR_STEP: 0.1,
}
number_3 = MockNumberEntityAttr()
number_3.hass = hass
@ -243,6 +256,12 @@ async def test_attributes(hass: HomeAssistant) -> None:
assert number_3.step == 100.0
assert number_3.unit_of_measurement == "native_dogs"
assert number_3.value == 500.0
assert number_3.capability_attributes == {
ATTR_MAX: 1000.0,
ATTR_MIN: -1000.0,
ATTR_MODE: NumberMode.AUTO,
ATTR_STEP: 100.0,
}
number_4 = MockNumberEntityDescr()
number_4.hass = hass
@ -251,6 +270,12 @@ async def test_attributes(hass: HomeAssistant) -> None:
assert number_4.step == 2.0
assert number_4.unit_of_measurement == "native_rabbits"
assert number_4.value is None
assert number_4.capability_attributes == {
ATTR_MAX: 10.0,
ATTR_MIN: -10.0,
ATTR_MODE: NumberMode.AUTO,
ATTR_STEP: 2.0,
}
async def test_sync_set_value(hass: HomeAssistant) -> None: