1

I would like to ask if there is a way to detect the state of a switch, connected through a usb. The switch has 2 states, on and off. Possibly with Python, on Windows.

Or, am I able to implement a script that will consider the switch to be a keyboard extension.

Thank you in advance!

EDIT

#import usb.core
#import usb.util
import usb

# find our device
#dev = usb.core.find(find_all=True)
busses = usb.busses()
# was it found?
#if dev is None:
#    raise ValueError('Device not found')


for bus in busses:
    devices = bus.devices
    for dev in devices:
        try:
            _name = usb.util.get_string(dev.dev, 19, 1)
        except:
            continue
        #dev.set_configuration()
        #cfg = dev.get_active_configuration()
        #interface_number = cfg[(0,0)].bInterfaceNumber
        #5alternate_settting = usb.control.get_interface(interface_number)
        print "Device name:",_name
        print "Device:", dev.filename
        print "  idVendor:",hex(dev.idVendor)
        print "  idProduct:",hex(dev.idProduct)
        for config in dev.configurations:
            print "  Configuration:", config.value
            print "    Total length:", config.totalLength 
            print "    selfPowered:", config.selfPowered
            print "    remoteWakeup:", config.remoteWakeup
            print "    maxPower:", config.maxPower
        print
Hasturkun
  • 35,395
  • 6
  • 71
  • 104
Rincer
  • 23
  • 1
  • 6

2 Answers2

1

Have you taken a look at PyUSB? See http://pyusb.sourceforge.net/docs/1.0/tutorial.html for a tutorial on the usage of PyUSB. The source of that library would help you if you want to implement something closer to the hardware as well.

http://libhid.alioth.debian.org/ looks like another decent library written in C with Python bindings.

Edit

In response to your attempted code, it looks like you're using the legacy PyUSB interface. If you print(dev), you'll either find it shows up like <usb.legacy.Device object at 0x1dac210> or you'll find that you're using an older version of the library (<usb.Device object at 0x13e6810>). Make sure you have 1.0 and make sure that you're using the newer methods to access the devices. It will be something like <usb.core.Device object at 0x1e0c3d0> For example, usb.core.find() will give you a device back that does indeed have a set_configuration(). Try working through the tutorial again.

gfortune
  • 2,589
  • 14
  • 14
  • ok, I am trying pyusb now and I am able to see the name,idVendor and idProduct of the attached devices...however I get an error when trying `for bus in busses: devices = bus.devices for dev in devices: try: _name = usb.util.get_string(dev.dev, 19, 1) except: continue dev.set_configuration()` #here I get 'Device' object has no attribute 'set_configuration' – Rincer Mar 06 '12 at 15:18
  • The code indicates that a Device object does indeed have a set_configuration method. Full code and full traceback are needed. You could just edit your original question and add that information. – gfortune Mar 06 '12 at 16:05
  • ok, i've edited the original question and i've added the source – Rincer Mar 06 '12 at 16:18
  • right...I've done what you said, it was just that...before using the old version, I did used the newer, but I got some error...that is fixed now, ok...it works...for example...I've set set_configuration() to my mouse (USB one) and it stopped working :D ok. I guess we are getting somewhere...now... the switch is single-click and I suppose it won't have drivers...so...how do I detect when it's pushed...? Any idea...? I've searched a lot, but...nothing for the moment – Rincer Mar 06 '12 at 21:14
  • You'll need to start by identifying the actual device that is your switch and then pick the endpoint to read from. I think I'd probably do some of the reading suggested in the "Talk to me honey" section of that tutorial on the flavors of transfers and go from there. Determining the correct endpoint seems like an important step. I'm afraid that's probably all the more direction I'll be able to give. – gfortune Mar 06 '12 at 22:24
  • ok...I went over the examples again, i've read some USB stuff...and I think i've done it...I mean...I can read data from my usb mouse, but for a switch, It may be totally different, but still...it works – Rincer Mar 06 '12 at 23:29
  • one thing that bothers me is in the usb.core.find function... I mean, i know the call for, lets say mouse, but for the switch, that I don't. I've read that for physical devices it is 5...but does the switch count as physical device. – Rincer Mar 07 '12 at 00:00
0

Ok, I have the solution now, I will post it, but I have a question...when I run the code, sometimes it says that the device is busy and it will generate an error and when it works... it will wait for an interrupt, however if you move the mouse, it will stay static on the screen but it will produce an interrupt. The same can be said for clicking a button, it will produce an interrupt, but the mouse will stay static and to use it again, you need to take it out from the usb and put it in again.

import usb.core
import usb.util
#import usb

# find our device
dev = usb.core.find(find_all=True)


#the second device it finds is my mouse
device = dev[2]

#print device
#physical device call: 5
#usb HID call: 3

_name = usb.util.get_string(device, 19, 1)
print _name

#we take the first configuration of the device

device.set_configuration()
print "Config set..."

#we access the configuration we've found
cfg = device.get_active_configuration()

#we access the intherface with number 0 and alternate setting with number 0
interface_number = cfg[(0,0)].bInterfaceNumber
alternate_setting = usb.control.get_interface(device,interface_number)

#we find the alterng settings for interface_number and altering_setting
intf = usb.util.find_descriptor(cfg, bInterfaceNumber = interface_number,\   
bAlternateSetting = alternate_setting)

#Finds the first IN endpoint
ep = usb.util.find_descriptor(
intf,
# match the first IN endpoint
custom_match = \
lambda e: \
    usb.util.endpoint_direction(e.bEndpointAddress) == \
   usb.util.ENDPOINT_IN
)

#inorder for you to detect a state from the device, it has to be(for mouse, moved,    
#clicked)
#otherwise it generates error

#make use of the error, if the mouse isn't pushed, do nothing and wait, if pushed...     
#print the state
#and exit from the loop

print "Waiting for signal..."


#device.detach_kernel_driver(0)


#click of the scroll button has array('B', [4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
#0, 0]) signal

while True:
    try:
       print ep.read(16)
       print "Received!"
       break
    except:
        continue

#assert ep is not 0

#_name=device.ctrl_transfer(bmRequestType=33, bRequest=11, wValue=0x0300)
#print _name

So I guess it removes the drivers of the mouse first, then it talks with the device, then interrupt is produced by me clicking a button, then...how can I say, use your drivers again and end program...because it is inconvinient to reinput the usb mouse every time.

Rincer
  • 23
  • 1
  • 6