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:
try: if not self._setup_onvif(cam_name):
self.cams[cam_name] = { self.failed_cams.add(cam_name)
"onvif": ONVIFCamera(
cam.onvif.host, # Start a background thread to retry failed camera initializations
cam.onvif.port, self.retry_thread = Thread(target=self._retry_failed_cams, daemon=True)
cam.onvif.user, self.retry_thread.start()
cam.onvif.password,
wsdl_dir=str( def _retry_failed_cams(self):
Path(find_spec("onvif").origin).parent / "wsdl" while True:
), for cam_name in list(self.failed_cams):
adjust_time=cam.onvif.ignore_time_mismatch, if self._setup_onvif(cam_name):
encrypt=not cam.onvif.tls_insecure, self.failed_cams.remove(cam_name)
), sleep(60)
"init": False,
"active": False,
"features": [], def _setup_onvif(self, camera_name: str) -> bool:
"presets": {}, try:
} onvif: ONVIFCamera = ONVIFCamera(
except ONVIFError as e: self.config.cameras[camera_name].onvif.host,
logger.error(f"Onvif connection to {cam.name} failed: {e}") self.config.cameras[camera_name].onvif.port,
self.config.cameras[camera_name].onvif.user,
self.config.cameras[camera_name].onvif.password,
wsdl_dir=str(
Path(find_spec("onvif").origin).parent / "wsdl"
),
adjust_time=self.config.cameras[camera_name].onvif.ignore_time_mismatch,
encrypt=not self.config.cameras[camera_name].onvif.tls_insecure,
)
self.cams[camera_name] = {
"onvif": onvif,
"init": False,
"active": False,
"features": [],
"presets": {},
}
return True
except ONVIFError as 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"]