title: PyUSB communication with Raspberry Pi and custom temp / humidity sensor
body: <p>I have:
  USB HID raw temp/humidity sensor
  raspberry Pi B</p>
  
  <p>I want:
  python to get data from USB sensor on the PI</p>
  
  <p>With the help of several different web pages and some answers on this site, I have found the device, I can show the interface details and send an array and get one data point, but then the device is busy and times out.  Why would it only send one reading and then require replugging to get another data point?  My first thought was maybe it is the device, but the device works just fine on my windows box.  Is my python code wrong?
  The USB device sends 16 bit data on interrupt IN endpoint #1 and receives data on interrupt OUT endpoint 2 (because that is how I wrote the firmware).</p>
  
  <p>Python code:</p>
  
  <pre><code>    #!/usr/bin/env python
  import usb
  import sys
  
  dev = usb.core.find(idVendor=0x1dfd, idProduct=0x0006)
  if not dev:
      raise IOError('Device not found')
  else:
  #    dev.set_configuration()
      cfg = dev.get_active_configuration();
  #    cfg = [(0,0)]
      print ("Device located")
  print ('configuration ' + str(cfg));
  for configuration in dev:
      for interface in configuration:
          ifnum = interface.bInterfaceNumber
          if not dev.is_kernel_driver_active(ifnum):
              continue
          try:
              print "detach %s: %s" % (dev, ifnum)
              dev.detach_kernel_driver(ifnum)
              reattach = True
              renum = ifnum
          except usb.core.USBError, e:
              pass
  dev.set_configuration()
  
  interface_number = 0
  alternate_setting = usb.control.get_interface(dev,interface_number)
  intf = usb.util.find_descriptor(cfg, bInterfaceNumber = interface_number,bAlternateSetting = alternate_setting)
  epO = usb.util.find_descriptor(
      intf,
      custom_match = \
      lambda f: \
      usb.util.endpoint_direction(f.bEndpointAddress) == \
      usb.util.ENDPOINT_OUT
  )
  epI = usb.util.find_descriptor(
      intf,
      custom_match = \
      lambda f: \
      usb.util.endpoint_direction(f.bEndpointAddress) == \
      usb.util.ENDPOINT_IN
  )
  # write the data
  print('epI length    ' + str(epI.bLength))
  print('ep desc type  ' + str(epI.bDescriptorType))
  print('ep address    ' + str(epI.bEndpointAddress))
  print('ep xfer type  ' + str(epI.bmAttributes))
  #    print('ep synch type ' + str(epI.bmAttributes[1]))
  #    print('ep Use type   ' + str(epI.bmAttributes[2]))
  print('ep max packet ' + str(epI.wMaxPacketSize))
  print('ep interval   ' + str(epI.bInterval))
  
  print('epO length    ' + str(epO.bLength))
  print('ep desc type  ' + str(epO.bDescriptorType))
  print('ep address    ' + str(epO.bEndpointAddress))
  print('ep xfer type  ' + str(epO.bmAttributes))
  #    print('ep synch type ' + str(epO.bmAttributes[1]))
  #    print('ep Use type   ' + str(epO.bmAttributes[2]))
  print('ep max packet ' + str(epO.wMaxPacketSize))
  print('ep interval   ' + str(epO.bInterval))
  
  print('dev length      ' + str(dev.bLength))
  print('dev num configs ' + str(dev.bNumConfigurations))
  print('dev class       ' + str(dev.bDeviceClass))
  
  assert epO is not None
  assert epI is not None
  msg = '2234567890123456' #first character is the command
  print('writing to USB  -&gt;' + msg)
  print(str(dev))
  #    dev.write(epO, msg, 100)
  epO.write(msg)
  print('reading from USB...')
  ret = epI.read(16)
  #    ret = dev.read(2,len(msg),100)    #  device timeout is 50 ms,
  sret = ''.join([chr(x) for x in ret])
  print(sret)
  # This is needed to release interface, otherwise attach_kernel_driver fails
  # due to "Resource busy"
  usb.util.dispose_resources(dev)
  
  # It may raise USBError if there's e.g. no kernel driver loads
  if reattach:
      print('Reattaching Kernel Driver')
      dev.attach_kernel_driver(renum)
  </code></pre>
  
  <p>and here is the response when executed on the PI:</p>
  
  <pre><code>Device located
  configuration &lt;usb.core.Configuration object at 0xb6a6e6d0&gt;
  detach &lt;usb.core.Device object at 0xb6a6e750&gt;: 0
  epI length    7
  ep desc type  5
  ep address    129
  ep xfer type  3
  ep max packet 16
  ep interval   50
  epO length    7
  ep desc type  5
  ep address    2
  ep xfer type  3
  ep max packet 16
  ep interval   50
  dev length      18
  dev num configs 1
  dev class       0
  writing to USB  -&gt;
  &lt;usb.core.Device object at 0xb6a6e750&gt;
  2234567890123456
  reading from USB...
  
  227.45,51.0 ## The first response has this after the last line above
  
  ## the second try gives this response instead:
  
  Traceback (most recent call last):
  File "./t8.py", line 78, in &lt;module&gt;
  ret = epI.read(16)
  File "/usr/local/lib/python2.7/dist-packages/usb/core.py", line 300, in read
  return self.device.read(self.bEndpointAddress, size, self.interface, timeout)
  File "/usr/local/lib/python2.7/dist-packages/usb/core.py", line 670, in read
  self.__get_timeout(timeout)
  File "/usr/local/lib/python2.7/dist-packages/usb/backend/libusb1.py", line 798, in intr_read
  timeout)
  File "/usr/local/lib/python2.7/dist-packages/usb/backend/libusb1.py", line 889, in __read
  _check(retval)
  File "/usr/local/lib/python2.7/dist-packages/usb/backend/libusb1.py", line 571, in _check
  raise USBError(_str_error[ret], ret, _libusb_errno[ret])
  usb.core.USBError: [Errno 110] Operation timed out
  </code></pre>
  
  <p>I searched and found that I can check the linux messages for USB with this command:</p>
  
  <pre><code>grep usb /var/log/messages
  </code></pre>
  
  <p>and I found this message:</p>
  
  <pre><code>Nov  3 02:16:06 raspberrypi kernel: [123725.144960] usb 1-1.3: usbfs: process 10698 (python) did not claim interface 0 before use
  </code></pre>
  
  <p>I added the reattach code and that went away.  I searched and found that others had the issue and it might be pyUSB.  I updated to the b2 release.  Now the device print command gives a full HID report printout when the print(dev) command is given.  Very nice, but the original problem of the device timeout remains and it is not looking like it has to do with a claimed interface.</p>
  
  <p>Any insight on how I can prevent the timeout so the device can give more than one set of data?</p>
  
  <p>Thanks for your help.</p>