Throw nest climate API errors as HomeAssistantErrors (#72474)

This commit is contained in:
Allen Porter 2022-05-25 13:00:48 -07:00 committed by GitHub
parent 3e0e8dd105
commit c181af92a2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 84 additions and 10 deletions

View File

@ -6,6 +6,7 @@ from typing import Any, cast
from google_nest_sdm.device import Device
from google_nest_sdm.device_manager import DeviceManager
from google_nest_sdm.device_traits import FanTrait, TemperatureTrait
from google_nest_sdm.exceptions import ApiException
from google_nest_sdm.thermostat_traits import (
ThermostatEcoTrait,
ThermostatHeatCoolTrait,
@ -30,6 +31,7 @@ from homeassistant.components.climate.const import (
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import ATTR_TEMPERATURE, TEMP_CELSIUS
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import HomeAssistantError
from homeassistant.helpers.entity import DeviceInfo
from homeassistant.helpers.entity_platform import AddEntitiesCallback
@ -294,7 +296,10 @@ class ThermostatEntity(ClimateEntity):
hvac_mode = HVACMode.OFF
api_mode = THERMOSTAT_INV_MODE_MAP[hvac_mode]
trait = self._device.traits[ThermostatModeTrait.NAME]
await trait.set_mode(api_mode)
try:
await trait.set_mode(api_mode)
except ApiException as err:
raise HomeAssistantError(f"Error setting HVAC mode: {err}") from err
async def async_set_temperature(self, **kwargs: Any) -> None:
"""Set new target temperature."""
@ -308,20 +313,26 @@ class ThermostatEntity(ClimateEntity):
if ThermostatTemperatureSetpointTrait.NAME not in self._device.traits:
return
trait = self._device.traits[ThermostatTemperatureSetpointTrait.NAME]
if self.preset_mode == PRESET_ECO or hvac_mode == HVACMode.HEAT_COOL:
if low_temp and high_temp:
await trait.set_range(low_temp, high_temp)
elif hvac_mode == HVACMode.COOL and temp:
await trait.set_cool(temp)
elif hvac_mode == HVACMode.HEAT and temp:
await trait.set_heat(temp)
try:
if self.preset_mode == PRESET_ECO or hvac_mode == HVACMode.HEAT_COOL:
if low_temp and high_temp:
await trait.set_range(low_temp, high_temp)
elif hvac_mode == HVACMode.COOL and temp:
await trait.set_cool(temp)
elif hvac_mode == HVACMode.HEAT and temp:
await trait.set_heat(temp)
except ApiException as err:
raise HomeAssistantError(f"Error setting HVAC mode: {err}") from err
async def async_set_preset_mode(self, preset_mode: str) -> None:
"""Set new target preset mode."""
if preset_mode not in self.preset_modes:
raise ValueError(f"Unsupported preset_mode '{preset_mode}'")
trait = self._device.traits[ThermostatEcoTrait.NAME]
await trait.set_mode(PRESET_INV_MODE_MAP[preset_mode])
try:
await trait.set_mode(PRESET_INV_MODE_MAP[preset_mode])
except ApiException as err:
raise HomeAssistantError(f"Error setting HVAC mode: {err}") from err
async def async_set_fan_mode(self, fan_mode: str) -> None:
"""Set new target fan mode."""
@ -331,4 +342,7 @@ class ThermostatEntity(ClimateEntity):
duration = None
if fan_mode != FAN_OFF:
duration = MAX_FAN_DURATION
await trait.set_timer(FAN_INV_MODE_MAP[fan_mode], duration=duration)
try:
await trait.set_timer(FAN_INV_MODE_MAP[fan_mode], duration=duration)
except ApiException as err:
raise HomeAssistantError(f"Error setting HVAC mode: {err}") from err

View File

@ -6,8 +6,10 @@ pubsub subscriber.
"""
from collections.abc import Awaitable, Callable
from http import HTTPStatus
from typing import Any
import aiohttp
from google_nest_sdm.auth import AbstractAuth
from google_nest_sdm.event import EventMessage
import pytest
@ -41,6 +43,7 @@ from homeassistant.components.climate.const import (
)
from homeassistant.const import ATTR_TEMPERATURE
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import HomeAssistantError
from .common import (
DEVICE_COMMAND,
@ -1380,3 +1383,60 @@ async def test_thermostat_invalid_set_preset_mode(
# Preset is unchanged
assert thermostat.attributes[ATTR_PRESET_MODE] == PRESET_NONE
assert thermostat.attributes[ATTR_PRESET_MODES] == [PRESET_ECO, PRESET_NONE]
async def test_thermostat_hvac_mode_failure(
hass: HomeAssistant,
setup_platform: PlatformSetup,
auth: FakeAuth,
create_device: CreateDevice,
) -> None:
"""Test setting an hvac_mode that is not supported."""
create_device.create(
{
"sdm.devices.traits.ThermostatHvac": {"status": "OFF"},
"sdm.devices.traits.ThermostatMode": {
"availableModes": ["HEAT", "COOL", "HEATCOOL", "OFF"],
"mode": "OFF",
},
"sdm.devices.traits.Fan": {
"timerMode": "OFF",
"timerTimeout": "2019-05-10T03:22:54Z",
},
"sdm.devices.traits.ThermostatEco": {
"availableModes": ["MANUAL_ECO", "OFF"],
"mode": "OFF",
"heatCelsius": 15.0,
"coolCelsius": 28.0,
},
}
)
await setup_platform()
assert len(hass.states.async_all()) == 1
thermostat = hass.states.get("climate.my_thermostat")
assert thermostat is not None
assert thermostat.state == HVAC_MODE_OFF
assert thermostat.attributes[ATTR_HVAC_ACTION] == CURRENT_HVAC_OFF
auth.responses = [aiohttp.web.Response(status=HTTPStatus.BAD_REQUEST)]
with pytest.raises(HomeAssistantError):
await common.async_set_hvac_mode(hass, HVAC_MODE_HEAT)
await hass.async_block_till_done()
auth.responses = [aiohttp.web.Response(status=HTTPStatus.BAD_REQUEST)]
with pytest.raises(HomeAssistantError):
await common.async_set_temperature(
hass, hvac_mode=HVAC_MODE_HEAT, temperature=25.0
)
await hass.async_block_till_done()
auth.responses = [aiohttp.web.Response(status=HTTPStatus.BAD_REQUEST)]
with pytest.raises(HomeAssistantError):
await common.async_set_fan_mode(hass, FAN_ON)
await hass.async_block_till_done()
auth.responses = [aiohttp.web.Response(status=HTTPStatus.BAD_REQUEST)]
with pytest.raises(HomeAssistantError):
await common.async_set_preset_mode(hass, PRESET_ECO)
await hass.async_block_till_done()