Reolink improve error handeling (#104301)

* Raise proper HomeAssistantError

* fix styling

* Use ServiceValidationError
This commit is contained in:
starkillerOG 2023-11-21 17:21:48 +01:00 committed by GitHub
parent dece6c8042
commit 6d529a82d7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 92 additions and 23 deletions

View File

@ -6,6 +6,7 @@ from dataclasses import dataclass
from typing import Any from typing import Any
from reolink_aio.api import GuardEnum, Host, PtzEnum from reolink_aio.api import GuardEnum, Host, PtzEnum
from reolink_aio.exceptions import ReolinkError
from homeassistant.components.button import ( from homeassistant.components.button import (
ButtonDeviceClass, ButtonDeviceClass,
@ -15,6 +16,7 @@ from homeassistant.components.button import (
from homeassistant.config_entries import ConfigEntry from homeassistant.config_entries import ConfigEntry
from homeassistant.const import EntityCategory from homeassistant.const import EntityCategory
from homeassistant.core import HomeAssistant from homeassistant.core import HomeAssistant
from homeassistant.exceptions import HomeAssistantError
from homeassistant.helpers.entity_platform import AddEntitiesCallback from homeassistant.helpers.entity_platform import AddEntitiesCallback
from . import ReolinkData from . import ReolinkData
@ -181,7 +183,10 @@ class ReolinkButtonEntity(ReolinkChannelCoordinatorEntity, ButtonEntity):
async def async_press(self) -> None: async def async_press(self) -> None:
"""Execute the button action.""" """Execute the button action."""
await self.entity_description.method(self._host.api, self._channel) try:
await self.entity_description.method(self._host.api, self._channel)
except ReolinkError as err:
raise HomeAssistantError(err) from err
class ReolinkHostButtonEntity(ReolinkHostCoordinatorEntity, ButtonEntity): class ReolinkHostButtonEntity(ReolinkHostCoordinatorEntity, ButtonEntity):
@ -202,4 +207,7 @@ class ReolinkHostButtonEntity(ReolinkHostCoordinatorEntity, ButtonEntity):
async def async_press(self) -> None: async def async_press(self) -> None:
"""Execute the button action.""" """Execute the button action."""
await self.entity_description.method(self._host.api) try:
await self.entity_description.method(self._host.api)
except ReolinkError as err:
raise HomeAssistantError(err) from err

View File

@ -6,6 +6,7 @@ from dataclasses import dataclass
import logging import logging
from reolink_aio.api import DUAL_LENS_MODELS, Host from reolink_aio.api import DUAL_LENS_MODELS, Host
from reolink_aio.exceptions import ReolinkError
from homeassistant.components.camera import ( from homeassistant.components.camera import (
Camera, Camera,
@ -14,6 +15,7 @@ from homeassistant.components.camera import (
) )
from homeassistant.config_entries import ConfigEntry from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant from homeassistant.core import HomeAssistant
from homeassistant.exceptions import HomeAssistantError
from homeassistant.helpers.entity_platform import AddEntitiesCallback from homeassistant.helpers.entity_platform import AddEntitiesCallback
from . import ReolinkData from . import ReolinkData
@ -147,6 +149,9 @@ class ReolinkCamera(ReolinkChannelCoordinatorEntity, Camera):
self, width: int | None = None, height: int | None = None self, width: int | None = None, height: int | None = None
) -> bytes | None: ) -> bytes | None:
"""Return a still image response from the camera.""" """Return a still image response from the camera."""
return await self._host.api.get_snapshot( try:
self._channel, self.entity_description.stream return await self._host.api.get_snapshot(
) self._channel, self.entity_description.stream
)
except ReolinkError as err:
raise HomeAssistantError(err) from err

View File

@ -6,6 +6,7 @@ from dataclasses import dataclass
from typing import Any from typing import Any
from reolink_aio.api import Host from reolink_aio.api import Host
from reolink_aio.exceptions import InvalidParameterError, ReolinkError
from homeassistant.components.light import ( from homeassistant.components.light import (
ATTR_BRIGHTNESS, ATTR_BRIGHTNESS,
@ -16,6 +17,7 @@ from homeassistant.components.light import (
from homeassistant.config_entries import ConfigEntry from homeassistant.config_entries import ConfigEntry
from homeassistant.const import EntityCategory from homeassistant.const import EntityCategory
from homeassistant.core import HomeAssistant from homeassistant.core import HomeAssistant
from homeassistant.exceptions import HomeAssistantError, ServiceValidationError
from homeassistant.helpers.entity_platform import AddEntitiesCallback from homeassistant.helpers.entity_platform import AddEntitiesCallback
from . import ReolinkData from . import ReolinkData
@ -129,9 +131,12 @@ class ReolinkLightEntity(ReolinkChannelCoordinatorEntity, LightEntity):
async def async_turn_off(self, **kwargs: Any) -> None: async def async_turn_off(self, **kwargs: Any) -> None:
"""Turn light off.""" """Turn light off."""
await self.entity_description.turn_on_off_fn( try:
self._host.api, self._channel, False await self.entity_description.turn_on_off_fn(
) self._host.api, self._channel, False
)
except ReolinkError as err:
raise HomeAssistantError(err) from err
self.async_write_ha_state() self.async_write_ha_state()
async def async_turn_on(self, **kwargs: Any) -> None: async def async_turn_on(self, **kwargs: Any) -> None:
@ -140,11 +145,19 @@ class ReolinkLightEntity(ReolinkChannelCoordinatorEntity, LightEntity):
brightness := kwargs.get(ATTR_BRIGHTNESS) brightness := kwargs.get(ATTR_BRIGHTNESS)
) is not None and self.entity_description.set_brightness_fn is not None: ) is not None and self.entity_description.set_brightness_fn is not None:
brightness_pct = int(brightness / 255.0 * 100) brightness_pct = int(brightness / 255.0 * 100)
await self.entity_description.set_brightness_fn( try:
self._host.api, self._channel, brightness_pct await self.entity_description.set_brightness_fn(
) self._host.api, self._channel, brightness_pct
)
except InvalidParameterError as err:
raise ServiceValidationError(err) from err
except ReolinkError as err:
raise HomeAssistantError(err) from err
await self.entity_description.turn_on_off_fn( try:
self._host.api, self._channel, True await self.entity_description.turn_on_off_fn(
) self._host.api, self._channel, True
)
except ReolinkError as err:
raise HomeAssistantError(err) from err
self.async_write_ha_state() self.async_write_ha_state()

View File

@ -6,6 +6,7 @@ from dataclasses import dataclass
from typing import Any from typing import Any
from reolink_aio.api import Host from reolink_aio.api import Host
from reolink_aio.exceptions import InvalidParameterError, ReolinkError
from homeassistant.components.number import ( from homeassistant.components.number import (
NumberEntity, NumberEntity,
@ -15,6 +16,7 @@ from homeassistant.components.number import (
from homeassistant.config_entries import ConfigEntry from homeassistant.config_entries import ConfigEntry
from homeassistant.const import EntityCategory, UnitOfTime from homeassistant.const import EntityCategory, UnitOfTime
from homeassistant.core import HomeAssistant from homeassistant.core import HomeAssistant
from homeassistant.exceptions import HomeAssistantError, ServiceValidationError
from homeassistant.helpers.entity_platform import AddEntitiesCallback from homeassistant.helpers.entity_platform import AddEntitiesCallback
from . import ReolinkData from . import ReolinkData
@ -399,5 +401,10 @@ class ReolinkNumberEntity(ReolinkChannelCoordinatorEntity, NumberEntity):
async def async_set_native_value(self, value: float) -> None: async def async_set_native_value(self, value: float) -> None:
"""Update the current value.""" """Update the current value."""
await self.entity_description.method(self._host.api, self._channel, value) try:
await self.entity_description.method(self._host.api, self._channel, value)
except InvalidParameterError as err:
raise ServiceValidationError(err) from err
except ReolinkError as err:
raise HomeAssistantError(err) from err
self.async_write_ha_state() self.async_write_ha_state()

View File

@ -13,11 +13,13 @@ from reolink_aio.api import (
StatusLedEnum, StatusLedEnum,
TrackMethodEnum, TrackMethodEnum,
) )
from reolink_aio.exceptions import InvalidParameterError, ReolinkError
from homeassistant.components.select import SelectEntity, SelectEntityDescription from homeassistant.components.select import SelectEntity, SelectEntityDescription
from homeassistant.config_entries import ConfigEntry from homeassistant.config_entries import ConfigEntry
from homeassistant.const import EntityCategory from homeassistant.const import EntityCategory
from homeassistant.core import HomeAssistant from homeassistant.core import HomeAssistant
from homeassistant.exceptions import HomeAssistantError, ServiceValidationError
from homeassistant.helpers.entity_platform import AddEntitiesCallback from homeassistant.helpers.entity_platform import AddEntitiesCallback
from . import ReolinkData from . import ReolinkData
@ -161,5 +163,10 @@ class ReolinkSelectEntity(ReolinkChannelCoordinatorEntity, SelectEntity):
async def async_select_option(self, option: str) -> None: async def async_select_option(self, option: str) -> None:
"""Change the selected option.""" """Change the selected option."""
await self.entity_description.method(self._host.api, self._channel, option) try:
await self.entity_description.method(self._host.api, self._channel, option)
except InvalidParameterError as err:
raise ServiceValidationError(err) from err
except ReolinkError as err:
raise HomeAssistantError(err) from err
self.async_write_ha_state() self.async_write_ha_state()

View File

@ -6,6 +6,7 @@ from dataclasses import dataclass
from typing import Any from typing import Any
from reolink_aio.api import Host from reolink_aio.api import Host
from reolink_aio.exceptions import InvalidParameterError, ReolinkError
from homeassistant.components.siren import ( from homeassistant.components.siren import (
ATTR_DURATION, ATTR_DURATION,
@ -16,6 +17,7 @@ from homeassistant.components.siren import (
) )
from homeassistant.config_entries import ConfigEntry from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant from homeassistant.core import HomeAssistant
from homeassistant.exceptions import HomeAssistantError, ServiceValidationError
from homeassistant.helpers.entity_platform import AddEntitiesCallback from homeassistant.helpers.entity_platform import AddEntitiesCallback
from . import ReolinkData from . import ReolinkData
@ -84,10 +86,23 @@ class ReolinkSirenEntity(ReolinkChannelCoordinatorEntity, SirenEntity):
async def async_turn_on(self, **kwargs: Any) -> None: async def async_turn_on(self, **kwargs: Any) -> None:
"""Turn on the siren.""" """Turn on the siren."""
if (volume := kwargs.get(ATTR_VOLUME_LEVEL)) is not None: if (volume := kwargs.get(ATTR_VOLUME_LEVEL)) is not None:
await self._host.api.set_volume(self._channel, int(volume * 100)) try:
await self._host.api.set_volume(self._channel, int(volume * 100))
except InvalidParameterError as err:
raise ServiceValidationError(err) from err
except ReolinkError as err:
raise HomeAssistantError(err) from err
duration = kwargs.get(ATTR_DURATION) duration = kwargs.get(ATTR_DURATION)
await self._host.api.set_siren(self._channel, True, duration) try:
await self._host.api.set_siren(self._channel, True, duration)
except InvalidParameterError as err:
raise ServiceValidationError(err) from err
except ReolinkError as err:
raise HomeAssistantError(err) from err
async def async_turn_off(self, **kwargs: Any) -> None: async def async_turn_off(self, **kwargs: Any) -> None:
"""Turn off the siren.""" """Turn off the siren."""
await self._host.api.set_siren(self._channel, False, None) try:
await self._host.api.set_siren(self._channel, False, None)
except ReolinkError as err:
raise HomeAssistantError(err) from err

View File

@ -6,11 +6,13 @@ from dataclasses import dataclass
from typing import Any from typing import Any
from reolink_aio.api import Host from reolink_aio.api import Host
from reolink_aio.exceptions import ReolinkError
from homeassistant.components.switch import SwitchEntity, SwitchEntityDescription from homeassistant.components.switch import SwitchEntity, SwitchEntityDescription
from homeassistant.config_entries import ConfigEntry from homeassistant.config_entries import ConfigEntry
from homeassistant.const import EntityCategory from homeassistant.const import EntityCategory
from homeassistant.core import HomeAssistant from homeassistant.core import HomeAssistant
from homeassistant.exceptions import HomeAssistantError
from homeassistant.helpers.entity_platform import AddEntitiesCallback from homeassistant.helpers.entity_platform import AddEntitiesCallback
from . import ReolinkData from . import ReolinkData
@ -247,12 +249,18 @@ class ReolinkSwitchEntity(ReolinkChannelCoordinatorEntity, SwitchEntity):
async def async_turn_on(self, **kwargs: Any) -> None: async def async_turn_on(self, **kwargs: Any) -> None:
"""Turn the entity on.""" """Turn the entity on."""
await self.entity_description.method(self._host.api, self._channel, True) try:
await self.entity_description.method(self._host.api, self._channel, True)
except ReolinkError as err:
raise HomeAssistantError(err) from err
self.async_write_ha_state() self.async_write_ha_state()
async def async_turn_off(self, **kwargs: Any) -> None: async def async_turn_off(self, **kwargs: Any) -> None:
"""Turn the entity off.""" """Turn the entity off."""
await self.entity_description.method(self._host.api, self._channel, False) try:
await self.entity_description.method(self._host.api, self._channel, False)
except ReolinkError as err:
raise HomeAssistantError(err) from err
self.async_write_ha_state() self.async_write_ha_state()
@ -279,10 +287,16 @@ class ReolinkNVRSwitchEntity(ReolinkHostCoordinatorEntity, SwitchEntity):
async def async_turn_on(self, **kwargs: Any) -> None: async def async_turn_on(self, **kwargs: Any) -> None:
"""Turn the entity on.""" """Turn the entity on."""
await self.entity_description.method(self._host.api, True) try:
await self.entity_description.method(self._host.api, True)
except ReolinkError as err:
raise HomeAssistantError(err) from err
self.async_write_ha_state() self.async_write_ha_state()
async def async_turn_off(self, **kwargs: Any) -> None: async def async_turn_off(self, **kwargs: Any) -> None:
"""Turn the entity off.""" """Turn the entity off."""
await self.entity_description.method(self._host.api, False) try:
await self.entity_description.method(self._host.api, False)
except ReolinkError as err:
raise HomeAssistantError(err) from err
self.async_write_ha_state() self.async_write_ha_state()