1// Phase 0: list HID devices so we can identify the MX Creative Console halves.
2// Keypad is expected as Elgato (0x0fd9); the Bluetooth dialpad is likely
3// Logitech (0x046d) speaking HID++.
4const { devices } = await import("node-hid");
5
6const VENDOR_NAMES: Record<number, string> = {
7 0x046d: "Logitech",
8 0x0fd9: "Elgato",
9 0x05ac: "Apple",
10};
11
12const hex = (n: number | undefined, width = 4) => "0x" + (n ?? 0).toString(16).padStart(width, "0");
13
14const all = devices();
15
16const format = (d: import("node-hid").Device) =>
17 [
18 `${hex(d.vendorId)}:${hex(d.productId)}`,
19 (VENDOR_NAMES[d.vendorId] ?? "?").padEnd(8),
20 `usage=${hex(d.usagePage)}/${hex(d.usage)}`,
21 `iface=${d.interface}`,
22 `| ${d.manufacturer ?? ""} ${d.product ?? ""}`.trim(),
23 d.path ? `\n path=${d.path}` : "",
24 ].join(" ");
25
26const interesting = all.filter(
27 (d) => d.vendorId === 0x046d || d.vendorId === 0x0fd9,
28);
29
30console.info(`Total HID devices: ${all.length}`);
31console.info(`\n=== Logitech (0x046d) + Elgato (0x0fd9) ===`);
32if (interesting.length === 0) {
33 console.info(" (none found — dialpad may not surface as a HID device)");
34} else {
35 for (const d of interesting) console.info(" " + format(d));
36}
37
38console.info(`\n=== All vendors present ===`);
39const byVendor = new Map<number, number>();
40for (const d of all) byVendor.set(d.vendorId, (byVendor.get(d.vendorId) ?? 0) + 1);
41for (const [vid, count] of [...byVendor].sort((a, b) => b[1] - a[1])) {
42 console.info(` ${hex(vid)} ${(VENDOR_NAMES[vid] ?? "").padEnd(8)} ${count}`);
43}