How to Set Up PTZ Autotracking with ONVIF Cameras in Frigate

Enable PTZ autotracking by configuring an onvif block with host credentials, setting autotracking.enabled: true, and defining required_zones that trigger camera movement when objects enter the monitored area.

Frigate’s PTZ autotracking feature automatically commands compatible ONVIF-enabled cameras to keep detected objects centered using relative movement commands. This capability leverages the ONVIFCamera class in frigate/ptz/onvif.py to manage connections and issue PTZ instructions based on real-time detection data from the Frigate object detector. The system requires specific ONVIF PTZ capabilities to function and can be configured to return to a preset position when tracking ends.

Prerequisites and Camera Capability Discovery

Before enabling autotracking, Frigate verifies that your camera supports the required PTZ operations. When the service starts, it queries the camera’s PTZ service for the RelativePanTiltTranslationSpace with a TranslationSpaceFov entry (lines 288-300 in frigate/ptz/onvif.py). This confirms the device supports relative-move-within-field-of-view operations necessary for autotracking.

If your camera firmware does not report these capabilities, or if it fails to provide move status feedback, Frigate logs a warning and disables autotracking for that camera. You can verify compatibility using Frigate’s internal API endpoint before deploying the full configuration.

Configuration Structure

Autotracking requires two distinct configuration blocks: the onvif connection parameters and the autotracking behavior settings.

ONVIF Connection Block

The onvif block in your camera configuration (defined in frigate/config/camera/onvif.py) establishes the ONVIF client connection:

cameras:
  front_door:
    onvif:
      host: 192.168.1.10
      port: 80
      username: admin
      password: secret
      return_preset: Home
      # profile: "Profile_1"  # optional: specify PTZ-enabled media profile

      # insecure: true      # optional: skip TLS verification

Autotracking Parameters

The autotracking block enables the feature and defines trigger conditions:

    autotracking:
      enabled: true
      required_zones:
        - porch
      objects:
        - person
      zoom_mode: relative
      return_delay: 5
  • required_zones: Tracking only activates when an object enters these named zones
  • objects: Filter which detection classes trigger tracking (e.g., person, car)
  • zoom_mode: Options are disabled, relative, or absolute (lines 718-733 in frigate/ptz/onvif.py)
  • return_preset: The ONVIF preset name to return to after tracking ends (defined in frigate/config/camera/onvif.py lines 55-62)
  • return_delay: Seconds to wait before returning to the preset after tracking stops

The Autotracking Execution Flow

Understanding the internal mechanics helps troubleshoot issues and optimize performance.

Tracking Trigger Logic

When the detector marks an object as a true positive and it enters a required_zone, the autotracker in frigate/ptz/autotrack.py receives a callback (lines 150-210). The logic calculates the vector needed to center the object in the frame based on the detection bounding box coordinates relative to the frame center.

PTZ Command Execution

The autotracker uses the ONVIF PTZ service (create_ptz_service()) to issue RelativeMove commands. These commands move the camera just enough to keep the object centered. If zoom_mode is enabled, Frigate sends additional AbsoluteMove or RelativeMove commands to adjust zoom levels dynamically (lines 718-733 in frigate/ptz/onvif.py).

Move Status Monitoring

After issuing commands, Frigate polls the camera’s GetStatus or MoveStatus endpoints to determine when the PTZ motors are idle. If the camera never reports status changes (common with certain Hikvision firmware versions), the autotracker disables itself and logs a warning message (lines 1079-1083 in frigate/ptz/onvif.py).

Return Behavior

When tracking ends—either because the object is lost, PTZ limits are reached, or via manual stop—Frigate automatically sends the camera to the return_preset position after waiting the configured return_delay seconds.

Remote Control via MQTT

You can enable or disable autotracking at runtime using MQTT topics, useful for integration with home automation systems:


# Enable autotracking

mosquitto_pub -t "frigate/front_door/ptz_autotracker/set" -m "ON"

# Disable autotracking

mosquitto_pub -t "frigate/front_door/ptz_autotracker/set" -m "OFF"

These commands are handled by the autotracker logic in frigate/ptz/autotrack.py and take effect immediately without requiring a Frigate restart.

Verifying Camera Compatibility

To test ONVIF capabilities before full configuration, use Frigate’s internal API probe function:

import asyncio
from frigate.api.camera import probe_onvif

async def test_camera():
    result = await probe_onvif(
        host="192.168.1.10",
        port=80,
        username="admin",
        password="secret",
        auth_type="basic",
        tls=False,
    )
    print(result)

asyncio.run(test_camera())

This endpoint (implemented in frigate/api/camera.py) constructs an ONVIFCamera instance and queries the device’s PTZ capabilities, returning a JSON object detailing supported translation spaces and move operations.

Summary

  • Capability Verification: Frigate checks for RelativePanTiltTranslationSpace with TranslationSpaceFov support in frigate/ptz/onvif.py before enabling autotracking
  • Zone-Based Triggering: Tracking only activates when objects enter the required_zones defined in your configuration
  • Status Polling: The system monitors GetStatus responses to synchronize commands; cameras that don’t report status disable the feature automatically
  • MQTT Control: Runtime enable/disable is available via frigate/{camera_name}/ptz_autotracker/set topics
  • Return Presets: Configure return_preset and return_delay to automatically reposition the camera after tracking sessions

Frequently Asked Questions

What ONVIF capabilities are required for PTZ autotracking?

Your camera must support the RelativePanTiltTranslationSpace with a TranslationSpaceFov entry in its ONVIF PTZ service capabilities. Frigate queries this during initialization (lines 288-300 in frigate/ptz/onvif.py) to confirm the device can execute relative moves within the field of view. Without this capability, the autotracker initializes in a disabled state and logs a compatibility warning.

Why does my camera stop autotracking with a warning about move status?

Frigate polls the camera’s GetStatus or MoveStatus endpoints after each PTZ command to detect when movement completes. If your camera firmware (notably some Hikvision variants) returns static values or fails to update the move status, Frigate cannot synchronize subsequent commands safely. The system disables autotracking and logs a warning (lines 1079-1083 in frigate/ptz/onvif.py) to prevent erratic camera behavior.

Can I temporarily disable autotracking without editing the configuration file?

Yes. Send an MQTT message to frigate/{camera_name}/ptz_autotracker/set with the payload OFF to disable tracking immediately. Send ON to re-enable it. This is handled by the autotracker callback logic in frigate/ptz/autotrack.py and does not require a Frigate service restart.

How do I configure the camera to return to a specific position after tracking?

Define the return_preset option in your onvif configuration block with the exact name of an ONVIF preset stored in your camera. Set return_delay to specify how many seconds to wait after tracking ends before executing the return movement. These settings are validated against the Pydantic schema in frigate/config/camera/onvif.py (lines 55-62).

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →