# How to Set Up PTZ Autotracking with ONVIF Cameras in Frigate

> Easily set up PTZ autotracking for ONVIF cameras in Frigate. Configure autotracking and required zones to automatically follow detected objects, enhancing your surveillance.

- Repository: [Blake Blackshear/frigate](https://github.com/blakeblackshear/frigate)
- Tags: how-to-guide
- Published: 2026-05-25

---

**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`](https://github.com/blakeblackshear/frigate/blob/main/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`](https://github.com/blakeblackshear/frigate/blob/main/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`](https://github.com/blakeblackshear/frigate/blob/main/frigate/config/camera/onvif.py)) establishes the ONVIF client connection:

```yaml
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:

```yaml
    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`](https://github.com/blakeblackshear/frigate/blob/main/frigate/ptz/onvif.py))
- **`return_preset`**: The ONVIF preset name to return to after tracking ends (defined in [`frigate/config/camera/onvif.py`](https://github.com/blakeblackshear/frigate/blob/main/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`](https://github.com/blakeblackshear/frigate/blob/main/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`](https://github.com/blakeblackshear/frigate/blob/main/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`](https://github.com/blakeblackshear/frigate/blob/main/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:

```bash

# 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`](https://github.com/blakeblackshear/frigate/blob/main/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:

```python
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`](https://github.com/blakeblackshear/frigate/blob/main/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`](https://github.com/blakeblackshear/frigate/blob/main/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`](https://github.com/blakeblackshear/frigate/blob/main/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`](https://github.com/blakeblackshear/frigate/blob/main/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`](https://github.com/blakeblackshear/frigate/blob/main/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`](https://github.com/blakeblackshear/frigate/blob/main/frigate/config/camera/onvif.py) (lines 55-62).