mirror of
https://github.com/home-assistant/core.git
synced 2025-07-19 19:27:45 +00:00
Avoid duplicate property calls when writing sensor state (#101853)
* Avoid duplicate attribute lookups when writing sensor state _numeric_state_expected would call self.device_class, self.state_class, self.native_unit_of_measurement, and self.suggested_display_precision a second time when the `state` path already had these values. * one more * avoid another
This commit is contained in:
parent
f0317f0d59
commit
6ce5f190c1
@ -150,6 +150,28 @@ class SensorEntityDescription(EntityDescription):
|
|||||||
unit_of_measurement: None = None # Type override, use native_unit_of_measurement
|
unit_of_measurement: None = None # Type override, use native_unit_of_measurement
|
||||||
|
|
||||||
|
|
||||||
|
def _numeric_state_expected(
|
||||||
|
device_class: SensorDeviceClass | None,
|
||||||
|
state_class: SensorStateClass | str | None,
|
||||||
|
native_unit_of_measurement: str | None,
|
||||||
|
suggested_display_precision: int | None,
|
||||||
|
) -> bool:
|
||||||
|
"""Return true if the sensor must be numeric."""
|
||||||
|
# Note: the order of the checks needs to be kept aligned
|
||||||
|
# with the checks in `state` property.
|
||||||
|
if device_class in NON_NUMERIC_DEVICE_CLASSES:
|
||||||
|
return False
|
||||||
|
if (
|
||||||
|
state_class is not None
|
||||||
|
or native_unit_of_measurement is not None
|
||||||
|
or suggested_display_precision is not None
|
||||||
|
):
|
||||||
|
return True
|
||||||
|
# Sensors with custom device classes will have the device class
|
||||||
|
# converted to None and are not considered numeric
|
||||||
|
return device_class is not None
|
||||||
|
|
||||||
|
|
||||||
class SensorEntity(Entity):
|
class SensorEntity(Entity):
|
||||||
"""Base class for sensor entities."""
|
"""Base class for sensor entities."""
|
||||||
|
|
||||||
@ -284,20 +306,12 @@ class SensorEntity(Entity):
|
|||||||
@property
|
@property
|
||||||
def _numeric_state_expected(self) -> bool:
|
def _numeric_state_expected(self) -> bool:
|
||||||
"""Return true if the sensor must be numeric."""
|
"""Return true if the sensor must be numeric."""
|
||||||
# Note: the order of the checks needs to be kept aligned
|
return _numeric_state_expected(
|
||||||
# with the checks in `state` property.
|
try_parse_enum(SensorDeviceClass, self.device_class),
|
||||||
device_class = try_parse_enum(SensorDeviceClass, self.device_class)
|
self.state_class,
|
||||||
if device_class in NON_NUMERIC_DEVICE_CLASSES:
|
self.native_unit_of_measurement,
|
||||||
return False
|
self.suggested_display_precision,
|
||||||
if (
|
)
|
||||||
self.state_class is not None
|
|
||||||
or self.native_unit_of_measurement is not None
|
|
||||||
or self.suggested_display_precision is not None
|
|
||||||
):
|
|
||||||
return True
|
|
||||||
# Sensors with custom device classes will have the device class
|
|
||||||
# converted to None and are not considered numeric
|
|
||||||
return device_class is not None
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def options(self) -> list[str] | None:
|
def options(self) -> list[str] | None:
|
||||||
@ -377,10 +391,8 @@ class SensorEntity(Entity):
|
|||||||
def state_attributes(self) -> dict[str, Any] | None:
|
def state_attributes(self) -> dict[str, Any] | None:
|
||||||
"""Return state attributes."""
|
"""Return state attributes."""
|
||||||
if last_reset := self.last_reset:
|
if last_reset := self.last_reset:
|
||||||
if (
|
state_class = self.state_class
|
||||||
self.state_class != SensorStateClass.TOTAL
|
if state_class != SensorStateClass.TOTAL and not self._last_reset_reported:
|
||||||
and not self._last_reset_reported
|
|
||||||
):
|
|
||||||
self._last_reset_reported = True
|
self._last_reset_reported = True
|
||||||
report_issue = self._suggest_report_issue()
|
report_issue = self._suggest_report_issue()
|
||||||
# This should raise in Home Assistant Core 2022.5
|
# This should raise in Home Assistant Core 2022.5
|
||||||
@ -393,11 +405,11 @@ class SensorEntity(Entity):
|
|||||||
),
|
),
|
||||||
self.entity_id,
|
self.entity_id,
|
||||||
type(self),
|
type(self),
|
||||||
self.state_class,
|
state_class,
|
||||||
report_issue,
|
report_issue,
|
||||||
)
|
)
|
||||||
|
|
||||||
if self.state_class == SensorStateClass.TOTAL:
|
if state_class == SensorStateClass.TOTAL:
|
||||||
return {ATTR_LAST_RESET: last_reset.isoformat()}
|
return {ATTR_LAST_RESET: last_reset.isoformat()}
|
||||||
|
|
||||||
return None
|
return None
|
||||||
@ -470,9 +482,9 @@ class SensorEntity(Entity):
|
|||||||
native_unit_of_measurement = self.native_unit_of_measurement
|
native_unit_of_measurement = self.native_unit_of_measurement
|
||||||
|
|
||||||
if (
|
if (
|
||||||
self.device_class == SensorDeviceClass.TEMPERATURE
|
native_unit_of_measurement
|
||||||
and native_unit_of_measurement
|
|
||||||
in {UnitOfTemperature.CELSIUS, UnitOfTemperature.FAHRENHEIT}
|
in {UnitOfTemperature.CELSIUS, UnitOfTemperature.FAHRENHEIT}
|
||||||
|
and self.device_class == SensorDeviceClass.TEMPERATURE
|
||||||
):
|
):
|
||||||
return self.hass.config.units.temperature_unit
|
return self.hass.config.units.temperature_unit
|
||||||
|
|
||||||
@ -590,7 +602,9 @@ class SensorEntity(Entity):
|
|||||||
|
|
||||||
# If the sensor has neither a device class, a state class, a unit of measurement
|
# If the sensor has neither a device class, a state class, a unit of measurement
|
||||||
# nor a precision then there are no further checks or conversions
|
# nor a precision then there are no further checks or conversions
|
||||||
if not self._numeric_state_expected:
|
if not _numeric_state_expected(
|
||||||
|
device_class, state_class, native_unit_of_measurement, suggested_precision
|
||||||
|
):
|
||||||
return value
|
return value
|
||||||
|
|
||||||
# From here on a numerical value is expected
|
# From here on a numerical value is expected
|
||||||
|
Loading…
x
Reference in New Issue
Block a user