Skip to content

Instantly share code, notes, and snippets.

@hawkeye217
Last active March 31, 2024 17:26
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save hawkeye217/152a1d4ba80760dac95d46e143d37112 to your computer and use it in GitHub Desktop.
Save hawkeye217/152a1d4ba80760dac95d46e143d37112 to your computer and use it in GitHub Desktop.
Check if an ONVIF-capable IP PTZ camera supports RelativeMove with FOV
# This script can help you determine if your PTZ is capable of
# working with Frigate NVR's autotracker.
#
# Cameras with a "YES" printed for each parameter at the end of
# the output will likely be supported by Frigate.
#
# Make sure you're using python3 with the onvif-zeep package
# Update the values for your camera below, then run:
# pip3 install onvif-zeep
# python3 ./fovtest.py
from onvif import ONVIFCamera
# UPDATE the IP address, ONVIF port, "admin" and "password" with your camera's details.
mycam = ONVIFCamera('192.168.1.100', 80, 'admin', 'password', '/etc/onvif/wsdl/')
print('Connected to ONVIF camera')
# Create media service object
media = mycam.create_media_service()
print('Created media service object')
print
# Get target profile
media_profiles = media.GetProfiles()
print('Media profiles')
print(media_profiles)
for key, onvif_profile in enumerate(media_profiles):
if (
not onvif_profile.VideoEncoderConfiguration
or onvif_profile.VideoEncoderConfiguration.Encoding != "H264"
):
continue
# Configure PTZ options
if onvif_profile.PTZConfiguration:
if onvif_profile.PTZConfiguration.DefaultContinuousPanTiltVelocitySpace is not None:
media_profile = onvif_profile
token = media_profile.token
print('Chosen token')
print(token)
print
# Create ptz service object
print('Creating PTZ object')
ptz = mycam.create_ptz_service()
print('Created PTZ service object')
print
# Get PTZ configuration options for getting option ranges
request = ptz.create_type("GetConfigurations")
configs = ptz.GetConfigurations(request)[0]
print('PTZ configurations:')
print(configs)
print()
request = ptz.create_type('GetConfigurationOptions')
request.ConfigurationToken = media_profile.PTZConfiguration.token
ptz_configuration_options = ptz.GetConfigurationOptions(request)
print('PTZ configuration options:')
print(ptz_configuration_options)
print()
print('PTZ service capabilities:')
request = ptz.create_type('GetServiceCapabilities')
service_capabilities = ptz.GetServiceCapabilities(request)
print(service_capabilities)
print()
print('PTZ status:')
request = ptz.create_type("GetStatus")
request.ProfileToken = token
status = ptz.GetStatus(request)
print(status)
pantilt_space_id = next(
(
i
for i, space in enumerate(
ptz_configuration_options.Spaces.RelativePanTiltTranslationSpace
)
if "TranslationSpaceFov" in space["URI"]
),
None,
)
zoom_space_id = next(
(
i
for i, space in enumerate(
ptz_configuration_options.Spaces.RelativeZoomTranslationSpace
)
if "TranslationGenericSpace" in space["URI"]
),
None,
)
def find_by_key(dictionary, target_key):
if target_key in dictionary:
return dictionary[target_key]
else:
for value in dictionary.values():
if isinstance(value, dict):
result = find_by_key(value, target_key)
if result is not None:
return result
return None
if find_by_key(vars(service_capabilities), "MoveStatus"):
print("YES - GetServiceCapabilities shows that the camera supports MoveStatus.")
else:
print("NO - GetServiceCapabilities shows that the camera does not support MoveStatus.")
# there doesn't seem to be an onvif standard with this optional parameter
# some cameras can report MoveStatus with or without PanTilt or Zoom attributes
pan_tilt_status = getattr(status.MoveStatus, "PanTilt", None)
zoom_status = getattr(status.MoveStatus, "Zoom", None)
if pan_tilt_status is not None and pan_tilt_status == "IDLE" and (
zoom_status is None or zoom_status == "IDLE"
):
print("YES - MoveStatus is reporting IDLE.")
# if it's not an attribute, see if MoveStatus even exists in the status result
if pan_tilt_status is None:
pan_tilt_status = getattr(status.MoveStatus, "MoveStatus", None)
# we're unsupported
if pan_tilt_status is None or (isinstance(pan_tilt_status, str) and pan_tilt_status not in [
"IDLE",
"MOVING",
]):
print("NO - MoveStatus not reporting IDLE or MOVING.")
if pantilt_space_id is not None and configs.DefaultRelativePanTiltTranslationSpace is not None:
print("YES - RelativeMove Pan/Tilt (FOV) is supported.")
else:
print("NO - RelativeMove Pan/Tilt is unsupported.")
if zoom_space_id is not None:
print("YES - RelativeMove Zoom is supported.")
else:
print("NO - RelativeMove Zoom is unsupported.")
@hawkeye217
Copy link
Author

hawkeye217 commented Jul 6, 2023

Another user reported that lines 15 and 27 needed to be changed to _token (from token) for their camera, but I wonder if it's camera specific...

This works with my camera using python3's onvif-zeep package, version 0.2.12.

@kirsch33
Copy link

kirsch33 commented Jul 6, 2023

edit: removing this comment until I confirm its not just me using a weird version of python/onvif package

ignore me, i was using python-onvif package with python 2.x

false alarm

@Dvalin21
Copy link

Dvalin21 commented Oct 2, 2023

So I installed the dependencies to run this script. I was able to get the full operation of my camera.

PTZ configuration options:
{
    'Spaces': {
        'AbsolutePanTiltPositionSpace': [
            {
                'URI': 'http://www.onvif.org/ver10/tptz/PanTiltSpaces/PositionGenericSpace',
                'XRange': {
                    'Min': -1.0,
                    'Max': 1.0
                },
                'YRange': {
                    'Min': -1.0,
                    'Max': 1.0
                }
            }
        ],
        'AbsoluteZoomPositionSpace': [
            {
                'URI': 'http://www.onvif.org/ver10/tptz/ZoomSpaces/PositionGenericSpace',
                'XRange': {
                    'Min': 0.0,
                    'Max': 1.0
                }
            }
        ],
        'RelativePanTiltTranslationSpace': [
            {
                'URI': 'http://www.onvif.org/ver10/tptz/PanTiltSpaces/TranslationGenericSpace',
                'XRange': {
                    'Min': -1.0,
                    'Max': 1.0
                },
                'YRange': {
                    'Min': -1.0,
                    'Max': 1.0
                }
            }
        ],
        'RelativeZoomTranslationSpace': [
            {
                'URI': 'http://www.onvif.org/ver10/tptz/ZoomSpaces/TranslationGenericSpace',
                'XRange': {
                    'Min': -1.0,
                    'Max': 1.0
                }
            }
        ],
        'ContinuousPanTiltVelocitySpace': [
            {
                'URI': 'http://www.onvif.org/ver10/tptz/PanTiltSpaces/VelocityGenericSpace',
                'XRange': {
                    'Min': -1.0,
                    'Max': 1.0
                },
                'YRange': {
                    'Min': -1.0,
                    'Max': 1.0
                }
            }
        ],
        'ContinuousZoomVelocitySpace': [
            {
                'URI': 'http://www.onvif.org/ver10/tptz/ZoomSpaces/VelocityGenericSpace',
                'XRange': {
                    'Min': -1.0,
                    'Max': 1.0
                }
            }
        ],
        'PanTiltSpeedSpace': [
            {
                'URI': 'http://www.onvif.org/ver10/tptz/PanTiltSpaces/GenericSpeedSpace',
                'XRange': {
                    'Min': 1.0,
                    'Max': 8.0
                }
            }
        ],
        'ZoomSpeedSpace': [
            {
                'URI': 'http://www.onvif.org/ver10/tptz/ZoomSpaces/ZoomGenericSpeedSpace',
                'XRange': {
                    'Min': 1.0,
                    'Max': 8.0
                }
            }
        ],
        'Extension': None,
        '_attr_1': None
    },
    'PTZTimeout': {
        'Min': datetime.timedelta(seconds=1),
        'Max': datetime.timedelta(seconds=100)
    },
    '_value_1': [
        <Element {http://www.onvif.org/ver10/schema}PTControlDirection at 0x7fb049061680>
    ],
    'PTControlDirection': None,
    'Extension': None,
    '_attr_1': None
}

PTZ service capabilities:
{
    '_value_1': None,
    'EFlip': True,
    'Reverse': True,
    'GetCompatibleConfigurations': True,
    '_attr_1': {
        'MoveStatus': 'true',
        'StatusPosition': 'true'
    }
}

PTZ status:
{
    'Position': {
        'PanTilt': {
            'x': -1.0,
            'y': -1.0,
            'space': 'http://www.onvif.org/ver10/tptz/PanTiltSpaces/PositionGenericSpace'
        },
        'Zoom': {
            'x': 0.0,
            'space': 'http://www.onvif.org/ver10/tptz/ZoomSpaces/PositionGenericSpace'
        }
    },
    'MoveStatus': {
        'PanTilt': 'IDLE',
        'Zoom': 'IDLE'
    },
    'Error': None,
    'UtcTime': datetime.datetime(2023, 10, 2, 6, 29, 35, tzinfo=<isodate.tzinfo.Utc object at 0x7fb04a7d36a0>),
    '_value_1': None,
    '_attr_1': None
}
NO - RelativeMove Pan/Tilt is unsupported.
YES - RelativeMove Zoom is supported.

And of course from the if else statement is shows No not supported RelativeMove Pan/Tilt. But if you look at the full capability list, it is capable. It even goes as far as to show its pan and tilt is idle. Was this script for a particular band of onvif camera? Thanks.

@hawkeye217
Copy link
Author

So I installed the dependencies to run this script. I was able to get the full operation of my camera.

NO - RelativeMove Pan/Tilt is unsupported.
YES - RelativeMove Zoom is supported.

And of course from the if else statement is shows No not supported RelativeMove Pan/Tilt. But if you look at the full capability list, it is capable. It even goes as far as to show its pan and tilt is idle. Was this script for a particular band of onvif camera? Thanks.

Not sure if you found this gist publicly or from Frigate NVR's documentation, but this script is particular to Frigate as it checks a camera's capability for particular features.

Your camera supports relative movement, but it does not support relative movement within the field of view. Here's the output from a camera that does support it:

        'RelativePanTiltTranslationSpace': [
            {
                'URI': 'http://www.onvif.org/ver10/tptz/PanTiltSpaces/TranslationGenericSpace',
                'XRange': {
                    'Min': -1.0,
                    'Max': 1.0
                },
                'YRange': {
                    'Min': -1.0,
                    'Max': 1.0
                }
            },
            {
                'URI': 'http://www.onvif.org/ver10/tptz/PanTiltSpaces/TranslationSpaceFov',
                'XRange': {
                    'Min': -1.0,
                    'Max': 1.0
                },
                'YRange': {
                    'Min': -1.0,
                    'Max': 1.0
                }
            }
        ],

Notice the URI in the 2nd entry - it contains TranslationSpaceFov, which is the capability that Frigate NVR needs. This is why you're seeing a "NO" in your output.

Hope that helps!

@Dvalin21
Copy link

Dvalin21 commented Oct 4, 2023

100% Thanks a bunch. I understand better on what I need to look for

@kquinsland
Copy link

For the next guy that struggles, gets stuck / googles their way here:

Amcrest IP4M-1051B with V2.620.00AC000.3.R, Build Date: 2019-12-18 and with V2.620.00AC003.0.R, Build Date: 2022-07-27 gives:

YES - MoveStatus is reporting IDLE.
NO - RelativeMove Pan/Tilt is unsupported.
YES - RelativeMove Zoom is supported.

For a Amcrest IP4M-1041B with V2.800.0000000.15.R, Build Date: 2021-07-16 and with V2.800.00AC003.0.R, Build Date: 2022-08-11 the results are:

YES - MoveStatus is reporting IDLE.
YES - RelativeMove Pan/Tilt (FOV) is supported.
YES - RelativeMove Zoom is supported.

Note: The onvif service port will be the same port as the web interface (80 or 443 probably. not 8000) and you must use the root/admin credentials for onvif control unless you disable auth all-together! ( "security" on these cheap IP cameras is a joke )

@hipitihop
Copy link

hipitihop commented Feb 24, 2024

Also for the next guy that meanders their way here:

Hikvision DS-2DE2A404IW-DE3 it's a PTZ mini dome with:

Firmware Version V5.7.11 build 230612
Encoding Version V7.3 build 220830
Web Version V4.0.1.0 build 220706

I had to do the following:
In Hikvision camera web UI:

  • enable onvif in Integration Protocol
  • switch authentication from digest to digest/WSSE
  • add an onvif user, in my case frigate. With operator or admin rights.

image

In this script:

  • specify same onvif user and password.
  • use port 80 (seems to be the default for Hikvision)
  • I'm on ubuntu 22.04 and so I also had to point to a different path for the WSDL, here '/etc/onvif/wsdl/ but in my case '/usr/local/lib/python3.10/site-packages/wsdl/' otherwise script fails.

After I got the WSDL path right and the script ran, it would give vague unknown fault error. To see what was going on, I also had to add the following to the top of the script, to get more debugging from zeep.

mport logging
from zeep.transports import Transport

logging.basicConfig(level=logging.DEBUG)
logger = logging.getLogger('zeep.transports')
logger.setLevel(logging.DEBUG)

transport = Transport(operation_timeout=10)  # Adjust the timeout as necessary

This is what led me to finally see error from the camera:

...
DEBUG:urllib3.connectionpool:Starting new HTTP connection (1): 192.168.1.79:80
DEBUG:urllib3.connectionpool:http://192.168.1.79:80 "POST /onvif/Media HTTP/1.1" 401 234
DEBUG:zeep.transports:HTTP Response from http://192.168.1.79/onvif/Media (status: 401):
<!DOCTYPE html>
<html><head><title>Document Error: Unauthorized</title></head>
<body><h2>Access Error: 401 -- Unauthorized</h2>
<p>Authentication Error: This onvif request requires authentication information</p>
</body>
</html>
...

This prompted me to change the camera onvif authentication from digest to digest/WSSE.
I'm sure this extra logging will likely help in other scenarios/issues for some people.

With this in place the script finally produced

YES - MoveStatus is reporting IDLE.
YES - RelativeMove Pan/Tilt (FOV) is supported.
YES - RelativeMove Zoom is supported.

And in the frigate web UI with matching onvif configuration and specifying port: 80, I finally see a perfectly working extra control panel
image

@Dvalin21
Copy link

So I purchased a LS-Vision LS-WL342-20X Camera. Its a chinese manufactured camera, but to my surprise it partially works with frigate's onvif functions. I can only get it to tilt up or down, but not pan. Wont zoom, and I dont get the presets selection to the right.

When I ran the script I got the following

Connected to ONVIF camera
Created media service object
Media profiles
[{
    'Name': 'FixedProfile01',
    'VideoSourceConfiguration': {
        'Name': 'VideoSourceConfiguration01',
        'UseCount': 2,
        'SourceToken': 'VideoSource001',
        'Bounds': {
            'x': 0,
            'y': 0,
            'width': 1920,
            'height': 1080
        },
        '_value_1': None,
        'Extension': None,
        'token': 'VideoSourceConfiguration001',
        '_attr_1': {
    }
    },
    'AudioSourceConfiguration': {
        'Name': 'AudioSourceConfiguration01',
        'UseCount': 2,
        'SourceToken': 'AudioSource001',
        '_value_1': None,
        'token': 'AudioSourceConfiguration001',
        '_attr_1': {
    }
    },
    'VideoEncoderConfiguration': {
        'Name': 'VideoEncoder01',
        'UseCount': 2,
        'Encoding': 'H264',
        'Resolution': {
            'Width': 1920,
            'Height': 1080
        },
        'Quality': 4.0,
        'RateControl': {
            'FrameRateLimit': 15,
            'EncodingInterval': 1,
            'BitrateLimit': 2
        },
        'MPEG4': None,
        'H264': {
            'GovLength': 30,
            'H264Profile': 'Main'
        },
        'Multicast': {
            'Address': {
                'Type': 'IPv4',
                'IPv4Address': '224.0.0.123',
                'IPv6Address': None
            },
            'Port': 8600,
            'TTL': 120,
            'AutoStart': False,
            '_value_1': None,
            '_attr_1': None
        },
        'SessionTimeout': datetime.timedelta(seconds=60),
        '_value_1': None,
        'token': 'VideoEncoderConfiguration001',
        '_attr_1': {
    }
    },
    'AudioEncoderConfiguration': {
        'Name': 'AudioEncoder01',
        'UseCount': 2,
        'Encoding': 'G711',
        'Bitrate': 128,
        'SampleRate': 8000,
        'Multicast': {
            'Address': {
                'Type': 'IPv4',
                'IPv4Address': '224.0.0.123',
                'IPv6Address': None
            },
            'Port': 8600,
            'TTL': 120,
            'AutoStart': False,
            '_value_1': None,
            '_attr_1': None
        },
        'SessionTimeout': datetime.timedelta(seconds=60),
        '_value_1': None,
        'token': 'AudioEncoderConfiguration001',
        '_attr_1': {
    }
    },
    'VideoAnalyticsConfiguration': None,
    'PTZConfiguration': {
        'Name': 'PTZConfiguration01',
        'UseCount': 2,
        'NodeToken': 'PTZNode01',
        'DefaultAbsolutePantTiltPositionSpace': None,
        'DefaultAbsoluteZoomPositionSpace': None,
        'DefaultRelativePanTiltTranslationSpace': None,
        'DefaultRelativeZoomTranslationSpace': None,
        'DefaultContinuousPanTiltVelocitySpace': 'http://www.onvif.org/ver10/tptz/PanTiltSpaces/VelocityGenericSpace',
        'DefaultContinuousZoomVelocitySpace': 'http://www.onvif.org/ver10/tptz/ZoomSpaces/VelocityGenericSpace',
        'DefaultPTZSpeed': None,
        'DefaultPTZTimeout': datetime.timedelta(seconds=10),
        'PanTiltLimits': None,
        'ZoomLimits': None,
        'Extension': None,
        'token': 'PTZConfig001',
        '_attr_1': {
    }
    },
    'MetadataConfiguration': None,
    'Extension': None,
    'token': 'FixedProfile001',
    'fixed': True,
    '_attr_1': {
}
}, {
    'Name': 'FixedProfile02',
    'VideoSourceConfiguration': {
        'Name': 'VideoSourceConfiguration01',
        'UseCount': 2,
        'SourceToken': 'VideoSource001',
        'Bounds': {
            'x': 0,
            'y': 0,
            'width': 784,
            'height': 440
        },
        '_value_1': None,
        'Extension': None,
        'token': 'VideoSourceConfiguration001',
        '_attr_1': {
    }
    },
    'AudioSourceConfiguration': {
        'Name': 'AudioSourceConfiguration01',
        'UseCount': 2,
        'SourceToken': 'AudioSource001',
        '_value_1': None,
        'token': 'AudioSourceConfiguration001',
        '_attr_1': {
    }
    },
    'VideoEncoderConfiguration': {
        'Name': 'VideoEncoder02',
        'UseCount': 2,
        'Encoding': 'H264',
        'Resolution': {
            'Width': 784,
            'Height': 440
        },
        'Quality': 4.0,
        'RateControl': {
            'FrameRateLimit': 15,
            'EncodingInterval': 1,
            'BitrateLimit': 2
        },
        'MPEG4': None,
        'H264': {
            'GovLength': 30,
            'H264Profile': 'Main'
        },
        'Multicast': {
            'Address': {
                'Type': 'IPv4',
                'IPv4Address': '224.0.0.123',
                'IPv6Address': None
            },
            'Port': 8600,
            'TTL': 120,
            'AutoStart': False,
            '_value_1': None,
            '_attr_1': None
        },
        'SessionTimeout': datetime.timedelta(seconds=60),
        '_value_1': None,
        'token': 'VideoEncoderConfiguration002',
        '_attr_1': {
    }
    },
    'AudioEncoderConfiguration': {
        'Name': 'AudioEncoder01',
        'UseCount': 2,
        'Encoding': 'G711',
        'Bitrate': 128,
        'SampleRate': 8000,
        'Multicast': {
            'Address': {
                'Type': 'IPv4',
                'IPv4Address': '224.0.0.123',
                'IPv6Address': None
            },
            'Port': 8600,
            'TTL': 120,
            'AutoStart': False,
            '_value_1': None,
            '_attr_1': None
        },
        'SessionTimeout': datetime.timedelta(seconds=60),
        '_value_1': None,
        'token': 'AudioEncoderConfiguration001',
        '_attr_1': {
    }
    },
    'VideoAnalyticsConfiguration': None,
    'PTZConfiguration': {
        'Name': 'PTZConfiguration01',
        'UseCount': 2,
        'NodeToken': 'PTZNode01',
        'DefaultAbsolutePantTiltPositionSpace': None,
        'DefaultAbsoluteZoomPositionSpace': None,
        'DefaultRelativePanTiltTranslationSpace': None,
        'DefaultRelativeZoomTranslationSpace': None,
        'DefaultContinuousPanTiltVelocitySpace': 'http://www.onvif.org/ver10/tptz/PanTiltSpaces/VelocityGenericSpace',
        'DefaultContinuousZoomVelocitySpace': 'http://www.onvif.org/ver10/tptz/ZoomSpaces/VelocityGenericSpace',
        'DefaultPTZSpeed': None,
        'DefaultPTZTimeout': datetime.timedelta(seconds=10),
        'PanTiltLimits': None,
        'ZoomLimits': None,
        'Extension': None,
        'token': 'PTZConfig001',
        '_attr_1': {
    }
    },
    'MetadataConfiguration': None,
    'Extension': None,
    'token': 'FixedProfile002',
    'fixed': True,
    '_attr_1': {
}
}, {
    'Name': 'FixedProfile03',
    'VideoSourceConfiguration': {
        'Name': 'VideoSourceConfiguration02',
        'UseCount': 2,
        'SourceToken': 'VideoSource002',
        'Bounds': {
            'x': 0,
            'y': 0,
            'width': 1920,
            'height': 1080
        },
        '_value_1': None,
        'Extension': None,
        'token': 'VideoSourceConfiguration002',
        '_attr_1': {
    }
    },
    'AudioSourceConfiguration': {
        'Name': 'AudioSourceConfiguration01',
        'UseCount': 2,
        'SourceToken': 'AudioSource001',
        '_value_1': None,
        'token': 'AudioSourceConfiguration001',
        '_attr_1': {
    }
    },
    'VideoEncoderConfiguration': {
        'Name': 'VideoEncoder03',
        'UseCount': 2,
        'Encoding': 'H264',
        'Resolution': {
            'Width': 1920,
            'Height': 1080
        },
        'Quality': 4.0,
        'RateControl': {
            'FrameRateLimit': 15,
            'EncodingInterval': 1,
            'BitrateLimit': 2
        },
        'MPEG4': None,
        'H264': {
            'GovLength': 30,
            'H264Profile': 'Main'
        },
        'Multicast': {
            'Address': {
                'Type': 'IPv4',
                'IPv4Address': '224.0.0.123',
                'IPv6Address': None
            },
            'Port': 8600,
            'TTL': 120,
            'AutoStart': False,
            '_value_1': None,
            '_attr_1': None
        },
        'SessionTimeout': datetime.timedelta(seconds=60),
        '_value_1': None,
        'token': 'VideoEncoderConfiguration003',
        '_attr_1': {
    }
    },
    'AudioEncoderConfiguration': {
        'Name': 'AudioEncoder01',
        'UseCount': 2,
        'Encoding': 'G711',
        'Bitrate': 128,
        'SampleRate': 8000,
        'Multicast': {
            'Address': {
                'Type': 'IPv4',
                'IPv4Address': '224.0.0.123',
                'IPv6Address': None
            },
            'Port': 8600,
            'TTL': 120,
            'AutoStart': False,
            '_value_1': None,
            '_attr_1': None
        },
        'SessionTimeout': datetime.timedelta(seconds=60),
        '_value_1': None,
        'token': 'AudioEncoderConfiguration001',
        '_attr_1': {
    }
    },
    'VideoAnalyticsConfiguration': None,
    'PTZConfiguration': None,
    'MetadataConfiguration': None,
    'Extension': None,
    'token': 'FixedProfile003',
    'fixed': True,
    '_attr_1': {
}
}, {
    'Name': 'FixedProfile04',
    'VideoSourceConfiguration': {
        'Name': 'VideoSourceConfiguration02',
        'UseCount': 2,
        'SourceToken': 'VideoSource002',
        'Bounds': {
            'x': 0,
            'y': 0,
            'width': 784,
            'height': 440
        },
        '_value_1': None,
        'Extension': None,
        'token': 'VideoSourceConfiguration002',
        '_attr_1': {
    }
    },
    'AudioSourceConfiguration': {
        'Name': 'AudioSourceConfiguration01',
        'UseCount': 2,
        'SourceToken': 'AudioSource001',
        '_value_1': None,
        'token': 'AudioSourceConfiguration001',
        '_attr_1': {
    }
    },
    'VideoEncoderConfiguration': {
        'Name': 'VideoEncoder04',
        'UseCount': 2,
        'Encoding': 'H264',
        'Resolution': {
            'Width': 784,
            'Height': 440
        },
        'Quality': 4.0,
        'RateControl': {
            'FrameRateLimit': 15,
            'EncodingInterval': 1,
            'BitrateLimit': 2
        },
        'MPEG4': None,
        'H264': {
            'GovLength': 30,
            'H264Profile': 'Main'
        },
        'Multicast': {
            'Address': {
                'Type': 'IPv4',
                'IPv4Address': '224.0.0.123',
                'IPv6Address': None
            },
            'Port': 8600,
            'TTL': 120,
            'AutoStart': False,
            '_value_1': None,
            '_attr_1': None
        },
        'SessionTimeout': datetime.timedelta(seconds=60),
        '_value_1': None,
        'token': 'VideoEncoderConfiguration004',
        '_attr_1': {
    }
    },
    'AudioEncoderConfiguration': {
        'Name': 'AudioEncoder01',
        'UseCount': 2,
        'Encoding': 'G711',
        'Bitrate': 128,
        'SampleRate': 8000,
        'Multicast': {
            'Address': {
                'Type': 'IPv4',
                'IPv4Address': '224.0.0.123',
                'IPv6Address': None
            },
            'Port': 8600,
            'TTL': 120,
            'AutoStart': False,
            '_value_1': None,
            '_attr_1': None
        },
        'SessionTimeout': datetime.timedelta(seconds=60),
        '_value_1': None,
        'token': 'AudioEncoderConfiguration001',
        '_attr_1': {
    }
    },
    'VideoAnalyticsConfiguration': None,
    'PTZConfiguration': None,
    'MetadataConfiguration': None,
    'Extension': None,
    'token': 'FixedProfile004',
    'fixed': True,
    '_attr_1': {
}
}, {
    'Name': 'FixedProfile05',
    'VideoSourceConfiguration': {
        'Name': 'VideoSourceConfiguration03',
        'UseCount': 2,
        'SourceToken': 'VideoSource003',
        'Bounds': {
            'x': 0,
            'y': 0,
            'width': 1920,
            'height': 1080
        },
        '_value_1': None,
        'Extension': None,
        'token': 'VideoSourceConfiguration003',
        '_attr_1': {
    }
    },
    'AudioSourceConfiguration': {
        'Name': 'AudioSourceConfiguration01',
        'UseCount': 2,
        'SourceToken': 'AudioSource001',
        '_value_1': None,
        'token': 'AudioSourceConfiguration001',
        '_attr_1': {
    }
    },
    'VideoEncoderConfiguration': {
        'Name': 'VideoEncoder05',
        'UseCount': 2,
        'Encoding': 'H264',
        'Resolution': {
            'Width': 1920,
            'Height': 1080
        },
        'Quality': 4.0,
        'RateControl': {
            'FrameRateLimit': 15,
            'EncodingInterval': 1,
            'BitrateLimit': 2
        },
        'MPEG4': None,
        'H264': {
            'GovLength': 30,
            'H264Profile': 'Main'
        },
        'Multicast': {
            'Address': {
                'Type': 'IPv4',
                'IPv4Address': '224.0.0.123',
                'IPv6Address': None
            },
            'Port': 8600,
            'TTL': 120,
            'AutoStart': False,
            '_value_1': None,
            '_attr_1': None
        },
        'SessionTimeout': datetime.timedelta(seconds=60),
        '_value_1': None,
        'token': 'VideoEncoderConfiguration005',
        '_attr_1': {
    }
    },
    'AudioEncoderConfiguration': {
        'Name': 'AudioEncoder01',
        'UseCount': 2,
        'Encoding': 'G711',
        'Bitrate': 128,
        'SampleRate': 8000,
        'Multicast': {
            'Address': {
                'Type': 'IPv4',
                'IPv4Address': '224.0.0.123',
                'IPv6Address': None
            },
            'Port': 8600,
            'TTL': 120,
            'AutoStart': False,
            '_value_1': None,
            '_attr_1': None
        },
        'SessionTimeout': datetime.timedelta(seconds=60),
        '_value_1': None,
        'token': 'AudioEncoderConfiguration001',
        '_attr_1': {
    }
    },
    'VideoAnalyticsConfiguration': None,
    'PTZConfiguration': None,
    'MetadataConfiguration': None,
    'Extension': None,
    'token': 'FixedProfile005',
    'fixed': True,
    '_attr_1': {
}
}, {
    'Name': 'FixedProfile06',
    'VideoSourceConfiguration': {
        'Name': 'VideoSourceConfiguration03',
        'UseCount': 2,
        'SourceToken': 'VideoSource003',
        'Bounds': {
            'x': 0,
            'y': 0,
            'width': 784,
            'height': 440
        },
        '_value_1': None,
        'Extension': None,
        'token': 'VideoSourceConfiguration003',
        '_attr_1': {
    }
    },
    'AudioSourceConfiguration': {
        'Name': 'AudioSourceConfiguration01',
        'UseCount': 2,
        'SourceToken': 'AudioSource001',
        '_value_1': None,
        'token': 'AudioSourceConfiguration001',
        '_attr_1': {
    }
    },
    'VideoEncoderConfiguration': {
        'Name': 'VideoEncoder06',
        'UseCount': 2,
        'Encoding': 'H264',
        'Resolution': {
            'Width': 784,
            'Height': 440
        },
        'Quality': 4.0,
        'RateControl': {
            'FrameRateLimit': 15,
            'EncodingInterval': 1,
            'BitrateLimit': 2
        },
        'MPEG4': None,
        'H264': {
            'GovLength': 30,
            'H264Profile': 'Main'
        },
        'Multicast': {
            'Address': {
                'Type': 'IPv4',
                'IPv4Address': '224.0.0.123',
                'IPv6Address': None
            },
            'Port': 8600,
            'TTL': 120,
            'AutoStart': False,
            '_value_1': None,
            '_attr_1': None
        },
        'SessionTimeout': datetime.timedelta(seconds=60),
        '_value_1': None,
        'token': 'VideoEncoderConfiguration006',
        '_attr_1': {
    }
    },
    'AudioEncoderConfiguration': {
        'Name': 'AudioEncoder01',
        'UseCount': 2,
        'Encoding': 'G711',
        'Bitrate': 128,
        'SampleRate': 8000,
        'Multicast': {
            'Address': {
                'Type': 'IPv4',
                'IPv4Address': '224.0.0.123',
                'IPv6Address': None
            },
            'Port': 8600,
            'TTL': 120,
            'AutoStart': False,
            '_value_1': None,
            '_attr_1': None
        },
        'SessionTimeout': datetime.timedelta(seconds=60),
        '_value_1': None,
        'token': 'AudioEncoderConfiguration001',
        '_attr_1': {
    }
    },
    'VideoAnalyticsConfiguration': None,
    'PTZConfiguration': None,
    'MetadataConfiguration': None,
    'Extension': None,
    'token': 'FixedProfile006',
    'fixed': True,
    '_attr_1': {
}
}, {
    'Name': 'axxon0',
    'VideoSourceConfiguration': {
        'Name': 'VideoSourceConfiguration01',
        'UseCount': 2,
        'SourceToken': 'VideoSource001',
        'Bounds': {
            'x': 0,
            'y': 0,
            'width': 784,
            'height': 440
        },
        '_value_1': None,
        'Extension': None,
        'token': 'VideoSourceConfiguration001',
        '_attr_1': {
    }
    },
    'AudioSourceConfiguration': {
        'Name': 'AudioSourceConfiguration01',
        'UseCount': 2,
        'SourceToken': 'AudioSource001',
        '_value_1': None,
        'token': 'AudioSourceConfiguration001',
        '_attr_1': {
    }
    },
    'VideoEncoderConfiguration': {
        'Name': 'VideoEncoder01',
        'UseCount': 2,
        'Encoding': 'H264',
        'Resolution': {
            'Width': 1920,
            'Height': 1080
        },
        'Quality': 4.0,
        'RateControl': {
            'FrameRateLimit': 15,
            'EncodingInterval': 1,
            'BitrateLimit': 2
        },
        'MPEG4': None,
        'H264': {
            'GovLength': 30,
            'H264Profile': 'Main'
        },
        'Multicast': {
            'Address': {
                'Type': 'IPv4',
                'IPv4Address': '224.0.0.123',
                'IPv6Address': None
            },
            'Port': 8600,
            'TTL': 120,
            'AutoStart': False,
            '_value_1': None,
            '_attr_1': None
        },
        'SessionTimeout': datetime.timedelta(seconds=60),
        '_value_1': None,
        'token': 'VideoEncoderConfiguration001',
        '_attr_1': {
    }
    },
    'AudioEncoderConfiguration': {
        'Name': 'AudioEncoder01',
        'UseCount': 2,
        'Encoding': 'G711',
        'Bitrate': 128,
        'SampleRate': 8000,
        'Multicast': {
            'Address': {
                'Type': 'IPv4',
                'IPv4Address': '224.0.0.123',
                'IPv6Address': None
            },
            'Port': 8600,
            'TTL': 120,
            'AutoStart': False,
            '_value_1': None,
            '_attr_1': None
        },
        'SessionTimeout': datetime.timedelta(seconds=60),
        '_value_1': None,
        'token': 'AudioEncoderConfiguration001',
        '_attr_1': {
    }
    },
    'VideoAnalyticsConfiguration': None,
    'PTZConfiguration': {
        'Name': 'PTZConfiguration01',
        'UseCount': 2,
        'NodeToken': 'PTZNode01',
        'DefaultAbsolutePantTiltPositionSpace': None,
        'DefaultAbsoluteZoomPositionSpace': None,
        'DefaultRelativePanTiltTranslationSpace': None,
        'DefaultRelativeZoomTranslationSpace': None,
        'DefaultContinuousPanTiltVelocitySpace': 'http://www.onvif.org/ver10/tptz/PanTiltSpaces/VelocityGenericSpace',
        'DefaultContinuousZoomVelocitySpace': 'http://www.onvif.org/ver10/tptz/ZoomSpaces/VelocityGenericSpace',
        'DefaultPTZSpeed': None,
        'DefaultPTZTimeout': datetime.timedelta(seconds=10),
        'PanTiltLimits': None,
        'ZoomLimits': None,
        'Extension': None,
        'token': 'PTZConfig001',
        '_attr_1': {
    }
    },
    'MetadataConfiguration': None,
    'Extension': None,
    'token': 'axxon0',
    'fixed': False,
    '_attr_1': {
}
}]
Chosen token
axxon0
Creating PTZ object
Created PTZ service object
Traceback (most recent call last):
  File "/home/keith/./fovtest.py", line 53, in <module>
    configs = ptz.GetConfigurations(request)[0]
  File "/home/keith/.local/lib/python3.10/site-packages/zeep/xsd/valueobjects.py", line 140, in __getitem__
    return self.__values__[key]
KeyError: 0

It looks like it didn't complete. Right as it got to Creating PTZ Object it stops. Any suggestions? Thanks

@hawkeye217
Copy link
Author

I made some recent fixes to Frigate to bypass lots of these autotracking-specific checks and allow users with less capable cameras to still use PTZ controls. You can cherry-pick the fix yourself if you're familiar with how to do that, or you can just wait for the fixes in the next release of Frigate.

@Dvalin21
Copy link

I made some recent fixes to Frigate to bypass lots of these autotracking-specific checks and allow users with less capable cameras to still use PTZ controls. You can cherry-pick the fix yourself if you're familiar with how to do that, or you can just wait for the fixes in the next release of Frigate.

Yeah, Ill have to wait until the next release, but good news for many!! Thank you sir for you contributions!!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment