test_ptz_camera.py 2.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. import sys
  2. import os
  3. sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
  4. from unittest.mock import MagicMock
  5. import pytest
  6. from ptz_camera import PTZCamera, PTZCommand
  7. @pytest.fixture
  8. def fake_sdk():
  9. return MagicMock()
  10. def make_camera(fake_sdk, **ptz_overrides):
  11. cam = PTZCamera(fake_sdk, camera_config={"ip": "1.2.3.4", "port": 37777,
  12. "username": "u", "password": "p",
  13. "channel": 0, **ptz_overrides})
  14. cam.connected = True
  15. cam.login_handle = 1
  16. fake_sdk.ptz_control.return_value = True
  17. return cam
  18. def capture_goto_call(cam):
  19. """返回最后一次 EXACTGOTO 调用的 (pan*10, tilt*10, zoom)。"""
  20. calls = cam.sdk.ptz_control.call_args_list
  21. for call in reversed(calls):
  22. args = call[0]
  23. if args[2] == PTZCommand.EXACTGOTO:
  24. return args[3], args[4], args[5]
  25. raise AssertionError("EXACTGOTO not called")
  26. def test_goto_no_flip(fake_sdk):
  27. cam = make_camera(fake_sdk, mount_type="wall", pan_flip=False, tilt_flip=False)
  28. assert cam.goto_exact_position(30.0, 10.0, 2)
  29. p1, p2, p3 = capture_goto_call(cam)
  30. assert p1 == 300
  31. assert p2 == 100
  32. assert p3 == 2
  33. def test_goto_tilt_flip(fake_sdk):
  34. cam = make_camera(fake_sdk, mount_type="wall", pan_flip=False, tilt_flip=True)
  35. assert cam.goto_exact_position(30.0, 10.0, 2)
  36. p1, p2, p3 = capture_goto_call(cam)
  37. assert p1 == 300
  38. assert p2 == -100
  39. assert p3 == 2
  40. def test_goto_ceiling_mount_flips_tilt(fake_sdk):
  41. cam = make_camera(fake_sdk, mount_type="ceiling", pan_flip=False, tilt_flip=False)
  42. assert cam.goto_exact_position(30.0, 10.0, 2)
  43. p1, p2, p3 = capture_goto_call(cam)
  44. assert p1 == 300
  45. assert p2 == -100
  46. assert p3 == 2
  47. def test_goto_pan_flip(fake_sdk):
  48. cam = make_camera(fake_sdk, mount_type="wall", pan_flip=True, tilt_flip=False)
  49. assert cam.goto_exact_position(30.0, 10.0, 2)
  50. p1, p2, p3 = capture_goto_call(cam)
  51. assert p1 == 2100 # (30+180)*10
  52. assert p2 == 100
  53. assert p3 == 2
  54. def test_goto_pan_and_tilt_flip(fake_sdk):
  55. cam = make_camera(fake_sdk, mount_type="wall", pan_flip=True, tilt_flip=True)
  56. assert cam.goto_exact_position(30.0, 10.0, 2)
  57. p1, p2, p3 = capture_goto_call(cam)
  58. assert p1 == 2100
  59. assert p2 == -100
  60. assert p3 == 2
  61. def test_calculate_position_does_not_apply_flips(fake_sdk):
  62. """calculate_ptz_position 返回视觉坐标,翻转统一在 goto_exact_position 处理。"""
  63. cam = make_camera(fake_sdk, mount_type="wall", pan_flip=True, tilt_flip=True,
  64. pan_range=(0, 90), tilt_range=(-45, 45), pan_center=45, tilt_center=0)
  65. pan, tilt, zoom = cam.calculate_ptz_position(0.5, 0.5, 3)
  66. assert pan == 45.0
  67. assert tilt == 0.0
  68. assert zoom == 3