FalkTannhaeuser / python-onvif-zeep

ONVIF Client Implementation in Python 2+3 (using https://github.com/mvantellingen/python-zeep instead of suds as SOAP client)
MIT License
428 stars 140 forks source link

Events example not working #8

Open lhotamir opened 6 years ago

lhotamir commented 6 years ago

I have tried the events.py example, but I am getting the following error:

Traceback (most recent call last): File "/usr/lib/python3.5/site-packages/zeep-2.4.0-py3.5.egg/zeep/xsd/schema.py", line 499, in _get_instance return items[qname] KeyError: <lxml.etree.QName object at 0x7ff1bda46940> During handling of the above exception, another exception occurred: Traceback (most recent call last): File "events.py", line 12, in req = pullpoint.create_type('PullMessages') File "/usr/lib/python3.5/site-packages/onvif_zeep-0.2.7-py3.5.egg/onvif/client.py", line 120, in self.create_type = lambda x: self.zeep_client.get_element('ns0:' + x)() File "/usr/lib/python3.5/site-packages/zeep-2.4.0-py3.5.egg/zeep/client.py", line 256, in get_element return self.wsdl.types.get_element(name) File "/usr/lib/python3.5/site-packages/zeep-2.4.0-py3.5.egg/zeep/xsd/schema.py", line 136, in get_element return self._get_instance(qname, 'get_element', 'element') File "/usr/lib/python3.5/site-packages/zeep-2.4.0-py3.5.egg/zeep/xsd/schema.py", line 244, in _get_instance raise last_exception File "/usr/lib/python3.5/site-packages/zeep-2.4.0-py3.5.egg/zeep/xsd/schema.py", line 240, in _get_instance return method(qname) File "/usr/lib/python3.5/site-packages/zeep-2.4.0-py3.5.egg/zeep/xsd/schema.py", line 471, in get_element return self._get_instance(qname, self._elements, 'element') File "/usr/lib/python3.5/site-packages/zeep-2.4.0-py3.5.egg/zeep/xsd/schema.py", line 514, in _get_instance location=self._location) zeep.exceptions.LookupError: No element 'PullMessages' in namespace http://docs.oasis-open.org/wsrf/rw-2. Available elements are: -

I googled around but I cannot find any solution.

andrej-vasilj commented 6 years ago

I'm having the same problem, any updates for this?

tringler commented 6 years ago

I can also confirm the problem

lhotamir commented 6 years ago

I have managed to get through the error I mentioned by this this change in onvif/client.py:

@@ -117,7 +117,7 @@ class ONVIFService(object):
 #        print(">>>>>", self.ws_client.__dict__)
         #print(">>>>>", self.zeep_client.type_factory('ns1').__dict__)
         #self.create_type = self.ws_client.factory.create
-        self.create_type = lambda x: self.zeep_client.get_element('ns0:' + x)()
+        self.create_type = lambda x: self.zeep_client.get_element('ns7:' + x)()
         #print('ONVIFService() EXIT')

However there are more problems, because when PullMessages is called, the subscription id created by create_pullpoint_service method is not used.

iomihai commented 6 years ago

I got this to work for me. First the pullpoint subscription xaddr is not properly set. Either replace in client.py:274

self.xaddrs['http://www.onvif.org/ver10/events/wsdl/PullPointSubscription'] = self.event.CreatePullPointSubscription().SubscriptionReference.Address

with

self.xaddrs['http://www.onvif.org/ver10/events/wsdl/PullPointSubscription'] = self.event.CreatePullPointSubscription().SubscriptionReference.Address._value_1

and create a proxy service

onvif_camera.create_pullpoint_service()
plp = onvif_camera.pullpoint.zeep_client.create_service('{http://www.onvif.org/ver10/events/wsdl}PullPointSubscriptionBinding', onvif_camera.xaddrs['http://www.onvif.org/ver10/events/wsdl/PullPointSubscription'])

or if you do not mind a inconsistent .xaddrs you can create the proxy with the ._value_1 attribute

onvif_camera.create_pullpoint_service()
plp = onvif_camera.pullpoint.zeep_client.create_service('{http://www.onvif.org/ver10/events/wsdl}PullPointSubscriptionBinding', onvif_camera.xaddrs['http://www.onvif.org/ver10/events/wsdl/PullPointSubscription']._value_1)

Then you can retrieve the messages through the service proxy

plp.PullMessages(Timeout=timedelta(seconds=20), MessageLimit=100)

The same thing can work through binding, you still have to set the right address

onvif_camera.create_pullpoint_service()
service = onvif_camera.pullpoint.zeep_client._get_service('EventService')
port = onvif_camera.pullpoint.zeep_client._get_port(service, 'PullPointSubscription')
port.binding_options['address'] = onvif_camera.xaddrs['http://www.onvif.org/ver10/events/wsdl/PullPointSubscription']
plp = onvif_camera.pullpoint.zeep_client.bind('EventService', 'PullPointSubscription')
plp.PullMessages(Timeout=timedelta(seconds=20), MessageLimit=100)

I hope this helps.

ualex73 commented 5 years ago

Anybody got unsubscribing of events working?

ualex73 commented 5 years ago

I think the "events.wsdl" file is incomplete according to the specs: https://www.onvif.org/ver10/events/wsdl/event.wsdl

cache91 commented 5 years ago

i still am having this problem. Has anyone solved it yet ?

cache91 commented 5 years ago

Also does anyone have an example how the event message is printed ?

ualex73 commented 5 years ago

I spend 4-5 months some time on it, the following worked for my camera. Hope it helps.

a = ONVIFCamera('192.168.1.254', 8000, 'admin', 'password')
event = a('events')
b = event.CreatePullPointSubscription(InitialTerminationTime='PT600S')

a.update_event_xaddr(b.SubscriptionReference.Address._value_1)

pull = a('pullpoint')
req = pull.PullMessages(Timeout=datetime.timedelta(seconds=10), MessageLimit=30)

print(req)

header = xsd.ComplexType(
    xsd.Sequence([
        xsd.Element('{http://www.w3.org/2005/08/addressing}To', xsd.String()),
    ])
)

header_value = header(To=b.SubscriptionReference.Address._value_1)
#print(b.SubscriptionReference.Address._value_1)
#print(a.xaddrs)

submgr = a('subscriptionmanager')
submgr.Unsubscribe(_soapheaders=[header_value])

`

cache91 commented 5 years ago

@ualex73 : I am going to try this out. Thanks man. Will keep you posted

cache91 commented 5 years ago

@ualex73 : I am getting the following errors:


  b = event.CreatePullPointSubscription(InitialTerminationTime='PT600S'

TypeError: 'ONVIFCamera' object is not callable```
mmkolbe commented 5 years ago

Any news about this @cache91? I mean about the "TypeError: 'ONVIFCamera' object is not callable```"

mmkolbe commented 5 years ago

Has anyone got the @iomihai's solution tested?

ancker010 commented 3 years ago

Anyone have any updates on this? Are there alternative library options for ONVIF?

I'm specifically looking for how to unsubscribe gracefully.

hyb90 commented 6 months ago

I am still having this problem also, any work around can I use?