简体   繁体   中英

How to limit python input to certain USB device

I'm aiming to build a python script that lets me check items in and out based on a barcode. I've fledged out the primary functionality of the script, I'm stuck on a specification.

I want to be able to force a USB Device's output to always be the input to my python script. I don't want the python script to accept keyboard keystrokes. I want the script to intercept all inputs from my scanner, leaving my computer still able to be used while running the script.

I've tried using PyUSB and I can't understand how to get it to work for my specific use case.

I've attempted using the code found here https://github.com/vpatron/barcode_scanner_python as a reference, along with PyUSB documentation, however, I'm not receiving proper inputs.

Here are my USB Specifications for the device:

              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

Here is what my code currently looks like (copied from the above link for testing purposes with changes made for Product ID and Vendor ID, right now I'm just trying to see if I can get it to read the inputs correctly)

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, 0, 11, 0, 0, 0, 0, 0])   # h
    #   array('B', [0, 0, 23, 0, 0, 0, 0, 0])   # t
    #   array('B', [0, 0, 0, 0, 0, 0, 0, 0])    # nothing, ignore
    #   array('B', [0, 0, 23, 0, 0, 0, 0, 0])   # t
    #   array('B', [0, 0, 19, 0, 0, 0, 0, 0])   # p
    #   array('B', [2, 0, 51, 0, 0, 0, 0, 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 = ''

Inputs from my scanner look like this: 000045 or 000084

Essentially just typed out characters followed by an EOL, not serial

The above code does absolutely nothing, it's just a while loop, but my inputs don't print anything out...

You should be able to use it from PySerial by setting the scanner to serial port mode and installing the device driver.

It seems that unregistered users can not download it, but there seems to be a window to obtain device drivers and documents here.
The end of the model number is different, but can it be obtained by user registration?
Products 7200HP

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM