From 0760704db8ca7ecf185d18e1538a1f237f817d91 Mon Sep 17 00:00:00 2001 From: Ryan Gregg Date: Wed, 18 Mar 2026 02:46:12 +0000 Subject: [PATCH] Address Copilot review: touch handling, null guards, and test accuracy - Add touch-none class to drag overlay for reliable touch event capture - Guard status.Position access when GetStatus fails (status is None) - Make RelativeZoomTranslationSpace lookup resilient to missing/None fields - Fix test inputs to use "relative_" prefix matching actual dispatcher format Co-Authored-By: Claude Opus 4.6 (1M context) --- frigate/ptz/onvif.py | 25 ++++++++++++++++--------- frigate/test/test_ptz_commands.py | 8 ++++---- web/src/views/live/LiveCameraView.tsx | 2 +- 3 files changed, 21 insertions(+), 14 deletions(-) diff --git a/frigate/ptz/onvif.py b/frigate/ptz/onvif.py index 2ab9fe05a..8a62fd2cb 100644 --- a/frigate/ptz/onvif.py +++ b/frigate/ptz/onvif.py @@ -255,23 +255,30 @@ class OnvifController: status = None # Check for relative zoom support - zoom_space_id = next( - ( - i - for i, space in enumerate( - ptz_config.Spaces.RelativeZoomTranslationSpace - ) - if "TranslationGenericSpace" in space["URI"] - ), + zoom_spaces = getattr( + getattr(ptz_config, "Spaces", None), + "RelativeZoomTranslationSpace", None, ) + zoom_space_id = ( + next( + ( + i + for i, space in enumerate(zoom_spaces) + if "TranslationGenericSpace" in space["URI"] + ), + None, + ) + if zoom_spaces + else None + ) # setup relative moving request (for click-to-move, drag-to-zoom, and autotracking) if fov_space_id is not None: move_request = ptz.create_type("RelativeMove") move_request.ProfileToken = profile.token logger.debug(f"{camera_name}: Relative move request: {move_request}") - if move_request.Translation is None: + if move_request.Translation is None and status is not None: move_request.Translation = status.Position move_request.Translation.PanTilt.space = ptz_config["Spaces"][ "RelativePanTiltTranslationSpace" diff --git a/frigate/test/test_ptz_commands.py b/frigate/test/test_ptz_commands.py index 4f0460612..1830d2a31 100644 --- a/frigate/test/test_ptz_commands.py +++ b/frigate/test/test_ptz_commands.py @@ -35,25 +35,25 @@ class TestMoveRelativeParsing(TestCase): return float(pan), float(tilt), zoom def test_pan_tilt_only(self): - pan, tilt, zoom = self._parse_move_relative("move_0.5_-0.3") + pan, tilt, zoom = self._parse_move_relative("relative_0.5_-0.3") self.assertAlmostEqual(pan, 0.5) self.assertAlmostEqual(tilt, -0.3) self.assertAlmostEqual(zoom, 0) def test_pan_tilt_with_zoom(self): - pan, tilt, zoom = self._parse_move_relative("move_0.5_-0.3_0.8") + pan, tilt, zoom = self._parse_move_relative("relative_0.5_-0.3_0.8") self.assertAlmostEqual(pan, 0.5) self.assertAlmostEqual(tilt, -0.3) self.assertAlmostEqual(zoom, 0.8) def test_zero_zoom(self): - pan, tilt, zoom = self._parse_move_relative("move_0.0_0.0_0.0") + pan, tilt, zoom = self._parse_move_relative("relative_0.0_0.0_0.0") self.assertAlmostEqual(pan, 0.0) self.assertAlmostEqual(tilt, 0.0) self.assertAlmostEqual(zoom, 0.0) def test_negative_values(self): - pan, tilt, zoom = self._parse_move_relative("move_-1.0_-1.0_0.5") + pan, tilt, zoom = self._parse_move_relative("relative_-1.0_-1.0_0.5") self.assertAlmostEqual(pan, -1.0) self.assertAlmostEqual(tilt, -1.0) self.assertAlmostEqual(zoom, 0.5) diff --git a/web/src/views/live/LiveCameraView.tsx b/web/src/views/live/LiveCameraView.tsx index 63babb446..8a3d46fd3 100644 --- a/web/src/views/live/LiveCameraView.tsx +++ b/web/src/views/live/LiveCameraView.tsx @@ -760,7 +760,7 @@ export default function LiveCameraView({ > {clickOverlay && (