1
0
mirror of https://github.com/home-assistant/core.git synced 2026-05-08 17:49:37 +01:00

Exclude incompatible entities from temperature automations (#169901)

This commit is contained in:
Erik Montnemery
2026-05-06 13:10:53 +02:00
committed by GitHub
parent 52e1d9443c
commit 5f1201dbbe
4 changed files with 50 additions and 0 deletions
@@ -46,6 +46,21 @@ class TemperatureCondition(EntityNumericalConditionWithUnitBase):
_domain_specs = TEMPERATURE_DOMAIN_SPECS
_unit_converter = TemperatureConverter
def _should_include(self, state: State) -> bool:
"""Skip attribute-source entities that lack the temperature attribute.
Mirrors the temperature trigger: for climate / water_heater /
weather (attribute-based), the entity is filtered when the source
attribute is absent; sensor entities (state-value-based) fall
through to the base impl.
"""
if not super()._should_include(state):
return False
domain_spec = self._domain_specs[state.domain]
if domain_spec.value_source is None:
return True
return state.attributes.get(domain_spec.value_source) is not None
def _get_entity_unit(self, entity_state: State) -> str | None:
"""Get the temperature unit of an entity from its state."""
if entity_state.domain == SENSOR_DOMAIN:
@@ -46,6 +46,23 @@ class _TemperatureTriggerMixin(EntityNumericalStateTriggerWithUnitBase):
_domain_specs = TEMPERATURE_DOMAIN_SPECS
_unit_converter = TemperatureConverter
def _should_include(self, state: State) -> bool:
"""Skip attribute-source entities that lack the temperature attribute.
For domains whose tracked value comes from an attribute
(climate / water_heater / weather), require the attribute to be
present; otherwise the all/count check would treat an entity that
cannot report a temperature as a non-match and block behavior=last.
Sensor entities source their value from `state.state`, so they
fall through to the base impl.
"""
if not super()._should_include(state):
return False
domain_spec = self._domain_specs[state.domain]
if domain_spec.value_source is None:
return True
return state.attributes.get(domain_spec.value_source) is not None
def _get_entity_unit(self, state: State) -> str | None:
"""Get the temperature unit of an entity from its state."""
if state.domain == SENSOR_DOMAIN:
@@ -180,6 +180,7 @@ async def test_temperature_sensor_condition_behavior_all(
HVACMode.AUTO,
"current_temperature",
threshold_unit=UnitOfTemperature.CELSIUS,
attribute_required=True,
),
)
async def test_temperature_climate_condition_behavior_any(
@@ -217,6 +218,7 @@ async def test_temperature_climate_condition_behavior_any(
HVACMode.AUTO,
"current_temperature",
threshold_unit=UnitOfTemperature.CELSIUS,
attribute_required=True,
),
)
async def test_temperature_climate_condition_behavior_all(
@@ -254,6 +256,7 @@ async def test_temperature_climate_condition_behavior_all(
"eco",
"current_temperature",
threshold_unit=UnitOfTemperature.CELSIUS,
attribute_required=True,
),
)
async def test_temperature_water_heater_condition_behavior_any(
@@ -291,6 +294,7 @@ async def test_temperature_water_heater_condition_behavior_any(
"eco",
"current_temperature",
threshold_unit=UnitOfTemperature.CELSIUS,
attribute_required=True,
),
)
async def test_temperature_water_heater_condition_behavior_all(
@@ -329,6 +333,7 @@ async def test_temperature_water_heater_condition_behavior_all(
"temperature",
threshold_unit=UnitOfTemperature.CELSIUS,
unit_attributes=_WEATHER_UNIT_ATTRIBUTES,
attribute_required=True,
),
)
async def test_temperature_weather_condition_behavior_any(
@@ -367,6 +372,7 @@ async def test_temperature_weather_condition_behavior_any(
"temperature",
threshold_unit=UnitOfTemperature.CELSIUS,
unit_attributes=_WEATHER_UNIT_ATTRIBUTES,
attribute_required=True,
),
)
async def test_temperature_weather_condition_behavior_all(
@@ -263,12 +263,14 @@ async def test_temperature_trigger_sensor_crossed_threshold_behavior_last(
HVACMode.AUTO,
CLIMATE_ATTR_CURRENT_TEMPERATURE,
threshold_unit=UnitOfTemperature.CELSIUS,
attribute_required=True,
),
*parametrize_numerical_attribute_crossed_threshold_trigger_states(
"temperature.crossed_threshold",
HVACMode.AUTO,
CLIMATE_ATTR_CURRENT_TEMPERATURE,
threshold_unit=UnitOfTemperature.CELSIUS,
attribute_required=True,
),
],
)
@@ -308,6 +310,7 @@ async def test_temperature_trigger_climate_behavior_any(
HVACMode.AUTO,
CLIMATE_ATTR_CURRENT_TEMPERATURE,
threshold_unit=UnitOfTemperature.CELSIUS,
attribute_required=True,
),
],
)
@@ -347,6 +350,7 @@ async def test_temperature_trigger_climate_crossed_threshold_behavior_first(
HVACMode.AUTO,
CLIMATE_ATTR_CURRENT_TEMPERATURE,
threshold_unit=UnitOfTemperature.CELSIUS,
attribute_required=True,
),
],
)
@@ -389,12 +393,14 @@ async def test_temperature_trigger_climate_crossed_threshold_behavior_last(
"eco",
WATER_HEATER_ATTR_CURRENT_TEMPERATURE,
threshold_unit=UnitOfTemperature.CELSIUS,
attribute_required=True,
),
*parametrize_numerical_attribute_crossed_threshold_trigger_states(
"temperature.crossed_threshold",
"eco",
WATER_HEATER_ATTR_CURRENT_TEMPERATURE,
threshold_unit=UnitOfTemperature.CELSIUS,
attribute_required=True,
),
],
)
@@ -434,6 +440,7 @@ async def test_temperature_trigger_water_heater_behavior_any(
"eco",
WATER_HEATER_ATTR_CURRENT_TEMPERATURE,
threshold_unit=UnitOfTemperature.CELSIUS,
attribute_required=True,
),
],
)
@@ -473,6 +480,7 @@ async def test_temperature_trigger_water_heater_crossed_threshold_behavior_first
"eco",
WATER_HEATER_ATTR_CURRENT_TEMPERATURE,
threshold_unit=UnitOfTemperature.CELSIUS,
attribute_required=True,
),
],
)
@@ -516,6 +524,7 @@ async def test_temperature_trigger_water_heater_crossed_threshold_behavior_last(
ATTR_WEATHER_TEMPERATURE,
threshold_unit=UnitOfTemperature.CELSIUS,
unit_attributes=_WEATHER_UNIT_ATTRIBUTES,
attribute_required=True,
),
*parametrize_numerical_attribute_crossed_threshold_trigger_states(
"temperature.crossed_threshold",
@@ -523,6 +532,7 @@ async def test_temperature_trigger_water_heater_crossed_threshold_behavior_last(
ATTR_WEATHER_TEMPERATURE,
threshold_unit=UnitOfTemperature.CELSIUS,
unit_attributes=_WEATHER_UNIT_ATTRIBUTES,
attribute_required=True,
),
],
)
@@ -563,6 +573,7 @@ async def test_temperature_trigger_weather_behavior_any(
ATTR_WEATHER_TEMPERATURE,
threshold_unit=UnitOfTemperature.CELSIUS,
unit_attributes=_WEATHER_UNIT_ATTRIBUTES,
attribute_required=True,
),
],
)
@@ -603,6 +614,7 @@ async def test_temperature_trigger_weather_crossed_threshold_behavior_first(
ATTR_WEATHER_TEMPERATURE,
threshold_unit=UnitOfTemperature.CELSIUS,
unit_attributes=_WEATHER_UNIT_ATTRIBUTES,
attribute_required=True,
),
],
)