如何将python输入限制为某些USB设备

问题描述

我的目标是建立一个Python脚本,该脚本可让我根据条形码签入和签出项目。我已经完成了脚本的主要功能,但仍遵守规范。

我希望能够强制USB设备的输出始终是我的python脚本的输入。我不希望python脚本接受键盘击键。我希望脚本拦截来自扫描仪的所有输入,以便在运行脚本时仍可以使用我的计算机。

我尝试过使用PyUSB,但我不明白如何使它在我的特定用例下工作。

我尝试将https://github.com/vpatron/barcode_scanner_python处的代码与PyUSB文档一起用作参考,但是,我没有收到正确的输入。

这是我对设备的USB规格:

              7200N:
                  Product ID: 0x26e1
                  Vendor ID: 0x2dd6
                  Version: 1c.20
                  Serial Number: YS7249BC0286
                  Speed: Up to 12 Mb/sec
                  Manufacturer: SuperLead
                  Location ID: 0x14222000 / 10
                  Current Available (mA): 500
                  Current Required (mA): 400
                  Extra Operating Current (mA): 0

这是我的代码当前的样子(从上面的链接复制用于测试目的,对产品ID和供应商ID进行了更改,现在我只是想看看是否可以正确读取输入内容)

import usb.core
import usb.util

def hid2ascii(lst):
    """The USB HID device sends an 8-byte code for every character. This
    routine converts the HID code to an ASCII character.
    
    See https://www.usb.org/sites/default/files/documents/hut1_12v2.pdf
    for a complete code table. Only relevant codes are used here."""
    
    # Example input from scanner representing the string "http:":
    #   array('B',[0,11,0])   # h
    #   array('B',23,0])   # t
    #   array('B',0])    # nothing,ignore
    #   array('B',19,0])   # p
    #   array('B',[2,51,0])   # :
    
    assert len(lst) == 8,'Invalid data length (needs 8 bytes)'
    conv_table = {
        0:['',''],4:['a','A'],5:['b','B'],6:['c','C'],7:['d','D'],8:['e','E'],9:['f','F'],10:['g','G'],11:['h','H'],12:['i','I'],13:['j','J'],14:['k','K'],15:['l','L'],16:['m','M'],17:['n','N'],18:['o','O'],19:['p','P'],20:['q','Q'],21:['r','R'],22:['s','S'],23:['t','T'],24:['u','U'],25:['v','V'],26:['w','W'],27:['x','X'],28:['y','Y'],29:['z','Z'],30:['1','!'],31:['2','@'],32:['3','#'],33:['4','$'],34:['5','%'],35:['6','^'],36:['7','&'],37:['8','*'],38:['9','('],39:['0',')'],40:['\n','\n'],41:['\x1b','\x1b'],42:['\b','\b'],43:['\t','\t'],44:[' ',' '],45:['_','_'],46:['=','+'],47:['[','{'],48:[']','}'],49:['\\','|'],50:['#','~'],51:[';',':'],52:["'",'"'],53:['`',54:[',','<'],55:['.','>'],56:['/','?'],100:['\\',103:['=','='],}

    # A 2 in first byte seems to indicate to shift the key. For example
    # a code for ';' but with 2 in first byte really means ':'.
    if lst[0] == 2:
        shift = 1
    else:
        shift = 0
        
    # The character to convert is in the third byte
    ch = lst[2]
    if ch not in conv_table:
        print ("Warning: data not in conversion table")
        return ''
    return conv_table[ch][shift]



# find our device
dev = usb.core.find(idVendor=0x2dd6,idProduct=0x26e1)

if dev is None:
    raise ValueError('USB device not found')

# Disconnect it from kernel
needs_reattach = False
if dev.is_kernel_driver_active(0):
    needs_reattach = True
    dev.detach_kernel_driver(0)
    print ("Detached USB device from kernel driver")

# set the active configuration. With no arguments,the first
# configuration will be the active one
dev.set_configuration()

# get an endpoint instance
cfg = dev.get_active_configuration()
intf = cfg[(0,0)]

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)

assert ep is not None,("Endpoint for USB device not found. Something is wrong.")

# Loop through a series of 8-byte transactions and convert each to an
# ASCII character. Print output after 0.5 seconds of no data.
line = ''
while True:
    try:
        # Wait up to 0.5 seconds for data. 500 = 0.5 second timeout.
        data = ep.read(1000,500)  
        ch = hid2ascii(data)
        line += ch
    except KeyboardInterrupt:
        print ("Stopping program")
        dev.reset()
        if needs_reattach:
            dev.attach_kernel_driver(0)
            print ("Reattached USB device to kernel driver")
        break
    except usb.core.USBError:
        # Timed out. End of the data stream. Print the scan line.
        if len(line) > 0:
            print (line)
            line = ''

扫描仪的输入如下所示: 000045000084

基本上只是键入字符,然后是EOL,而不是串行

上面的代码绝对不执行任何操作,只是一个while循环,但是我的输入没有输出任何内容...

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)