首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >WebHID API:如何解析来自inputReport事件的数据?

WebHID API:如何解析来自inputReport事件的数据?
EN

Stack Overflow用户
提问于 2021-04-08 23:34:59
回答 1查看 451关注 0票数 1

我试图抓取传感器输入从我的数字化器(X倾斜,Y倾斜,提示压力,提示开关,橡皮擦,钢笔,.etc)使用WebHID API。这就是我到目前为止所得到的:

index.js:

代码语言:javascript
运行
复制
page_log = text => {
  let p = document.createElement("p");
  p.textContent = text;
  log.appendChild(p);
};

let device;

if (!("hid" in navigator)) {
  page_log("WebHID is not available yet.");
}

navigator.hid.getDevices().then(devices => {
  if (devices.length == 0) {
    page_log(`No HID devices selected. Press the "request device" button.`);
    return;
  }
  if (devices.length > 1) {
    page_log(`You have multiple devices.`);
  }
  device = devices[0];
  page_log(`User previously selected "${device.productName}" HID device.`);
  page_log(`Now press "open device" button to receive input reports.`);
});

requestDeviceButton.onclick = async event => {
  document.body.style.display = "none";
  try {
    const filters = [
      {
        vendorId: 0x056a, // Wacom Co., Ltd
        productId: 0x00b1 //PTZ-630 [Intuos3 (6x8)]
      },
      {
        vendorId: 0x056a, // Wacom Co., Ltd
        productId: 0x00b2 //PTZ-930 [Intuos3 (9x12)]
      },
      {
        vendorId: 0x056a, // Wacom Co., Ltd
        productId: 0x00b3 //PTZ-1230 [Intuos3 (12x12)]
      },
      {
        vendorId: 0x056a, // Wacom Co., Ltd
        productId: 0x00b4 //PTZ-1231W [Intuos3 (12x19)]
      },
    ];

    [device] = await navigator.hid.requestDevice({ filters });
    if (!device) return;

    page_log(`User selected "${device.productName}" HID device.`);
    page_log(`Now press "open device" button to receive input reports.`);
  } finally {
    document.body.style.display = "";
  }
};


openButton.onclick = async event => {
  if (!device) return;

  await device.open().catch(console.error);
  page_log(`Waiting for user to press button...`);

  device.addEventListener("inputreport", event => {
    const { data, device, reportId } = event;

    let buffArray = new Uint8Array(data.buffer);
    console.log(buffArray);
    // console.log(device);
  
  });
};

控制台输出:

代码语言:javascript
运行
复制
index.js:72 Uint8Array(9) [224, 49, 125, 58, 74, 0, 35, 195, 85]
index.js:72 Uint8Array(9) [224, 49, 109, 58, 64, 0, 35, 194, 94]
index.js:72 Uint8Array(9) [224, 49, 94, 58, 43, 0, 35, 194, 102]
index.js:72 Uint8Array(9) [224, 49, 82, 58, 22, 0, 35, 193, 113]
index.js:72 Uint8Array(9) [224, 49, 52, 58, 1, 0, 35, 193, 123]
index.js:72 Uint8Array(9) [224, 49, 26, 57, 228, 0, 35, 192, 128]
index.js:72 Uint8Array(9) [224, 48, 253, 57, 190, 0, 35, 64, 141]
index.js:72 Uint8Array(9) [224, 48, 223, 57, 137, 0, 35, 65, 148]
index.js:72 Uint8Array(9) [224, 48, 203, 57, 90, 0, 35, 66, 159]
index.js:72 Uint8Array(9) [224, 48, 186, 57, 36, 0, 35, 66, 167]
index.js:72 Uint8Array(9) [224, 48, 177, 56, 242, 0, 35, 67, 174]
index.js:72 Uint8Array(9) [224, 48, 166, 56, 208, 0, 35, 196, 178]

如何找出每个数字对应的传感器?

我尝试过阅读WebHID规范HID使用表,但是到目前为止我还无法找到我需要的信息来解密输出。

更新:

在安装了Wacom的官方驱动程序后,我在Windows上进行了测试,我从InputReport获得了更多的数据。

输出:(Windows / wacom驱动程序)

代码语言:javascript
运行
复制
index.js:73 reportId: 15
index.js:76 Uint8Array(10) [2, 224, 55, 229, 45, 137, 0, 30, 176, 195]
index.js:73 reportId: 15
index.js:76 Uint8Array(21) [2, 224, 55, 163, 45, 99, 0, 31, 49, 189, 15, 2, 224, 55, 98, 45, 69, 0, 31, 49, 190]
index.js:73 reportId: 7
index.js:76 Uint8Array(37) [32, 29, 90, 238, 97, 50, 3, 0, 0, 34, 8, 16, 0, 87, 126, 112, 8, 34, 8, 16, 0, 0, 0, 0, 0, 0, 0, 212, 254, 192, 249, 232, 28, 184, 136, 0, 0]
index.js:73 reportId: 7
index.js:76 Uint8Array(37) [32, 241, 89, 197, 97, 30, 3, 0, 0, 34, 8, 16, 0, 87, 126, 112, 8, 34, 8, 16, 0, 0, 0, 0, 0, 0, 0, 56, 255, 36, 250, 76, 29, 228, 137, 0, 0]
index.js:73 reportId: 7
index.js:76 Uint8Array(37) [32, 162, 89, 144, 97, 30, 3, 0, 0, 34, 8, 16, 0, 87, 126, 112, 8, 34, 8, 16, 0, 0, 0, 0, 0, 0, 0, 56, 255, 36, 250, 76, 29, 228, 137, 0, 0]
index.js:73 reportId: 7
index.js:76 Uint8Array(37) [32, 136, 89, 123, 97, 22, 3, 0, 0, 34, 8, 16, 0, 87, 126, 112, 8, 34, 8, 16, 0, 0, 0, 0, 0, 0, 0, 56, 255, 36, 250, 76, 29, 228, 137, 0, 0]
index.js:73 reportId: 15
index.js:76 Uint8Array(10) [2, 224, 55, 34, 45, 31, 0, 31, 178, 185]
index.js:73 reportId: 15
index.js:76 Uint8Array(32) [2, 224, 54, 215, 45, 2, 0, 32, 50, 183, 15, 2, 224, 54, 139, 44, 226, 0, 32, 179, 183, 15, 2, 224, 54, 62, 44, 187, 0, 33, 52, 178]
index.js:73 reportId: 7
index.js:76 Uint8Array(37) [32, 27, 89, 51, 97, 14, 3, 0, 0, 34, 8, 16, 0, 87, 126, 112, 8, 34, 8, 16, 0, 0, 0, 0, 0, 0, 0, 156, 255, 136, 250, 176, 29, 16, 139, 0, 0]
index.js:73 reportId: 7
index.js:76 Uint8Array(37) [32, 171, 88, 237, 96, 6, 3, 0, 0, 34, 8, 16, 0, 87, 126, 112, 8, 34, 8, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 136, 250, 176, 29, 0, 0, 0, 0]
index.js:73 reportId: 7
index.js:76 Uint8Array(37) [32, 53, 88, 163, 96, 254, 2, 0, 0, 34, 8, 16, 0, 87, 126, 112, 8, 34, 8, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 236, 250, 20, 30, 0, 0, 0, 0]
index.js:73 reportId: 15
index.js:76 Uint8Array(10) [2, 224, 53, 239, 44, 147, 0, 34, 54, 175]

注意:这次我记录了reportId,因为我现在得到了两个不同的。

我还注意到HIDDevice.collections对象中的不同数据:

这一次,我在我的outputReports中得到了一些东西。

输出:(Linux用于比较)

代码语言:javascript
运行
复制
index.js:73 reportId: 2
index.js:74 Uint8Array(9) [224, 31, 174, 22, 67, 0, 38, 203, 177]
index.js:73 reportId: 2
index.js:74 Uint8Array(9) [224, 31, 33, 21, 8, 0, 39, 204, 180]
index.js:73 reportId: 2
index.js:74 Uint8Array(9) [224, 30, 165, 20, 8, 0, 40, 77, 183]
index.js:73 reportId: 2
index.js:74 Uint8Array(9) [224, 30, 16, 19, 51, 0, 40, 206, 182]
index.js:73 reportId: 2
index.js:74 Uint8Array(9) [224, 29, 134, 18, 97, 0, 41, 80, 181]
index.js:73 reportId: 2
index.js:74 Uint8Array(9) [224, 29, 9, 17, 191, 0, 39, 80, 183]
index.js:73 reportId: 2
index.js:74 Uint8Array(9) [224, 28, 210, 17, 27, 0, 36, 215, 184]
index.js:73 reportId: 2
index.js:74 Uint8Array(9) [224, 28, 225, 16, 150, 0, 35, 86, 186]
index.js:73 reportId: 2
index.js:74 Uint8Array(9) [224, 29, 45, 16, 15, 0, 33, 83, 184]
index.js:73 reportId: 2
index.js:74 Uint8Array(9) [224, 29, 162, 15, 153, 0, 32, 83, 190]
index.js:73 reportId: 2
index.js:74 Uint8Array(9) [224, 30, 110, 15, 51, 0, 32, 86, 195]
index.js:73 reportId: 2
index.js:74 Uint8Array(9) [224, 31, 96, 14, 214, 0, 31, 87, 199]
index.js:73 reportId: 2
index.js:74 Uint8Array(9) [160, 32, 212, 14, 142, 0, 26, 216, 202]

我在linux上获得的HIDDevice.collections也是:

因此,我仍然不明白如何使用featureReportsInputReportsOutputReports来映射数据。因此,我在Windows上从Wacom的驱动程序中得到的隐藏数据比linux多。

更新2:

我一直在查看Windows上的HIDDevice.collection对象,并将其与在Linux上运行usbhid-dumphidrd-convert (使它们具有可读性)所获得的Report Descriptors进行比较。这就是我到目前为止发现的。

  • 看起来,我所需要看的只是带有适当reportIDreportID元素,因为我只是试图读取发送到主机的传感器数据。
  • 我查看items数组,看看报告发送了哪些数据。
代码语言:javascript
运行
复制
- I look at the index number of the item in `items` to know the order to extract the data from the DataView (my `data` variable).
- I look at `reportCount` and `reportSize` to know the shape of the data for that item in the DataView.
- I look at the _"Usage"_ each item to know what the data is for. 
    - Unfortunately WebHID doesn't seem to expose _"Usage"_ on a per item bases (Like my _"Report Descriptors"_ from `usbhid-dump` shows). Instead it only exposes it on a per collection basis.
    - The "Usage" (if it was available) could be looked up in the [HID Usage Tables](https://usb.org/document-library/hid-usage-tables-122) by looking up the "Usage Page" by the hex value of `usagePage` for the `collection`, then doing the same for the given `usage` hex value.

示例:

代码语言:javascript
运行
复制
    if (reportId !== 7) return;
    console.log('reportId: ' + reportId);
    let zero_through_six = data.getUint8(0);


    let report_data = [
      (zero_through_six & 128) == 128,  //0 (1-bit)
      (zero_through_six & 64) == 64,    //1 (1-bit)
      (zero_through_six & 32) == 32,    //2 (1-bit)
      (zero_through_six & 16) == 16,    //3 (1-bit)
      (zero_through_six & 8) == 8,      //4 (1-bit)
      (zero_through_six & 4) == 4,      //5 (1-bit)
      zero_through_six & 3,             //6 (2-bits)
      data.getUint16(1), //7
      data.getUint16(3), //8
      data.getUint16(5), //9
      data.getUint16(7), //10
      data.getUint32(9), //11
      data.getBigUint64(13), //12
      data.getUint32(21), //13
      data.getUint16(23), //14
      data.getUint16(25), //15
      data.getUint16(27), //16
      data.getUint16(29), //17
      data.getUint16(31), //18
      data.getUint16(33), //19
    ];

    console.log(report_data);

  });

这是我在Windows版本中拆分数据和数组时所做的事情。第一项1-6为1位,items7为2位,项目为7-10 16位等.

同样,由于WebHID没有按项公开“使用”,所以每个项映射到的传感器/按钮仍然未知。至少在简单的单独测试之外,这在如此复杂的设备上很难做到。

更新3:

事实证明,我并不真的需要WebHID API作为我的用例(从我的数字化器获得传感器输入)。看起来PointerEventMouseEvent属性满足了我的需求。(真的,我应该先看一下实际(;一_一)),至少,我已经学会了如何使用WebHID API。

EN

回答 1

Stack Overflow用户

发布于 2021-04-13 07:57:20

我想https://web.dev/devices-introduction/会很有用,因为它解释了如何选择合适的API来与您选择的硬件设备进行通信。

很高兴你搞清楚了!

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67013159

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档