Throw nest climate API errors as HomeAssistantErrors (#72474)
This commit is contained in:
parent
3e0e8dd105
commit
c181af92a2
2 changed files with 84 additions and 10 deletions
|
@ -6,6 +6,7 @@ from typing import Any, cast
|
||||||
from google_nest_sdm.device import Device
|
from google_nest_sdm.device import Device
|
||||||
from google_nest_sdm.device_manager import DeviceManager
|
from google_nest_sdm.device_manager import DeviceManager
|
||||||
from google_nest_sdm.device_traits import FanTrait, TemperatureTrait
|
from google_nest_sdm.device_traits import FanTrait, TemperatureTrait
|
||||||
|
from google_nest_sdm.exceptions import ApiException
|
||||||
from google_nest_sdm.thermostat_traits import (
|
from google_nest_sdm.thermostat_traits import (
|
||||||
ThermostatEcoTrait,
|
ThermostatEcoTrait,
|
||||||
ThermostatHeatCoolTrait,
|
ThermostatHeatCoolTrait,
|
||||||
|
@ -30,6 +31,7 @@ from homeassistant.components.climate.const import (
|
||||||
from homeassistant.config_entries import ConfigEntry
|
from homeassistant.config_entries import ConfigEntry
|
||||||
from homeassistant.const import ATTR_TEMPERATURE, TEMP_CELSIUS
|
from homeassistant.const import ATTR_TEMPERATURE, TEMP_CELSIUS
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
|
from homeassistant.exceptions import HomeAssistantError
|
||||||
from homeassistant.helpers.entity import DeviceInfo
|
from homeassistant.helpers.entity import DeviceInfo
|
||||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||||
|
|
||||||
|
@ -294,7 +296,10 @@ class ThermostatEntity(ClimateEntity):
|
||||||
hvac_mode = HVACMode.OFF
|
hvac_mode = HVACMode.OFF
|
||||||
api_mode = THERMOSTAT_INV_MODE_MAP[hvac_mode]
|
api_mode = THERMOSTAT_INV_MODE_MAP[hvac_mode]
|
||||||
trait = self._device.traits[ThermostatModeTrait.NAME]
|
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:
|
async def async_set_temperature(self, **kwargs: Any) -> None:
|
||||||
"""Set new target temperature."""
|
"""Set new target temperature."""
|
||||||
|
@ -308,20 +313,26 @@ class ThermostatEntity(ClimateEntity):
|
||||||
if ThermostatTemperatureSetpointTrait.NAME not in self._device.traits:
|
if ThermostatTemperatureSetpointTrait.NAME not in self._device.traits:
|
||||||
return
|
return
|
||||||
trait = self._device.traits[ThermostatTemperatureSetpointTrait.NAME]
|
trait = self._device.traits[ThermostatTemperatureSetpointTrait.NAME]
|
||||||
if self.preset_mode == PRESET_ECO or hvac_mode == HVACMode.HEAT_COOL:
|
try:
|
||||||
if low_temp and high_temp:
|
if self.preset_mode == PRESET_ECO or hvac_mode == HVACMode.HEAT_COOL:
|
||||||
await trait.set_range(low_temp, high_temp)
|
if low_temp and high_temp:
|
||||||
elif hvac_mode == HVACMode.COOL and temp:
|
await trait.set_range(low_temp, high_temp)
|
||||||
await trait.set_cool(temp)
|
elif hvac_mode == HVACMode.COOL and temp:
|
||||||
elif hvac_mode == HVACMode.HEAT and temp:
|
await trait.set_cool(temp)
|
||||||
await trait.set_heat(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:
|
async def async_set_preset_mode(self, preset_mode: str) -> None:
|
||||||
"""Set new target preset mode."""
|
"""Set new target preset mode."""
|
||||||
if preset_mode not in self.preset_modes:
|
if preset_mode not in self.preset_modes:
|
||||||
raise ValueError(f"Unsupported preset_mode '{preset_mode}'")
|
raise ValueError(f"Unsupported preset_mode '{preset_mode}'")
|
||||||
trait = self._device.traits[ThermostatEcoTrait.NAME]
|
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:
|
async def async_set_fan_mode(self, fan_mode: str) -> None:
|
||||||
"""Set new target fan mode."""
|
"""Set new target fan mode."""
|
||||||
|
@ -331,4 +342,7 @@ class ThermostatEntity(ClimateEntity):
|
||||||
duration = None
|
duration = None
|
||||||
if fan_mode != FAN_OFF:
|
if fan_mode != FAN_OFF:
|
||||||
duration = MAX_FAN_DURATION
|
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
|
||||||
|
|
|
@ -6,8 +6,10 @@ pubsub subscriber.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from collections.abc import Awaitable, Callable
|
from collections.abc import Awaitable, Callable
|
||||||
|
from http import HTTPStatus
|
||||||
from typing import Any
|
from typing import Any
|
||||||
|
|
||||||
|
import aiohttp
|
||||||
from google_nest_sdm.auth import AbstractAuth
|
from google_nest_sdm.auth import AbstractAuth
|
||||||
from google_nest_sdm.event import EventMessage
|
from google_nest_sdm.event import EventMessage
|
||||||
import pytest
|
import pytest
|
||||||
|
@ -41,6 +43,7 @@ from homeassistant.components.climate.const import (
|
||||||
)
|
)
|
||||||
from homeassistant.const import ATTR_TEMPERATURE
|
from homeassistant.const import ATTR_TEMPERATURE
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
|
from homeassistant.exceptions import HomeAssistantError
|
||||||
|
|
||||||
from .common import (
|
from .common import (
|
||||||
DEVICE_COMMAND,
|
DEVICE_COMMAND,
|
||||||
|
@ -1380,3 +1383,60 @@ async def test_thermostat_invalid_set_preset_mode(
|
||||||
# Preset is unchanged
|
# Preset is unchanged
|
||||||
assert thermostat.attributes[ATTR_PRESET_MODE] == PRESET_NONE
|
assert thermostat.attributes[ATTR_PRESET_MODE] == PRESET_NONE
|
||||||
assert thermostat.attributes[ATTR_PRESET_MODES] == [PRESET_ECO, 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()
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue