Bump reolink-aio to 0.3.0 (#86259)
* Bump reolink-aio to 0.3.0 * fix typo * ReolinkException
This commit is contained in:
parent
4be7b62607
commit
3c4455c696
7 changed files with 38 additions and 60 deletions
|
@ -12,8 +12,10 @@ import async_timeout
|
||||||
from reolink_aio.exceptions import (
|
from reolink_aio.exceptions import (
|
||||||
ApiError,
|
ApiError,
|
||||||
InvalidContentTypeError,
|
InvalidContentTypeError,
|
||||||
|
LoginError,
|
||||||
NoDataError,
|
NoDataError,
|
||||||
ReolinkError,
|
ReolinkError,
|
||||||
|
UnexpectedDataError,
|
||||||
)
|
)
|
||||||
|
|
||||||
from homeassistant.config_entries import ConfigEntry
|
from homeassistant.config_entries import ConfigEntry
|
||||||
|
@ -23,7 +25,7 @@ from homeassistant.exceptions import ConfigEntryAuthFailed, ConfigEntryNotReady
|
||||||
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed
|
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed
|
||||||
|
|
||||||
from .const import DOMAIN
|
from .const import DOMAIN
|
||||||
from .exceptions import UserNotAdmin
|
from .exceptions import ReolinkException, UserNotAdmin
|
||||||
from .host import ReolinkHost
|
from .host import ReolinkHost
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
@ -45,12 +47,7 @@ async def async_setup_entry(hass: HomeAssistant, config_entry: ConfigEntry) -> b
|
||||||
host = ReolinkHost(hass, config_entry.data, config_entry.options)
|
host = ReolinkHost(hass, config_entry.data, config_entry.options)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
if not await host.async_init():
|
await host.async_init()
|
||||||
await host.stop()
|
|
||||||
raise ConfigEntryNotReady(
|
|
||||||
f"Error while trying to setup {host.api.host}:{host.api.port}: "
|
|
||||||
"failed to obtain data from device."
|
|
||||||
)
|
|
||||||
except UserNotAdmin as err:
|
except UserNotAdmin as err:
|
||||||
raise ConfigEntryAuthFailed(err) from UserNotAdmin
|
raise ConfigEntryAuthFailed(err) from UserNotAdmin
|
||||||
except (
|
except (
|
||||||
|
@ -58,7 +55,10 @@ async def async_setup_entry(hass: HomeAssistant, config_entry: ConfigEntry) -> b
|
||||||
asyncio.TimeoutError,
|
asyncio.TimeoutError,
|
||||||
ApiError,
|
ApiError,
|
||||||
InvalidContentTypeError,
|
InvalidContentTypeError,
|
||||||
|
LoginError,
|
||||||
NoDataError,
|
NoDataError,
|
||||||
|
ReolinkException,
|
||||||
|
UnexpectedDataError,
|
||||||
) as err:
|
) as err:
|
||||||
await host.stop()
|
await host.stop()
|
||||||
raise ConfigEntryNotReady(
|
raise ConfigEntryNotReady(
|
||||||
|
|
|
@ -8,14 +8,14 @@ from typing import Any
|
||||||
from reolink_aio.exceptions import ApiError, CredentialsInvalidError, ReolinkError
|
from reolink_aio.exceptions import ApiError, CredentialsInvalidError, ReolinkError
|
||||||
import voluptuous as vol
|
import voluptuous as vol
|
||||||
|
|
||||||
from homeassistant import config_entries, exceptions
|
from homeassistant import config_entries
|
||||||
from homeassistant.const import CONF_HOST, CONF_PASSWORD, CONF_PORT, CONF_USERNAME
|
from homeassistant.const import CONF_HOST, CONF_PASSWORD, CONF_PORT, CONF_USERNAME
|
||||||
from homeassistant.core import callback
|
from homeassistant.core import callback
|
||||||
from homeassistant.data_entry_flow import FlowResult
|
from homeassistant.data_entry_flow import FlowResult
|
||||||
from homeassistant.helpers import config_validation as cv
|
from homeassistant.helpers import config_validation as cv
|
||||||
|
|
||||||
from .const import CONF_PROTOCOL, CONF_USE_HTTPS, DEFAULT_PROTOCOL, DOMAIN
|
from .const import CONF_PROTOCOL, CONF_USE_HTTPS, DEFAULT_PROTOCOL, DOMAIN
|
||||||
from .exceptions import UserNotAdmin
|
from .exceptions import ReolinkException, UserNotAdmin
|
||||||
from .host import ReolinkHost
|
from .host import ReolinkHost
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
@ -96,25 +96,25 @@ class ReolinkFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
|
||||||
if user_input is not None:
|
if user_input is not None:
|
||||||
host = ReolinkHost(self.hass, user_input, DEFAULT_OPTIONS)
|
host = ReolinkHost(self.hass, user_input, DEFAULT_OPTIONS)
|
||||||
try:
|
try:
|
||||||
await async_obtain_host_settings(host)
|
await host.async_init()
|
||||||
except UserNotAdmin:
|
except UserNotAdmin:
|
||||||
errors[CONF_USERNAME] = "not_admin"
|
errors[CONF_USERNAME] = "not_admin"
|
||||||
placeholders["username"] = host.api.username
|
placeholders["username"] = host.api.username
|
||||||
placeholders["userlevel"] = host.api.user_level
|
placeholders["userlevel"] = host.api.user_level
|
||||||
except CannotConnect:
|
|
||||||
errors[CONF_HOST] = "cannot_connect"
|
|
||||||
except CredentialsInvalidError:
|
except CredentialsInvalidError:
|
||||||
errors[CONF_HOST] = "invalid_auth"
|
errors[CONF_HOST] = "invalid_auth"
|
||||||
except ApiError as err:
|
except ApiError as err:
|
||||||
placeholders["error"] = str(err)
|
placeholders["error"] = str(err)
|
||||||
errors[CONF_HOST] = "api_error"
|
errors[CONF_HOST] = "api_error"
|
||||||
except ReolinkError as err:
|
except (ReolinkError, ReolinkException) as err:
|
||||||
placeholders["error"] = str(err)
|
placeholders["error"] = str(err)
|
||||||
errors[CONF_HOST] = "cannot_connect"
|
errors[CONF_HOST] = "cannot_connect"
|
||||||
except Exception as err: # pylint: disable=broad-except
|
except Exception as err: # pylint: disable=broad-except
|
||||||
_LOGGER.exception("Unexpected exception")
|
_LOGGER.exception("Unexpected exception")
|
||||||
placeholders["error"] = str(err)
|
placeholders["error"] = str(err)
|
||||||
errors[CONF_HOST] = "unknown"
|
errors[CONF_HOST] = "unknown"
|
||||||
|
finally:
|
||||||
|
await host.stop()
|
||||||
|
|
||||||
if not errors:
|
if not errors:
|
||||||
user_input[CONF_PORT] = host.api.port
|
user_input[CONF_PORT] = host.api.port
|
||||||
|
@ -160,16 +160,3 @@ class ReolinkFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
|
||||||
errors=errors,
|
errors=errors,
|
||||||
description_placeholders=placeholders,
|
description_placeholders=placeholders,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
async def async_obtain_host_settings(host: ReolinkHost) -> None:
|
|
||||||
"""Initialize the Reolink host and get the host information."""
|
|
||||||
try:
|
|
||||||
if not await host.async_init():
|
|
||||||
raise CannotConnect
|
|
||||||
finally:
|
|
||||||
await host.stop()
|
|
||||||
|
|
||||||
|
|
||||||
class CannotConnect(exceptions.HomeAssistantError):
|
|
||||||
"""Error to indicate we cannot connect."""
|
|
||||||
|
|
|
@ -2,5 +2,13 @@
|
||||||
from homeassistant.exceptions import HomeAssistantError
|
from homeassistant.exceptions import HomeAssistantError
|
||||||
|
|
||||||
|
|
||||||
class UserNotAdmin(HomeAssistantError):
|
class ReolinkException(HomeAssistantError):
|
||||||
|
"""BaseException for the Reolink integration."""
|
||||||
|
|
||||||
|
|
||||||
|
class ReolinkSetupException(ReolinkException):
|
||||||
|
"""Raised when setting up the Reolink host failed."""
|
||||||
|
|
||||||
|
|
||||||
|
class UserNotAdmin(ReolinkException):
|
||||||
"""Raised when user is not admin."""
|
"""Raised when user is not admin."""
|
||||||
|
|
|
@ -8,18 +8,14 @@ from typing import Any
|
||||||
|
|
||||||
import aiohttp
|
import aiohttp
|
||||||
from reolink_aio.api import Host
|
from reolink_aio.api import Host
|
||||||
from reolink_aio.exceptions import (
|
from reolink_aio.exceptions import ReolinkError
|
||||||
ApiError,
|
|
||||||
CredentialsInvalidError,
|
|
||||||
InvalidContentTypeError,
|
|
||||||
)
|
|
||||||
|
|
||||||
from homeassistant.const import CONF_HOST, CONF_PASSWORD, CONF_PORT, CONF_USERNAME
|
from homeassistant.const import CONF_HOST, CONF_PASSWORD, CONF_PORT, CONF_USERNAME
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
from homeassistant.helpers.device_registry import format_mac
|
from homeassistant.helpers.device_registry import format_mac
|
||||||
|
|
||||||
from .const import CONF_PROTOCOL, CONF_USE_HTTPS, DEFAULT_TIMEOUT
|
from .const import CONF_PROTOCOL, CONF_USE_HTTPS, DEFAULT_TIMEOUT
|
||||||
from .exceptions import UserNotAdmin
|
from .exceptions import ReolinkSetupException, UserNotAdmin
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
@ -59,14 +55,14 @@ class ReolinkHost:
|
||||||
"""Return the API object."""
|
"""Return the API object."""
|
||||||
return self._api
|
return self._api
|
||||||
|
|
||||||
async def async_init(self) -> bool:
|
async def async_init(self) -> None:
|
||||||
"""Connect to Reolink host."""
|
"""Connect to Reolink host."""
|
||||||
self._api.expire_session()
|
self._api.expire_session()
|
||||||
|
|
||||||
await self._api.get_host_data()
|
await self._api.get_host_data()
|
||||||
|
|
||||||
if self._api.mac_address is None:
|
if self._api.mac_address is None:
|
||||||
return False
|
raise ReolinkSetupException("Could not get mac address")
|
||||||
|
|
||||||
if not self._api.is_admin:
|
if not self._api.is_admin:
|
||||||
await self.stop()
|
await self.stop()
|
||||||
|
@ -96,11 +92,13 @@ class ReolinkHost:
|
||||||
enable_rtsp = True
|
enable_rtsp = True
|
||||||
|
|
||||||
if enable_onvif or enable_rtmp or enable_rtsp:
|
if enable_onvif or enable_rtmp or enable_rtsp:
|
||||||
if not await self._api.set_net_port(
|
try:
|
||||||
|
await self._api.set_net_port(
|
||||||
enable_onvif=enable_onvif,
|
enable_onvif=enable_onvif,
|
||||||
enable_rtmp=enable_rtmp,
|
enable_rtmp=enable_rtmp,
|
||||||
enable_rtsp=enable_rtsp,
|
enable_rtsp=enable_rtsp,
|
||||||
):
|
)
|
||||||
|
except ReolinkError:
|
||||||
if enable_onvif:
|
if enable_onvif:
|
||||||
_LOGGER.error(
|
_LOGGER.error(
|
||||||
"Failed to enable ONVIF on %s. Set it to ON to receive notifications",
|
"Failed to enable ONVIF on %s. Set it to ON to receive notifications",
|
||||||
|
@ -120,8 +118,6 @@ class ReolinkHost:
|
||||||
|
|
||||||
self._unique_id = format_mac(self._api.mac_address)
|
self._unique_id = format_mac(self._api.mac_address)
|
||||||
|
|
||||||
return True
|
|
||||||
|
|
||||||
async def update_states(self) -> None:
|
async def update_states(self) -> None:
|
||||||
"""Call the API of the camera device to update the internal states."""
|
"""Call the API of the camera device to update the internal states."""
|
||||||
await self._api.get_states()
|
await self._api.get_states()
|
||||||
|
@ -145,22 +141,9 @@ class ReolinkHost:
|
||||||
self._api.host,
|
self._api.host,
|
||||||
self._api.port,
|
self._api.port,
|
||||||
)
|
)
|
||||||
except ApiError as err:
|
except ReolinkError as err:
|
||||||
_LOGGER.error(
|
_LOGGER.error(
|
||||||
"Reolink API error while logging out for host %s:%s: %s",
|
"Reolink error while logging out for host %s:%s: %s",
|
||||||
self._api.host,
|
|
||||||
self._api.port,
|
|
||||||
str(err),
|
|
||||||
)
|
|
||||||
except CredentialsInvalidError:
|
|
||||||
_LOGGER.error(
|
|
||||||
"Reolink credentials error while logging out for host %s:%s",
|
|
||||||
self._api.host,
|
|
||||||
self._api.port,
|
|
||||||
)
|
|
||||||
except InvalidContentTypeError as err:
|
|
||||||
_LOGGER.error(
|
|
||||||
"Reolink content type error while logging out for host %s:%s: %s",
|
|
||||||
self._api.host,
|
self._api.host,
|
||||||
self._api.port,
|
self._api.port,
|
||||||
str(err),
|
str(err),
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
"name": "Reolink IP NVR/camera",
|
"name": "Reolink IP NVR/camera",
|
||||||
"config_flow": true,
|
"config_flow": true,
|
||||||
"documentation": "https://www.home-assistant.io/integrations/reolink",
|
"documentation": "https://www.home-assistant.io/integrations/reolink",
|
||||||
"requirements": ["reolink-aio==0.2.3"],
|
"requirements": ["reolink-aio==0.3.0"],
|
||||||
"codeowners": ["@starkillerOG"],
|
"codeowners": ["@starkillerOG"],
|
||||||
"iot_class": "local_polling",
|
"iot_class": "local_polling",
|
||||||
"loggers": ["reolink_aio"]
|
"loggers": ["reolink_aio"]
|
||||||
|
|
|
@ -2221,7 +2221,7 @@ regenmaschine==2022.11.0
|
||||||
renault-api==0.1.11
|
renault-api==0.1.11
|
||||||
|
|
||||||
# homeassistant.components.reolink
|
# homeassistant.components.reolink
|
||||||
reolink-aio==0.2.3
|
reolink-aio==0.3.0
|
||||||
|
|
||||||
# homeassistant.components.python_script
|
# homeassistant.components.python_script
|
||||||
restrictedpython==6.0
|
restrictedpython==6.0
|
||||||
|
|
|
@ -1566,7 +1566,7 @@ regenmaschine==2022.11.0
|
||||||
renault-api==0.1.11
|
renault-api==0.1.11
|
||||||
|
|
||||||
# homeassistant.components.reolink
|
# homeassistant.components.reolink
|
||||||
reolink-aio==0.2.3
|
reolink-aio==0.3.0
|
||||||
|
|
||||||
# homeassistant.components.python_script
|
# homeassistant.components.python_script
|
||||||
restrictedpython==6.0
|
restrictedpython==6.0
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue