Skip to content
This repository has been archived by the owner on Dec 15, 2024. It is now read-only.

Commit

Permalink
chore: wait-for-device.ts usb script (#165)
Browse files Browse the repository at this point in the history
  • Loading branch information
ert78gb authored Dec 1, 2024
1 parent 6aa6e86 commit 2983496
Show file tree
Hide file tree
Showing 2 changed files with 126 additions and 3 deletions.
11 changes: 8 additions & 3 deletions packages/uhk-common/src/models/uhk-products.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ export interface VidPidPair {

export interface UhkDeviceProduct {
id: UHK_DEVICE_IDS_TYPE;
// The reference of the device when provided as CLI argument
asCliArg: string;
firmwareUpgradeMethod: FIRMWARE_UPGRADE_METHODS_TYPE,
// Use it in logs instead of the name because UHK 80 left and right have the same name.
// But we have to differentiate them in the logs
Expand All @@ -28,6 +30,7 @@ export interface UhkDeviceProduct {

export const UNKNOWN_DEVICE: UhkDeviceProduct = {
id: 0 as UHK_DEVICE_IDS_TYPE,
asCliArg: '',
firmwareUpgradeMethod: FIRMWARE_UPGRADE_METHODS.KBOOT,
logName: 'Unknown',
name: 'Unknown',
Expand All @@ -39,6 +42,7 @@ export const UNKNOWN_DEVICE: UhkDeviceProduct = {

export const UHK_60_DEVICE: UhkDeviceProduct = {
id: UHK_DEVICE_IDS.UHK60V1_RIGHT,
asCliArg: 'uhk60v1',
firmwareUpgradeMethod: FIRMWARE_UPGRADE_METHODS.KBOOT,
logName: 'UHK 60 v1',
name: 'UHK 60 v1',
Expand Down Expand Up @@ -73,6 +77,7 @@ export const UHK_60_DEVICE: UhkDeviceProduct = {

export const UHK_60_V2_DEVICE: UhkDeviceProduct = {
id: UHK_DEVICE_IDS.UHK60V2_RIGHT,
asCliArg: 'uhk60v2',
firmwareUpgradeMethod: FIRMWARE_UPGRADE_METHODS.KBOOT,
logName: 'UHK 60 v2',
name: 'UHK 60 v2',
Expand Down Expand Up @@ -107,6 +112,7 @@ export const UHK_60_V2_DEVICE: UhkDeviceProduct = {

export const UHK_80_DEVICE_LEFT: UhkDeviceProduct = {
id: UHK_DEVICE_IDS.UHK80_LEFT,
asCliArg: 'uhk80left',
firmwareUpgradeMethod: FIRMWARE_UPGRADE_METHODS.MCUBOOT,
logName: 'UHK 80 left',
name: 'UHK 80',
Expand All @@ -122,13 +128,13 @@ export const UHK_80_DEVICE_LEFT: UhkDeviceProduct = {
pid: 0x0006, // decimal 6
},
],
// TODO: Implement when we know
buspal: [],
reportId: 4,
};

export const UHK_80_DEVICE: UhkDeviceProduct = {
id: UHK_DEVICE_IDS.UHK80_RIGHT,
asCliArg: 'uhk80',
firmwareUpgradeMethod: FIRMWARE_UPGRADE_METHODS.MCUBOOT,
logName: 'UHK 80 right',
name: 'UHK 80',
Expand All @@ -144,13 +150,13 @@ export const UHK_80_DEVICE: UhkDeviceProduct = {
pid: 0x0008, // decimal 8
},
],
// TODO: Implement when we know
buspal: [],
reportId: 4,
};

export const UHK_DONGLE: UhkDeviceProduct = {
id: UHK_DEVICE_IDS.UHK_DONGLE,
asCliArg: 'dongle',
firmwareUpgradeMethod: FIRMWARE_UPGRADE_METHODS.MCUBOOT,
logName: 'UHK Dongle',
name: 'UHK Dongle',
Expand All @@ -166,7 +172,6 @@ export const UHK_DONGLE: UhkDeviceProduct = {
pid: 0x0004, // decimal 4
},
],
// TODO: Implement when we know
buspal: [],
reportId: 4,
};
Expand Down
118 changes: 118 additions & 0 deletions packages/usb/wait-for-device.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
#!/usr/bin/env -S node --loader ts-node/esm --no-warnings=ExperimentalWarning

import { devicesAsync } from 'node-hid';
import { SerialPort } from 'serialport';
import {
ALL_UHK_DEVICES,
FIRMWARE_UPGRADE_METHODS,
VidPidPair,
} from 'uhk-common';
import {
isUhkCommunicationUsage,
snooze,
} from 'uhk-usb';

import { yargs } from './src/index.js';

const REENUMERATION_MODES = ['device', 'bootloader', 'buspal'];
const reenumerationOptions = REENUMERATION_MODES.join('|');
const devicesOptions = ALL_UHK_DEVICES.map(uhkDevice => uhkDevice.asCliArg).join('|');

const argv = yargs
.scriptName('./wait-for-device.ts')
.usage(`Usage: $0 {${devicesOptions}} {${reenumerationOptions}} timeout`)
.demandCommand(2, 'Device and enumeration mode are required. Timeout in seconds is optional, default value 5 seconds.')
.argv;

const deviceArg = argv._[0] as string;
const enumerationModeArg = argv._[1] as string;
const timeoutArg = argv._[2] as string;

const uhkDeviceProduct = ALL_UHK_DEVICES.find(uhkDevice => uhkDevice.asCliArg === deviceArg);

if (!uhkDeviceProduct) {
console.error(`Invalid device: ${deviceArg}. Available options: ${devicesOptions}`);
process.exit(1);
}

const reenumerationMode = REENUMERATION_MODES.find(value => value === enumerationModeArg);

if (!reenumerationMode) {
console.error(`Invalid reenumeration mode: ${enumerationModeArg}. Available options: ${reenumerationOptions}`);
process.exit(1);
}

if (reenumerationMode === 'buspal' && uhkDeviceProduct.buspal.length === 0) {
console.error(`${deviceArg} does not support buspal reenumeration mode.`);
process.exit(1);
}

let timeout = 5000;

if (timeoutArg) {
const tmpTimeout = Number(timeoutArg);
if (Number.isNaN(tmpTimeout)) {
console.error(`Invalid timeout: ${timeoutArg}. Please provide a number.`);
process.exit(1);
}

timeout = tmpTimeout;
}


let vidPids: VidPidPair[];

if (reenumerationMode === 'device') {
vidPids = uhkDeviceProduct.keyboard;
}
else if (reenumerationMode === 'bootloader') {
vidPids = uhkDeviceProduct.bootloader;
}
else if (reenumerationMode === 'buspal') {
vidPids = uhkDeviceProduct.buspal;
}
else {
console.error(`Not implemented reenumeration mode mapping: ${reenumerationMode}`);
}

const startTime = new Date();

let found = false;

while (new Date().getTime() - startTime.getTime() < timeout && !found) {

if (reenumerationMode === 'bootloader' && uhkDeviceProduct.firmwareUpgradeMethod === FIRMWARE_UPGRADE_METHODS.MCUBOOT) {
const serialDevices = await SerialPort.list();

for (const serialDevice of serialDevices) {
found = vidPids.some(vidPid => Number.parseInt(serialDevice.vendorId, 16) === vidPid.vid && Number.parseInt(serialDevice.productId, 16) === vidPid.pid);

if (found) {
break;
}
}
}
else {
const hidDevices = await devicesAsync();
for (const hidDevice of hidDevices) {
found = vidPids.some(vidPid => {
return vidPid.vid === hidDevice.vendorId && vidPid.pid === hidDevice.productId
&& (reenumerationMode !== 'device' || isUhkCommunicationUsage(hidDevice));
});

if (found) {
break;
}
}
}

await snooze(100);
}

if (found) {
process.exit(0);
}
else {
console.error('Cannot find device within timeout');
process.exit(1);
}

0 comments on commit 2983496

Please sign in to comment.