Custom classes for Process and Metrics (#13950)

* Subclass Process for audio_process

* Introduce custom mp.Process subclass

In preparation to switch the multiprocessing startup method away from
"fork", we cannot rely on os.fork cloning the log state at fork time.
Instead, we have to set up logging before we run the business logic of
each process.

* Make camera_metrics into a class

* Make ptz_metrics into a class

* Fixed PtzMotionEstimator.ptz_metrics type annotation

* Removed pointless variables

* Do not start audio processor when no audio cameras are configured
This commit is contained in:
gtsiam
2024-09-27 15:53:23 +03:00
committed by GitHub
parent 1f328be1bd
commit c0bd3b362c
16 changed files with 471 additions and 448 deletions

View File

@@ -18,6 +18,7 @@ from norfair.camera_motion import (
TranslationTransformationGetter,
)
from frigate.camera import PTZMetrics
from frigate.comms.dispatcher import Dispatcher
from frigate.config import CameraConfig, FrigateConfig, ZoomingModeEnum
from frigate.const import (
@@ -31,7 +32,6 @@ from frigate.const import (
CONFIG_DIR,
)
from frigate.ptz.onvif import OnvifController
from frigate.types import PTZMetricsTypes
from frigate.util.builtin import update_yaml_file
from frigate.util.image import SharedMemoryFrameManager, intersection_over_union
@@ -49,24 +49,19 @@ def ptz_moving_at_frame_time(frame_time, ptz_start_time, ptz_stop_time):
class PtzMotionEstimator:
def __init__(
self, config: CameraConfig, ptz_metrics: dict[str, PTZMetricsTypes]
) -> None:
def __init__(self, config: CameraConfig, ptz_metrics: PTZMetrics) -> None:
self.frame_manager = SharedMemoryFrameManager()
self.norfair_motion_estimator = None
self.camera_config = config
self.coord_transformations = None
self.ptz_metrics = ptz_metrics
self.ptz_start_time = self.ptz_metrics["ptz_start_time"]
self.ptz_stop_time = self.ptz_metrics["ptz_stop_time"]
self.ptz_metrics["ptz_reset"].set()
self.ptz_metrics.reset.set()
logger.debug(f"{config.name}: Motion estimator init")
def motion_estimator(self, detections, frame_time, camera):
# If we've just started up or returned to our preset, reset motion estimator for new tracking session
if self.ptz_metrics["ptz_reset"].is_set():
self.ptz_metrics["ptz_reset"].clear()
if self.ptz_metrics.reset.is_set():
self.ptz_metrics.reset.clear()
# homography is nice (zooming) but slow, translation is pan/tilt only but fast.
if (
@@ -88,7 +83,9 @@ class PtzMotionEstimator:
self.coord_transformations = None
if ptz_moving_at_frame_time(
frame_time, self.ptz_start_time.value, self.ptz_stop_time.value
frame_time,
self.ptz_metrics.start_time.value,
self.ptz_metrics.stop_time.value,
):
logger.debug(
f"{camera}: Motion estimator running - frame time: {frame_time}"
@@ -148,7 +145,7 @@ class PtzAutoTrackerThread(threading.Thread):
self,
config: FrigateConfig,
onvif: OnvifController,
ptz_metrics: dict[str, PTZMetricsTypes],
ptz_metrics: dict[str, PTZMetrics],
dispatcher: Dispatcher,
stop_event: MpEvent,
) -> None:
@@ -182,7 +179,7 @@ class PtzAutoTracker:
self,
config: FrigateConfig,
onvif: OnvifController,
ptz_metrics: PTZMetricsTypes,
ptz_metrics: PTZMetrics,
dispatcher: Dispatcher,
stop_event: MpEvent,
) -> None:
@@ -248,7 +245,7 @@ class PtzAutoTracker:
f"Disabling autotracking for {camera}: onvif connection failed"
)
camera_config.onvif.autotracking.enabled = False
self.ptz_metrics[camera]["ptz_autotracker_enabled"].value = False
self.ptz_metrics[camera].autotracker_enabled.value = False
return
if not self.onvif.cams[camera]["init"]:
@@ -257,7 +254,7 @@ class PtzAutoTracker:
f"Disabling autotracking for {camera}: Unable to initialize onvif"
)
camera_config.onvif.autotracking.enabled = False
self.ptz_metrics[camera]["ptz_autotracker_enabled"].value = False
self.ptz_metrics[camera].autotracker_enabled.value = False
return
if "pt-r-fov" not in self.onvif.cams[camera]["features"]:
@@ -265,7 +262,7 @@ class PtzAutoTracker:
f"Disabling autotracking for {camera}: FOV relative movement not supported"
)
camera_config.onvif.autotracking.enabled = False
self.ptz_metrics[camera]["ptz_autotracker_enabled"].value = False
self.ptz_metrics[camera].autotracker_enabled.value = False
return
move_status_supported = self.onvif.get_service_capabilities(camera)
@@ -275,7 +272,7 @@ class PtzAutoTracker:
f"Disabling autotracking for {camera}: ONVIF MoveStatus not supported"
)
camera_config.onvif.autotracking.enabled = False
self.ptz_metrics[camera]["ptz_autotracker_enabled"].value = False
self.ptz_metrics[camera].autotracker_enabled.value = False
return
if self.onvif.cams[camera]["init"]:
@@ -295,12 +292,16 @@ class PtzAutoTracker:
float(val)
for val in camera_config.onvif.autotracking.movement_weights
]
self.ptz_metrics[camera][
"ptz_min_zoom"
].value = camera_config.onvif.autotracking.movement_weights[0]
self.ptz_metrics[camera][
"ptz_max_zoom"
].value = camera_config.onvif.autotracking.movement_weights[1]
self.ptz_metrics[
camera
].min_zoom.value = (
camera_config.onvif.autotracking.movement_weights[0]
)
self.ptz_metrics[
camera
].max_zoom.value = (
camera_config.onvif.autotracking.movement_weights[1]
)
self.intercept[camera] = (
camera_config.onvif.autotracking.movement_weights[2]
)
@@ -309,7 +310,7 @@ class PtzAutoTracker:
)
else:
camera_config.onvif.autotracking.enabled = False
self.ptz_metrics[camera]["ptz_autotracker_enabled"].value = False
self.ptz_metrics[camera].autotracker_enabled.value = False
logger.warning(
f"Autotracker recalibration is required for {camera}. Disabling autotracking."
)
@@ -317,7 +318,7 @@ class PtzAutoTracker:
if camera_config.onvif.autotracking.calibrate_on_startup:
self._calibrate_camera(camera)
self.ptz_metrics[camera]["ptz_tracking_active"].clear()
self.ptz_metrics[camera].tracking_active.clear()
self.dispatcher.publish(f"{camera}/ptz_autotracker/active", "OFF", retain=False)
self.autotracker_init[camera] = True
@@ -363,10 +364,10 @@ class PtzAutoTracker:
1,
)
while not self.ptz_metrics[camera]["ptz_motor_stopped"].is_set():
while not self.ptz_metrics[camera].motor_stopped.is_set():
self.onvif.get_camera_status(camera)
zoom_out_values.append(self.ptz_metrics[camera]["ptz_zoom_level"].value)
zoom_out_values.append(self.ptz_metrics[camera].zoom_level.value)
self.onvif._zoom_absolute(
camera,
@@ -374,10 +375,10 @@ class PtzAutoTracker:
1,
)
while not self.ptz_metrics[camera]["ptz_motor_stopped"].is_set():
while not self.ptz_metrics[camera].motor_stopped.is_set():
self.onvif.get_camera_status(camera)
zoom_in_values.append(self.ptz_metrics[camera]["ptz_zoom_level"].value)
zoom_in_values.append(self.ptz_metrics[camera].zoom_level.value)
if (
self.config.cameras[camera].onvif.autotracking.zooming
@@ -392,12 +393,10 @@ class PtzAutoTracker:
1,
)
while not self.ptz_metrics[camera]["ptz_motor_stopped"].is_set():
while not self.ptz_metrics[camera].motor_stopped.is_set():
self.onvif.get_camera_status(camera)
zoom_out_values.append(
self.ptz_metrics[camera]["ptz_zoom_level"].value
)
zoom_out_values.append(self.ptz_metrics[camera].zoom_level.value)
# relative move to 0.01
self.onvif._move_relative(
@@ -408,33 +407,31 @@ class PtzAutoTracker:
1,
)
while not self.ptz_metrics[camera]["ptz_motor_stopped"].is_set():
while not self.ptz_metrics[camera].motor_stopped.is_set():
self.onvif.get_camera_status(camera)
zoom_in_values.append(
self.ptz_metrics[camera]["ptz_zoom_level"].value
)
zoom_in_values.append(self.ptz_metrics[camera].zoom_level.value)
self.ptz_metrics[camera]["ptz_max_zoom"].value = max(zoom_in_values)
self.ptz_metrics[camera]["ptz_min_zoom"].value = min(zoom_out_values)
self.ptz_metrics[camera].max_zoom.value = max(zoom_in_values)
self.ptz_metrics[camera].min_zoom.value = min(zoom_out_values)
logger.debug(
f'{camera}: Calibration values: max zoom: {self.ptz_metrics[camera]["ptz_max_zoom"].value}, min zoom: {self.ptz_metrics[camera]["ptz_min_zoom"].value}'
f"{camera}: Calibration values: max zoom: {self.ptz_metrics[camera].max_zoom.value}, min zoom: {self.ptz_metrics[camera].min_zoom.value}"
)
else:
self.ptz_metrics[camera]["ptz_max_zoom"].value = 1
self.ptz_metrics[camera]["ptz_min_zoom"].value = 0
self.ptz_metrics[camera].max_zoom.value = 1
self.ptz_metrics[camera].min_zoom.value = 0
self.onvif._move_to_preset(
camera,
self.config.cameras[camera].onvif.autotracking.return_preset.lower(),
)
self.ptz_metrics[camera]["ptz_reset"].set()
self.ptz_metrics[camera]["ptz_motor_stopped"].clear()
self.ptz_metrics[camera].reset.set()
self.ptz_metrics[camera].motor_stopped.clear()
# Wait until the camera finishes moving
while not self.ptz_metrics[camera]["ptz_motor_stopped"].is_set():
while not self.ptz_metrics[camera].motor_stopped.is_set():
self.onvif.get_camera_status(camera)
for step in range(num_steps):
@@ -445,7 +442,7 @@ class PtzAutoTracker:
self.onvif._move_relative(camera, pan, tilt, 0, 1)
# Wait until the camera finishes moving
while not self.ptz_metrics[camera]["ptz_motor_stopped"].is_set():
while not self.ptz_metrics[camera].motor_stopped.is_set():
self.onvif.get_camera_status(camera)
stop_time = time.time()
@@ -462,11 +459,11 @@ class PtzAutoTracker:
camera,
self.config.cameras[camera].onvif.autotracking.return_preset.lower(),
)
self.ptz_metrics[camera]["ptz_reset"].set()
self.ptz_metrics[camera]["ptz_motor_stopped"].clear()
self.ptz_metrics[camera].reset.set()
self.ptz_metrics[camera].motor_stopped.clear()
# Wait until the camera finishes moving
while not self.ptz_metrics[camera]["ptz_motor_stopped"].is_set():
while not self.ptz_metrics[camera].motor_stopped.is_set():
self.onvif.get_camera_status(camera)
logger.info(
@@ -512,8 +509,8 @@ class PtzAutoTracker:
self.config.cameras[camera].onvif.autotracking.movement_weights = ", ".join(
str(v)
for v in [
self.ptz_metrics[camera]["ptz_min_zoom"].value,
self.ptz_metrics[camera]["ptz_max_zoom"].value,
self.ptz_metrics[camera].min_zoom.value,
self.ptz_metrics[camera].max_zoom.value,
self.intercept[camera],
*self.move_coefficients[camera],
]
@@ -649,8 +646,8 @@ class PtzAutoTracker:
# if we're receiving move requests during a PTZ move, ignore them
if ptz_moving_at_frame_time(
frame_time,
self.ptz_metrics[camera]["ptz_start_time"].value,
self.ptz_metrics[camera]["ptz_stop_time"].value,
self.ptz_metrics[camera].start_time.value,
self.ptz_metrics[camera].stop_time.value,
):
# instead of dequeueing this might be a good place to preemptively move based
# on an estimate - for fast moving objects, etc.
@@ -671,19 +668,17 @@ class PtzAutoTracker:
self.onvif._move_relative(camera, pan, tilt, 0, 1)
# Wait until the camera finishes moving
while not self.ptz_metrics[camera][
"ptz_motor_stopped"
].is_set():
while not self.ptz_metrics[camera].motor_stopped.is_set():
self.onvif.get_camera_status(camera)
if (
zoom > 0
and self.ptz_metrics[camera]["ptz_zoom_level"].value != zoom
and self.ptz_metrics[camera].zoom_level.value != zoom
):
self.onvif._zoom_absolute(camera, zoom, 1)
# Wait until the camera finishes moving
while not self.ptz_metrics[camera]["ptz_motor_stopped"].is_set():
while not self.ptz_metrics[camera].motor_stopped.is_set():
self.onvif.get_camera_status(camera)
if self.config.cameras[camera].onvif.autotracking.movement_weights:
@@ -691,7 +686,7 @@ class PtzAutoTracker:
f"{camera}: Predicted movement time: {self._predict_movement_time(camera, pan, tilt)}"
)
logger.debug(
f'{camera}: Actual movement time: {self.ptz_metrics[camera]["ptz_stop_time"].value-self.ptz_metrics[camera]["ptz_start_time"].value}'
f"{camera}: Actual movement time: {self.ptz_metrics[camera].stop_time.value-self.ptz_metrics[camera].start_time.value}"
)
# save metrics for better estimate calculations
@@ -709,12 +704,12 @@ class PtzAutoTracker:
{
"pan": pan,
"tilt": tilt,
"start_timestamp": self.ptz_metrics[camera][
"ptz_start_time"
].value,
"end_timestamp": self.ptz_metrics[camera][
"ptz_stop_time"
].value,
"start_timestamp": self.ptz_metrics[
camera
].start_time.value,
"end_timestamp": self.ptz_metrics[
camera
].stop_time.value,
}
)
@@ -734,8 +729,8 @@ class PtzAutoTracker:
return clipped, diff
if (
frame_time > self.ptz_metrics[camera]["ptz_start_time"].value
and frame_time > self.ptz_metrics[camera]["ptz_stop_time"].value
frame_time > self.ptz_metrics[camera].start_time.value
and frame_time > self.ptz_metrics[camera].stop_time.value
and not self.move_queue_locks[camera].locked()
):
# we can split up any large moves caused by velocity estimated movements if necessary
@@ -954,12 +949,12 @@ class PtzAutoTracker:
)
at_max_zoom = (
self.ptz_metrics[camera]["ptz_zoom_level"].value
== self.ptz_metrics[camera]["ptz_max_zoom"].value
self.ptz_metrics[camera].zoom_level.value
== self.ptz_metrics[camera].max_zoom.value
)
at_min_zoom = (
self.ptz_metrics[camera]["ptz_zoom_level"].value
== self.ptz_metrics[camera]["ptz_min_zoom"].value
self.ptz_metrics[camera].zoom_level.value
== self.ptz_metrics[camera].min_zoom.value
)
# debug zooming
@@ -1100,7 +1095,7 @@ class PtzAutoTracker:
zoom = 0
result = None
current_zoom_level = self.ptz_metrics[camera]["ptz_zoom_level"].value
current_zoom_level = self.ptz_metrics[camera].zoom_level.value
target_box = max(
obj.obj_data["box"][2] - obj.obj_data["box"][0],
obj.obj_data["box"][3] - obj.obj_data["box"][1],
@@ -1123,8 +1118,8 @@ class PtzAutoTracker:
) is not None:
# divide zoom in 10 increments and always zoom out more than in
level = (
self.ptz_metrics[camera]["ptz_max_zoom"].value
- self.ptz_metrics[camera]["ptz_min_zoom"].value
self.ptz_metrics[camera].max_zoom.value
- self.ptz_metrics[camera].min_zoom.value
) / 20
if result:
zoom = min(1.0, current_zoom_level + level)
@@ -1219,7 +1214,7 @@ class PtzAutoTracker:
logger.debug(
f"{camera}: New object: {obj.obj_data['id']} {obj.obj_data['box']} {obj.obj_data['frame_time']}"
)
self.ptz_metrics[camera]["ptz_tracking_active"].set()
self.ptz_metrics[camera].tracking_active.set()
self.dispatcher.publish(
f"{camera}/ptz_autotracker/active", "ON", retain=False
)
@@ -1243,8 +1238,8 @@ class PtzAutoTracker:
if not ptz_moving_at_frame_time(
obj.obj_data["frame_time"],
self.ptz_metrics[camera]["ptz_start_time"].value,
self.ptz_metrics[camera]["ptz_stop_time"].value,
self.ptz_metrics[camera].start_time.value,
self.ptz_metrics[camera].stop_time.value,
):
if self.tracked_object_metrics[camera]["below_distance_threshold"]:
logger.debug(
@@ -1325,7 +1320,7 @@ class PtzAutoTracker:
if not self.autotracker_init[camera]:
self._autotracker_setup(self.config.cameras[camera], camera)
# regularly update camera status
if not self.ptz_metrics[camera]["ptz_motor_stopped"].is_set():
if not self.ptz_metrics[camera].motor_stopped.is_set():
self.onvif.get_camera_status(camera)
# return to preset if tracking is over
@@ -1334,7 +1329,7 @@ class PtzAutoTracker:
and self.tracked_object_history[camera]
and (
# might want to use a different timestamp here?
self.ptz_metrics[camera]["ptz_frame_time"].value
self.ptz_metrics[camera].frame_time.value
- self.tracked_object_history[camera][-1]["frame_time"]
>= autotracker_config.timeout
)
@@ -1348,9 +1343,9 @@ class PtzAutoTracker:
while not self.move_queues[camera].empty():
self.move_queues[camera].get()
self.ptz_metrics[camera]["ptz_motor_stopped"].wait()
self.ptz_metrics[camera].motor_stopped.wait()
logger.debug(
f"{camera}: Time is {self.ptz_metrics[camera]['ptz_frame_time'].value}, returning to preset: {autotracker_config.return_preset}"
f"{camera}: Time is {self.ptz_metrics[camera].frame_time.value}, returning to preset: {autotracker_config.return_preset}"
)
self.onvif._move_to_preset(
camera,
@@ -1358,11 +1353,11 @@ class PtzAutoTracker:
)
# update stored zoom level from preset
if not self.ptz_metrics[camera]["ptz_motor_stopped"].is_set():
if not self.ptz_metrics[camera].motor_stopped.is_set():
self.onvif.get_camera_status(camera)
self.ptz_metrics[camera]["ptz_tracking_active"].clear()
self.ptz_metrics[camera].tracking_active.clear()
self.dispatcher.publish(
f"{camera}/ptz_autotracker/active", "OFF", retain=False
)
self.ptz_metrics[camera]["ptz_reset"].set()
self.ptz_metrics[camera].reset.set()

View File

@@ -10,8 +10,8 @@ from onvif import ONVIFCamera, ONVIFError
from zeep.exceptions import Fault, TransportError
from zeep.transports import Transport
from frigate.camera import PTZMetrics
from frigate.config import FrigateConfig, ZoomingModeEnum
from frigate.types import PTZMetricsTypes
from frigate.util.builtin import find_by_key
logger = logging.getLogger(__name__)
@@ -33,8 +33,10 @@ class OnvifCommandEnum(str, Enum):
class OnvifController:
ptz_metrics: dict[str, PTZMetrics]
def __init__(
self, config: FrigateConfig, ptz_metrics: dict[str, PTZMetricsTypes]
self, config: FrigateConfig, ptz_metrics: dict[str, PTZMetrics]
) -> None:
self.cams: dict[str, ONVIFCamera] = {}
self.config = config
@@ -389,14 +391,14 @@ class OnvifController:
return
self.cams[camera_name]["active"] = True
self.ptz_metrics[camera_name]["ptz_motor_stopped"].clear()
self.ptz_metrics[camera_name].motor_stopped.clear()
logger.debug(
f"{camera_name}: PTZ start time: {self.ptz_metrics[camera_name]['ptz_frame_time'].value}"
f"{camera_name}: PTZ start time: {self.ptz_metrics[camera_name].frame_time.value}"
)
self.ptz_metrics[camera_name]["ptz_start_time"].value = self.ptz_metrics[
self.ptz_metrics[camera_name].start_time.value = self.ptz_metrics[
camera_name
]["ptz_frame_time"].value
self.ptz_metrics[camera_name]["ptz_stop_time"].value = 0
].frame_time.value
self.ptz_metrics[camera_name].stop_time.value = 0
onvif: ONVIFCamera = self.cams[camera_name]["onvif"]
move_request = self.cams[camera_name]["relative_move_request"]
@@ -464,9 +466,9 @@ class OnvifController:
return
self.cams[camera_name]["active"] = True
self.ptz_metrics[camera_name]["ptz_motor_stopped"].clear()
self.ptz_metrics[camera_name]["ptz_start_time"].value = 0
self.ptz_metrics[camera_name]["ptz_stop_time"].value = 0
self.ptz_metrics[camera_name].motor_stopped.clear()
self.ptz_metrics[camera_name].start_time.value = 0
self.ptz_metrics[camera_name].stop_time.value = 0
move_request = self.cams[camera_name]["move_request"]
onvif: ONVIFCamera = self.cams[camera_name]["onvif"]
preset_token = self.cams[camera_name]["presets"][preset]
@@ -515,14 +517,14 @@ class OnvifController:
return
self.cams[camera_name]["active"] = True
self.ptz_metrics[camera_name]["ptz_motor_stopped"].clear()
self.ptz_metrics[camera_name].motor_stopped.clear()
logger.debug(
f"{camera_name}: PTZ start time: {self.ptz_metrics[camera_name]['ptz_frame_time'].value}"
f"{camera_name}: PTZ start time: {self.ptz_metrics[camera_name].frame_time.value}"
)
self.ptz_metrics[camera_name]["ptz_start_time"].value = self.ptz_metrics[
self.ptz_metrics[camera_name].start_time.value = self.ptz_metrics[
camera_name
]["ptz_frame_time"].value
self.ptz_metrics[camera_name]["ptz_stop_time"].value = 0
].frame_time.value
self.ptz_metrics[camera_name].stop_time.value = 0
onvif: ONVIFCamera = self.cams[camera_name]["onvif"]
move_request = self.cams[camera_name]["absolute_move_request"]
@@ -653,36 +655,36 @@ class OnvifController:
if pan_tilt_status == "IDLE" and (zoom_status is None or zoom_status == "IDLE"):
self.cams[camera_name]["active"] = False
if not self.ptz_metrics[camera_name]["ptz_motor_stopped"].is_set():
self.ptz_metrics[camera_name]["ptz_motor_stopped"].set()
if not self.ptz_metrics[camera_name].motor_stopped.is_set():
self.ptz_metrics[camera_name].motor_stopped.set()
logger.debug(
f"{camera_name}: PTZ stop time: {self.ptz_metrics[camera_name]['ptz_frame_time'].value}"
f"{camera_name}: PTZ stop time: {self.ptz_metrics[camera_name].frame_time.value}"
)
self.ptz_metrics[camera_name]["ptz_stop_time"].value = self.ptz_metrics[
self.ptz_metrics[camera_name].stop_time.value = self.ptz_metrics[
camera_name
]["ptz_frame_time"].value
].frame_time.value
else:
self.cams[camera_name]["active"] = True
if self.ptz_metrics[camera_name]["ptz_motor_stopped"].is_set():
self.ptz_metrics[camera_name]["ptz_motor_stopped"].clear()
if self.ptz_metrics[camera_name].motor_stopped.is_set():
self.ptz_metrics[camera_name].motor_stopped.clear()
logger.debug(
f"{camera_name}: PTZ start time: {self.ptz_metrics[camera_name]['ptz_frame_time'].value}"
f"{camera_name}: PTZ start time: {self.ptz_metrics[camera_name].frame_time.value}"
)
self.ptz_metrics[camera_name][
"ptz_start_time"
].value = self.ptz_metrics[camera_name]["ptz_frame_time"].value
self.ptz_metrics[camera_name]["ptz_stop_time"].value = 0
self.ptz_metrics[camera_name].start_time.value = self.ptz_metrics[
camera_name
].frame_time.value
self.ptz_metrics[camera_name].stop_time.value = 0
if (
self.config.cameras[camera_name].onvif.autotracking.zooming
!= ZoomingModeEnum.disabled
):
# store absolute zoom level as 0 to 1 interpolated from the values of the camera
self.ptz_metrics[camera_name]["ptz_zoom_level"].value = numpy.interp(
self.ptz_metrics[camera_name].zoom_level.value = numpy.interp(
round(status.Position.Zoom.x, 2),
[0, 1],
[
@@ -691,23 +693,23 @@ class OnvifController:
],
)
logger.debug(
f'{camera_name}: Camera zoom level: {self.ptz_metrics[camera_name]["ptz_zoom_level"].value}'
f"{camera_name}: Camera zoom level: {self.ptz_metrics[camera_name].zoom_level.value}"
)
# some hikvision cams won't update MoveStatus, so warn if it hasn't changed
if (
not self.ptz_metrics[camera_name]["ptz_motor_stopped"].is_set()
and not self.ptz_metrics[camera_name]["ptz_reset"].is_set()
and self.ptz_metrics[camera_name]["ptz_start_time"].value != 0
and self.ptz_metrics[camera_name]["ptz_frame_time"].value
> (self.ptz_metrics[camera_name]["ptz_start_time"].value + 10)
and self.ptz_metrics[camera_name]["ptz_stop_time"].value == 0
not self.ptz_metrics[camera_name].motor_stopped.is_set()
and not self.ptz_metrics[camera_name].reset.is_set()
and self.ptz_metrics[camera_name].start_time.value != 0
and self.ptz_metrics[camera_name].frame_time.value
> (self.ptz_metrics[camera_name].start_time.value + 10)
and self.ptz_metrics[camera_name].stop_time.value == 0
):
logger.debug(
f'Start time: {self.ptz_metrics[camera_name]["ptz_start_time"].value}, Stop time: {self.ptz_metrics[camera_name]["ptz_stop_time"].value}, Frame time: {self.ptz_metrics[camera_name]["ptz_frame_time"].value}'
f"Start time: {self.ptz_metrics[camera_name].start_time.value}, Stop time: {self.ptz_metrics[camera_name].stop_time.value}, Frame time: {self.ptz_metrics[camera_name].frame_time.value}"
)
# set the stop time so we don't come back into this again and spam the logs
self.ptz_metrics[camera_name]["ptz_stop_time"].value = self.ptz_metrics[
self.ptz_metrics[camera_name].stop_time.value = self.ptz_metrics[
camera_name
]["ptz_frame_time"].value
].frame_time.value
logger.warning(f"Camera {camera_name} is still in ONVIF 'MOVING' status.")