Limit available heat/cool modes for HomeKit thermostats (#28586)
* Limit available heat/cool modes for HomeKit thermostats. The Home app only shows appropriate modes (heat/cool/auto) for the device. Depending on the climate integration, disabling the auto start might be needed. * Include improved mapping for HVAC modes in tests
This commit is contained in:
parent
27530be46f
commit
c5f4872aea
2 changed files with 115 additions and 29 deletions
|
@ -7,6 +7,7 @@ from homeassistant.components.climate.const import (
|
||||||
ATTR_CURRENT_TEMPERATURE,
|
ATTR_CURRENT_TEMPERATURE,
|
||||||
ATTR_HVAC_ACTION,
|
ATTR_HVAC_ACTION,
|
||||||
ATTR_HVAC_MODE,
|
ATTR_HVAC_MODE,
|
||||||
|
ATTR_HVAC_MODES,
|
||||||
ATTR_MAX_TEMP,
|
ATTR_MAX_TEMP,
|
||||||
ATTR_MIN_TEMP,
|
ATTR_MIN_TEMP,
|
||||||
ATTR_TARGET_TEMP_HIGH,
|
ATTR_TARGET_TEMP_HIGH,
|
||||||
|
@ -23,6 +24,8 @@ from homeassistant.components.climate.const import (
|
||||||
HVAC_MODE_HEAT,
|
HVAC_MODE_HEAT,
|
||||||
HVAC_MODE_HEAT_COOL,
|
HVAC_MODE_HEAT_COOL,
|
||||||
HVAC_MODE_OFF,
|
HVAC_MODE_OFF,
|
||||||
|
HVAC_MODE_AUTO,
|
||||||
|
HVAC_MODE_FAN_ONLY,
|
||||||
SERVICE_SET_HVAC_MODE as SERVICE_SET_HVAC_MODE_THERMOSTAT,
|
SERVICE_SET_HVAC_MODE as SERVICE_SET_HVAC_MODE_THERMOSTAT,
|
||||||
SERVICE_SET_TEMPERATURE as SERVICE_SET_TEMPERATURE_THERMOSTAT,
|
SERVICE_SET_TEMPERATURE as SERVICE_SET_TEMPERATURE_THERMOSTAT,
|
||||||
SUPPORT_TARGET_TEMPERATURE_RANGE,
|
SUPPORT_TARGET_TEMPERATURE_RANGE,
|
||||||
|
@ -60,13 +63,18 @@ from .util import temperature_to_homekit, temperature_to_states
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
HC_HOMEKIT_VALID_MODES_WATER_HEATER = {
|
||||||
|
"Heat": 1,
|
||||||
|
}
|
||||||
UNIT_HASS_TO_HOMEKIT = {TEMP_CELSIUS: 0, TEMP_FAHRENHEIT: 1}
|
UNIT_HASS_TO_HOMEKIT = {TEMP_CELSIUS: 0, TEMP_FAHRENHEIT: 1}
|
||||||
UNIT_HOMEKIT_TO_HASS = {c: s for s, c in UNIT_HASS_TO_HOMEKIT.items()}
|
UNIT_HOMEKIT_TO_HASS = {c: s for s, c in UNIT_HASS_TO_HOMEKIT.items()}
|
||||||
HC_HASS_TO_HOMEKIT = {
|
HC_HASS_TO_HOMEKIT = {
|
||||||
HVAC_MODE_OFF: 0,
|
HVAC_MODE_OFF: 0,
|
||||||
HVAC_MODE_HEAT: 1,
|
HVAC_MODE_HEAT: 1,
|
||||||
HVAC_MODE_COOL: 2,
|
HVAC_MODE_COOL: 2,
|
||||||
|
HVAC_MODE_AUTO: 3,
|
||||||
HVAC_MODE_HEAT_COOL: 3,
|
HVAC_MODE_HEAT_COOL: 3,
|
||||||
|
HVAC_MODE_FAN_ONLY: 2,
|
||||||
}
|
}
|
||||||
HC_HOMEKIT_TO_HASS = {c: s for s, c in HC_HASS_TO_HOMEKIT.items()}
|
HC_HOMEKIT_TO_HASS = {c: s for s, c in HC_HASS_TO_HOMEKIT.items()}
|
||||||
|
|
||||||
|
@ -97,9 +105,9 @@ class Thermostat(HomeAccessory):
|
||||||
|
|
||||||
# Add additional characteristics if auto mode is supported
|
# Add additional characteristics if auto mode is supported
|
||||||
self.chars = []
|
self.chars = []
|
||||||
features = self.hass.states.get(self.entity_id).attributes.get(
|
state = self.hass.states.get(self.entity_id)
|
||||||
ATTR_SUPPORTED_FEATURES, 0
|
features = state.attributes.get(ATTR_SUPPORTED_FEATURES, 0)
|
||||||
)
|
|
||||||
if features & SUPPORT_TARGET_TEMPERATURE_RANGE:
|
if features & SUPPORT_TARGET_TEMPERATURE_RANGE:
|
||||||
self.chars.extend(
|
self.chars.extend(
|
||||||
(CHAR_COOLING_THRESHOLD_TEMPERATURE, CHAR_HEATING_THRESHOLD_TEMPERATURE)
|
(CHAR_COOLING_THRESHOLD_TEMPERATURE, CHAR_HEATING_THRESHOLD_TEMPERATURE)
|
||||||
|
@ -107,12 +115,44 @@ class Thermostat(HomeAccessory):
|
||||||
|
|
||||||
serv_thermostat = self.add_preload_service(SERV_THERMOSTAT, self.chars)
|
serv_thermostat = self.add_preload_service(SERV_THERMOSTAT, self.chars)
|
||||||
|
|
||||||
# Current and target mode characteristics
|
# Current mode characteristics
|
||||||
self.char_current_heat_cool = serv_thermostat.configure_char(
|
self.char_current_heat_cool = serv_thermostat.configure_char(
|
||||||
CHAR_CURRENT_HEATING_COOLING, value=0
|
CHAR_CURRENT_HEATING_COOLING, value=0
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Target mode characteristics
|
||||||
|
hc_modes = state.attributes.get(ATTR_HVAC_MODES, None)
|
||||||
|
if hc_modes is None:
|
||||||
|
_LOGGER.error(
|
||||||
|
"%s: HVAC modes not yet available. Please disable auto start for homekit.",
|
||||||
|
self.entity_id,
|
||||||
|
)
|
||||||
|
hc_modes = (
|
||||||
|
HVAC_MODE_HEAT,
|
||||||
|
HVAC_MODE_COOL,
|
||||||
|
HVAC_MODE_HEAT_COOL,
|
||||||
|
HVAC_MODE_OFF,
|
||||||
|
)
|
||||||
|
|
||||||
|
# determine available modes for this entity, prefer AUTO over HEAT_COOL and COOL over FAN_ONLY
|
||||||
|
self.hc_homekit_to_hass = {
|
||||||
|
c: s
|
||||||
|
for s, c in HC_HASS_TO_HOMEKIT.items()
|
||||||
|
if (
|
||||||
|
s in hc_modes
|
||||||
|
and not (
|
||||||
|
(s == HVAC_MODE_HEAT_COOL and HVAC_MODE_AUTO in hc_modes)
|
||||||
|
or (s == HVAC_MODE_FAN_ONLY and HVAC_MODE_COOL in hc_modes)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
hc_valid_values = {k: v for v, k in self.hc_homekit_to_hass.items()}
|
||||||
|
|
||||||
self.char_target_heat_cool = serv_thermostat.configure_char(
|
self.char_target_heat_cool = serv_thermostat.configure_char(
|
||||||
CHAR_TARGET_HEATING_COOLING, value=0, setter_callback=self.set_heat_cool
|
CHAR_TARGET_HEATING_COOLING,
|
||||||
|
value=0,
|
||||||
|
setter_callback=self.set_heat_cool,
|
||||||
|
valid_values=hc_valid_values,
|
||||||
)
|
)
|
||||||
|
|
||||||
# Current and target temperature characteristics
|
# Current and target temperature characteristics
|
||||||
|
@ -185,7 +225,7 @@ class Thermostat(HomeAccessory):
|
||||||
"""Change operation mode to value if call came from HomeKit."""
|
"""Change operation mode to value if call came from HomeKit."""
|
||||||
_LOGGER.debug("%s: Set heat-cool to %d", self.entity_id, value)
|
_LOGGER.debug("%s: Set heat-cool to %d", self.entity_id, value)
|
||||||
self._flag_heat_cool = True
|
self._flag_heat_cool = True
|
||||||
hass_value = HC_HOMEKIT_TO_HASS[value]
|
hass_value = self.hc_homekit_to_hass[value]
|
||||||
params = {ATTR_ENTITY_ID: self.entity_id, ATTR_HVAC_MODE: hass_value}
|
params = {ATTR_ENTITY_ID: self.entity_id, ATTR_HVAC_MODE: hass_value}
|
||||||
self.call_service(
|
self.call_service(
|
||||||
DOMAIN_CLIMATE, SERVICE_SET_HVAC_MODE_THERMOSTAT, params, hass_value
|
DOMAIN_CLIMATE, SERVICE_SET_HVAC_MODE_THERMOSTAT, params, hass_value
|
||||||
|
@ -318,7 +358,10 @@ class WaterHeater(HomeAccessory):
|
||||||
CHAR_CURRENT_HEATING_COOLING, value=1
|
CHAR_CURRENT_HEATING_COOLING, value=1
|
||||||
)
|
)
|
||||||
self.char_target_heat_cool = serv_thermostat.configure_char(
|
self.char_target_heat_cool = serv_thermostat.configure_char(
|
||||||
CHAR_TARGET_HEATING_COOLING, value=1, setter_callback=self.set_heat_cool
|
CHAR_TARGET_HEATING_COOLING,
|
||||||
|
value=1,
|
||||||
|
setter_callback=self.set_heat_cool,
|
||||||
|
valid_values=HC_HOMEKIT_VALID_MODES_WATER_HEATER,
|
||||||
)
|
)
|
||||||
|
|
||||||
self.char_current_temp = serv_thermostat.configure_char(
|
self.char_current_temp = serv_thermostat.configure_char(
|
||||||
|
|
|
@ -24,6 +24,8 @@ from homeassistant.components.climate.const import (
|
||||||
HVAC_MODE_HEAT,
|
HVAC_MODE_HEAT,
|
||||||
HVAC_MODE_HEAT_COOL,
|
HVAC_MODE_HEAT_COOL,
|
||||||
HVAC_MODE_OFF,
|
HVAC_MODE_OFF,
|
||||||
|
HVAC_MODE_FAN_ONLY,
|
||||||
|
HVAC_MODE_AUTO,
|
||||||
)
|
)
|
||||||
from homeassistant.components.homekit.const import (
|
from homeassistant.components.homekit.const import (
|
||||||
ATTR_VALUE,
|
ATTR_VALUE,
|
||||||
|
@ -64,7 +66,20 @@ async def test_thermostat(hass, hk_driver, cls, events):
|
||||||
"""Test if accessory and HA are updated accordingly."""
|
"""Test if accessory and HA are updated accordingly."""
|
||||||
entity_id = "climate.test"
|
entity_id = "climate.test"
|
||||||
|
|
||||||
hass.states.async_set(entity_id, HVAC_MODE_OFF)
|
hass.states.async_set(
|
||||||
|
entity_id,
|
||||||
|
HVAC_MODE_OFF,
|
||||||
|
{
|
||||||
|
ATTR_HVAC_MODES: [
|
||||||
|
HVAC_MODE_HEAT,
|
||||||
|
HVAC_MODE_HEAT_COOL,
|
||||||
|
HVAC_MODE_FAN_ONLY,
|
||||||
|
HVAC_MODE_COOL,
|
||||||
|
HVAC_MODE_OFF,
|
||||||
|
HVAC_MODE_AUTO,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
)
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
acc = cls.thermostat(hass, hk_driver, "Climate", entity_id, 2, None)
|
acc = cls.thermostat(hass, hk_driver, "Climate", entity_id, 2, None)
|
||||||
await hass.async_add_job(acc.run)
|
await hass.async_add_job(acc.run)
|
||||||
|
@ -120,7 +135,7 @@ async def test_thermostat(hass, hk_driver, cls, events):
|
||||||
|
|
||||||
hass.states.async_set(
|
hass.states.async_set(
|
||||||
entity_id,
|
entity_id,
|
||||||
HVAC_MODE_COOL,
|
HVAC_MODE_FAN_ONLY,
|
||||||
{
|
{
|
||||||
ATTR_TEMPERATURE: 20.0,
|
ATTR_TEMPERATURE: 20.0,
|
||||||
ATTR_CURRENT_TEMPERATURE: 25.0,
|
ATTR_CURRENT_TEMPERATURE: 25.0,
|
||||||
|
@ -164,9 +179,8 @@ async def test_thermostat(hass, hk_driver, cls, events):
|
||||||
|
|
||||||
hass.states.async_set(
|
hass.states.async_set(
|
||||||
entity_id,
|
entity_id,
|
||||||
HVAC_MODE_HEAT_COOL,
|
HVAC_MODE_AUTO,
|
||||||
{
|
{
|
||||||
ATTR_HVAC_MODES: [HVAC_MODE_HEAT, HVAC_MODE_COOL],
|
|
||||||
ATTR_TEMPERATURE: 22.0,
|
ATTR_TEMPERATURE: 22.0,
|
||||||
ATTR_CURRENT_TEMPERATURE: 18.0,
|
ATTR_CURRENT_TEMPERATURE: 18.0,
|
||||||
ATTR_HVAC_ACTION: CURRENT_HVAC_HEAT,
|
ATTR_HVAC_ACTION: CURRENT_HVAC_HEAT,
|
||||||
|
@ -183,7 +197,6 @@ async def test_thermostat(hass, hk_driver, cls, events):
|
||||||
entity_id,
|
entity_id,
|
||||||
HVAC_MODE_HEAT_COOL,
|
HVAC_MODE_HEAT_COOL,
|
||||||
{
|
{
|
||||||
ATTR_HVAC_MODES: [HVAC_MODE_HEAT, HVAC_MODE_COOL],
|
|
||||||
ATTR_TEMPERATURE: 22.0,
|
ATTR_TEMPERATURE: 22.0,
|
||||||
ATTR_CURRENT_TEMPERATURE: 25.0,
|
ATTR_CURRENT_TEMPERATURE: 25.0,
|
||||||
ATTR_HVAC_ACTION: CURRENT_HVAC_COOL,
|
ATTR_HVAC_ACTION: CURRENT_HVAC_COOL,
|
||||||
|
@ -198,9 +211,8 @@ async def test_thermostat(hass, hk_driver, cls, events):
|
||||||
|
|
||||||
hass.states.async_set(
|
hass.states.async_set(
|
||||||
entity_id,
|
entity_id,
|
||||||
HVAC_MODE_HEAT_COOL,
|
HVAC_MODE_AUTO,
|
||||||
{
|
{
|
||||||
ATTR_HVAC_MODES: [HVAC_MODE_HEAT, HVAC_MODE_COOL],
|
|
||||||
ATTR_TEMPERATURE: 22.0,
|
ATTR_TEMPERATURE: 22.0,
|
||||||
ATTR_CURRENT_TEMPERATURE: 22.0,
|
ATTR_CURRENT_TEMPERATURE: 22.0,
|
||||||
ATTR_HVAC_ACTION: CURRENT_HVAC_IDLE,
|
ATTR_HVAC_ACTION: CURRENT_HVAC_IDLE,
|
||||||
|
@ -226,14 +238,23 @@ async def test_thermostat(hass, hk_driver, cls, events):
|
||||||
assert len(events) == 1
|
assert len(events) == 1
|
||||||
assert events[-1].data[ATTR_VALUE] == "19.0°C"
|
assert events[-1].data[ATTR_VALUE] == "19.0°C"
|
||||||
|
|
||||||
await hass.async_add_job(acc.char_target_heat_cool.client_update_value, 1)
|
await hass.async_add_job(acc.char_target_heat_cool.client_update_value, 2)
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
assert call_set_hvac_mode
|
assert call_set_hvac_mode
|
||||||
assert call_set_hvac_mode[0].data[ATTR_ENTITY_ID] == entity_id
|
assert call_set_hvac_mode[0].data[ATTR_ENTITY_ID] == entity_id
|
||||||
assert call_set_hvac_mode[0].data[ATTR_HVAC_MODE] == HVAC_MODE_HEAT
|
assert call_set_hvac_mode[0].data[ATTR_HVAC_MODE] == HVAC_MODE_COOL
|
||||||
assert acc.char_target_heat_cool.value == 1
|
assert acc.char_target_heat_cool.value == 2
|
||||||
assert len(events) == 2
|
assert len(events) == 2
|
||||||
assert events[-1].data[ATTR_VALUE] == HVAC_MODE_HEAT
|
assert events[-1].data[ATTR_VALUE] == HVAC_MODE_COOL
|
||||||
|
|
||||||
|
await hass.async_add_job(acc.char_target_heat_cool.client_update_value, 3)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
assert call_set_hvac_mode
|
||||||
|
assert call_set_hvac_mode[1].data[ATTR_ENTITY_ID] == entity_id
|
||||||
|
assert call_set_hvac_mode[1].data[ATTR_HVAC_MODE] == HVAC_MODE_AUTO
|
||||||
|
assert acc.char_target_heat_cool.value == 3
|
||||||
|
assert len(events) == 3
|
||||||
|
assert events[-1].data[ATTR_VALUE] == HVAC_MODE_AUTO
|
||||||
|
|
||||||
|
|
||||||
async def test_thermostat_auto(hass, hk_driver, cls, events):
|
async def test_thermostat_auto(hass, hk_driver, cls, events):
|
||||||
|
@ -261,7 +282,6 @@ async def test_thermostat_auto(hass, hk_driver, cls, events):
|
||||||
entity_id,
|
entity_id,
|
||||||
HVAC_MODE_HEAT_COOL,
|
HVAC_MODE_HEAT_COOL,
|
||||||
{
|
{
|
||||||
ATTR_HVAC_MODE: HVAC_MODE_HEAT_COOL,
|
|
||||||
ATTR_TARGET_TEMP_HIGH: 22.0,
|
ATTR_TARGET_TEMP_HIGH: 22.0,
|
||||||
ATTR_TARGET_TEMP_LOW: 20.0,
|
ATTR_TARGET_TEMP_LOW: 20.0,
|
||||||
ATTR_CURRENT_TEMPERATURE: 18.0,
|
ATTR_CURRENT_TEMPERATURE: 18.0,
|
||||||
|
@ -278,9 +298,8 @@ async def test_thermostat_auto(hass, hk_driver, cls, events):
|
||||||
|
|
||||||
hass.states.async_set(
|
hass.states.async_set(
|
||||||
entity_id,
|
entity_id,
|
||||||
HVAC_MODE_HEAT_COOL,
|
HVAC_MODE_COOL,
|
||||||
{
|
{
|
||||||
ATTR_HVAC_MODE: HVAC_MODE_HEAT_COOL,
|
|
||||||
ATTR_TARGET_TEMP_HIGH: 23.0,
|
ATTR_TARGET_TEMP_HIGH: 23.0,
|
||||||
ATTR_TARGET_TEMP_LOW: 19.0,
|
ATTR_TARGET_TEMP_LOW: 19.0,
|
||||||
ATTR_CURRENT_TEMPERATURE: 24.0,
|
ATTR_CURRENT_TEMPERATURE: 24.0,
|
||||||
|
@ -291,15 +310,14 @@ async def test_thermostat_auto(hass, hk_driver, cls, events):
|
||||||
assert acc.char_heating_thresh_temp.value == 19.0
|
assert acc.char_heating_thresh_temp.value == 19.0
|
||||||
assert acc.char_cooling_thresh_temp.value == 23.0
|
assert acc.char_cooling_thresh_temp.value == 23.0
|
||||||
assert acc.char_current_heat_cool.value == 2
|
assert acc.char_current_heat_cool.value == 2
|
||||||
assert acc.char_target_heat_cool.value == 3
|
assert acc.char_target_heat_cool.value == 2
|
||||||
assert acc.char_current_temp.value == 24.0
|
assert acc.char_current_temp.value == 24.0
|
||||||
assert acc.char_display_units.value == 0
|
assert acc.char_display_units.value == 0
|
||||||
|
|
||||||
hass.states.async_set(
|
hass.states.async_set(
|
||||||
entity_id,
|
entity_id,
|
||||||
HVAC_MODE_HEAT_COOL,
|
HVAC_MODE_AUTO,
|
||||||
{
|
{
|
||||||
ATTR_HVAC_MODE: HVAC_MODE_HEAT_COOL,
|
|
||||||
ATTR_TARGET_TEMP_HIGH: 23.0,
|
ATTR_TARGET_TEMP_HIGH: 23.0,
|
||||||
ATTR_TARGET_TEMP_LOW: 19.0,
|
ATTR_TARGET_TEMP_LOW: 19.0,
|
||||||
ATTR_CURRENT_TEMPERATURE: 21.0,
|
ATTR_CURRENT_TEMPERATURE: 21.0,
|
||||||
|
@ -346,7 +364,6 @@ async def test_thermostat_power_state(hass, hk_driver, cls, events):
|
||||||
HVAC_MODE_HEAT,
|
HVAC_MODE_HEAT,
|
||||||
{
|
{
|
||||||
ATTR_SUPPORTED_FEATURES: 4096,
|
ATTR_SUPPORTED_FEATURES: 4096,
|
||||||
ATTR_HVAC_MODE: HVAC_MODE_HEAT,
|
|
||||||
ATTR_TEMPERATURE: 23.0,
|
ATTR_TEMPERATURE: 23.0,
|
||||||
ATTR_CURRENT_TEMPERATURE: 18.0,
|
ATTR_CURRENT_TEMPERATURE: 18.0,
|
||||||
ATTR_HVAC_ACTION: CURRENT_HVAC_HEAT,
|
ATTR_HVAC_ACTION: CURRENT_HVAC_HEAT,
|
||||||
|
@ -364,7 +381,6 @@ async def test_thermostat_power_state(hass, hk_driver, cls, events):
|
||||||
entity_id,
|
entity_id,
|
||||||
HVAC_MODE_OFF,
|
HVAC_MODE_OFF,
|
||||||
{
|
{
|
||||||
ATTR_HVAC_MODE: HVAC_MODE_HEAT,
|
|
||||||
ATTR_TEMPERATURE: 23.0,
|
ATTR_TEMPERATURE: 23.0,
|
||||||
ATTR_CURRENT_TEMPERATURE: 18.0,
|
ATTR_CURRENT_TEMPERATURE: 18.0,
|
||||||
ATTR_HVAC_ACTION: CURRENT_HVAC_IDLE,
|
ATTR_HVAC_ACTION: CURRENT_HVAC_IDLE,
|
||||||
|
@ -378,7 +394,6 @@ async def test_thermostat_power_state(hass, hk_driver, cls, events):
|
||||||
entity_id,
|
entity_id,
|
||||||
HVAC_MODE_OFF,
|
HVAC_MODE_OFF,
|
||||||
{
|
{
|
||||||
ATTR_HVAC_MODE: HVAC_MODE_OFF,
|
|
||||||
ATTR_TEMPERATURE: 23.0,
|
ATTR_TEMPERATURE: 23.0,
|
||||||
ATTR_CURRENT_TEMPERATURE: 18.0,
|
ATTR_CURRENT_TEMPERATURE: 18.0,
|
||||||
ATTR_HVAC_ACTION: CURRENT_HVAC_IDLE,
|
ATTR_HVAC_ACTION: CURRENT_HVAC_IDLE,
|
||||||
|
@ -423,7 +438,6 @@ async def test_thermostat_fahrenheit(hass, hk_driver, cls, events):
|
||||||
entity_id,
|
entity_id,
|
||||||
HVAC_MODE_HEAT_COOL,
|
HVAC_MODE_HEAT_COOL,
|
||||||
{
|
{
|
||||||
ATTR_HVAC_MODE: HVAC_MODE_HEAT_COOL,
|
|
||||||
ATTR_TARGET_TEMP_HIGH: 75.2,
|
ATTR_TARGET_TEMP_HIGH: 75.2,
|
||||||
ATTR_TARGET_TEMP_LOW: 68.1,
|
ATTR_TARGET_TEMP_LOW: 68.1,
|
||||||
ATTR_TEMPERATURE: 71.6,
|
ATTR_TEMPERATURE: 71.6,
|
||||||
|
@ -503,6 +517,34 @@ async def test_thermostat_temperature_step_whole(hass, hk_driver, cls):
|
||||||
assert acc.char_target_temp.properties[PROP_MIN_STEP] == 1.0
|
assert acc.char_target_temp.properties[PROP_MIN_STEP] == 1.0
|
||||||
|
|
||||||
|
|
||||||
|
async def test_thermostat_hvac_modes(hass, hk_driver, cls):
|
||||||
|
"""Test if unsupported HVAC modes are deactivated in HomeKit."""
|
||||||
|
entity_id = "climate.test"
|
||||||
|
|
||||||
|
hass.states.async_set(
|
||||||
|
entity_id, HVAC_MODE_OFF, {ATTR_HVAC_MODES: [HVAC_MODE_HEAT, HVAC_MODE_OFF]}
|
||||||
|
)
|
||||||
|
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
acc = cls.thermostat(hass, hk_driver, "Climate", entity_id, 2, None)
|
||||||
|
await hass.async_add_job(acc.run)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
with pytest.raises(ValueError):
|
||||||
|
await hass.async_add_job(acc.char_target_heat_cool.set_value, 3)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
assert acc.char_target_heat_cool.value == 0
|
||||||
|
|
||||||
|
await hass.async_add_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_job(acc.char_target_heat_cool.set_value, 2)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
assert acc.char_target_heat_cool.value == 1
|
||||||
|
|
||||||
|
|
||||||
async def test_water_heater(hass, hk_driver, cls, events):
|
async def test_water_heater(hass, hk_driver, cls, events):
|
||||||
"""Test if accessory and HA are updated accordingly."""
|
"""Test if accessory and HA are updated accordingly."""
|
||||||
entity_id = "water_heater.test"
|
entity_id = "water_heater.test"
|
||||||
|
@ -571,7 +613,8 @@ async def test_water_heater(hass, hk_driver, cls, events):
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
assert acc.char_target_heat_cool.value == 1
|
assert acc.char_target_heat_cool.value == 1
|
||||||
|
|
||||||
await hass.async_add_job(acc.char_target_heat_cool.client_update_value, 3)
|
with pytest.raises(ValueError):
|
||||||
|
await hass.async_add_job(acc.char_target_heat_cool.set_value, 3)
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
assert acc.char_target_heat_cool.value == 1
|
assert acc.char_target_heat_cool.value == 1
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue