From 5d282db439cc5f2bb3ca6e6116bda19d74ae86b8 Mon Sep 17 00:00:00 2001 From: Pascal Reeb Date: Sun, 30 Oct 2022 16:36:19 +0100 Subject: [PATCH] Handle HTTPError on nuki integration (#80801) fix(nuki): handle requests errors --- homeassistant/components/nuki/config_flow.py | 12 +---- homeassistant/components/nuki/helpers.py | 9 ++++ homeassistant/components/nuki/lock.py | 48 +++++++++++++++----- 3 files changed, 48 insertions(+), 21 deletions(-) diff --git a/homeassistant/components/nuki/config_flow.py b/homeassistant/components/nuki/config_flow.py index 85144d9bb77..310197d55d8 100644 --- a/homeassistant/components/nuki/config_flow.py +++ b/homeassistant/components/nuki/config_flow.py @@ -8,13 +8,13 @@ from pynuki.bridge import InvalidCredentialsException from requests.exceptions import RequestException import voluptuous as vol -from homeassistant import config_entries, exceptions +from homeassistant import config_entries from homeassistant.components import dhcp from homeassistant.const import CONF_HOST, CONF_PORT, CONF_TOKEN from homeassistant.data_entry_flow import FlowResult from .const import DEFAULT_PORT, DEFAULT_TIMEOUT, DOMAIN -from .helpers import parse_id +from .helpers import CannotConnect, InvalidAuth, parse_id _LOGGER = logging.getLogger(__name__) @@ -153,11 +153,3 @@ class NukiConfigFlow(config_entries.ConfigFlow, domain=DOMAIN): return self.async_show_form( step_id="user", data_schema=data_schema, errors=errors ) - - -class CannotConnect(exceptions.HomeAssistantError): - """Error to indicate we cannot connect.""" - - -class InvalidAuth(exceptions.HomeAssistantError): - """Error to indicate there is invalid auth.""" diff --git a/homeassistant/components/nuki/helpers.py b/homeassistant/components/nuki/helpers.py index 3deedf9d8db..45b7420754a 100644 --- a/homeassistant/components/nuki/helpers.py +++ b/homeassistant/components/nuki/helpers.py @@ -1,6 +1,15 @@ """nuki integration helpers.""" +from homeassistant import exceptions def parse_id(hardware_id): """Parse Nuki ID.""" return hex(hardware_id).split("x")[-1].upper() + + +class CannotConnect(exceptions.HomeAssistantError): + """Error to indicate we cannot connect.""" + + +class InvalidAuth(exceptions.HomeAssistantError): + """Error to indicate there is invalid auth.""" diff --git a/homeassistant/components/nuki/lock.py b/homeassistant/components/nuki/lock.py index 8b6c843f48a..4b89b0d3535 100644 --- a/homeassistant/components/nuki/lock.py +++ b/homeassistant/components/nuki/lock.py @@ -6,6 +6,7 @@ from typing import Any from pynuki import NukiLock, NukiOpener from pynuki.constants import MODE_OPENER_CONTINUOUS +from requests.exceptions import RequestException import voluptuous as vol from homeassistant.components.lock import LockEntity, LockEntityFeature @@ -26,6 +27,7 @@ from .const import ( DOMAIN as NUKI_DOMAIN, ERROR_STATES, ) +from .helpers import CannotConnect async def async_setup_entry( @@ -114,15 +116,24 @@ class NukiLockEntity(NukiDeviceEntity): def lock(self, **kwargs: Any) -> None: """Lock the device.""" - self._nuki_device.lock() + try: + self._nuki_device.lock() + except RequestException as err: + raise CannotConnect from err def unlock(self, **kwargs: Any) -> None: """Unlock the device.""" - self._nuki_device.unlock() + try: + self._nuki_device.unlock() + except RequestException as err: + raise CannotConnect from err def open(self, **kwargs: Any) -> None: """Open the door latch.""" - self._nuki_device.unlatch() + try: + self._nuki_device.unlatch() + except RequestException as err: + raise CannotConnect from err def lock_n_go(self, unlatch: bool) -> None: """Lock and go. @@ -130,7 +141,10 @@ class NukiLockEntity(NukiDeviceEntity): This will first unlock the door, then wait for 20 seconds (or another amount of time depending on the lock settings) and relock. """ - self._nuki_device.lock_n_go(unlatch) + try: + self._nuki_device.lock_n_go(unlatch) + except RequestException as err: + raise CannotConnect from err class NukiOpenerEntity(NukiDeviceEntity): @@ -148,15 +162,24 @@ class NukiOpenerEntity(NukiDeviceEntity): def lock(self, **kwargs: Any) -> None: """Disable ring-to-open.""" - self._nuki_device.deactivate_rto() + try: + self._nuki_device.deactivate_rto() + except RequestException as err: + raise CannotConnect from err def unlock(self, **kwargs: Any) -> None: """Enable ring-to-open.""" - self._nuki_device.activate_rto() + try: + self._nuki_device.activate_rto() + except RequestException as err: + raise CannotConnect from err def open(self, **kwargs: Any) -> None: """Buzz open the door.""" - self._nuki_device.electric_strike_actuation() + try: + self._nuki_device.electric_strike_actuation() + except RequestException as err: + raise CannotConnect from err def lock_n_go(self, unlatch: bool) -> None: """Stub service.""" @@ -168,7 +191,10 @@ class NukiOpenerEntity(NukiDeviceEntity): rings the bell. This is similar to ring-to-open, except that it does not automatically deactivate """ - if enable: - self._nuki_device.activate_continuous_mode() - else: - self._nuki_device.deactivate_continuous_mode() + try: + if enable: + self._nuki_device.activate_continuous_mode() + else: + self._nuki_device.deactivate_continuous_mode() + except RequestException as err: + raise CannotConnect from err