Handle alexa invalid climate temp adjustment (#99740)

* Handle temp adjust when target state not set

* Update homeassistant/components/alexa/errors.py

Co-authored-by: Robert Resch <robert@resch.dev>

* black

---------

Co-authored-by: Robert Resch <robert@resch.dev>
This commit is contained in:
Jan Bouwhuis 2023-09-06 18:54:16 +02:00 committed by GitHub
parent 7a6c8767b3
commit 7c7456df99
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 84 additions and 1 deletions

View file

@ -90,6 +90,13 @@ class AlexaUnsupportedThermostatModeError(AlexaError):
error_type = "UNSUPPORTED_THERMOSTAT_MODE" error_type = "UNSUPPORTED_THERMOSTAT_MODE"
class AlexaUnsupportedThermostatTargetStateError(AlexaError):
"""Class to represent unsupported climate target state error."""
namespace = "Alexa.ThermostatController"
error_type = "INVALID_TARGET_STATE"
class AlexaTempRangeError(AlexaError): class AlexaTempRangeError(AlexaError):
"""Class to represent TempRange errors.""" """Class to represent TempRange errors."""

View file

@ -73,6 +73,7 @@ from .errors import (
AlexaSecurityPanelAuthorizationRequired, AlexaSecurityPanelAuthorizationRequired,
AlexaTempRangeError, AlexaTempRangeError,
AlexaUnsupportedThermostatModeError, AlexaUnsupportedThermostatModeError,
AlexaUnsupportedThermostatTargetStateError,
AlexaVideoActionNotPermittedForContentError, AlexaVideoActionNotPermittedForContentError,
) )
from .state_report import AlexaDirective, AlexaResponse, async_enable_proactive_mode from .state_report import AlexaDirective, AlexaResponse, async_enable_proactive_mode
@ -911,7 +912,13 @@ async def async_api_adjust_target_temp(
} }
) )
else: else:
target_temp = float(entity.attributes[ATTR_TEMPERATURE]) + temp_delta current_target_temp: str | None = entity.attributes.get(ATTR_TEMPERATURE)
if current_target_temp is None:
raise AlexaUnsupportedThermostatTargetStateError(
"The current target temperature is not set, "
"cannot adjust target temperature"
)
target_temp = float(current_target_temp) + temp_delta
if target_temp < min_temp or target_temp > max_temp: if target_temp < min_temp or target_temp > max_temp:
raise AlexaTempRangeError(hass, target_temp, min_temp, max_temp) raise AlexaTempRangeError(hass, target_temp, min_temp, max_temp)

View file

@ -2471,6 +2471,75 @@ async def test_thermostat(hass: HomeAssistant) -> None:
assert call.data["preset_mode"] == "eco" assert call.data["preset_mode"] == "eco"
async def test_no_current_target_temp_adjusting_temp(hass: HomeAssistant) -> None:
"""Test thermostat adjusting temp with no initial target temperature."""
hass.config.units = US_CUSTOMARY_SYSTEM
device = (
"climate.test_thermostat",
"cool",
{
"temperature": None,
"target_temp_high": None,
"target_temp_low": None,
"current_temperature": 75.0,
"friendly_name": "Test Thermostat",
"supported_features": 1 | 2 | 4 | 128,
"hvac_modes": ["off", "heat", "cool", "auto", "dry", "fan_only"],
"preset_mode": None,
"preset_modes": ["eco"],
"min_temp": 50,
"max_temp": 90,
},
)
appliance = await discovery_test(device, hass)
assert appliance["endpointId"] == "climate#test_thermostat"
assert appliance["displayCategories"][0] == "THERMOSTAT"
assert appliance["friendlyName"] == "Test Thermostat"
capabilities = assert_endpoint_capabilities(
appliance,
"Alexa.PowerController",
"Alexa.ThermostatController",
"Alexa.TemperatureSensor",
"Alexa.EndpointHealth",
"Alexa",
)
properties = await reported_properties(hass, "climate#test_thermostat")
properties.assert_equal("Alexa.ThermostatController", "thermostatMode", "COOL")
properties.assert_not_has_property(
"Alexa.ThermostatController",
"targetSetpoint",
)
properties.assert_equal(
"Alexa.TemperatureSensor", "temperature", {"value": 75.0, "scale": "FAHRENHEIT"}
)
thermostat_capability = get_capability(capabilities, "Alexa.ThermostatController")
assert thermostat_capability is not None
configuration = thermostat_capability["configuration"]
assert configuration["supportsScheduling"] is False
supported_modes = ["OFF", "HEAT", "COOL", "AUTO", "ECO", "CUSTOM"]
for mode in supported_modes:
assert mode in configuration["supportedModes"]
# Adjust temperature where target temp is not set
msg = await assert_request_fails(
"Alexa.ThermostatController",
"AdjustTargetTemperature",
"climate#test_thermostat",
"climate.set_temperature",
hass,
payload={"targetSetpointDelta": {"value": -5.0, "scale": "KELVIN"}},
)
assert msg["event"]["payload"]["type"] == "INVALID_TARGET_STATE"
assert msg["event"]["payload"]["message"] == (
"The current target temperature is not set, cannot adjust target temperature"
)
async def test_thermostat_dual(hass: HomeAssistant) -> None: async def test_thermostat_dual(hass: HomeAssistant) -> None:
"""Test thermostat discovery with auto mode, with upper and lower target temperatures.""" """Test thermostat discovery with auto mode, with upper and lower target temperatures."""
hass.config.units = US_CUSTOMARY_SYSTEM hass.config.units = US_CUSTOMARY_SYSTEM