Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions homeassistant/components/climate/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -373,7 +373,7 @@ def state_attributes(self) -> dict[str, Any]:
}

if ClimateEntityFeature.TARGET_TEMPERATURE in supported_features:
data[ClimateEntityStateAttribute.TEMPERATURE] = show_temp(
data[ClimateEntityStateAttribute.TARGET_TEMPERATURE] = show_temp(
hass,
self.target_temperature,
temperature_unit,
Expand All @@ -392,7 +392,7 @@ def state_attributes(self) -> dict[str, Any]:
data[ClimateEntityStateAttribute.CURRENT_HUMIDITY] = current_humidity

if ClimateEntityFeature.TARGET_HUMIDITY in supported_features:
data[ClimateEntityStateAttribute.HUMIDITY] = self.target_humidity
data[ClimateEntityStateAttribute.TARGET_HUMIDITY] = self.target_humidity

if ClimateEntityFeature.FAN_MODE in supported_features:
data[ClimateEntityStateAttribute.FAN_MODE] = self.fan_mode
Expand Down
9 changes: 5 additions & 4 deletions homeassistant/components/climate/condition.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ class ClimateTargetTemperatureCondition(EntityNumericalConditionWithUnitBase):

_base_unit = UnitOfTemperature.CELSIUS
_domain_specs = {
DOMAIN: DomainSpec(value_source=ClimateEntityStateAttribute.TEMPERATURE)
DOMAIN: DomainSpec(value_source=ClimateEntityStateAttribute.TARGET_TEMPERATURE)
}
_unit_converter = TemperatureConverter

Expand All @@ -67,7 +67,7 @@ def _should_include(self, state: State) -> bool:
"""Skip climate entities that do not expose a target temperature."""
return (
super()._should_include(state)
and state.attributes.get(ClimateEntityStateAttribute.TEMPERATURE)
and state.attributes.get(ClimateEntityStateAttribute.TARGET_TEMPERATURE)
is not None
)

Expand All @@ -82,7 +82,7 @@ class ClimateTargetHumidityCondition(EntityNumericalConditionBase):
"""Condition for climate target humidity."""

_domain_specs = {
DOMAIN: DomainSpec(value_source=ClimateEntityStateAttribute.HUMIDITY)
DOMAIN: DomainSpec(value_source=ClimateEntityStateAttribute.TARGET_HUMIDITY)
}
_valid_unit = "%"

Expand All @@ -91,7 +91,8 @@ def _should_include(self, state: State) -> bool:
"""Skip climate entities that do not expose a target humidity."""
return (
super()._should_include(state)
and state.attributes.get(ClimateEntityStateAttribute.HUMIDITY) is not None
and state.attributes.get(ClimateEntityStateAttribute.TARGET_HUMIDITY)
is not None
)


Expand Down
17 changes: 14 additions & 3 deletions homeassistant/components/climate/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

from enum import IntFlag, StrEnum

from homeassistant.helpers.deprecation import EnumWithDeprecatedMembers


class HVACMode(StrEnum):
"""HVAC mode for climate devices."""
Expand Down Expand Up @@ -153,15 +155,24 @@ class ClimateEntityCapabilityAttribute(StrEnum):
SWING_HORIZONTAL_MODES = "swing_horizontal_modes"


class ClimateEntityStateAttribute(StrEnum):
class ClimateEntityStateAttribute(
StrEnum,
metaclass=EnumWithDeprecatedMembers,
deprecated={
"TEMPERATURE": ("ClimateEntityStateAttribute.TARGET_TEMPERATURE", "2027.2.0"),
"HUMIDITY": ("ClimateEntityStateAttribute.TARGET_HUMIDITY", "2027.2.0"),
},
):
"""State attributes for climate entities."""

CURRENT_TEMPERATURE = "current_temperature"
TEMPERATURE = "temperature"
TARGET_TEMPERATURE = "temperature"
TEMPERATURE = "temperature" # Deprecated, replaced with TARGET_TEMPERATURE
TARGET_TEMP_HIGH = "target_temp_high"
TARGET_TEMP_LOW = "target_temp_low"
CURRENT_HUMIDITY = "current_humidity"
HUMIDITY = "humidity"
TARGET_HUMIDITY = "humidity"
HUMIDITY = "humidity" # Deprecated, replaced with TARGET_HUMIDITY
FAN_MODE = "fan_mode"
HVAC_ACTION = "hvac_action"
PRESET_MODE = "preset_mode"
Expand Down
14 changes: 8 additions & 6 deletions homeassistant/components/climate/reproduce_state.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,14 @@

# Maps a state attribute to the service call argument used to restore it.
_STATE_ATTRIBUTE_TO_SERVICE_ARG: dict[ClimateEntityStateAttribute, str] = {
ClimateEntityStateAttribute.TEMPERATURE: ATTR_TEMPERATURE,
ClimateEntityStateAttribute.TARGET_TEMPERATURE: ATTR_TEMPERATURE,
ClimateEntityStateAttribute.TARGET_TEMP_HIGH: ATTR_TARGET_TEMP_HIGH,
ClimateEntityStateAttribute.TARGET_TEMP_LOW: ATTR_TARGET_TEMP_LOW,
ClimateEntityStateAttribute.PRESET_MODE: ATTR_PRESET_MODE,
ClimateEntityStateAttribute.SWING_MODE: ATTR_SWING_MODE,
ClimateEntityStateAttribute.SWING_HORIZONTAL_MODE: ATTR_SWING_HORIZONTAL_MODE,
ClimateEntityStateAttribute.FAN_MODE: ATTR_FAN_MODE,
ClimateEntityStateAttribute.HUMIDITY: ATTR_HUMIDITY,
ClimateEntityStateAttribute.TARGET_HUMIDITY: ATTR_HUMIDITY,
}


Expand Down Expand Up @@ -70,15 +70,15 @@ async def call_service(
await call_service(SERVICE_SET_HVAC_MODE, [], {ATTR_HVAC_MODE: state.state})

if (
state.attributes.get(ClimateEntityStateAttribute.TEMPERATURE) is not None
state.attributes.get(ClimateEntityStateAttribute.TARGET_TEMPERATURE) is not None
or state.attributes.get(ClimateEntityStateAttribute.TARGET_TEMP_HIGH)
is not None
or state.attributes.get(ClimateEntityStateAttribute.TARGET_TEMP_LOW) is not None
):
await call_service(
SERVICE_SET_TEMPERATURE,
[
ClimateEntityStateAttribute.TEMPERATURE,
ClimateEntityStateAttribute.TARGET_TEMPERATURE,
ClimateEntityStateAttribute.TARGET_TEMP_HIGH,
ClimateEntityStateAttribute.TARGET_TEMP_LOW,
],
Expand Down Expand Up @@ -116,8 +116,10 @@ async def call_service(
):
await call_service(SERVICE_SET_FAN_MODE, [ClimateEntityStateAttribute.FAN_MODE])

if ClimateEntityStateAttribute.HUMIDITY in state.attributes:
await call_service(SERVICE_SET_HUMIDITY, [ClimateEntityStateAttribute.HUMIDITY])
if ClimateEntityStateAttribute.TARGET_HUMIDITY in state.attributes:
await call_service(
SERVICE_SET_HUMIDITY, [ClimateEntityStateAttribute.TARGET_HUMIDITY]
)


async def async_reproduce_states(
Expand Down
8 changes: 4 additions & 4 deletions homeassistant/components/climate/significant_change.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,14 @@
ClimateEntityStateAttribute.CURRENT_HUMIDITY,
ClimateEntityStateAttribute.CURRENT_TEMPERATURE,
ClimateEntityStateAttribute.FAN_MODE,
ClimateEntityStateAttribute.HUMIDITY,
ClimateEntityStateAttribute.TARGET_HUMIDITY,
ClimateEntityStateAttribute.HVAC_ACTION,
ClimateEntityStateAttribute.PRESET_MODE,
ClimateEntityStateAttribute.SWING_MODE,
ClimateEntityStateAttribute.SWING_HORIZONTAL_MODE,
ClimateEntityStateAttribute.TARGET_TEMP_HIGH,
ClimateEntityStateAttribute.TARGET_TEMP_LOW,
ClimateEntityStateAttribute.TEMPERATURE,
ClimateEntityStateAttribute.TARGET_TEMPERATURE,
}


Expand Down Expand Up @@ -74,7 +74,7 @@ def async_check_significant_change(
ClimateEntityStateAttribute.CURRENT_TEMPERATURE,
ClimateEntityStateAttribute.TARGET_TEMP_HIGH,
ClimateEntityStateAttribute.TARGET_TEMP_LOW,
ClimateEntityStateAttribute.TEMPERATURE,
ClimateEntityStateAttribute.TARGET_TEMPERATURE,
]:
if ha_unit == UnitOfTemperature.FAHRENHEIT:
absolute_change = 1.0
Expand All @@ -83,7 +83,7 @@ def async_check_significant_change(

if attr_name in [
ClimateEntityStateAttribute.CURRENT_HUMIDITY,
ClimateEntityStateAttribute.HUMIDITY,
ClimateEntityStateAttribute.TARGET_HUMIDITY,
]:
absolute_change = 1.0

Expand Down
9 changes: 5 additions & 4 deletions homeassistant/components/climate/trigger.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ class _ClimateTargetTemperatureTriggerMixin(EntityNumericalStateTriggerWithUnitB

_base_unit = UnitOfTemperature.CELSIUS
_domain_specs = {
DOMAIN: DomainSpec(value_source=ClimateEntityStateAttribute.TEMPERATURE)
DOMAIN: DomainSpec(value_source=ClimateEntityStateAttribute.TARGET_TEMPERATURE)
}
_unit_converter = TemperatureConverter

Expand All @@ -65,7 +65,7 @@ def _should_include(self, state: State) -> bool:
"""Skip climate entities that do not expose a target temperature."""
return (
super()._should_include(state)
and state.attributes.get(ClimateEntityStateAttribute.TEMPERATURE)
and state.attributes.get(ClimateEntityStateAttribute.TARGET_TEMPERATURE)
is not None
)

Expand Down Expand Up @@ -94,7 +94,7 @@ class _ClimateTargetHumidityTriggerMixin(EntityNumericalStateTriggerBase):
"""Mixin for climate target humidity triggers."""

_domain_specs = {
DOMAIN: DomainSpec(value_source=ClimateEntityStateAttribute.HUMIDITY)
DOMAIN: DomainSpec(value_source=ClimateEntityStateAttribute.TARGET_HUMIDITY)
}
_valid_unit = "%"

Expand All @@ -103,7 +103,8 @@ def _should_include(self, state: State) -> bool:
"""Skip climate entities that do not expose a target humidity."""
return (
super()._should_include(state)
and state.attributes.get(ClimateEntityStateAttribute.HUMIDITY) is not None
and state.attributes.get(ClimateEntityStateAttribute.TARGET_HUMIDITY)
is not None
)


Expand Down
8 changes: 6 additions & 2 deletions homeassistant/components/generic_thermostat/climate.py
Original file line number Diff line number Diff line change
Expand Up @@ -352,7 +352,9 @@ def _async_startup(_: Event | None = None) -> None:
if self._target_temp is None:
# If we have a previously saved temperature
if (
old_state.attributes.get(ClimateEntityStateAttribute.TEMPERATURE)
old_state.attributes.get(
ClimateEntityStateAttribute.TARGET_TEMPERATURE
)
is None
):
if self.ac_mode:
Expand All @@ -365,7 +367,9 @@ def _async_startup(_: Event | None = None) -> None:
)
else:
self._target_temp = float(
old_state.attributes[ClimateEntityStateAttribute.TEMPERATURE]
old_state.attributes[
ClimateEntityStateAttribute.TARGET_TEMPERATURE
]
)
if (
self.preset_modes
Expand Down
6 changes: 4 additions & 2 deletions homeassistant/components/modbus/climate.py
Original file line number Diff line number Diff line change
Expand Up @@ -315,9 +315,11 @@ async def async_added_to_hass(self) -> None:
"""Handle entity which will be added."""
await self.async_base_added_to_hass()
state = await self.async_get_last_state()
if state and state.attributes.get(ClimateEntityStateAttribute.TEMPERATURE):
if state and state.attributes.get(
ClimateEntityStateAttribute.TARGET_TEMPERATURE
):
self._attr_target_temperature = float(
state.attributes[ClimateEntityStateAttribute.TEMPERATURE]
state.attributes[ClimateEntityStateAttribute.TARGET_TEMPERATURE]
)

@override
Expand Down
2 changes: 1 addition & 1 deletion homeassistant/components/prometheus/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -831,7 +831,7 @@ def _handle_light(self, state: State) -> None:
def _handle_climate(self, state: State) -> None:
self._temperature_metric(
state,
ClimateEntityStateAttribute.TEMPERATURE,
ClimateEntityStateAttribute.TARGET_TEMPERATURE,
"climate_target_temperature_celsius",
"Target temperature in degrees Celsius",
)
Expand Down
3 changes: 2 additions & 1 deletion homeassistant/components/switchbot_cloud/climate.py
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,8 @@ async def async_added_to_hass(self) -> None:
ClimateEntityStateAttribute.FAN_MODE, self._attr_fan_mode
)
self._attr_target_temperature = last_state.attributes.get(
ClimateEntityStateAttribute.TEMPERATURE, self._attr_target_temperature
ClimateEntityStateAttribute.TARGET_TEMPERATURE,
self._attr_target_temperature,
)

def _get_mode(self, hvac_mode: HVACMode | None) -> int:
Expand Down
4 changes: 2 additions & 2 deletions homeassistant/components/teslemetry/climate.py
Original file line number Diff line number Diff line change
Expand Up @@ -292,7 +292,7 @@ async def async_added_to_hass(self) -> None:
ClimateEntityStateAttribute.CURRENT_TEMPERATURE
)
self._attr_target_temperature = state.attributes.get(
ClimateEntityStateAttribute.TEMPERATURE
ClimateEntityStateAttribute.TARGET_TEMPERATURE
)
self._attr_preset_mode = state.attributes.get(
ClimateEntityStateAttribute.PRESET_MODE
Expand Down Expand Up @@ -542,7 +542,7 @@ async def async_added_to_hass(self) -> None:
ClimateEntityStateAttribute.CURRENT_TEMPERATURE
)
self._attr_target_temperature = state.attributes.get(
ClimateEntityStateAttribute.TEMPERATURE
ClimateEntityStateAttribute.TARGET_TEMPERATURE
)

self.async_on_remove(
Expand Down
4 changes: 2 additions & 2 deletions tests/components/actron_air/snapshots/test_climate.ambr
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@
<ClimateEntityCapabilityAttribute.MAX_TEMP: 'max_temp'>: 30,
<ClimateEntityCapabilityAttribute.MIN_TEMP: 'min_temp'>: 16,
<EntityStateAttribute.SUPPORTED_FEATURES: 'supported_features'>: <ClimateEntityFeature: 385>,
<ClimateEntityStateAttribute.TEMPERATURE: 'temperature'>: 24.0,
<ClimateEntityStateAttribute.TARGET_TEMPERATURE: 'temperature'>: 24.0,
}),
'context': <ANY>,
'entity_id': 'climate.living_room_living_room',
Expand Down Expand Up @@ -148,7 +148,7 @@
<ClimateEntityCapabilityAttribute.MAX_TEMP: 'max_temp'>: 30.0,
<ClimateEntityCapabilityAttribute.MIN_TEMP: 'min_temp'>: 16.0,
<EntityStateAttribute.SUPPORTED_FEATURES: 'supported_features'>: <ClimateEntityFeature: 393>,
<ClimateEntityStateAttribute.TEMPERATURE: 'temperature'>: 24.0,
<ClimateEntityStateAttribute.TARGET_TEMPERATURE: 'temperature'>: 24.0,
}),
'context': <ANY>,
'entity_id': 'climate.test_system',
Expand Down
2 changes: 1 addition & 1 deletion tests/components/airobot/snapshots/test_climate.ambr
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@
'boost',
]),
<EntityStateAttribute.SUPPORTED_FEATURES: 'supported_features'>: <ClimateEntityFeature: 17>,
<ClimateEntityStateAttribute.TEMPERATURE: 'temperature'>: 22.0,
<ClimateEntityStateAttribute.TARGET_TEMPERATURE: 'temperature'>: 22.0,
}),
'context': <ANY>,
'entity_id': 'climate.test_thermostat',
Expand Down
2 changes: 1 addition & 1 deletion tests/components/airpatrol/snapshots/test_climate.ambr
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@
'on',
'off',
]),
<ClimateEntityStateAttribute.TEMPERATURE: 'temperature'>: 22.0,
<ClimateEntityStateAttribute.TARGET_TEMPERATURE: 'temperature'>: 22.0,
}),
'context': <ANY>,
'entity_id': 'climate.living_room',
Expand Down
2 changes: 1 addition & 1 deletion tests/components/balboa/snapshots/test_climate.ambr
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@
'rest',
]),
<EntityStateAttribute.SUPPORTED_FEATURES: 'supported_features'>: <ClimateEntityFeature: 401>,
<ClimateEntityStateAttribute.TEMPERATURE: 'temperature'>: 40.0,
<ClimateEntityStateAttribute.TARGET_TEMPERATURE: 'temperature'>: 40.0,
}),
'context': <ANY>,
'entity_id': 'climate.fakespa',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@
<EntityStateAttribute.SUPPORTED_FEATURES: 'supported_features'>: <ClimateEntityFeature: 395>,
<ClimateEntityStateAttribute.TARGET_TEMP_HIGH: 'target_temp_high'>: None,
<ClimateEntityStateAttribute.TARGET_TEMP_LOW: 'target_temp_low'>: None,
<ClimateEntityStateAttribute.TEMPERATURE: 'temperature'>: 72,
<ClimateEntityStateAttribute.TARGET_TEMPERATURE: 'temperature'>: 72,
}),
'context': <ANY>,
'entity_id': 'climate.system_1_zone_1',
Expand Down
4 changes: 2 additions & 2 deletions tests/components/bsblan/snapshots/test_climate.ambr
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@
'none',
]),
<EntityStateAttribute.SUPPORTED_FEATURES: 'supported_features'>: <ClimateEntityFeature: 401>,
<ClimateEntityStateAttribute.TEMPERATURE: 'temperature'>: 18.5,
<ClimateEntityStateAttribute.TARGET_TEMPERATURE: 'temperature'>: 18.5,
}),
'context': <ANY>,
'entity_id': 'climate.heating_circuit_1',
Expand Down Expand Up @@ -145,7 +145,7 @@
'none',
]),
<EntityStateAttribute.SUPPORTED_FEATURES: 'supported_features'>: <ClimateEntityFeature: 401>,
<ClimateEntityStateAttribute.TEMPERATURE: 'temperature'>: 18.5,
<ClimateEntityStateAttribute.TARGET_TEMPERATURE: 'temperature'>: 18.5,
}),
'context': <ANY>,
'entity_id': 'climate.heating_circuit_1',
Expand Down
4 changes: 2 additions & 2 deletions tests/components/ccm15/snapshots/test_climate.ambr
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@
'on',
]),
<ClimateEntityCapabilityAttribute.TARGET_TEMP_STEP: 'target_temp_step'>: 1,
<ClimateEntityStateAttribute.TEMPERATURE: 'temperature'>: 23,
<ClimateEntityStateAttribute.TARGET_TEMPERATURE: 'temperature'>: 23,
}),
'context': <ANY>,
'entity_id': 'climate.midea_0',
Expand Down Expand Up @@ -187,7 +187,7 @@
'on',
]),
<ClimateEntityCapabilityAttribute.TARGET_TEMP_STEP: 'target_temp_step'>: 1,
<ClimateEntityStateAttribute.TEMPERATURE: 'temperature'>: 24,
<ClimateEntityStateAttribute.TARGET_TEMPERATURE: 'temperature'>: 24,
}),
'context': <ANY>,
'entity_id': 'climate.midea_1',
Expand Down
2 changes: 1 addition & 1 deletion tests/components/comelit/snapshots/test_climate.ambr
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@
]),
<EntityStateAttribute.SUPPORTED_FEATURES: 'supported_features'>: <ClimateEntityFeature: 401>,
<ClimateEntityCapabilityAttribute.TARGET_TEMP_STEP: 'target_temp_step'>: 0.1,
<ClimateEntityStateAttribute.TEMPERATURE: 'temperature'>: 5.0,
<ClimateEntityStateAttribute.TARGET_TEMPERATURE: 'temperature'>: 5.0,
}),
'context': <ANY>,
'entity_id': 'climate.climate0',
Expand Down
2 changes: 1 addition & 1 deletion tests/components/compit/snapshots/test_climate.ambr
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@
'away',
]),
<EntityStateAttribute.SUPPORTED_FEATURES: 'supported_features'>: <ClimateEntityFeature: 25>,
<ClimateEntityStateAttribute.TEMPERATURE: 'temperature'>: 22.0,
<ClimateEntityStateAttribute.TARGET_TEMPERATURE: 'temperature'>: 22.0,
}),
'context': <ANY>,
'entity_id': 'climate.nano_color_2',
Expand Down
Loading
Loading