python-onvif-zeep icon indicating copy to clipboard operation
python-onvif-zeep copied to clipboard

Python onvif PTZ ContinuousMove has an error Argument Value Invalid

Open lsirikh opened this issue 3 years ago • 1 comments

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>

lsirikh avatar Nov 11 '22 01:11 lsirikh

try removing ns0 from the query

igorq777 avatar Nov 17 '23 08:11 igorq777