问题描述
我正在尝试使用 WebHID API 从我的数字转换器(X 倾斜、Y 倾斜、提示压力、提示开关、橡皮擦、笔、Puck 等)获取传感器输入。这是我到目前为止所得到的:
index.js:
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,Ltd
productId: 0x00b2 //PTZ-930 [Intuos3 (9x12)]
},Ltd
productId: 0x00b3 //PTZ-1230 [Intuos3 (12x12)]
},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);
});
};
控制台输出:
index.js:72 Uint8Array(9) [224,49,125,58,74,35,195,85]
index.js:72 Uint8Array(9) [224,109,64,194,94]
index.js:72 Uint8Array(9) [224,94,43,102]
index.js:72 Uint8Array(9) [224,82,22,193,113]
index.js:72 Uint8Array(9) [224,52,1,123]
index.js:72 Uint8Array(9) [224,26,57,228,192,128]
index.js:72 Uint8Array(9) [224,48,253,190,141]
index.js:72 Uint8Array(9) [224,223,137,65,148]
index.js:72 Uint8Array(9) [224,203,90,66,159]
index.js:72 Uint8Array(9) [224,186,36,167]
index.js:72 Uint8Array(9) [224,177,56,242,67,174]
index.js:72 Uint8Array(9) [224,166,208,196,178]
如何找出每个数字对应的传感器?
我尝试阅读 WebHID spec 和 HID Usage Tables,但到目前为止我一直无法找到破译输出所需的信息。
更新:
我在安装 wacom 官方驱动程序后在 Windows 中进行了测试,我从 InputReport 中获得了更多数据。
index.js:73 reportId: 15
index.js:76 Uint8Array(10) [2,224,55,229,45,30,176,195]
index.js:73 reportId: 15
index.js:76 Uint8Array(21) [2,163,99,31,189,15,2,98,69,190]
index.js:73 reportId: 7
index.js:76 Uint8Array(37) [32,29,238,97,50,3,34,8,16,87,126,112,212,254,249,232,28,184,136,0]
index.js:73 reportId: 7
index.js:76 Uint8Array(37) [32,241,89,197,255,250,76,162,144,123,0]
index.js:73 reportId: 15
index.js:76 Uint8Array(10) [2,178,185]
index.js:73 reportId: 15
index.js:76 Uint8Array(32) [2,54,215,32,183,139,44,226,179,62,187,33,178]
index.js:73 reportId: 7
index.js:76 Uint8Array(37) [32,27,51,14,156,171,88,237,96,6,53,236,20,239,147,175]
注意:这次我已经记录了 reportId
,因为我现在得到了 2 个不同的。
我还注意到 HIDDevice.collections
对象中的不同数据:
这次我在我的 outputReports
中得到了一些东西。
输出:(Linux 比较)
index.js:73 reportId: 2
index.js:74 Uint8Array(9) [224,174,38,177]
index.js:73 reportId: 2
index.js:74 Uint8Array(9) [224,21,39,204,180]
index.js:73 reportId: 2
index.js:74 Uint8Array(9) [224,165,40,77,183]
index.js:73 reportId: 2
index.js:74 Uint8Array(9) [224,19,206,182]
index.js:73 reportId: 2
index.js:74 Uint8Array(9) [224,134,18,41,80,181]
index.js:73 reportId: 2
index.js:74 Uint8Array(9) [224,9,17,191,210,184]
index.js:73 reportId: 2
index.js:74 Uint8Array(9) [224,225,150,86,186]
index.js:73 reportId: 2
index.js:74 Uint8Array(9) [224,83,153,190]
index.js:73 reportId: 2
index.js:74 Uint8Array(9) [224,110,195]
index.js:73 reportId: 2
index.js:74 Uint8Array(9) [224,214,199]
index.js:73 reportId: 2
index.js:74 Uint8Array(9) [160,142,216,202]
还有我在 linux 上得到的 HIDDevice.collections
:
所以我仍然不明白如何使用 featureReports
、InputReports
或 OutputReports
映射数据。所以我发现我从 Windows 上的 wacom 驱动程序中获得的 HID 数据多于 linux。
更新 2:
我一直在查看 Windows 输出上的 HIDDevice.collection
对象,并将其与 Report Descriptors
进行比较,我通过使用 usbhid-dump
运行 hidrd-convert
(以使它们易于阅读)在 Linux 上。这是我目前发现的。
看起来我只需要查看带有相应
inputReports
的reportID
元素,因为我只是尝试读取发送到主机的传感器数据。>-
我查看
items
数组以了解报告发送的数据。- 我查看
items
中项目的索引号以了解从 DataView(我的data
变量)中提取数据的顺序。 - 我查看
reportCount
和reportSize
以了解 DataView 中该项目的数据形状。 - 我查看每个项目的“使用情况”以了解数据的用途。
- 不幸的是,WebHID 似乎没有在每个项目的基础上公开“使用情况”(就像我在
usbhid-dump
中展示的“Report Descriptors”)。相反,它仅在每个集合的基础上公开它。 - 可以通过
usagePage
的collection
十六进制值查找“使用页面”,在 HID Usage Tables 中查找“使用”(如果可用),然后对给定的usage
十六进制值执行相同的操作。
- 不幸的是,WebHID 似乎没有在每个项目的基础上公开“使用情况”(就像我在
- 我查看
示例:
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 版本上拆分我进入的数据和数组时所做的事情。第一个 items[1-6] 是 1 位,items[7] 2 位,items[7-10] 16-位等等。
同样,由于 WebHID 不会在每个项目的基础上公开“使用情况”,因此每个项目映射到的传感器/按钮仍然未知。至少除了简单的单独测试之外,这在如此复杂的设备上很难做到。
更新 3:
事实证明,我的用例并不真正需要 WebHID API
(从我的数字化仪获取传感器输入)。看起来 PointerEvent
和 MouseEvent
属性满足了我的需求。 (真的,应该先看看那个(;一_一)) 至少,我学到了一些如何使用WebHID API。
解决方法
我想 https://web.dev/devices-introduction/ 会很有用,因为它解释了如何选择合适的 API 来与您选择的硬件设备进行通信。
很高兴你想通了!