quatanium / python-onvif

ONVIF Client Implementation in Python
MIT License
473 stars 321 forks source link

TypeError: string indices must be integers - with a Chinese ONVIF Cameras #8

Closed tetherit closed 8 years ago

tetherit commented 9 years ago

When I try to connect to my camera, I get the following:

mycam = ONVIFCamera('192.168.88.11', 80, 'admin', '', '/etc/onvif/wsdl/')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "onvif/client.py", line 225, in __init__
    self.update_xaddrs()
  File "onvif/client.py", line 237, in update_xaddrs
    self.xaddrs[item['Namespace']] = item['XAddr']
TypeError: string indices must be integers
sinchb commented 9 years ago

maybe...the value returned by the camera is invalid. can you paste more? for example, print the item in the trace above :)

thanks for your report

tetherit commented 9 years ago

Sure, in latest version this is the trace:

>>> mycam = ONVIFCamera('192.168.88.11', 80, 'admin', '', '/usr/local/lib/python2.7/site-packages/etc/onvif/wsdl/')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/lib/python2.7/site-packages/onvif/client.py", line 216, in __init__
    self.update_xaddrs()
  File "/usr/local/lib/python2.7/site-packages/onvif/client.py", line 228, in update_xaddrs
    print(item)
TypeError: string indices must be integers

I added a "print(item)" above line 228 and it shows:

>>> from onvif import ONVIFCamera
>>> mycam = ONVIFCamera('192.168.88.11', 80, 'admin', '', '/usr/local/lib/python2.7/site-packages/etc/onvif/wsdl/')
Other!
< the same trace shows here >
tetherit commented 9 years ago

A quick workaround is to add a check to make sure the item is a dict:

    def update_xaddrs(self):
        # Establish devicemgmt service first
        self.devicemgmt  = self.create_devicemgmt_service()

        # Get XAddr of services on the device
        self.xaddrs = { }
        services = self.devicemgmt.GetServices({'IncludeCapability': False})
        for item in services:
            if isinstance(item,dict): 
                self.xaddrs[item['Namespace']] = item['XAddr']

After that I seem to be able to use it as intended :D

>>> from onvif import ONVIFCamera
>>> mycam = ONVIFCamera('192.168.88.11', 80, 'admin', '', '/usr/local/lib/python2.7/site-packages/etc/onvif/wsdl/')
>>> mycam.devicemgmt.GetHostname()
(HostnameInformation){
   FromDHCP = False
   Name = "IPC483895"
 }
sinchb commented 9 years ago

Your suggestion is very helpful ! Thanks a lot. But I still want to know the type of the wrong item.

I think your debug code print (item) doesn't work. The exception is throwed from update_xaddrs, so the debug code should be placed in the for loop in method update_xaddrs:

       for item in services:
            print item
            if isinstance(item, dict): 
                self.xaddrs[item['Namespace']] = item['XAddr']
tetherit commented 9 years ago

Alright :) - made the change, this is what I see:

>>> mycam = ONVIFCamera('192.168.88.11', 80, 'admin', '', '/usr/local/lib/python2.7/site-packages/etc/onvif/wsdl/')
Other!
>>>
sinchb commented 9 years ago

the value returned by the chinese camera is so strange... If you can print the whole services like this:

    print services
    for item in services:
        print item
        if isinstance(item, dict): 
            self.xaddrs[item['Namespace']] = item['XAddr']
tetherit commented 9 years ago

Hi sorry, was away on a conference, this is what I see when I add print services:

>>> mycam = ONVIFCamera('192.168.88.11', 80, 'admin', '', '/usr/local/lib/python2.7/site-packages/etc/onvif/wsdl/')
[Other!]
Other!
sinchb commented 9 years ago

really strange... OK, It's better to add a check to validate the services type. Thank you for your report :)

tetherit commented 8 years ago

Just wanted to report that the same issue exists in the latest version (0.1.3) :( -

>>> mycam = ONVIFCamera('192.168.88.11', 80, 'admin', '', '/usr/local/wsdl')
ERROR:onvif:Unexcept service type
Traceback (most recent call last):
  File "/usr/local/lib/python2.7/site-packages/onvif/client.py", line 240, in update_xaddrs
    self.xaddrs[item['Namespace']] = item['XAddr']
TypeError: string indices must be integers
tetherit commented 8 years ago

Ah but this was fixed in latest trunk, thank you! Closing.