Avoid starting ONVIF PullPoint if the camera reports its unsupported (#92333)

This commit is contained in:
J. Nick Koston 2023-05-01 11:33:52 -05:00 committed by GitHub
parent 2bc2c4a651
commit 324df197d1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 28 additions and 9 deletions

View File

@ -6,6 +6,7 @@ from contextlib import suppress
import datetime as dt import datetime as dt
import os import os
import time import time
from typing import Any
from httpx import RequestError from httpx import RequestError
import onvif import onvif
@ -55,6 +56,7 @@ class ONVIFDevice:
self.info: DeviceInfo = DeviceInfo() self.info: DeviceInfo = DeviceInfo()
self.capabilities: Capabilities = Capabilities() self.capabilities: Capabilities = Capabilities()
self.onvif_capabilities: dict[str, Any] | None = None
self.profiles: list[Profile] = [] self.profiles: list[Profile] = []
self.max_resolution: int = 0 self.max_resolution: int = 0
self.platforms: list[Platform] = [] self.platforms: list[Platform] = []
@ -98,6 +100,10 @@ class ONVIFDevice:
# Get all device info # Get all device info
await self.device.update_xaddrs() await self.device.update_xaddrs()
# Get device capabilities
self.onvif_capabilities = await self.device.get_capabilities()
await self.async_check_date_and_time() await self.async_check_date_and_time()
# Create event manager # Create event manager
@ -107,8 +113,9 @@ class ONVIFDevice:
# Fetch basic device info and capabilities # Fetch basic device info and capabilities
self.info = await self.async_get_device_info() self.info = await self.async_get_device_info()
LOGGER.debug("Camera %s info = %s", self.name, self.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) # Check profiles before capabilities since the camera may be slow to respond
# once the event manager is started in async_get_capabilities.
self.profiles = await self.async_get_profiles() self.profiles = await self.async_get_profiles()
LOGGER.debug("Camera %s profiles = %s", self.name, self.profiles) LOGGER.debug("Camera %s profiles = %s", self.name, self.profiles)
@ -116,6 +123,9 @@ class ONVIFDevice:
if not self.profiles: if not self.profiles:
raise ONVIFError("No camera profiles found") raise ONVIFError("No camera profiles found")
self.capabilities = await self.async_get_capabilities()
LOGGER.debug("Camera %s capabilities = %s", self.name, self.capabilities)
if self.capabilities.ptz: if self.capabilities.ptz:
self.device.create_ptz_service() self.device.create_ptz_service()
@ -299,7 +309,14 @@ class ONVIFDevice:
events = False events = False
with suppress(*GET_CAPABILITIES_EXCEPTIONS, XMLParseError): with suppress(*GET_CAPABILITIES_EXCEPTIONS, XMLParseError):
events = await self.events.async_start() onvif_capabilities = self.onvif_capabilities or {}
pull_point_support = onvif_capabilities.get("Events", {}).get(
"WSPullPointSupport"
)
LOGGER.debug("%s: WSPullPointSupport: %s", self.name, pull_point_support)
events = await self.events.async_start(
pull_point_support is not False, True
)
return Capabilities(snapshot, events, ptz, imaging) return Capabilities(snapshot, events, ptz, imaging)

View File

@ -123,11 +123,13 @@ class EventManager:
if not self._listeners: if not self._listeners:
self.pullpoint_manager.async_cancel_pull_messages() self.pullpoint_manager.async_cancel_pull_messages()
async def async_start(self) -> bool: async def async_start(self, try_pullpoint: bool, try_webhook: bool) -> bool:
"""Start polling events.""" """Start polling events."""
# Always start pull point first, since it will populate the event list # Always start pull point first, since it will populate the event list
event_via_pull_point = await self.pullpoint_manager.async_start() event_via_pull_point = (
events_via_webhook = await self.webhook_manager.async_start() try_pullpoint and await self.pullpoint_manager.async_start()
)
events_via_webhook = try_webhook and await self.webhook_manager.async_start()
return events_via_webhook or event_via_pull_point return events_via_webhook or event_via_pull_point
async def async_stop(self) -> None: async def async_stop(self) -> None:

View File

@ -8,5 +8,5 @@
"documentation": "https://www.home-assistant.io/integrations/onvif", "documentation": "https://www.home-assistant.io/integrations/onvif",
"iot_class": "local_push", "iot_class": "local_push",
"loggers": ["onvif", "wsdiscovery", "zeep"], "loggers": ["onvif", "wsdiscovery", "zeep"],
"requirements": ["onvif-zeep-async==1.3.0", "WSDiscovery==2.0.0"] "requirements": ["onvif-zeep-async==1.3.1", "WSDiscovery==2.0.0"]
} }

View File

@ -1258,7 +1258,7 @@ ondilo==0.2.0
onkyo-eiscp==1.2.7 onkyo-eiscp==1.2.7
# homeassistant.components.onvif # homeassistant.components.onvif
onvif-zeep-async==1.3.0 onvif-zeep-async==1.3.1
# homeassistant.components.opengarage # homeassistant.components.opengarage
open-garage==0.2.0 open-garage==0.2.0

View File

@ -945,7 +945,7 @@ omnilogic==0.4.5
ondilo==0.2.0 ondilo==0.2.0
# homeassistant.components.onvif # homeassistant.components.onvif
onvif-zeep-async==1.3.0 onvif-zeep-async==1.3.1
# homeassistant.components.opengarage # homeassistant.components.opengarage
open-garage==0.2.0 open-garage==0.2.0