Added threaded retry for setting up ONVIF Session

This commit is contained in:
Vania Toperich 2025-02-13 14:40:41 +01:00
parent d6b5dc93cc
commit 29bd4335b9

View File

@ -6,6 +6,9 @@ from enum import Enum
from importlib.util import find_spec from importlib.util import find_spec
from pathlib import Path from pathlib import Path
from threading import Thread
from time import sleep
import numpy import numpy
from onvif import ONVIFCamera, ONVIFError, ONVIFService from onvif import ONVIFCamera, ONVIFError, ONVIFService
from zeep.exceptions import Fault, TransportError from zeep.exceptions import Fault, TransportError
@ -41,32 +44,52 @@ class OnvifController:
self.cams: dict[str, ONVIFCamera] = {} self.cams: dict[str, ONVIFCamera] = {}
self.config = config self.config = config
self.ptz_metrics = ptz_metrics self.ptz_metrics = ptz_metrics
self.failed_cams = set()
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:
if not self._setup_onvif(cam_name):
self.failed_cams.add(cam_name)
# Start a background thread to retry failed camera initializations
self.retry_thread = Thread(target=self._retry_failed_cams, daemon=True)
self.retry_thread.start()
def _retry_failed_cams(self):
while True:
for cam_name in list(self.failed_cams):
if self._setup_onvif(cam_name):
self.failed_cams.remove(cam_name)
sleep(60)
def _setup_onvif(self, camera_name: str) -> bool:
try: try:
self.cams[cam_name] = { onvif: ONVIFCamera = ONVIFCamera(
"onvif": ONVIFCamera( self.config.cameras[camera_name].onvif.host,
cam.onvif.host, self.config.cameras[camera_name].onvif.port,
cam.onvif.port, self.config.cameras[camera_name].onvif.user,
cam.onvif.user, self.config.cameras[camera_name].onvif.password,
cam.onvif.password,
wsdl_dir=str( wsdl_dir=str(
Path(find_spec("onvif").origin).parent / "wsdl" Path(find_spec("onvif").origin).parent / "wsdl"
), ),
adjust_time=cam.onvif.ignore_time_mismatch, adjust_time=self.config.cameras[camera_name].onvif.ignore_time_mismatch,
encrypt=not cam.onvif.tls_insecure, encrypt=not self.config.cameras[camera_name].onvif.tls_insecure,
), )
self.cams[camera_name] = {
"onvif": onvif,
"init": False, "init": False,
"active": False, "active": False,
"features": [], "features": [],
"presets": {}, "presets": {},
} }
return True
except ONVIFError as e: except ONVIFError as e:
logger.error(f"Onvif connection to {cam.name} failed: {e}") logger.error(f"Onvif connection to {camera_name} failed: {e}")
return False
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"]