从处理函数中检索数据/异常

时间:2013-05-02 09:56:49

标签: python pywinusb

我正在尝试使用Python和pywinusb-0.3.2在有效请求到达Web服务器时从USB秤中读取数据(requested_serial_number来自查询字符串)。

所以我在do_GET

中有以下代码
all_hids = hid.find_all_hid_devices()

if all_hids:
    for index, device in enumerate(all_hids):
        if device.serial_number == requested_serial_number:
            device.open()
            try:
                device.set_raw_data_handler(scales_handler)
                while True:
                    sleep(0.1)
            except GotStableWeightException as e:
                self.do_HEAD(200)
                self.send_body(e.value)

这是我的scales_handler(加上自定义异常定义):

def scales_handler(data):
    print("Byte 0: {0}".format(data[0]))
    print("Byte 1: {0}".format(data[1]))
    print("Byte 2: {0}".format(data[2]))
    print("Byte 3: {0}".format(data[3]))
    print("Byte 4: {0}".format(data[4]))
    print("Byte 5: {0}".format(data[5]))
    print("All: {0}".format(data))
    if data[1] == 4:
        raise GotStableWeightException(data[4] + (256 * data[5]))

class GotStableWeightException(Exception):
    def __init__(self, value):
        self.value = value
    def __str__(self):
        return repr(self.value)

所以过程是:

  1. Python使用http.server HTTPServerBaseHTTPRequestHandler
  2. 开始在端口8000上侦听请求
  3. 请求进入并发送到我的do_GET函数。
  4. do_GET执行一些基本验证,然后搜索匹配的USB HID(我的第一个代码示例)。
  5. 如果找到匹配项,则会打开设备并传入数据处理程序。
  6. 我想要实现的目标:

    我想让数据处理程序继续读取比例,直到data[1] == 4(表示从比例读数稳定)。此时,我想在do_GET中检索此读数并将其发送到等待的HTTP客户端,关闭设备并结束该功能。

    但是,GotStableWeightException我的do_GET没有被捕获,我认为因为它被抛入了另一个线程。我刚开始使用多个线程进行编程,而且一旦匹配do_GET条件,我就无法弄清楚如何将结果返回data[1] == 4

    修改

    我得到了什么:

    以下是我在scales_handler终端中看到的输出:

    Byte 0: 3
    Byte 1: 4
    Byte 2: 2
    Byte 3: 0
    Byte 4: 204
    Byte 5: 0
    All: [3, 4, 2, 0, 204, 0]
    Exception in thread Thread-1:
    Traceback (most recent call last):
      File "C:\Python33\lib\threading.py", line 639, in _bootstrap_inner
        self.run()
      File "C:\Python33\lib\site-packages\pywinusb-0.3.2-py3.3.egg\pywinusb\hid\core.py", line 886, in run
        hid_object._process_raw_report(raw_report)
      File "C:\Python33\lib\site-packages\pywinusb-0.3.2-py3.3.egg\pywinusb\hid\helpers.py", line 64, in new_function
        return function_target(*args, **kw)
      File "C:\Python33\lib\site-packages\pywinusb-0.3.2-py3.3.egg\pywinusb\hid\core.py", line 714, in _process_raw_report
        self.__raw_handler(helpers.ReadOnlyList(raw_report))
      File "C:\USB HID Scales\server.py", line 28, in scales_handler
        raise GotStableWeightException(data[4] + (256 * data[5]))
    GotStableWeightException: 204
    

1 个答案:

答案 0 :(得分:1)

所以device是一个线程HidDevice类。正如您所指出的,在此线程对象中引发异常不会被处理程序(您的do_GET)捕获。

但是,我想知道引发异常是否真的是最容易做的事情(异常往往是为错误和问题保留)。为了实现您的目标,是否可以使用global变量并执行类似的操作;

global e_value
e_value = None

def scales_handler(data):
    print("Byte 0: {0}".format(data[0]))
    print("Byte 1: {0}".format(data[1]))
    print("Byte 2: {0}".format(data[2]))
    print("Byte 3: {0}".format(data[3]))
    print("Byte 4: {0}".format(data[4]))
    print("Byte 5: {0}".format(data[5]))
    print("All: {0}".format(data))
    if data[1] == 4:
        e_value = data[4] + (256 * data[5]))

devices = []
try:
    for index, device in enumerate(all_hids):
        if device.serial_number == requested_serial_number:
            devices.append(device)
            device.open()
            device.set_raw_data_handler(sample_handler)
    while True:  
        time.sleep(0.1)
finally:
    for device in devices:
        device.close()

if e_value is not None:
    self.do_HEAD(200)
    self.send_body(e_value) 

我无法证明您的设备是什么,所以我应该警告这不是线程安全的 - 如果多个设备有data[1] == 4,那么您将只设置e_value设备来访问它。 (虽然使用全局数组和计数器对象修复这个很简单。)