mirror of
https://github.com/home-assistant/core.git
synced 2026-09-25 17:04:04 -04:00
Fix HomeKit power control for Daikin zone climates (#178408)
This commit is contained in:
@@ -416,8 +416,11 @@ class DaikinZoneClimate(DaikinEntity, ClimateEntity):
|
||||
@property
|
||||
@override
|
||||
def hvac_modes(self) -> list[HVACMode]:
|
||||
"""Return the hvac modes (mirrors the main unit)."""
|
||||
return [self._main_hvac_mode]
|
||||
"""Return the main unit HVAC mode and zone power off."""
|
||||
main_mode = self._main_hvac_mode
|
||||
if main_mode == HVACMode.OFF:
|
||||
return [HVACMode.OFF]
|
||||
return [main_mode, HVACMode.OFF]
|
||||
|
||||
@property
|
||||
@override
|
||||
@@ -549,7 +552,13 @@ class DaikinZoneClimate(DaikinEntity, ClimateEntity):
|
||||
|
||||
@override
|
||||
async def async_set_hvac_mode(self, hvac_mode: HVACMode) -> None:
|
||||
"""Disallow changing HVAC mode via zone climate."""
|
||||
"""Set zone power without changing the main unit HVAC mode."""
|
||||
if hvac_mode == HVACMode.OFF:
|
||||
await self.async_turn_off()
|
||||
return
|
||||
if hvac_mode == self._main_hvac_mode:
|
||||
await self.async_turn_on()
|
||||
return
|
||||
raise HomeAssistantError(
|
||||
translation_domain=DOMAIN,
|
||||
translation_key="zone_hvac_read_only",
|
||||
|
||||
@@ -279,29 +279,31 @@ async def test_zone_climate_parameters_unavailable(
|
||||
assert state.state == STATE_UNAVAILABLE
|
||||
|
||||
|
||||
async def test_zone_climate_hvac_modes_read_only(
|
||||
async def test_zone_climate_rejects_main_mode_change(
|
||||
hass: HomeAssistant,
|
||||
entity_registry: er.EntityRegistry,
|
||||
zone_device: ZoneDevice,
|
||||
) -> None:
|
||||
"""Changing HVAC mode through a zone climate is blocked."""
|
||||
"""Changing the main HVAC mode through a zone climate is blocked."""
|
||||
configure_zone_device(zone_device, zones=[["Living", "1", 22]])
|
||||
await _async_setup_daikin(hass, zone_device)
|
||||
entity_id = _zone_entity_id(entity_registry, zone_device, 0)
|
||||
assert entity_id is not None
|
||||
|
||||
with pytest.raises(HomeAssistantError) as err:
|
||||
with pytest.raises(ServiceValidationError) as err:
|
||||
await hass.services.async_call(
|
||||
CLIMATE_DOMAIN,
|
||||
SERVICE_SET_HVAC_MODE,
|
||||
{
|
||||
ATTR_ENTITY_ID: entity_id,
|
||||
ATTR_HVAC_MODE: HVACMode.HEAT,
|
||||
ATTR_HVAC_MODE: HVACMode.COOL,
|
||||
},
|
||||
blocking=True,
|
||||
)
|
||||
|
||||
assert err.value.translation_key == "zone_hvac_read_only"
|
||||
assert err.value.translation_key == "not_valid_hvac_mode"
|
||||
zone_device.set_zone.assert_not_awaited()
|
||||
zone_device.set.assert_not_awaited()
|
||||
|
||||
|
||||
async def test_zone_climate_set_temperature_requires_heat_or_cool(
|
||||
@@ -360,7 +362,7 @@ async def test_zone_climate_properties(
|
||||
assert state.attributes[ATTR_TEMPERATURE] == 18.0
|
||||
assert state.attributes[ATTR_MIN_TEMP] == 22.0
|
||||
assert state.attributes[ATTR_MAX_TEMP] == 26.0
|
||||
assert state.attributes[ATTR_HVAC_MODES] == [HVACMode.COOL]
|
||||
assert state.attributes[ATTR_HVAC_MODES] == [HVACMode.COOL, HVACMode.OFF]
|
||||
assert state.attributes[ATTR_SUPPORTED_FEATURES] == (
|
||||
ClimateEntityFeature.TARGET_TEMPERATURE
|
||||
| ClimateEntityFeature.TURN_OFF
|
||||
@@ -377,6 +379,7 @@ async def test_zone_climate_properties(
|
||||
"expected_climate_state",
|
||||
"expected_switch_state",
|
||||
"main_mode",
|
||||
"service_data",
|
||||
),
|
||||
[
|
||||
pytest.param(
|
||||
@@ -386,6 +389,7 @@ async def test_zone_climate_properties(
|
||||
HVACMode.COOL,
|
||||
STATE_ON,
|
||||
"cool",
|
||||
{},
|
||||
id="climate-turn-on",
|
||||
),
|
||||
pytest.param(
|
||||
@@ -395,6 +399,7 @@ async def test_zone_climate_properties(
|
||||
HVACMode.OFF,
|
||||
STATE_OFF,
|
||||
"cool",
|
||||
{},
|
||||
id="climate-turn-off",
|
||||
),
|
||||
pytest.param(
|
||||
@@ -404,6 +409,7 @@ async def test_zone_climate_properties(
|
||||
HVACMode.OFF,
|
||||
STATE_OFF,
|
||||
"cool",
|
||||
{},
|
||||
id="climate-toggle-off",
|
||||
),
|
||||
pytest.param(
|
||||
@@ -413,8 +419,29 @@ async def test_zone_climate_properties(
|
||||
HVACMode.OFF,
|
||||
STATE_OFF,
|
||||
"off",
|
||||
{},
|
||||
id="climate-toggle-zone-on-main-off",
|
||||
),
|
||||
pytest.param(
|
||||
SERVICE_SET_HVAC_MODE,
|
||||
"0",
|
||||
"1",
|
||||
HVACMode.HEAT,
|
||||
STATE_ON,
|
||||
"hot",
|
||||
{ATTR_HVAC_MODE: HVACMode.HEAT},
|
||||
id="hvac-mode-turn-on",
|
||||
),
|
||||
pytest.param(
|
||||
SERVICE_SET_HVAC_MODE,
|
||||
"1",
|
||||
"0",
|
||||
HVACMode.OFF,
|
||||
STATE_OFF,
|
||||
"hot",
|
||||
{ATTR_HVAC_MODE: HVACMode.OFF},
|
||||
id="hvac-mode-turn-off",
|
||||
),
|
||||
],
|
||||
)
|
||||
async def test_zone_climate_power_controls(
|
||||
@@ -427,6 +454,7 @@ async def test_zone_climate_power_controls(
|
||||
expected_climate_state: HVACMode,
|
||||
expected_switch_state: str,
|
||||
main_mode: str,
|
||||
service_data: dict[str, HVACMode],
|
||||
) -> None:
|
||||
"""Zone climate and switch power controls stay synchronized."""
|
||||
configure_zone_device(
|
||||
@@ -449,7 +477,7 @@ async def test_zone_climate_power_controls(
|
||||
await hass.services.async_call(
|
||||
CLIMATE_DOMAIN,
|
||||
service,
|
||||
{ATTR_ENTITY_ID: climate_entity_id},
|
||||
{ATTR_ENTITY_ID: climate_entity_id, **service_data},
|
||||
blocking=True,
|
||||
)
|
||||
|
||||
@@ -504,10 +532,15 @@ async def test_zone_switch_updates_zone_climate(
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("mode", "expected_state"),
|
||||
("mode", "expected_state", "expected_modes"),
|
||||
[
|
||||
pytest.param("auto", HVACMode.HEAT_COOL, id="auto"),
|
||||
pytest.param("off", HVACMode.OFF, id="off"),
|
||||
pytest.param(
|
||||
"auto",
|
||||
HVACMode.HEAT_COOL,
|
||||
[HVACMode.HEAT_COOL, HVACMode.OFF],
|
||||
id="auto",
|
||||
),
|
||||
pytest.param("off", HVACMode.OFF, [HVACMode.OFF], id="off"),
|
||||
],
|
||||
)
|
||||
async def test_zone_climate_target_temperature_inactive_mode(
|
||||
@@ -516,6 +549,7 @@ async def test_zone_climate_target_temperature_inactive_mode(
|
||||
zone_device: ZoneDevice,
|
||||
mode: str,
|
||||
expected_state: HVACMode,
|
||||
expected_modes: list[HVACMode],
|
||||
) -> None:
|
||||
"""In non-heating/cooling modes, zone target temperature is None."""
|
||||
configure_zone_device(
|
||||
@@ -532,6 +566,7 @@ async def test_zone_climate_target_temperature_inactive_mode(
|
||||
state = hass.states.get(entity_id)
|
||||
assert state is not None
|
||||
assert state.state == expected_state
|
||||
assert state.attributes[ATTR_HVAC_MODES] == expected_modes
|
||||
assert state.attributes[ATTR_TEMPERATURE] is None
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user