Start onvif events later (#92354)

This commit is contained in:
J. Nick Koston 2023-05-02 05:17:01 -05:00 committed by GitHub
parent 2636a46a5f
commit c0fa078b0b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -100,6 +100,7 @@ class ONVIFDevice:
# Get all device info # Get all device info
await self.device.update_xaddrs() await self.device.update_xaddrs()
LOGGER.debug("%s: xaddrs = %s", self.name, self.device.xaddrs)
# Get device capabilities # Get device capabilities
self.onvif_capabilities = await self.device.get_capabilities() self.onvif_capabilities = await self.device.get_capabilities()
@ -112,10 +113,20 @@ 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("%s: camera info = %s", self.name, self.info)
# Check profiles before capabilities since the camera may be slow to respond #
# once the event manager is started in async_get_capabilities. # We need to check capabilities before profiles, because we need the data
# from capabilities to determine profiles correctly.
#
# We no longer initialize events in capabilities to avoid the problem
# where cameras become slow to respond for a bit after starting events, and
# instead we start events last and than update capabilities.
#
LOGGER.debug("%s: fetching initial capabilities", self.name)
self.capabilities = await self.async_get_capabilities()
LOGGER.debug("%s: fetching profiles", self.name)
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)
@ -123,10 +134,8 @@ 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:
LOGGER.debug("%s: creating PTZ service", self.name)
self.device.create_ptz_service() self.device.create_ptz_service()
# Determine max resolution from profiles # Determine max resolution from profiles
@ -136,6 +145,12 @@ class ONVIFDevice:
if profile.video.encoding == "H264" if profile.video.encoding == "H264"
) )
# Start events last since some cameras become slow to respond
# for a bit after starting events
LOGGER.debug("%s: starting events", self.name)
self.capabilities.events = await self.async_start_events()
LOGGER.debug("Camera %s capabilities = %s", self.name, self.capabilities)
async def async_stop(self, event=None): async def async_stop(self, event=None):
"""Shut it all down.""" """Shut it all down."""
if self.events: if self.events:
@ -307,23 +322,31 @@ class ONVIFDevice:
self.device.create_imaging_service() self.device.create_imaging_service()
imaging = True imaging = True
events = False return Capabilities(snapshot=snapshot, ptz=ptz, imaging=imaging)
async def async_start_events(self):
"""Start the event handler."""
with suppress(*GET_CAPABILITIES_EXCEPTIONS, XMLParseError): with suppress(*GET_CAPABILITIES_EXCEPTIONS, XMLParseError):
onvif_capabilities = self.onvif_capabilities or {} onvif_capabilities = self.onvif_capabilities or {}
pull_point_support = onvif_capabilities.get("Events", {}).get( pull_point_support = onvif_capabilities.get("Events", {}).get(
"WSPullPointSupport" "WSPullPointSupport"
) )
LOGGER.debug("%s: WSPullPointSupport: %s", self.name, pull_point_support) LOGGER.debug("%s: WSPullPointSupport: %s", self.name, pull_point_support)
events = await self.events.async_start( return await self.events.async_start(pull_point_support is not False, True)
pull_point_support is not False, True
)
return Capabilities(snapshot, events, ptz, imaging) return False
async def async_get_profiles(self) -> list[Profile]: async def async_get_profiles(self) -> list[Profile]:
"""Obtain media profiles for this device.""" """Obtain media profiles for this device."""
media_service = self.device.create_media_service() media_service = self.device.create_media_service()
result = await media_service.GetProfiles() LOGGER.debug("%s: xaddr for media_service: %s", self.name, media_service.xaddr)
try:
result = await media_service.GetProfiles()
except GET_CAPABILITIES_EXCEPTIONS:
LOGGER.debug(
"%s: Could not get profiles from ONVIF device", self.name, exc_info=True
)
raise
profiles: list[Profile] = [] profiles: list[Profile] = []
if not isinstance(result, list): if not isinstance(result, list):