python-onvif-zeep
python-onvif-zeep copied to clipboard
Python onvif PTZ ContinuousMove has an error Argument Value Invalid
I am currently making a program to control onvif using python.
The problem is that there is an error that does not work properly in certain cameras.
The original Python text and the Request and Response Soap xml text are attached together.
In particular, there is a problem with motor control on the PTZ side.
Package Version
----------------------- --------------------
anyio 3.6.2
onvif-zeep 0.2.12
zeep 4.1.0
"""Example to fetch pullpoint events."""
import asyncio
import datetime as dt
import logging
from pytz import UTC
from zeep import xsd
from onvif import ONVIFCamera
logging.getLogger("zeep").setLevel(logging.DEBUG)
class OnvifTestClass():
def __init__(self) -> None:
print("OnvifTestClass was created")
async def run(self):
self.mycam = ONVIFCamera(
"192.168.1.65",
80,
"admin",
"pass12345",
wsdl_dir="C:/Users/Sensorway/source/python/python-onvif-zeep-async/onvif/wsdl",
)
#mycam.update_xaddrs()
self.mycam.update_xaddrs()
# try:
# self.analytics_service = self.mycam.create_analytics_service()
# except:
# pass
# try:
# self.devicemgmt_service = self.mycam.create_devicemgmt_service()
# except:
# pass
# try:
# self.deviceio_service = self.mycam.create_deviceio_service()
# except:
# pass
# try:
# self.event_service = self.mycam.create_events_service()
# for item in self.mycam.xaddrs:
# if "event" in item:
# factory = self.event_service.zeep_client.type_factory(item)
# print(factory)
# break
# except:
# pass
# try:
# self.imaging_service = self.mycam.create_imaging_service()
# except:
# pass
try:
self.media_service = self.mycam.create_media_service()
self.media_service_profiles = self.media_service.GetProfiles()
#print(self.media_profiles)
self.media_service_profile = self.media_service.GetProfiles()[0]
except:
pass
# try:
# self.onvif_service = self.mycam.create_onvif_service()
# except:
# pass
try:
self.ptz_service = self.mycam.create_ptz_service()
except:
pass
try:
self.pullPoint_service = self.mycam.create_pullpoint_service()
except:
pass
# try:
# self.receiver_service = self.mycam.create_receiver_service()
# except:
# pass
# try:
# self.recording_service = self.mycam.create_recording_service()
# except:
# pass
# try:
# self.replay_service = self.mycam.create_replay_service()
# except:
# pass
# try:
# self.search_service = self.mycam.create_search_service()
# except:
# pass
#self.eventTest()
self.getPtzConfig()
self.ptzContinuous()
#self.ptzStop()
def eventTest(self):
try:
service = self.pullPoint_service.zeep_client._get_service('EventService')
port = self.pullPoint_service.zeep_client._get_port(service, 'PullPointSubscription')
port.binding_options['address'] = self.mycam.xaddrs['http://www.onvif.org/ver10/events/wsdl/PullPointSubscription']
plp = self.pullPoint_service.zeep_client.bind('EventService', 'PullPointSubscription')
plp.PullMessages(Timeout=dt.timedelta(seconds=20), MessageLimit=100)
except Exception as e:
print("Exception raised during eventTest : ", e)
pass
def getPtzConfig(self):
try:
# Get PTZ configuration options for getting continuous move range
request = self.ptz_service.create_type('GetConfigurationOptions')
request.ConfigurationToken = self.media_service_profile.PTZConfiguration.token
self.ptz_configuration_options = self.ptz_service.GetConfigurationOptions(request)
print('PTZ configuration options:', self.ptz_configuration_options)
except Exception as e:
print("Exception raised during getPtzConfig : ", e)
pass
def ptzStop(self):
try:
request = self.ptz_service.create_type('ContinuousMove')
status = self.ptz_service.GetStatus({'ProfileToken': self.media_service_profile.token})
print('PTZ status:', status)
request.ConfigurationToken = self.media_service_profile.PTZConfiguration.token
request.PanTilt = True
request.Zoom = True
print('PTZ request:', request)
except Exception as e:
print("Exception raised during ptzStop : ", e)
pass
def ptzContinuous(self):
try:
request = self.ptz_service.create_type('ContinuousMove')
request.ProfileToken = self.media_service_profile.token
#request.ProfileToken = self.media_service_profile.PTZConfiguration.token
#request.NodeToken = self.media_service_profile.PTZConfiguration.NodeToken
request.Velocity = {'PanTilt': {'x': 0.5, 'y': 0.5}, 'Zoom': 0.0}
request.Timeout = "PT10S"
self.ptz_service.ContinuousMove(request)
except Exception as e:
print("Exception raised during ptzStop : ", e)
pass
def setVelocity(self, request):
try:
request.Velocity = self.ptz_service.GetStatus({'ProfileToken': self.media_service_profile.token}).Position
request.Velocity.PanTilt.space = self.ptz_configuration_options.Spaces.ContinuousPanTiltVelocitySpace[0].URI
request.Velocity.Zoom.space = self.ptz_configuration_options.Spaces.ContinuousZoomVelocitySpace[0].URI
return request
except Exception as e:
print("Exception raised during setVelocity : ", e)
return
def setMax(self):
# Get range of pan and tilt
# NOTE: X and Y are velocity vector
try:
self.XMAX = self.ptz_configuration_options.Spaces.ContinuousPanTiltVelocitySpace[0].XRange.Max
self.XMIN = self.ptz_configuration_options.Spaces.ContinuousPanTiltVelocitySpace[0].XRange.Min
self.YMAX = self.ptz_configuration_options.Spaces.ContinuousPanTiltVelocitySpace[0].YRange.Max
self.YMIN = self.ptz_configuration_options.Spaces.ContinuousPanTiltVelocitySpace[0].YRange.Min
self.ZMAX = self.ptz_configuration_options.Spaces.ContinuousZoomVelocitySpace[0].XRange.Max
self.ZMIN = self.ptz_configuration_options.Spaces.ContinuousZoomVelocitySpace[0].XRange.Min
except Exception as e:
print("Exception raised during setMax : ", e)
if __name__ == "__main__":
test_class = OnvifTestClass()
loop = asyncio.get_event_loop()
loop.run_until_complete(test_class.run())
DEBUG:zeep.transports:HTTP Post to http://192.168.1.65:80/onvif/ptz:
<?xml version='1.0' encoding='utf-8'?>
<soap-env:Envelope xmlns:soap-env="http://www.w3.org/2003/05/soap-envelope">
<soap-env:Header>
<wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<wsse:UsernameToken>
<wsse:Username>admin</wsse:Username>
<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest">BHlDKgrQxtAtAI0f/uky17bF0oI=</wsse:Password>
<wsse:Nonce EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">KcX+EgBq2kYMw1Rz7Lg6PQ==</wsse:Nonce>
<wsu:Created xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">2022-11-10T07:49:23+00:00</wsu:Created>
</wsse:UsernameToken>
</wsse:Security>
</soap-env:Header>
<soap-env:Body>
<ns0:ContinuousMove xmlns:ns0="http://www.onvif.org/ver20/ptz/wsdl">
<ns0:ProfileToken>ProfileA01</ns0:ProfileToken>
<ns0:Velocity>
<ns1:PanTilt xmlns:ns1="http://www.onvif.org/ver10/schema" x="0.5" y="0.5"/>
<ns2:Zoom xmlns:ns2="http://www.onvif.org/ver10/schema" x="0.0"/>
</ns0:Velocity>
<ns0:Timeout>PT10S</ns0:Timeout>
</ns0:ContinuousMove>
</soap-env:Body>
</soap-env:Envelope>
DEBUG:zeep.transports:HTTP Response from http://192.168.1.65:80/onvif/ptz (status: 200):
<soap:Envelope
xmlns:soap="http://www.w3.org/2003/05/soap-envelope"
xmlns:ter="http://www.onvif.org/ver10/error"
xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
xmlns:wsntw="http://docs.oasis-open.org/wsn/2004/06/wsn-WS-BaseNotification-1.2-draft-01.wsdl"
xmlns:xs="http://www.w3.org/2000/10/XMLSchema"
xmlns:wsa="http://www.w3.org/2005/08/addressing">
<soap:Body>
<soap:Fault>
<soap:Code>
<soap:Value>soap:Sender</soap:Value><soap:Subcode>
<soap:Value>ter:InvalidArgVal</soap:Value>
<soap:Subcode>
<soap:Value>ter:NoEntity</soap:Value>
</soap:Subcode>
</soap:Subcode>
</soap:Code>
<soap:Reason>
<soap:Text xml:lang="en">Argument Value Invalid</soap:Text>
</soap:Reason>
<soap:Node>http://www.w3.org/2003/05/soap-envelope/node/ultimateReceiver</soap:Node>
<soap:Role>http://www.w3.org/2003/05/soap-envelope/role/ultimateReceiver</soap:Role>
</soap:Fault>
</soap:Body>
</soap:Envelope>
try removing ns0 from the query