Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update error handling to use HomeAssistantError #627

Merged
merged 3 commits into from
Oct 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 30 additions & 18 deletions custom_components/wyzeapi/alarm_control_panel.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import logging
from datetime import timedelta
from typing import Optional, Callable, List, Any
from aiohttp.client_exceptions import ClientConnectionError

from homeassistant.components.alarm_control_panel import (
AlarmControlPanelEntity,
Expand All @@ -13,8 +14,10 @@
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import ATTR_ATTRIBUTION
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import HomeAssistantError
from wyzeapy import Wyzeapy, HMSService
from wyzeapy.services.hms_service import HMSMode
from wyzeapy.exceptions import AccessTokenError, ParameterError, UnknownApiError
from .token_manager import token_exception_handler

from .const import DOMAIN, CONF_CLIENT
Expand Down Expand Up @@ -63,33 +66,42 @@ def alarm_arm_vacation(self, code: Optional[str] = None) -> None:
def state(self):
return self._state

def alarm_disarm(self, code: Optional[str] = None) -> None:
raise NotImplementedError

def alarm_arm_home(self, code: Optional[str] = None) -> None:
raise NotImplementedError

def alarm_arm_away(self, code: Optional[str] = None) -> None:
raise NotImplementedError

SecKatie marked this conversation as resolved.
Show resolved Hide resolved
@token_exception_handler
async def async_alarm_disarm(self, code=None) -> None:
"""Send disarm command."""
await self._hms_service.set_mode(HMSMode.DISARMED)
self._state = "disarmed"
self._server_out_of_sync = True
try:
await self._hms_service.set_mode(HMSMode.DISARMED)
except (AccessTokenError, ParameterError, UnknownApiError) as err:
raise HomeAssistantError(f"Wyze returned an error: {err.args}") from err
except ClientConnectionError as err:
raise HomeAssistantError(err) from err
else:
self._state = "disarmed"
self._server_out_of_sync = True

@token_exception_handler
async def async_alarm_arm_home(self, code=None):
await self._hms_service.set_mode(HMSMode.HOME)
self._state = "armed_home"
self._server_out_of_sync = True
try:
await self._hms_service.set_mode(HMSMode.HOME)
except (AccessTokenError, ParameterError, UnknownApiError) as err:
raise HomeAssistantError(f"Wyze returned an error: {err.args}") from err
except ClientConnectionError as err:
raise HomeAssistantError(err) from err
else:
self._state = "armed_home"
self._server_out_of_sync = True

@token_exception_handler
async def async_alarm_arm_away(self, code=None):
await self._hms_service.set_mode(HMSMode.AWAY)
self._state = "armed_away"
self._server_out_of_sync = True
try:
await self._hms_service.set_mode(HMSMode.AWAY)
except (AccessTokenError, ParameterError, UnknownApiError) as err:
raise HomeAssistantError(f"Wyze returned an error: {err.args}") from err
except ClientConnectionError as err:
raise HomeAssistantError(err) from err
else:
self._state = "armed_away"
self._server_out_of_sync = True

def alarm_arm_night(self, code=None):
raise NotImplementedError
Expand Down
113 changes: 68 additions & 45 deletions custom_components/wyzeapi/climate.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
# Import the device class from the component that you want to support
from datetime import timedelta
from typing import List, Optional, Callable, Any
from aiohttp.client_exceptions import ClientConnectionError

from homeassistant.components.climate import (
ClimateEntity,
Expand All @@ -20,8 +21,10 @@
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import ATTR_ATTRIBUTION, UnitOfTemperature
from homeassistant.core import HomeAssistant, callback
from homeassistant.exceptions import HomeAssistantError
from homeassistant.helpers import device_registry as dr
from wyzeapy import Wyzeapy, ThermostatService
from wyzeapy.exceptions import AccessTokenError, ParameterError, UnknownApiError
from wyzeapy.services.thermostat_service import Thermostat, TemperatureUnit, Preset, FanMode, HVACState, HVACMode as WyzeHVACMode
from .token_manager import token_exception_handler

Expand Down Expand Up @@ -190,66 +193,86 @@ async def async_set_temperature(self, **kwargs) -> None:
target_temp_low = kwargs['target_temp_low']
target_temp_high = kwargs['target_temp_high']

if target_temp_low != self._thermostat.heat_set_point:
await self._thermostat_service.set_heat_point(self._thermostat, int(target_temp_low))
self._thermostat.heat_set_point = int(target_temp_low)
if target_temp_high != self._thermostat.cool_set_point:
await self._thermostat_service.set_cool_point(self._thermostat, int(target_temp_high))
self._thermostat.cool_set_point = int(target_temp_high)

self._server_out_of_sync = True
self.async_schedule_update_ha_state()
try:
if target_temp_low != self._thermostat.heat_set_point:
await self._thermostat_service.set_heat_point(self._thermostat, int(target_temp_low))
self._thermostat.heat_set_point = int(target_temp_low)
if target_temp_high != self._thermostat.cool_set_point:
await self._thermostat_service.set_cool_point(self._thermostat, int(target_temp_high))
self._thermostat.cool_set_point = int(target_temp_high)
except (AccessTokenError, ParameterError, UnknownApiError) as err:
raise HomeAssistantError(f"Wyze returned an error: {err.args}") from err
except ClientConnectionError as err:
raise HomeAssistantError(err) from err
else:
self._server_out_of_sync = True
self.async_schedule_update_ha_state()

async def async_set_humidity(self, humidity: int) -> None:
raise NotImplementedError

@token_exception_handler
async def async_set_fan_mode(self, fan_mode: str) -> None:
if fan_mode == FAN_ON:
await self._thermostat_service.set_fan_mode(self._thermostat, FanMode.ON)
self._thermostat.fan_mode = FanMode.ON
elif fan_mode == FAN_AUTO:
await self._thermostat_service.set_fan_mode(self._thermostat, FanMode.AUTO)
self._thermostat.fan_mode = FanMode.AUTO

self._server_out_of_sync = True
self.async_schedule_update_ha_state()
try:
if fan_mode == FAN_ON:
await self._thermostat_service.set_fan_mode(self._thermostat, FanMode.ON)
self._thermostat.fan_mode = FanMode.ON
elif fan_mode == FAN_AUTO:
await self._thermostat_service.set_fan_mode(self._thermostat, FanMode.AUTO)
self._thermostat.fan_mode = FanMode.AUTO
except (AccessTokenError, ParameterError, UnknownApiError) as err:
raise HomeAssistantError(f"Wyze returned an error: {err.args}") from err
except ClientConnectionError as err:
raise HomeAssistantError(err) from err
else:
self._server_out_of_sync = True
self.async_schedule_update_ha_state()

@token_exception_handler
async def async_set_hvac_mode(self, hvac_mode: str) -> None:
if hvac_mode == HVACMode.OFF:
await self._thermostat_service.set_hvac_mode(self._thermostat, WyzeHVACMode.OFF)
self._thermostat.hvac_mode = HVACMode.OFF
elif hvac_mode == HVACMode.HEAT:
await self._thermostat_service.set_hvac_mode(self._thermostat, WyzeHVACMode.HEAT)
self._thermostat.hvac_mode = HVACMode.HEAT
elif hvac_mode == HVACMode.COOL:
await self._thermostat_service.set_hvac_mode(self._thermostat, WyzeHVACMode.COOL)
self._thermostat.hvac_mode = HVACMode.COOL
elif hvac_mode == HVACMode.AUTO:
await self._thermostat_service.set_hvac_mode(self._thermostat, WyzeHVACMode.AUTO)
self._thermostat.hvac_mode = HVACMode.AUTO

self._server_out_of_sync = True
self.async_schedule_update_ha_state()
try:
if hvac_mode == HVACMode.OFF:
await self._thermostat_service.set_hvac_mode(self._thermostat, WyzeHVACMode.OFF)
self._thermostat.hvac_mode = HVACMode.OFF
elif hvac_mode == HVACMode.HEAT:
await self._thermostat_service.set_hvac_mode(self._thermostat, WyzeHVACMode.HEAT)
self._thermostat.hvac_mode = HVACMode.HEAT
elif hvac_mode == HVACMode.COOL:
await self._thermostat_service.set_hvac_mode(self._thermostat, WyzeHVACMode.COOL)
self._thermostat.hvac_mode = HVACMode.COOL
elif hvac_mode == HVACMode.AUTO:
await self._thermostat_service.set_hvac_mode(self._thermostat, WyzeHVACMode.AUTO)
self._thermostat.hvac_mode = HVACMode.AUTO
except (AccessTokenError, ParameterError, UnknownApiError) as err:
raise HomeAssistantError(f"Wyze returned an error: {err.args}") from err
except ClientConnectionError as err:
raise HomeAssistantError(err) from err
else:
self._server_out_of_sync = True
self.async_schedule_update_ha_state()

async def async_set_swing_mode(self, swing_mode: str) -> None:
raise NotImplementedError

@token_exception_handler
async def async_set_preset_mode(self, preset_mode: str) -> None:
if preset_mode == PRESET_SLEEP:
await self._thermostat_service.set_preset(self._thermostat, Preset.SLEEP)
self._thermostat.preset = Preset.SLEEP
elif preset_mode == PRESET_AWAY:
await self._thermostat_service.set_preset(self._thermostat, Preset.AWAY)
self._thermostat.preset = Preset.AWAY
elif preset_mode == PRESET_HOME:
await self._thermostat_service.set_preset(self._thermostat, Preset.HOME)
self._thermostat.preset = Preset.HOME

self._server_out_of_sync = True
self.async_schedule_update_ha_state()
try:
if preset_mode == PRESET_SLEEP:
await self._thermostat_service.set_preset(self._thermostat, Preset.SLEEP)
self._thermostat.preset = Preset.SLEEP
elif preset_mode == PRESET_AWAY:
await self._thermostat_service.set_preset(self._thermostat, Preset.AWAY)
self._thermostat.preset = Preset.AWAY
elif preset_mode == PRESET_HOME:
await self._thermostat_service.set_preset(self._thermostat, Preset.HOME)
self._thermostat.preset = Preset.HOME
except (AccessTokenError, ParameterError, UnknownApiError) as err:
raise HomeAssistantError(f"Wyze returned an error: {err.args}") from err
except ClientConnectionError as err:
raise HomeAssistantError(err) from err
else:
self._server_out_of_sync = True
self.async_schedule_update_ha_state()

async def async_turn_aux_heat_on(self) -> None:
raise NotImplementedError
Expand Down
72 changes: 43 additions & 29 deletions custom_components/wyzeapi/light.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
#!/usr/bin/python3

"""Platform for light integration."""
import asyncio
import logging
# Import the device class from the component that you want to support
from datetime import timedelta
from typing import Any, Callable, List
from aiohttp.client_exceptions import ClientConnectionError

import homeassistant.util.color as color_util
from homeassistant.components.light import (
Expand All @@ -21,7 +21,9 @@
from homeassistant.const import ATTR_ATTRIBUTION
from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers import device_registry as dr
from homeassistant.exceptions import HomeAssistantError
from wyzeapy import Wyzeapy, BulbService, CameraService
from wyzeapy.exceptions import AccessTokenError, ParameterError, UnknownApiError
from wyzeapy.services.bulb_service import Bulb
from wyzeapy.types import DeviceTypes, PropertyIDs
from wyzeapy.utils import create_pid_pair
Expand Down Expand Up @@ -100,12 +102,6 @@ def __init__(self, bulb_service: BulbService, bulb: Bulb, config_entry):

self._bulb_service = bulb_service

def turn_on(self, **kwargs: Any) -> None:
raise NotImplementedError

def turn_off(self, **kwargs: Any) -> None:
raise NotImplementedError

brg468 marked this conversation as resolved.
Show resolved Hide resolved
@property
def device_info(self):
return {
Expand Down Expand Up @@ -205,22 +201,30 @@ async def async_turn_on(self, **kwargs: Any) -> None:
self._bulb.effects = "3"

_LOGGER.debug("Turning on light")
loop = asyncio.get_event_loop()
loop.create_task(self._bulb_service.turn_on(self._bulb, self._local_control, options))
SecKatie marked this conversation as resolved.
Show resolved Hide resolved

self._bulb.on = True
self._just_updated = True
self.async_schedule_update_ha_state()
try:
await self._bulb_service.turn_on(self._bulb, self._local_control, options)
except (AccessTokenError, ParameterError, UnknownApiError) as err:
raise HomeAssistantError(f"Wyze returned an error: {err.args}") from err
except ClientConnectionError as err:
raise HomeAssistantError(err) from err
else:
self._bulb.on = True
self._just_updated = True
self.async_schedule_update_ha_state()

@token_exception_handler
async def async_turn_off(self, **kwargs: Any) -> None:
self._local_control = self._config_entry.options.get(BULB_LOCAL_CONTROL)
loop = asyncio.get_event_loop()
loop.create_task(self._bulb_service.turn_off(self._bulb, self._local_control))

self._bulb.on = False
self._just_updated = True
self.async_schedule_update_ha_state()
try:
await self._bulb_service.turn_off(self._bulb, self._local_control)
except (AccessTokenError, ParameterError, UnknownApiError) as err:
raise HomeAssistantError(f"Wyze returned an error: {err.args}") from err
except ClientConnectionError as err:
raise HomeAssistantError(err) from err
else:
self._bulb.on = False
self._just_updated = True
self.async_schedule_update_ha_state()

@property
def supported_color_modes(self):
Expand Down Expand Up @@ -380,20 +384,30 @@ def __init__(self, camera: Camera, camera_service: CameraService, light_type: st
@token_exception_handler
async def async_turn_on(self, **kwargs) -> None:
"""Turn the floodlight on."""
await self._service.floodlight_on(self._device)

self._device.floodlight = True
self._just_updated = True
self.async_schedule_update_ha_state()
try:
await self._service.floodlight_on(self._device)
except (AccessTokenError, ParameterError, UnknownApiError) as err:
raise HomeAssistantError(f"Wyze returned an error: {err.args}") from err
except ClientConnectionError as err:
raise HomeAssistantError(err) from err
else:
self._is_on = True
self._just_updated = True
self.async_schedule_update_ha_state()

@token_exception_handler
async def async_turn_off(self, **kwargs):
"""Turn the floodlight off."""
await self._service.floodlight_off(self._device)

self._device.floodlight = False
self._just_updated = True
self.async_schedule_update_ha_state()
try:
await self._service.floodlight_off(self._device)
except (AccessTokenError, ParameterError, UnknownApiError) as err:
raise HomeAssistantError(f"Wyze returned an error: {err.args}") from err
except ClientConnectionError as err:
raise HomeAssistantError(err) from err
else:
self._is_on = False
self._just_updated = True
self.async_schedule_update_ha_state()

@property
def should_poll(self) -> bool:
Expand Down
Loading
Loading