From cec3b5739037a30e41c87e3881cbb3816e65d2ca Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Wed, 8 Apr 2020 13:56:11 -0500 Subject: [PATCH] Fix thermostats that do not support off under homekit (#33809) TargetHeatingCoolingState: value=0 is an invalid value. would be raised when a thermostat did not support off. --- .../components/homekit/type_thermostats.py | 2 +- .../homekit/test_type_thermostats.py | 35 +++++++++++++++++++ 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/homeassistant/components/homekit/type_thermostats.py b/homeassistant/components/homekit/type_thermostats.py index ebb8ae3883e..d1bcb600d84 100644 --- a/homeassistant/components/homekit/type_thermostats.py +++ b/homeassistant/components/homekit/type_thermostats.py @@ -175,7 +175,7 @@ class Thermostat(HomeAccessory): self.char_target_heat_cool = serv_thermostat.configure_char( CHAR_TARGET_HEATING_COOLING, - value=0, + value=list(hc_valid_values.values())[0], setter_callback=self.set_heat_cool, valid_values=hc_valid_values, ) diff --git a/tests/components/homekit/test_type_thermostats.py b/tests/components/homekit/test_type_thermostats.py index e974b6d4811..7fe2f41b736 100644 --- a/tests/components/homekit/test_type_thermostats.py +++ b/tests/components/homekit/test_type_thermostats.py @@ -805,6 +805,41 @@ async def test_thermostat_hvac_modes_with_auto_only(hass, hk_driver, cls): assert acc.char_target_heat_cool.value == 3 +async def test_thermostat_hvac_modes_without_off(hass, hk_driver, cls): + """Test a thermostat that has no off.""" + entity_id = "climate.test" + + hass.states.async_set( + entity_id, HVAC_MODE_AUTO, {ATTR_HVAC_MODES: [HVAC_MODE_AUTO, HVAC_MODE_HEAT]} + ) + + await hass.async_block_till_done() + acc = cls.thermostat(hass, hk_driver, "Climate", entity_id, 2, None) + await acc.run_handler() + await hass.async_block_till_done() + hap = acc.char_target_heat_cool.to_HAP() + assert hap["valid-values"] == [1, 3] + assert acc.char_target_heat_cool.value == 3 + + await hass.async_add_executor_job(acc.char_target_heat_cool.set_value, 3) + await hass.async_block_till_done() + assert acc.char_target_heat_cool.value == 3 + + await hass.async_add_executor_job(acc.char_target_heat_cool.set_value, 1) + await hass.async_block_till_done() + assert acc.char_target_heat_cool.value == 1 + + with pytest.raises(ValueError): + await hass.async_add_executor_job(acc.char_target_heat_cool.set_value, 2) + await hass.async_block_till_done() + assert acc.char_target_heat_cool.value == 1 + + with pytest.raises(ValueError): + await hass.async_add_executor_job(acc.char_target_heat_cool.set_value, 0) + await hass.async_block_till_done() + assert acc.char_target_heat_cool.value == 1 + + async def test_water_heater(hass, hk_driver, cls, events): """Test if accessory and HA are updated accordingly.""" entity_id = "water_heater.test"