-
-
Save hawkeye217/152a1d4ba80760dac95d46e143d37112 to your computer and use it in GitHub Desktop.
# 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') | |
# 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) | |
# Create ptz service object | |
print('Creating PTZ object') | |
ptz = mycam.create_ptz_service() | |
print('Created PTZ service object') | |
# 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.") |
Looks like your camera's ONVIF implementation doesn't support a the GetServiceCapabilities call.
When I run the script I get the following response, does that mean my camera wouldn't work, or does it mean code not working prpoperly? I didn't get any yes or no;s.
Traceback (most recent call last): File "/home/manny/Downloads/./fovtest.py", line 15, in <module> mycam = ONVIFCamera('http://10.69.69.10', 80, 'myuser', 'mypw', '/etc/onvif/wsdl/') File "/usr/local/lib/python3.10/dist-packages/onvif/client.py", line 216, in __init__ self.update_xaddrs() File "/usr/local/lib/python3.10/dist-packages/onvif/client.py", line 223, in update_xaddrs self.devicemgmt = self.create_devicemgmt_service() File "/usr/local/lib/python3.10/dist-packages/onvif/client.py", line 333, in create_devicemgmt_service return self.create_onvif_service('devicemgmt', from_template) File "/usr/local/lib/python3.10/dist-packages/onvif/client.py", line 312, in create_onvif_service xaddr, wsdl_file, binding_name = self.get_definition(name, portType) File "/usr/local/lib/python3.10/dist-packages/onvif/client.py", line 292, in get_definition raise ONVIFError('No such file: %s' % wsdlpath) onvif.exceptions.ONVIFError: Unknown error: No such file: /etc/onvif/wsdl/devicemgmt.wsdl```
When running this on Windows, I worked around this by editing this in the fovtest.py:
mycam = ONVIFCamera('http://10.69.69.10', 80, 'myuser', 'mypw', '/etc/onvif/wsdl/')
to
mycam = ONVIFCamera('http://10.69.69.10', 80, 'myuser', 'mypw', '/wsdl/')
I then copied the wsdl folder as well as the fovtest.py to the root of my C drive and just ran the fovtest.py from there.
Hopefully this can help more people report back.
Unfortunately my super el cheapo Aliexpress PTZ cam doesn't support RelativeMove PanTilt (nor was I expecting it to of course! :D), but surprisingly it did support RelativeMove Zoom :)
At least now I know that when I invest in a decent PT(Z), I can run the script and quickly find out so that I can start to experiment with this feature in Frigate as I've been dying to try this as well as the upcoming LPR. Great job Frigate team!
Was thinking of an Amcrest PTZ which 'should' be supported according to the Frigate wiki but if anyone has any pointers it would be much appreciated.
How about implementing a wsdl path detection with something like this?
import os
from onvif import ONVIFCamera
import onvif as onvif_pkg
# 1) Try the 'wsdl' folder inside the onvif package itself
pkg_dir = os.path.dirname(onvif_pkg.__file__)
wsdl_dir1 = os.path.join(pkg_dir, 'wsdl')
# 2) Try the sibling 'wsdl' folder next to the onvif package
site_pkg = os.path.dirname(pkg_dir)
wsdl_dir2 = os.path.join(site_pkg, 'wsdl')
# 3) Fallback to /etc/onvif/wsdl
candidates = [wsdl_dir1, wsdl_dir2, '/etc/onvif/wsdl']
for d in candidates:
if os.path.isdir(d):
wsdl_dir = d
break
else:
raise FileNotFoundError(
"Could not find WSDL files; looked in:\n " +
"\n ".join(candidates)
)
# UPDATE the IP address, ONVIF port, "admin" and "password" with your camera's details.
mycam = ONVIFCamera('192.168.1.100', 80, 'admin', 'password', wsdl_dir)
It doesn't look like this low-end Dahua camera supports relative movement. It's missing two necessary firmware features to support Frigate's autotracking.
That page that is floating around that shows supported cameras, and shows Dahua with all green and no notes, should really be destroyed or updated 😞
Can't imagine how many people are spending how much money on cameras just to find out they won't work. 😢
I'm already on my second and now considering a 3rd, but am absolutely terrified I'm going to end up in the same boat, and even further in the hole.
I'm getting the following for all my cameras:
Connected to ONVIF camera
Created media service object
Media profiles
[{
'Name': 'MainStream',
'VideoSourceConfiguration': {
'Name': 'VideoSourceMain',
'UseCount': 2,
'SourceToken': 'VideoSourceMain',
'Bounds': {
'x': 0,
'y': 0,
'width': 3840,
'height': 2160
},
'_value_1': None,
'Extension': None,
'token': 'VideoSourceMain',
'_attr_1': {
}
},
'AudioSourceConfiguration': {
'Name': 'AudioMainName',
'UseCount': 2,
'SourceToken': 'AudioMainSrcToken',
'_value_1': None,
'token': 'AudioMainToken',
'_attr_1': {
}
},
'VideoEncoderConfiguration': {
'Name': 'VideoEncodeMain',
'UseCount': 1,
'Encoding': 'H264',
'Resolution': {
'Width': 3840,
'Height': 2160
},
'Quality': 100.0,
'RateControl': {
'FrameRateLimit': 20,
'EncodingInterval': 1,
'BitrateLimit': 0
},
'MPEG4': {
'GovLength': 0,
'Mpeg4Profile': 'SP'
},
'H264': {
'GovLength': 20,
'H264Profile': 'High'
},
'Multicast': {
'Address': {
'Type': 'IPv4',
'IPv4Address': '192.168.10.61',
'IPv6Address': None
},
'Port': 0,
'TTL': 0,
'AutoStart': False,
'_value_1': None,
'_attr_1': None
},
'SessionTimeout': datetime.timedelta(seconds=720),
'_value_1': None,
'token': 'VideoEncodeMain',
'_attr_1': {
}
},
'AudioEncoderConfiguration': {
'Name': 'AudioMain',
'UseCount': 2,
'Encoding': 'G711',
'Bitrate': 64000,
'SampleRate': 16000,
'Multicast': {
'Address': {
'Type': 'IPv4',
'IPv4Address': '192.168.10.61',
'IPv6Address': None
},
'Port': 80,
'TTL': 1,
'AutoStart': False,
'_value_1': None,
'_attr_1': None
},
'SessionTimeout': datetime.timedelta(microseconds=60000),
'_value_1': None,
'token': 'G711',
'_attr_1': {
}
},
'VideoAnalyticsConfiguration': {
'Name': 'VideoAnalyticsName',
'UseCount': 3,
'AnalyticsEngineConfiguration': {
'AnalyticsModule': [
{
'Parameters': {
'SimpleItem': [
{
'Name': 'Sensitivity',
'Value': '80'
}
],
'ElementItem': [
{
'_value_1': <Element {http://www.onvif.org/ver10/schema}CellLayout at 0x7f02b19844c0>,
'Name': 'Layout'
}
],
'Extension': None,
'_attr_1': None
},
'Name': 'MyCellMotionModule',
'Type': 'tt:CellMotionEngine'
}
],
'Extension': None,
'_attr_1': None
},
'RuleEngineConfiguration': {
'Rule': [
{
'Parameters': {
'SimpleItem': [
{
'Name': 'MinCount',
'Value': '5'
},
{
'Name': 'AlarmOnDelay',
'Value': '100'
},
{
'Name': 'AlarmOffDelay',
'Value': '100'
},
{
'Name': 'ActiveCells',
'Value': '0P8A8A=='
}
],
'ElementItem': [],
'Extension': None,
'_attr_1': None
},
'Name': 'MyMotionDetectorRule',
'Type': 'tt:CellMotionDetector'
}
],
'Extension': None,
'_attr_1': None
},
'_value_1': None,
'token': 'VideoAnalyticsToken',
'_attr_1': {
}
},
'PTZConfiguration': {
'Name': 'ptz0',
'UseCount': 2,
'NodeToken': 'ptz0',
'DefaultAbsolutePantTiltPositionSpace': 'http://www.onvif.org/ver10/tptz/PanTiltSpaces/PositionGenericSpace',
'DefaultAbsoluteZoomPositionSpace': 'http://www.onvif.org/ver10/tptz/ZoomSpaces/PositionGenericSpace',
'DefaultRelativePanTiltTranslationSpace': 'http://www.onvif.org/ver10/tptz/PanTiltSpaces/TranslationGenericSpace',
'DefaultRelativeZoomTranslationSpace': 'http://www.onvif.org/ver10/tptz/ZoomSpaces/TranslationGenericSpace',
'DefaultContinuousPanTiltVelocitySpace': 'http://www.onvif.org/ver10/tptz/PanTiltSpaces/VelocityGenericSpace',
'DefaultContinuousZoomVelocitySpace': 'http://www.onvif.org/ver10/tptz/ZoomSpaces/VelocityGenericSpace',
'DefaultPTZSpeed': {
'PanTilt': {
'x': 1.0,
'y': 1.0,
'space': 'http://www.onvif.org/ver10/tptz/PanTiltSpaces/GenericSpeedSpace'
},
'Zoom': {
'x': 1.0,
'space': 'http://www.onvif.org/ver10/tptz/ZoomSpaces/ZoomGenericSpeedSpace'
}
},
'DefaultPTZTimeout': datetime.timedelta(seconds=60),
'PanTiltLimits': {
'Range': {
'URI': 'http://www.onvif.org/ver10/tptz/PanTiltSpaces/PositionGenericSpace',
'XRange': {
'Min': -1.0,
'Max': 1.0
},
'YRange': {
'Min': -1.0,
'Max': 1.0
}
}
},
'ZoomLimits': {
'Range': {
'URI': 'http://www.onvif.org/ver10/tptz/ZoomSpaces/PositionGenericSpace',
'XRange': {
'Min': -1.0,
'Max': 1.0
}
}
},
'Extension': None,
'token': 'ptz0',
'_attr_1': {
}
},
'MetadataConfiguration': None,
'Extension': None,
'token': 'MainStream',
'fixed': False,
'_attr_1': {
}
}, {
'Name': 'SubStream',
'VideoSourceConfiguration': {
'Name': 'VideoSourceMain',
'UseCount': 2,
'SourceToken': 'VideoSourceMain',
'Bounds': {
'x': 0,
'y': 0,
'width': 720,
'height': 480
},
'_value_1': None,
'Extension': None,
'token': 'VideoSourceMain',
'_attr_1': {
}
},
'AudioSourceConfiguration': {
'Name': 'AudioMainName',
'UseCount': 2,
'SourceToken': 'AudioMainSrcToken',
'_value_1': None,
'token': 'AudioMainToken',
'_attr_1': {
}
},
'VideoEncoderConfiguration': {
'Name': 'VideoEncodeSub',
'UseCount': 1,
'Encoding': 'H264',
'Resolution': {
'Width': 720,
'Height': 480
},
'Quality': 100.0,
'RateControl': {
'FrameRateLimit': 25,
'EncodingInterval': 1,
'BitrateLimit': 2048
},
'MPEG4': {
'GovLength': 0,
'Mpeg4Profile': 'SP'
},
'H264': {
'GovLength': 20,
'H264Profile': 'High'
},
'Multicast': {
'Address': {
'Type': 'IPv4',
'IPv4Address': '192.168.10.61',
'IPv6Address': None
},
'Port': 0,
'TTL': 0,
'AutoStart': False,
'_value_1': None,
'_attr_1': None
},
'SessionTimeout': datetime.timedelta(seconds=720),
'_value_1': None,
'token': 'VideoEncodeSub',
'_attr_1': {
}
},
'AudioEncoderConfiguration': {
'Name': 'AudioMain',
'UseCount': 2,
'Encoding': 'G711',
'Bitrate': 64000,
'SampleRate': 16000,
'Multicast': {
'Address': {
'Type': 'IPv4',
'IPv4Address': '192.168.10.61',
'IPv6Address': None
},
'Port': 80,
'TTL': 1,
'AutoStart': False,
'_value_1': None,
'_attr_1': None
},
'SessionTimeout': datetime.timedelta(microseconds=60000),
'_value_1': None,
'token': 'G711',
'_attr_1': {
}
},
'VideoAnalyticsConfiguration': {
'Name': 'VideoAnalyticsName',
'UseCount': 3,
'AnalyticsEngineConfiguration': {
'AnalyticsModule': [
{
'Parameters': {
'SimpleItem': [
{
'Name': 'Sensitivity',
'Value': '80'
}
],
'ElementItem': [
{
'_value_1': <Element {http://www.onvif.org/ver10/schema}CellLayout at 0x7f02b1989c40>,
'Name': 'Layout'
}
],
'Extension': None,
'_attr_1': None
},
'Name': 'MyCellMotionModule',
'Type': 'tt:CellMotionEngine'
}
],
'Extension': None,
'_attr_1': None
},
'RuleEngineConfiguration': {
'Rule': [
{
'Parameters': {
'SimpleItem': [
{
'Name': 'MinCount',
'Value': '5'
},
{
'Name': 'AlarmOnDelay',
'Value': '100'
},
{
'Name': 'AlarmOffDelay',
'Value': '100'
},
{
'Name': 'ActiveCells',
'Value': '0P8A8A=='
}
],
'ElementItem': [],
'Extension': None,
'_attr_1': None
},
'Name': 'MyMotionDetectorRule',
'Type': 'tt:CellMotionDetector'
}
],
'Extension': None,
'_attr_1': None
},
'_value_1': None,
'token': 'VideoAnalyticsToken',
'_attr_1': {
}
},
'PTZConfiguration': {
'Name': 'ptz0',
'UseCount': 2,
'NodeToken': 'ptz0',
'DefaultAbsolutePantTiltPositionSpace': 'http://www.onvif.org/ver10/tptz/PanTiltSpaces/PositionGenericSpace',
'DefaultAbsoluteZoomPositionSpace': 'http://www.onvif.org/ver10/tptz/ZoomSpaces/PositionGenericSpace',
'DefaultRelativePanTiltTranslationSpace': 'http://www.onvif.org/ver10/tptz/PanTiltSpaces/TranslationGenericSpace',
'DefaultRelativeZoomTranslationSpace': 'http://www.onvif.org/ver10/tptz/ZoomSpaces/TranslationGenericSpace',
'DefaultContinuousPanTiltVelocitySpace': 'http://www.onvif.org/ver10/tptz/PanTiltSpaces/VelocityGenericSpace',
'DefaultContinuousZoomVelocitySpace': 'http://www.onvif.org/ver10/tptz/ZoomSpaces/VelocityGenericSpace',
'DefaultPTZSpeed': {
'PanTilt': {
'x': 1.0,
'y': 1.0,
'space': 'http://www.onvif.org/ver10/tptz/PanTiltSpaces/GenericSpeedSpace'
},
'Zoom': {
'x': 1.0,
'space': 'http://www.onvif.org/ver10/tptz/ZoomSpaces/ZoomGenericSpeedSpace'
}
},
'DefaultPTZTimeout': datetime.timedelta(seconds=60),
'PanTiltLimits': {
'Range': {
'URI': 'http://www.onvif.org/ver10/tptz/PanTiltSpaces/PositionGenericSpace',
'XRange': {
'Min': -1.0,
'Max': 1.0
},
'YRange': {
'Min': -1.0,
'Max': 1.0
}
}
},
'ZoomLimits': {
'Range': {
'URI': 'http://www.onvif.org/ver10/tptz/ZoomSpaces/PositionGenericSpace',
'XRange': {
'Min': -1.0,
'Max': 1.0
}
}
},
'Extension': None,
'token': 'ptz0',
'_attr_1': {
}
},
'MetadataConfiguration': None,
'Extension': None,
'token': 'SubStream',
'fixed': False,
'_attr_1': {
}
}]
Chosen token
SubStream
Creating PTZ object
Created PTZ service object
PTZ configurations:
{
'Name': 'ptz0',
'UseCount': 2,
'NodeToken': 'ptz0',
'DefaultAbsolutePantTiltPositionSpace': 'http://www.onvif.org/ver10/tptz/PanTiltSpaces/PositionGenericSpace',
'DefaultAbsoluteZoomPositionSpace': 'http://www.onvif.org/ver10/tptz/ZoomSpaces/PositionGenericSpace',
'DefaultRelativePanTiltTranslationSpace': 'http://www.onvif.org/ver10/tptz/PanTiltSpaces/TranslationGenericSpace',
'DefaultRelativeZoomTranslationSpace': 'http://www.onvif.org/ver10/tptz/ZoomSpaces/TranslationGenericSpace',
'DefaultContinuousPanTiltVelocitySpace': 'http://www.onvif.org/ver10/tptz/PanTiltSpaces/VelocityGenericSpace',
'DefaultContinuousZoomVelocitySpace': 'http://www.onvif.org/ver10/tptz/ZoomSpaces/VelocityGenericSpace',
'DefaultPTZSpeed': {
'PanTilt': {
'x': 1.0,
'y': 1.0,
'space': 'http://www.onvif.org/ver10/tptz/PanTiltSpaces/GenericSpeedSpace'
},
'Zoom': {
'x': 1.0,
'space': 'http://www.onvif.org/ver10/tptz/ZoomSpaces/ZoomGenericSpeedSpace'
}
},
'DefaultPTZTimeout': datetime.timedelta(seconds=60),
'PanTiltLimits': {
'Range': {
'URI': 'http://www.onvif.org/ver10/tptz/PanTiltSpaces/PositionGenericSpace',
'XRange': {
'Min': -1.0,
'Max': 1.0
},
'YRange': {
'Min': -1.0,
'Max': 1.0
}
}
},
'ZoomLimits': {
'Range': {
'URI': 'http://www.onvif.org/ver10/tptz/ZoomSpaces/PositionGenericSpace',
'XRange': {
'Min': -1.0,
'Max': 1.0
}
}
},
'Extension': None,
'token': 'ptz0',
'_attr_1': {
}
}
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': -1.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': 1.0
}
}
],
'ZoomSpeedSpace': [
{
'URI': 'http://www.onvif.org/ver10/tptz/ZoomSpaces/ZoomGenericSpeedSpace',
'XRange': {
'Min': -1.0,
'Max': 1.0
}
}
],
'Extension': None,
'_attr_1': None
},
'PTZTimeout': {
'Min': datetime.timedelta(seconds=1),
'Max': datetime.timedelta(seconds=60)
},
'_value_1': None,
'PTControlDirection': None,
'Extension': None,
'_attr_1': None
}
PTZ service capabilities:
Traceback (most recent call last):
File "/usr/local/lib/python3.11/dist-packages/onvif/client.py", line 23, in wrapped
return func(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/dist-packages/onvif/client.py", line 153, in wrapped
return call(params, callback)
^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/dist-packages/onvif/client.py", line 140, in call
ret = func(**params)
^^^^^^^^^^^^^^
File "/usr/lib/python3/dist-packages/zeep/proxy.py", line 46, in call
return self._proxy._binding.send(
^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3/dist-packages/zeep/wsdl/bindings/soap.py", line 135, in send
return self.process_reply(client, operation_obj, response)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3/dist-packages/zeep/wsdl/bindings/soap.py", line 229, in process_reply
return self.process_error(doc, operation)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3/dist-packages/zeep/wsdl/bindings/soap.py", line 391, in process_error
raise Fault(
zeep.exceptions.Fault
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/home/sdansro/./fovtest.py", line 65, in
service_capabilities = ptz.GetServiceCapabilities(request)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/dist-packages/onvif/client.py", line 26, in wrapped
raise ONVIFError(err)
onvif.exceptions.ONVIFError: Unknown error: