run get_camera_info onvifcontroller calls in dedicated loop

This commit is contained in:
Josh Hawkins 2025-05-06 13:16:58 -05:00
parent 3ddebbfcef
commit 1b02887b45
2 changed files with 25 additions and 5 deletions

View File

@ -111,7 +111,7 @@ def imagestream(
async def camera_ptz_info(request: Request, camera_name: str): async def camera_ptz_info(request: Request, camera_name: str):
if camera_name in request.app.frigate_config.cameras: if camera_name in request.app.frigate_config.cameras:
return JSONResponse( return JSONResponse(
content=await request.app.onvif.get_camera_info(camera_name), content=request.app.onvif.get_camera_info(camera_name),
) )
else: else:
return JSONResponse( return JSONResponse(

View File

@ -657,7 +657,7 @@ class OnvifController:
f"Error executing command {command} for camera {camera_name}: {e}" f"Error executing command {command} for camera {camera_name}: {e}"
) )
async def get_camera_info(self, camera_name: str) -> dict[str, any]: def get_camera_info(self, camera_name: str) -> dict[str, any]:
""" """
Get ptz capabilities and presets, attempting to reconnect if ONVIF is configured Get ptz capabilities and presets, attempting to reconnect if ONVIF is configured
but not initialized. but not initialized.
@ -685,8 +685,21 @@ class OnvifController:
} }
if camera_name not in self.cams.keys() and camera_name in self.config.cameras: if camera_name not in self.cams.keys() and camera_name in self.config.cameras:
success = await self._init_single_camera(camera_name) # Schedule _init_single_camera in the OnvifController's event loop
if not success: future = asyncio.run_coroutine_threadsafe(
self._init_single_camera(camera_name), self.loop
)
try:
success = future.result(timeout=10)
if not success:
return {}
except asyncio.TimeoutError:
logger.error(f"_init_single_camera timed out for camera {camera_name}")
return {}
except Exception as e:
logger.error(
f"Error in _init_single_camera for camera {camera_name}: {e}"
)
return {} return {}
# Reset retry count after timeout # Reset retry count after timeout
@ -704,7 +717,12 @@ class OnvifController:
f"Attempting ONVIF initialization for {camera_name} (retry {attempts + 1}/{self.max_retries})" f"Attempting ONVIF initialization for {camera_name} (retry {attempts + 1}/{self.max_retries})"
) )
try: try:
if await self._init_onvif(camera_name): # Schedule _init_onvif in the OnvifController's event loop
future = asyncio.run_coroutine_threadsafe(
self._init_onvif(camera_name), self.loop
)
success = future.result(timeout=10)
if success:
if camera_name in self.failed_cams: if camera_name in self.failed_cams:
del self.failed_cams[camera_name] del self.failed_cams[camera_name]
return { return {
@ -714,6 +732,8 @@ class OnvifController:
} }
else: else:
logger.warning(f"ONVIF initialization failed for {camera_name}") logger.warning(f"ONVIF initialization failed for {camera_name}")
except asyncio.TimeoutError:
logger.error(f"_init_onvif timed out for camera {camera_name}")
except Exception as e: except Exception as e:
logger.error( logger.error(
f"Error during ONVIF initialization for {camera_name}: {e}" f"Error during ONVIF initialization for {camera_name}: {e}"