mirror of
https://github.com/home-assistant/core.git
synced 2025-07-21 04:07:08 +00:00
Fix HomeKit requests with hvac mode and temperature in the same call (#56239)
This commit is contained in:
parent
aaadd42539
commit
7524daad86
@ -245,7 +245,7 @@ class Thermostat(HomeAccessory):
|
|||||||
def _set_chars(self, char_values):
|
def _set_chars(self, char_values):
|
||||||
_LOGGER.debug("Thermostat _set_chars: %s", char_values)
|
_LOGGER.debug("Thermostat _set_chars: %s", char_values)
|
||||||
events = []
|
events = []
|
||||||
params = {}
|
params = {ATTR_ENTITY_ID: self.entity_id}
|
||||||
service = None
|
service = None
|
||||||
state = self.hass.states.get(self.entity_id)
|
state = self.hass.states.get(self.entity_id)
|
||||||
features = state.attributes.get(ATTR_SUPPORTED_FEATURES, 0)
|
features = state.attributes.get(ATTR_SUPPORTED_FEATURES, 0)
|
||||||
@ -285,12 +285,20 @@ class Thermostat(HomeAccessory):
|
|||||||
target_hc = hc_fallback
|
target_hc = hc_fallback
|
||||||
break
|
break
|
||||||
|
|
||||||
service = SERVICE_SET_HVAC_MODE_THERMOSTAT
|
params[ATTR_HVAC_MODE] = self.hc_homekit_to_hass[target_hc]
|
||||||
hass_value = self.hc_homekit_to_hass[target_hc]
|
|
||||||
params = {ATTR_HVAC_MODE: hass_value}
|
|
||||||
events.append(
|
events.append(
|
||||||
f"{CHAR_TARGET_HEATING_COOLING} to {char_values[CHAR_TARGET_HEATING_COOLING]}"
|
f"{CHAR_TARGET_HEATING_COOLING} to {char_values[CHAR_TARGET_HEATING_COOLING]}"
|
||||||
)
|
)
|
||||||
|
# Many integrations do not actually implement `hvac_mode` for the
|
||||||
|
# `SERVICE_SET_TEMPERATURE_THERMOSTAT` service so we made a call to
|
||||||
|
# `SERVICE_SET_HVAC_MODE_THERMOSTAT` before calling `SERVICE_SET_TEMPERATURE_THERMOSTAT`
|
||||||
|
# to ensure the device is in the right mode before setting the temp.
|
||||||
|
self.async_call_service(
|
||||||
|
DOMAIN_CLIMATE,
|
||||||
|
SERVICE_SET_HVAC_MODE_THERMOSTAT,
|
||||||
|
params.copy(),
|
||||||
|
", ".join(events),
|
||||||
|
)
|
||||||
|
|
||||||
if CHAR_TARGET_TEMPERATURE in char_values:
|
if CHAR_TARGET_TEMPERATURE in char_values:
|
||||||
hc_target_temp = char_values[CHAR_TARGET_TEMPERATURE]
|
hc_target_temp = char_values[CHAR_TARGET_TEMPERATURE]
|
||||||
@ -357,7 +365,6 @@ class Thermostat(HomeAccessory):
|
|||||||
)
|
)
|
||||||
|
|
||||||
if service:
|
if service:
|
||||||
params[ATTR_ENTITY_ID] = self.entity_id
|
|
||||||
self.async_call_service(
|
self.async_call_service(
|
||||||
DOMAIN_CLIMATE,
|
DOMAIN_CLIMATE,
|
||||||
service,
|
service,
|
||||||
|
@ -560,6 +560,119 @@ async def test_thermostat_auto(hass, hk_driver, events):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
async def test_thermostat_mode_and_temp_change(hass, hk_driver, events):
|
||||||
|
"""Test if accessory where the mode and temp change in the same call."""
|
||||||
|
entity_id = "climate.test"
|
||||||
|
|
||||||
|
# support_auto = True
|
||||||
|
hass.states.async_set(
|
||||||
|
entity_id,
|
||||||
|
HVAC_MODE_OFF,
|
||||||
|
{
|
||||||
|
ATTR_SUPPORTED_FEATURES: SUPPORT_TARGET_TEMPERATURE
|
||||||
|
| SUPPORT_TARGET_TEMPERATURE_RANGE,
|
||||||
|
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()
|
||||||
|
acc = Thermostat(hass, hk_driver, "Climate", entity_id, 1, None)
|
||||||
|
hk_driver.add_accessory(acc)
|
||||||
|
|
||||||
|
await acc.run()
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
assert acc.char_cooling_thresh_temp.value == 23.0
|
||||||
|
assert acc.char_heating_thresh_temp.value == 19.0
|
||||||
|
|
||||||
|
assert acc.char_cooling_thresh_temp.properties[PROP_MAX_VALUE] == DEFAULT_MAX_TEMP
|
||||||
|
assert acc.char_cooling_thresh_temp.properties[PROP_MIN_VALUE] == 7.0
|
||||||
|
assert acc.char_cooling_thresh_temp.properties[PROP_MIN_STEP] == 0.1
|
||||||
|
assert acc.char_heating_thresh_temp.properties[PROP_MAX_VALUE] == DEFAULT_MAX_TEMP
|
||||||
|
assert acc.char_heating_thresh_temp.properties[PROP_MIN_VALUE] == 7.0
|
||||||
|
assert acc.char_heating_thresh_temp.properties[PROP_MIN_STEP] == 0.1
|
||||||
|
|
||||||
|
hass.states.async_set(
|
||||||
|
entity_id,
|
||||||
|
HVAC_MODE_COOL,
|
||||||
|
{
|
||||||
|
ATTR_TARGET_TEMP_HIGH: 23.0,
|
||||||
|
ATTR_TARGET_TEMP_LOW: 19.0,
|
||||||
|
ATTR_CURRENT_TEMPERATURE: 21.0,
|
||||||
|
ATTR_HVAC_ACTION: CURRENT_HVAC_COOL,
|
||||||
|
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()
|
||||||
|
assert acc.char_heating_thresh_temp.value == 19.0
|
||||||
|
assert acc.char_cooling_thresh_temp.value == 23.0
|
||||||
|
assert acc.char_current_heat_cool.value == HC_HEAT_COOL_COOL
|
||||||
|
assert acc.char_target_heat_cool.value == HC_HEAT_COOL_COOL
|
||||||
|
assert acc.char_current_temp.value == 21.0
|
||||||
|
assert acc.char_display_units.value == 0
|
||||||
|
|
||||||
|
# Set from HomeKit
|
||||||
|
call_set_temperature = async_mock_service(hass, DOMAIN_CLIMATE, "set_temperature")
|
||||||
|
call_set_hvac_mode = async_mock_service(hass, DOMAIN_CLIMATE, "set_hvac_mode")
|
||||||
|
|
||||||
|
char_heating_thresh_temp_iid = acc.char_heating_thresh_temp.to_HAP()[HAP_REPR_IID]
|
||||||
|
char_cooling_thresh_temp_iid = acc.char_cooling_thresh_temp.to_HAP()[HAP_REPR_IID]
|
||||||
|
char_target_heat_cool_iid = acc.char_target_heat_cool.to_HAP()[HAP_REPR_IID]
|
||||||
|
|
||||||
|
hk_driver.set_characteristics(
|
||||||
|
{
|
||||||
|
HAP_REPR_CHARS: [
|
||||||
|
{
|
||||||
|
HAP_REPR_AID: acc.aid,
|
||||||
|
HAP_REPR_IID: char_heating_thresh_temp_iid,
|
||||||
|
HAP_REPR_VALUE: 20.0,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
HAP_REPR_AID: acc.aid,
|
||||||
|
HAP_REPR_IID: char_cooling_thresh_temp_iid,
|
||||||
|
HAP_REPR_VALUE: 25.0,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
HAP_REPR_AID: acc.aid,
|
||||||
|
HAP_REPR_IID: char_target_heat_cool_iid,
|
||||||
|
HAP_REPR_VALUE: HC_HEAT_COOL_AUTO,
|
||||||
|
},
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"mock_addr",
|
||||||
|
)
|
||||||
|
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
assert call_set_hvac_mode[0]
|
||||||
|
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_COOL
|
||||||
|
assert call_set_temperature[0]
|
||||||
|
assert call_set_temperature[0].data[ATTR_ENTITY_ID] == entity_id
|
||||||
|
assert call_set_temperature[0].data[ATTR_TARGET_TEMP_LOW] == 20.0
|
||||||
|
assert call_set_temperature[0].data[ATTR_TARGET_TEMP_HIGH] == 25.0
|
||||||
|
assert acc.char_heating_thresh_temp.value == 20.0
|
||||||
|
assert acc.char_cooling_thresh_temp.value == 25.0
|
||||||
|
assert len(events) == 2
|
||||||
|
assert events[-2].data[ATTR_VALUE] == "TargetHeatingCoolingState to 3"
|
||||||
|
assert (
|
||||||
|
events[-1].data[ATTR_VALUE]
|
||||||
|
== "TargetHeatingCoolingState to 3, CoolingThresholdTemperature to 25.0°C, HeatingThresholdTemperature to 20.0°C"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
async def test_thermostat_humidity(hass, hk_driver, events):
|
async def test_thermostat_humidity(hass, hk_driver, events):
|
||||||
"""Test if accessory and HA are updated accordingly with humidity."""
|
"""Test if accessory and HA are updated accordingly with humidity."""
|
||||||
entity_id = "climate.test"
|
entity_id = "climate.test"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user