Miscellaneous fixes (0.18 beta) (#23725)
CI / AMD64 Build (push) Waiting to run
CI / ARM Build (push) Waiting to run
CI / Jetson Jetpack 6 (push) Waiting to run
CI / AMD64 Extra Build (push) Blocked by required conditions
CI / ARM Extra Build (push) Blocked by required conditions
CI / Synaptics Build (push) Blocked by required conditions
CI / Assemble and push default build (push) Blocked by required conditions

This commit is contained in:
Josh Hawkins
2026-07-15 18:49:05 -06:00
committed by GitHub
parent a8eca68438
commit c406a93d3d
20 changed files with 789 additions and 146 deletions
+46 -4
View File
@@ -20,6 +20,10 @@ from norfair.camera_motion import (
from frigate.camera import PTZMetrics
from frigate.comms.dispatcher import Dispatcher
from frigate.config import CameraConfig, FrigateConfig, ZoomingModeEnum
from frigate.config.camera.updater import (
CameraConfigUpdateEnum,
CameraConfigUpdateSubscriber,
)
from frigate.const import (
AUTOTRACKING_MAX_AREA_RATIO,
AUTOTRACKING_MAX_MOVE_METRICS,
@@ -194,7 +198,9 @@ class PtzAutoTrackerThread(threading.Thread):
def run(self):
while not self.stop_event.wait(1):
for camera, camera_config in self.config.cameras.items():
self.ptz_autotracker.check_for_updates()
for camera, camera_config in list(self.config.cameras.items()):
if not camera_config.enabled:
continue
@@ -211,6 +217,7 @@ class PtzAutoTrackerThread(threading.Thread):
self.ptz_autotracker.tracked_object[camera] = None
self.ptz_autotracker.tracked_object_history[camera].clear()
self.ptz_autotracker.config_subscriber.stop()
logger.info("Exiting autotracker...")
@@ -244,6 +251,16 @@ class PtzAutoTracker:
self.zoom_time: dict[str, float] = {}
self.zoom_factor: dict[str, object] = {}
self.config_subscriber = CameraConfigUpdateSubscriber(
self.config,
self.config.cameras,
[
CameraConfigUpdateEnum.add,
CameraConfigUpdateEnum.autotracking,
CameraConfigUpdateEnum.onvif,
],
)
# if cam is set to autotrack, onvif should be set up
for camera, camera_config in self.config.cameras.items():
if not camera_config.enabled:
@@ -260,6 +277,29 @@ class PtzAutoTracker:
# Wait for the coroutine to complete
future.result()
def check_for_updates(self) -> None:
"""Apply camera config updates and mirror autotracking state to ptz metrics.
The camera processes read autotracker_enabled rather than the config, so it
has to follow every path that can change autotracking, not just the mqtt
toggle that writes it directly.
"""
updates = self.config_subscriber.check_for_updates()
for cameras in updates.values():
for camera in cameras:
camera_config = self.config.cameras.get(camera)
metrics = self.ptz_metrics.get(camera)
# a camera added at runtime gets its metrics from the maintainer on
# another thread, which seeds them from this same config value
if camera_config is None or metrics is None:
continue
metrics.autotracker_enabled.value = (
camera_config.onvif.autotracking.enabled
)
async def _autotracker_setup(self, camera_config: CameraConfig, camera: str):
logger.debug(f"{camera}: Autotracker init")
@@ -1365,7 +1405,7 @@ class PtzAutoTracker:
camera_config = self.config.cameras[camera]
if camera_config.onvif.autotracking.enabled:
if not self.autotracker_init[camera]:
if not self.autotracker_init.get(camera):
future = asyncio.run_coroutine_threadsafe(
self._autotracker_setup(camera_config, camera), self.onvif.loop
)
@@ -1483,9 +1523,11 @@ class PtzAutoTracker:
}
async def camera_maintenance(self, camera):
# bail and don't check anything if we're calibrating or tracking an object
# bail and don't check anything if we're not set up yet, calibrating, or
# tracking an object. a camera enabled at runtime has no autotracker_init
# entry until autotrack_object sets it up
if (
not self.autotracker_init[camera]
not self.autotracker_init.get(camera)
or self.calibrating[camera]
or self.tracked_object[camera] is not None
):
+10 -9
View File
@@ -344,16 +344,17 @@ class OnvifController:
autotracking_config.enabled_in_config and autotracking_config.enabled
)
# autotracking-only: status request and service capabilities
if autotracking_enabled:
status_request = ptz.create_type("GetStatus")
status_request.ProfileToken = profile.token
self.cams[camera_name]["status_request"] = status_request
# these are local and cost nothing to build, and autotracking can be enabled
# after a camera is initialized, so always create them rather than baking the
# current config value into init state
status_request = ptz.create_type("GetStatus")
status_request.ProfileToken = profile.token
self.cams[camera_name]["status_request"] = status_request
service_capabilities_request = ptz.create_type("GetServiceCapabilities")
self.cams[camera_name]["service_capabilities_request"] = (
service_capabilities_request
)
service_capabilities_request = ptz.create_type("GetServiceCapabilities")
self.cams[camera_name]["service_capabilities_request"] = (
service_capabilities_request
)
# setup relative move request when FOV relative movement is supported
if (