create cameras in same event loop that will use them

This commit is contained in:
Josh Hawkins 2025-05-05 18:55:28 -05:00
parent 70752b4193
commit 8a61ccfe61

View File

@ -52,13 +52,14 @@ class OnvifController:
self.loop_thread = threading.Thread(target=self._run_event_loop, daemon=True) self.loop_thread = threading.Thread(target=self._run_event_loop, daemon=True)
self.loop_thread.start() self.loop_thread.start()
self.camera_configs = {}
for cam_name, cam in config.cameras.items(): for cam_name, cam in config.cameras.items():
if not cam.enabled: if not cam.enabled:
continue continue
if cam.onvif.host: if cam.onvif.host:
result = self._create_onvif_camera(cam_name, cam) self.camera_configs[cam_name] = cam
if result:
self.cams[cam_name] = result asyncio.run_coroutine_threadsafe(self._init_cameras(), self.loop)
def _run_event_loop(self) -> None: def _run_event_loop(self) -> None:
"""Run the event loop in a separate thread.""" """Run the event loop in a separate thread."""
@ -68,10 +69,11 @@ class OnvifController:
except Exception as e: except Exception as e:
logger.error(f"Onvif event loop terminated unexpectedly: {e}") logger.error(f"Onvif event loop terminated unexpectedly: {e}")
def _create_onvif_camera(self, cam_name: str, cam) -> dict | None: async def _init_cameras(self) -> None:
"""Create an ONVIF camera instance and handle failures.""" """Create an ONVIF camera instance and handle failures."""
for cam_name, cam in self.camera_configs.items():
try: try:
return { self.cams[cam_name] = {
"onvif": ONVIFCamera( "onvif": ONVIFCamera(
cam.onvif.host, cam.onvif.host,
cam.onvif.port, cam.onvif.port,
@ -87,14 +89,14 @@ class OnvifController:
"presets": {}, "presets": {},
} }
except (Fault, ONVIFError, TransportError, Exception) as e: except (Fault, ONVIFError, TransportError, Exception) as e:
logger.error(f"Failed to create ONVIF camera instance for {cam_name}: {e}") logger.error(
# track initial failures f"Failed to create ONVIF camera instance for {cam_name}: {e}"
)
self.failed_cams[cam_name] = { self.failed_cams[cam_name] = {
"retry_attempts": 0, "retry_attempts": 0,
"last_error": str(e), "last_error": str(e),
"last_attempt": time.time(), "last_attempt": time.time(),
} }
return None
async def _init_onvif(self, camera_name: str) -> bool: async def _init_onvif(self, camera_name: str) -> bool:
onvif: ONVIFCamera = self.cams[camera_name]["onvif"] onvif: ONVIFCamera = self.cams[camera_name]["onvif"]