diff --git a/homeassistant/components/onvif/__init__.py b/homeassistant/components/onvif/__init__.py index 77a5c6d1bd8..438a313c3ca 100644 --- a/homeassistant/components/onvif/__init__.py +++ b/homeassistant/components/onvif/__init__.py @@ -1,5 +1,7 @@ """The ONVIF integration.""" +from httpx import RequestError from onvif.exceptions import ONVIFAuthError, ONVIFError, ONVIFTimeoutError +from zeep.exceptions import Fault from homeassistant.components.ffmpeg import CONF_EXTRA_ARGUMENTS from homeassistant.components.stream import CONF_RTSP_TRANSPORT, RTSP_TRANSPORTS @@ -27,9 +29,25 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: device = ONVIFDevice(hass, entry) - if not await device.async_setup(): + try: + await device.async_setup() + except RequestError as err: await device.device.close() - return False + raise ConfigEntryNotReady( + f"Could not connect to camera {device.device.host}:{device.device.port}: {err}" + ) from err + except Fault as err: + await device.device.close() + # We do no know if the credentials are wrong or the camera is + # still booting up, so we will retry later + raise ConfigEntryNotReady( + f"Could not connect to camera, verify credentials are correct: {err}" + ) from err + except ONVIFError as err: + await device.device.close() + raise ConfigEntryNotReady( + f"Could not setup camera {device.device.host}:{device.device.port}: {err}" + ) from err if not device.available: raise ConfigEntryNotReady() diff --git a/homeassistant/components/onvif/device.py b/homeassistant/components/onvif/device.py index 1556ae8a1fe..d5baa829d05 100644 --- a/homeassistant/components/onvif/device.py +++ b/homeassistant/components/onvif/device.py @@ -83,7 +83,7 @@ class ONVIFDevice: """Return the password of this device.""" return self.config_entry.data[CONF_PASSWORD] - async def async_setup(self) -> bool: + async def async_setup(self) -> None: """Set up the device.""" self.device = get_device( self.hass, @@ -94,57 +94,34 @@ class ONVIFDevice: ) # Get all device info - try: - await self.device.update_xaddrs() - await self.async_check_date_and_time() + await self.device.update_xaddrs() + await self.async_check_date_and_time() - # Create event manager - assert self.config_entry.unique_id - self.events = EventManager( - self.hass, self.device, self.config_entry.unique_id - ) + # Create event manager + assert self.config_entry.unique_id + self.events = EventManager(self.hass, self.device, self.config_entry.unique_id) - # Fetch basic device info and capabilities - self.info = await self.async_get_device_info() - LOGGER.debug("Camera %s info = %s", self.name, self.info) - self.capabilities = await self.async_get_capabilities() - LOGGER.debug("Camera %s capabilities = %s", self.name, self.capabilities) - self.profiles = await self.async_get_profiles() - LOGGER.debug("Camera %s profiles = %s", self.name, self.profiles) + # Fetch basic device info and capabilities + self.info = await self.async_get_device_info() + LOGGER.debug("Camera %s info = %s", self.name, self.info) + self.capabilities = await self.async_get_capabilities() + LOGGER.debug("Camera %s capabilities = %s", self.name, self.capabilities) + self.profiles = await self.async_get_profiles() + LOGGER.debug("Camera %s profiles = %s", self.name, self.profiles) - # No camera profiles to add - if not self.profiles: - return False + # No camera profiles to add + if not self.profiles: + raise ONVIFError("No camera profiles found") - if self.capabilities.ptz: - self.device.create_ptz_service() + if self.capabilities.ptz: + self.device.create_ptz_service() - # Determine max resolution from profiles - self.max_resolution = max( - profile.video.resolution.width - for profile in self.profiles - if profile.video.encoding == "H264" - ) - except RequestError as err: - LOGGER.warning( - "Couldn't connect to camera '%s', but will retry later. Error: %s", - self.name, - err, - ) - self.available = False - await self.device.close() - except Fault as err: - LOGGER.error( - ( - "Couldn't connect to camera '%s', please verify " - "that the credentials are correct. Error: %s" - ), - self.name, - err, - ) - return False - - return True + # Determine max resolution from profiles + self.max_resolution = max( + profile.video.resolution.width + for profile in self.profiles + if profile.video.encoding == "H264" + ) async def async_stop(self, event=None): """Shut it all down."""