Skip to content

Commit

Permalink
Fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
gjohansson-ST committed Aug 14, 2024
1 parent c30a623 commit 0aa8088
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 43 deletions.
61 changes: 34 additions & 27 deletions homeassistant/components/climate/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -304,7 +304,7 @@ class ClimateEntity(Entity, cached_properties=CACHED_PROPERTIES_WITH_ATTR_):
_attr_target_humidity: float | None = None
_attr_target_temperature_high: float | None
_attr_target_temperature_low: float | None
_attr_min_temperature_range: float | None = None
_attr_min_temperature_range: float | None
_attr_target_temperature_step: float | None = None
_attr_target_temperature: float | None = None
_attr_temperature_unit: str
Expand Down Expand Up @@ -962,33 +962,40 @@ async def async_service_temperature_set(
kwargs[value] = temp

if (
(min_temp_range := entity.min_temperature_range)
and (low_temp := kwargs.get(ATTR_TARGET_TEMP_LOW))
and (high_temp := kwargs.get(ATTR_TARGET_TEMP_HIGH))
and high_temp - low_temp < min_temp_range
hasattr(entity, "min_temperature_range")
and (min_temp_range := entity.min_temperature_range)
and (target_low_temp := kwargs.get(ATTR_TARGET_TEMP_LOW))
and (target_high_temp := kwargs.get(ATTR_TARGET_TEMP_HIGH))
and (target_high_temp - target_low_temp) < min_temp_range
):
# Ensure there is a minimum gap from the new temp.
new_high_temp = high_temp
new_low_temp = low_temp
if (
entity.target_temperature_high
and abs(high_temp - entity.target_temperature_high) < 0.01
):
new_high_temp = low_temp + min_temp_range
else:
new_low_temp = high_temp - min_temp_range

if new_high_temp > (max_temp := entity.max_temp):
diff = new_high_temp - max_temp
new_high_temp -= diff
new_low_temp -= diff
elif new_low_temp < (min_temp := entity.min_temp):
diff = min_temp - new_low_temp
new_high_temp += diff
new_low_temp += diff

kwargs[ATTR_TARGET_TEMP_HIGH] = new_high_temp
kwargs[ATTR_TARGET_TEMP_LOW] = new_low_temp
# Ensure target_low_temp is not higher than target_high_temp.
if target_low_temp > target_high_temp:
raise ServiceValidationError(
translation_domain=DOMAIN,
translation_key="low_temp_higher_than_high_temp",
translation_placeholders={
"min_temp": str(target_low_temp),
"max_temp": str(target_high_temp),
},
)
# Ensure deadband between target temperatures.
if (target_high_temp - target_low_temp) < min_temp_range:
target_low_temp = target_high_temp - min_temp_range

# Guard target_low_temp isn't lower than entity low_temp
if target_low_temp < min_temp:
raise ServiceValidationError(
translation_domain=DOMAIN,
translation_key="range_to_small",
translation_placeholders={
"min_temp": str(target_low_temp),
"max_temp": str(target_high_temp),
"range": str(min_temp_range),
},
)

kwargs[ATTR_TARGET_TEMP_HIGH] = target_high_temp
kwargs[ATTR_TARGET_TEMP_LOW] = target_low_temp

await entity.async_set_temperature(**kwargs)

Expand Down
43 changes: 27 additions & 16 deletions tests/components/climate/test_init.py
Original file line number Diff line number Diff line change
Expand Up @@ -1391,8 +1391,8 @@ async def async_setup_entry_climate_platform(
SERVICE_SET_TEMPERATURE,
{
"entity_id": "climate.test",
ATTR_TARGET_TEMP_HIGH: 25,
ATTR_TARGET_TEMP_LOW: 23,
ATTR_TARGET_TEMP_HIGH: 20,
ATTR_TARGET_TEMP_LOW: 18,
},
blocking=True,
)
Expand All @@ -1401,17 +1401,28 @@ async def async_setup_entry_climate_platform(
assert state.attributes[ATTR_TARGET_TEMP_HIGH] == 20.0
assert state.attributes[ATTR_MIN_TEMP_RANGE] == 3.0

await hass.services.async_call(
DOMAIN,
SERVICE_SET_TEMPERATURE,
{
"entity_id": "climate.test",
ATTR_TARGET_TEMP_HIGH: 7,
ATTR_TARGET_TEMP_LOW: 5,
},
blocking=True,
)
state = hass.states.get("climate.test")
assert state.attributes[ATTR_TARGET_TEMP_LOW] == 10.0
assert state.attributes[ATTR_TARGET_TEMP_HIGH] == 13.0
assert state.attributes[ATTR_MIN_TEMP_RANGE] == 3.0
# Raises as not allowed for min temp to be higher than high temp
with pytest.raises(ServiceValidationError):
await hass.services.async_call(
DOMAIN,
SERVICE_SET_TEMPERATURE,
{
"entity_id": "climate.test",
ATTR_TARGET_TEMP_HIGH: 18,
ATTR_TARGET_TEMP_LOW: 20,
},
blocking=True,
)

# Raises due to low_temp falls outside of allowed range
with pytest.raises(ServiceValidationError):
await hass.services.async_call(
DOMAIN,
SERVICE_SET_TEMPERATURE,
{
"entity_id": "climate.test",
ATTR_TARGET_TEMP_HIGH: 12,
ATTR_TARGET_TEMP_LOW: 10,
},
blocking=True,
)

0 comments on commit 0aa8088

Please sign in to comment.