Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Can use only one ONVIFCamera instance at a time #11

Open
elsampsa opened this issue Aug 26, 2015 · 3 comments
Open

Can use only one ONVIFCamera instance at a time #11

elsampsa opened this issue Aug 26, 2015 · 3 comments

Comments

@elsampsa
Copy link

Hi,

Thanks for the nice module. It works like charm ..
.. except when one is trying to connect to several (2+) cameras simultaneously.

The included python code demonstrates the problem.. just change the ip addresses in the main method's cams list.

When there is only one camera in the list it works ok (tried with both cameras individually), however, when there are two cameras in the list, it gives

(400, u'Bad Request')

while trying to get the media profiles for the second camera in the list.

The only way I can make two cameras work with this onvif module simultaneously, is to start them as individual processes (i.e. using python's multiprocessing module).

I'd please like to know why such behaviour and if it could be easily fixed.

Kind Regards,

Sampsa

import onvif
import sys

def run(ip, user, passwd, interactive=True, launchcam=False):

  dx=0.1
  dy=0.1
  dz=0.1

  print
  print "Patience.. this will take a while.."
  print

  mycam = onvif.ONVIFCamera(ip, 80, user, passwd) 

  ptz=mycam.create_ptz_service()
  med=mycam.create_media_service() # the output of this can be found in "media_service.txt"
  # .. from the media service, we need a thing called "ProfileToken"

  # """
  pro=med.GetProfiles()[0] # in fact, there are three profiles.. for main stream, sub stream and third stream
  profiletoken=pro._token
  # """

  nodes=ptz.GetNodes()
  nodetoken=nodes[0]._token
  node=nodes[0]

  # lets check if this camera can do all required ptzs
  ok=True
  if (not hasattr(node,"SupportedPTZSpaces")): ok=False
  if (ok and (not hasattr(node.SupportedPTZSpaces,"RelativeZoomTranslationSpace"))): ok=False
  if (ok and (not hasattr(node.SupportedPTZSpaces,"RelativePanTiltTranslationSpace"))): ok=False

  if not ok:
    print "woops.. some relative movement possibilities are absent from this crappy camera"
    raise(Exception,"CrappyCam")

  print "Testing presets.."
  print
  gp=ptz.create_type('GetPresets')
  gp.ProfileToken=profiletoken
  presets=ptz.GetPresets(gp)
  c=1
  for preset in presets:
    if (hasattr(preset,"Name")): 
      name=preset.Name
    else:
      name=""
    print "preset>",name
    c+=1
  print
  print ".. presets ok"

  print "Relative zoom min and max values:",node.SupportedPTZSpaces.RelativeZoomTranslationSpace[0].XRange.Min,node.SupportedPTZSpaces.RelativeZoomTranslationSpace[0].XRange.Max
  print "Relative pan/tilt min and max values, x:",node.SupportedPTZSpaces.RelativePanTiltTranslationSpace[0].XRange.Min,node.SupportedPTZSpaces.RelativePanTiltTranslationSpace[0].XRange.Max
  print "Relative pan/tilt min and max values, y:",node.SupportedPTZSpaces.RelativePanTiltTranslationSpace[0].YRange.Min,node.SupportedPTZSpaces.RelativePanTiltTranslationSpace[0].YRange.Max
  print
  print "Controls: arrows keys, +/- for zooming.  Enter exits. Have fun!"
  print

  # lets prepare the relativemove object ..
  rm=ptz.create_type('RelativeMove')
  rm.ProfileToken=profiletoken

  if (interactive):
    if (launchcam):
      st="vlc rtsp://"+user+":"+passwd+"@"+ip
      p=subprocess.Popen(st,shell=True)
    # *** Lets prepare stdin ***
    fd = sys.stdin.fileno()
    old_settings = termios.tcgetattr(fd)
    tty.setraw(sys.stdin.fileno())

    # *** The main loop ***
    ok=True
    while ok:
      com=""
      inp=sys.stdin.read(1)
      if (ord(inp)==27):
        inp=sys.stdin.read(1)
        if (ord(inp)==91):
          # so this is an arrow key ..
          inp=sys.stdin.read(1)
          code=ord(inp)
          if (code==68):
            com="left"
          elif (code==65):
            com="up"
          elif (code==67):
            com="right"
          elif (code==66):
            com="down"
      else:
        code=ord(inp)
        if (code==43):
          com="in"
        elif (code==45):
          com="out"
        elif (code==13):
          com="exit"

      # print "com>",com  

      if (com!="" and com!="exit"):
        rm.Translation.PanTilt._x="0.0"
        rm.Translation.PanTilt._y="0.0"
        rm.Translation.Zoom._x="0.0"

      if (com=="exit"): 
        ok=False
      elif (com=="left"):
        print "left\n"
        rm.Translation.PanTilt._x=str(-dx)
      elif (com=="up"):
        print "up\n"
        rm.Translation.PanTilt._y=str(dy)
      elif (com=="right"):
        print "right\n"
        rm.Translation.PanTilt._x=str(dx)
      elif (com=="down"):  
        print "down\n"
        rm.Translation.PanTilt._y=str(-dy)
      elif (com=="in"):  
        print "zoom in\n"
        rm.Translation.Zoom._x=str(dz)
      elif (com=="out"): 
        print "zoom out\n"
        rm.Translation.Zoom._x=str(-dz)

      if (com!="" and com!="exit"):
        try:
          ptz.RelativeMove(rm)
        except:
          print "woops.. something went wrong!"
          ok=False
        print "\n"

      time.sleep(0.1)

    # recover terminal ..
    termios.tcsetattr(fd, termios.TCSADRAIN, old_settings)
    if (launchcam): p.terminate()

  else: # not interactive ..
    return mycam, profiletoken, ptz


if (__name__=="__main__"):
  cams=[
      ["192.168.1.151","admin","12345"],
      ["192.168.1.156","admin","12345"]
    ]
  for cam in cams:
    run(cam[0], cam[1], cam[2], interactive=False, launchcam=False)
@sinchb
Copy link
Contributor

sinchb commented Sep 9, 2015

Sorry for my late response. I'm in vacation... Thanks for your report :) I haven't run more than one instance in single process, but I think there is something wrong with suds cache. you can set the on_cache to True and try again:

 mycam = onvif.ONVIFCamera(ip, 80, user, passwd, on_cache=True) 

@ZaphodBox
Copy link

did you find a permanent solution ?
I have similar sort of issue.
I have Panasonic BL-VT164W & APKLINK HI3518e.
Let's call them cam1 & cam2
I first tried using single ONVIFCamera instance & send their details (i.e ip,port, username & password) one by one.
If I created cam1's instance & then cam2 -> it's OK
But if I created cam2's instance & then tried for cam1, it would show error

  File "C:\Python27\lib\site-packages\onvif-0.1.3-py2.7.egg\onvif\client.py", line 257, in __init__
    
  File "C:\Python27\lib\site-packages\onvif-0.1.3-py2.7.egg\onvif\client.py", line 273, in update_xaddrs
    capabilities = self.devicemgmt.GetCapabilities({'Category': 'All'})
  File "C:\Python27\lib\site-packages\onvif-0.1.3-py2.7.egg\onvif\client.py", line 32, in wrapped
    raise ONVIFError(err)
onvif.exceptions.ONVIFError: Sender not Authorized
[Finished in 4.5s]

Then I tried using 2 instances of ONVIFCamera class,
Still the camera creation order matters,& shows gives me same error as above

@fengzie
Copy link

fengzie commented Feb 28, 2018

I also meet 2 cameras problem when creating pullpoint.

The code is like below:

cam_list = {
    "192.168.1.218" : CamInfo("192.168.1.218", "admin", "12345"),
    "192.168.1.126" : CamInfo("192.168.1.126", "admin", "12345")
}

for cam in cam_list.values():
    logger.info("Init ONVIF Camera, ip: {}, user: {}, password: {}".format(cam.ip, cam.user, cam.password))
    cam.onvifCam = ONVIFCamera(cam.ip, 80, cam.user, cam.password, no_cache=True)
    cam.pullpoint = cam.onvifCam.create_pullpoint_service()

When ran 2 camera instances, it would show error

Traceback (most recent call last):
File "client.py", line 4, in
from audio_play_service import AudioService
File "/home/pi/elevator_client/audio_play_service.py", line 1, in
import cam_info
File "/home/pi/elevator_client/cam_info.py", line 38, in
cam.pullpoint = cam.onvifCam.create_pullpoint_service()
File "/usr/local/lib/python2.7/dist-packages/onvif-0.2.0-py2.7.egg/onvif/client.py", line 425, in create_pullpoint_service
return self.create_onvif_service('pullpoint', from_template, portType='PullPointSubscription')
File "/usr/local/lib/python2.7/dist-packages/onvif-0.2.0-py2.7.egg/onvif/client.py", line 364, in create_onvif_service
xaddr, wsdl_file = self.get_definition(name)
File "/usr/local/lib/python2.7/dist-packages/onvif-0.2.0-py2.7.egg/onvif/client.py", line 356, in get_definition
raise ONVIFError('Device doesnt support service: %s' % name) onvif.exceptions.ONVIFError: Unknown error: Device doesnt support service: pullpoint

There is no problem to run one camera. Is there some fix for the code?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants