or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

constants-errors.mddata-transfers.mddescriptors.mddevice-communication.mddevice-management.mdevent-handling.mdindex.mdinterfaces-endpoints.mdwebusb-api.md

device-management.mddocs/

0

# Device Discovery and Management

1

2

Device discovery and management provides functions to find, enumerate, and manage USB devices connected to the system. This includes listing all devices, finding specific devices by identifiers, and accessing device metadata.

3

4

## Capabilities

5

6

### Device Enumeration

7

8

Get a list of all USB devices currently attached to the system.

9

10

```typescript { .api }

11

/**

12

* Return a list of Device objects for the USB devices attached to the system

13

* @returns Array of Device objects representing connected USB devices

14

*/

15

function getDeviceList(): Device[];

16

```

17

18

**Usage Examples:**

19

20

```typescript

21

import { getDeviceList } from 'usb';

22

23

// Get all connected USB devices

24

const devices = getDeviceList();

25

console.log(`Found ${devices.length} USB devices`);

26

27

// Iterate through devices

28

devices.forEach((device, index) => {

29

console.log(`Device ${index}:`);

30

console.log(` Vendor ID: 0x${device.deviceDescriptor.idVendor.toString(16).padStart(4, '0')}`);

31

console.log(` Product ID: 0x${device.deviceDescriptor.idProduct.toString(16).padStart(4, '0')}`);

32

console.log(` Bus: ${device.busNumber}, Address: ${device.deviceAddress}`);

33

});

34

```

35

36

### Device Search by IDs

37

38

Find a specific device using vendor ID and product ID.

39

40

```typescript { .api }

41

/**

42

* Convenience method to get the first device with the specified VID and PID

43

* @param vid - USB vendor ID

44

* @param pid - USB product ID

45

* @returns Device object if found, undefined otherwise

46

*/

47

function findByIds(vid: number, pid: number): Device | undefined;

48

```

49

50

**Usage Examples:**

51

52

```typescript

53

import { findByIds } from 'usb';

54

55

// Find Arduino Uno (example IDs)

56

const arduino = findByIds(0x2341, 0x0043);

57

if (arduino) {

58

console.log('Arduino Uno found!');

59

console.log(`Bus: ${arduino.busNumber}, Address: ${arduino.deviceAddress}`);

60

} else {

61

console.log('Arduino Uno not connected');

62

}

63

64

// Find device by hex IDs

65

const customDevice = findByIds(0x1234, 0xABCD);

66

```

67

68

### Device Search by Serial Number

69

70

Find a device using its serial number string.

71

72

```typescript { .api }

73

/**

74

* Convenience method to get the device with the specified serial number

75

* @param serialNumber - Device serial number string

76

* @returns Promise resolving to Device if found, undefined otherwise

77

*/

78

function findBySerialNumber(serialNumber: string): Promise<Device | undefined>;

79

```

80

81

**Usage Examples:**

82

83

```typescript

84

import { findBySerialNumber } from 'usb';

85

86

// Find device by serial number

87

const device = await findBySerialNumber('ABC123DEF456');

88

if (device) {

89

console.log('Device found by serial number');

90

console.log(`Vendor: 0x${device.deviceDescriptor.idVendor.toString(16)}`);

91

} else {

92

console.log('Device with serial number not found');

93

}

94

95

// Handle with try-catch

96

try {

97

const myDevice = await findBySerialNumber('MY_DEVICE_SERIAL');

98

if (myDevice) {

99

// Use device

100

myDevice.open();

101

// ... perform operations

102

myDevice.close();

103

}

104

} catch (error) {

105

console.error('Error searching for device:', error);

106

}

107

```

108

109

### Device Object Properties

110

111

Each Device object contains metadata and properties for USB device access.

112

113

```typescript { .api }

114

/**

115

* USB Device class with properties and methods

116

*/

117

interface Device {

118

/** Integer USB bus number */

119

busNumber: number;

120

121

/** Integer USB device address */

122

deviceAddress: number;

123

124

/** Array containing USB device port numbers, or undefined if not supported */

125

portNumbers: number[];

126

127

/** Object with properties for the fields of the device descriptor */

128

deviceDescriptor: DeviceDescriptor;

129

130

/** List of Interface objects for the interfaces of the default configuration */

131

interfaces?: Interface[];

132

133

/** Timeout in milliseconds to use for control transfers */

134

timeout: number;

135

136

/** Object with properties for the fields of the active configuration descriptor */

137

readonly configDescriptor?: ConfigDescriptor;

138

139

/** Contains all config descriptors of the device */

140

readonly allConfigDescriptors: ConfigDescriptor[];

141

142

/** Contains the parent of the device, such as a hub. If no parent, this is null */

143

readonly parent: Device;

144

}

145

```

146

147

**Usage Examples:**

148

149

```typescript

150

import { getDeviceList } from 'usb';

151

152

const devices = getDeviceList();

153

const device = devices[0];

154

155

// Access device properties

156

console.log('Device Info:');

157

console.log(` Bus Number: ${device.busNumber}`);

158

console.log(` Device Address: ${device.deviceAddress}`);

159

console.log(` Port Numbers: [${device.portNumbers.join(', ')}]`);

160

161

// Access device descriptor

162

const desc = device.deviceDescriptor;

163

console.log(` Vendor ID: 0x${desc.idVendor.toString(16)}`);

164

console.log(` Product ID: 0x${desc.idProduct.toString(16)}`);

165

console.log(` Device Class: ${desc.bDeviceClass}`);

166

console.log(` USB Version: ${desc.bcdUSB.toString(16)}`);

167

168

// Check if device has parent (hub)

169

if (device.parent) {

170

console.log(` Connected through hub: Bus ${device.parent.busNumber}`);

171

}

172

173

// Access configuration information

174

if (device.configDescriptor) {

175

console.log(` Configuration Value: ${device.configDescriptor.bConfigurationValue}`);

176

console.log(` Number of Interfaces: ${device.configDescriptor.bNumInterfaces}`);

177

console.log(` Max Power: ${device.configDescriptor.bMaxPower * 2}mA`);

178

}

179

```

180

181

### Device Filtering and Selection

182

183

Filter devices based on various criteria.

184

185

**Usage Examples:**

186

187

```typescript

188

import { getDeviceList } from 'usb';

189

190

const devices = getDeviceList();

191

192

// Filter by device class (e.g., HID devices)

193

const hidDevices = devices.filter(device =>

194

device.deviceDescriptor.bDeviceClass === 3 // HID class

195

);

196

197

// Filter by manufacturer (requires opening device to get string)

198

const filterByManufacturer = async (manufacturerName: string) => {

199

const matchingDevices = [];

200

201

for (const device of devices) {

202

try {

203

device.open();

204

if (device.deviceDescriptor.iManufacturer > 0) {

205

device.getStringDescriptor(device.deviceDescriptor.iManufacturer, (error, value) => {

206

if (!error && value === manufacturerName) {

207

matchingDevices.push(device);

208

}

209

});

210

}

211

device.close();

212

} catch (error) {

213

// Skip devices that can't be opened

214

continue;

215

}

216

}

217

218

return matchingDevices;

219

};

220

221

// Filter by vendor ID range

222

const vendorDevices = devices.filter(device =>

223

device.deviceDescriptor.idVendor >= 0x1000 &&

224

device.deviceDescriptor.idVendor < 0x2000

225

);

226

227

// Find devices with specific interface class

228

const devicesWithAudioInterface = devices.filter(device => {

229

if (!device.configDescriptor) return false;

230

231

return device.configDescriptor.interfaces.some(interfaceGroup =>

232

interfaceGroup.some(altSetting => altSetting.bInterfaceClass === 1) // Audio class

233

);

234

});

235

```

236

237

### Utility Functions

238

239

Additional utility functions for USB management and debugging.

240

241

```typescript { .api }

242

/**

243

* Set the libusb debug level (between 0 and 4)

244

* Higher levels provide more verbose logging

245

* @param level - Debug level (0=none, 1=error, 2=warning, 3=info, 4=debug)

246

*/

247

function setDebugLevel(level: number): void;

248

249

/**

250

* Use USBDK Backend (Windows only)

251

* On Windows, use the USBDK backend of libusb instead of WinUSB

252

*/

253

function useUsbDkBackend(): void;

254

255

/**

256

* Restore (re-reference) the hotplug events unreferenced by unrefHotplugEvents()

257

* Hotplug events are referenced by default

258

*/

259

function refHotplugEvents(): void;

260

261

/**

262

* Unreference the hotplug events from the event loop

263

* Allows the process to exit even when listening for attach and detach events

264

*/

265

function unrefHotplugEvents(): void;

266

```

267

268

**Usage Examples:**

269

270

```typescript

271

import { setDebugLevel, useUsbDkBackend, refHotplugEvents, unrefHotplugEvents, usb } from 'usb';

272

273

// Enable debug logging

274

console.log('Enabling USB debug logging...');

275

setDebugLevel(3); // Info level logging

276

277

// On Windows, optionally use USBDK backend

278

if (process.platform === 'win32') {

279

console.log('Using USBDK backend on Windows');

280

useUsbDkBackend();

281

}

282

283

// Set up device monitoring with proper cleanup

284

function setupDeviceMonitoring() {

285

let deviceCount = 0;

286

287

// Set up event handlers

288

usb.on('attach', (device) => {

289

deviceCount++;

290

console.log(`Device attached (${deviceCount} total):`, {

291

vendorId: `0x${device.deviceDescriptor.idVendor.toString(16)}`,

292

productId: `0x${device.deviceDescriptor.idProduct.toString(16)}`,

293

busNumber: device.busNumber,

294

deviceAddress: device.deviceAddress

295

});

296

});

297

298

usb.on('detach', (device) => {

299

deviceCount--;

300

console.log(`Device detached (${deviceCount} total):`, {

301

vendorId: `0x${device.deviceDescriptor.idVendor.toString(16)}`,

302

productId: `0x${device.deviceDescriptor.idProduct.toString(16)}`

303

});

304

});

305

306

console.log('Device monitoring started');

307

console.log('Note: Process will not exit due to hotplug event listeners');

308

309

// Allow process to exit after some time

310

setTimeout(() => {

311

console.log('Unreferencing hotplug events to allow process exit...');

312

unrefHotplugEvents();

313

314

// Process can now exit naturally

315

console.log('Process can now exit. Device monitoring continues.');

316

317

// Later, if you want to prevent exit again

318

setTimeout(() => {

319

console.log('Re-referencing hotplug events...');

320

refHotplugEvents();

321

console.log('Process will now stay alive for hotplug events');

322

323

// Clean up after demo

324

setTimeout(() => {

325

console.log('Demo complete, stopping monitoring...');

326

usb.removeAllListeners('attach');

327

usb.removeAllListeners('detach');

328

}, 5000);

329

330

}, 3000);

331

}, 10000);

332

}

333

334

// Debug level examples

335

function demonstrateDebugLevels() {

336

console.log('Testing different debug levels:');

337

338

// Test each debug level

339

[0, 1, 2, 3, 4].forEach((level, index) => {

340

setTimeout(() => {

341

console.log(`\n--- Setting debug level to ${level} ---`);

342

setDebugLevel(level);

343

344

// Perform some USB operations to generate debug output

345

const devices = getDeviceList();

346

console.log(`Found ${devices.length} devices at debug level ${level}`);

347

348

if (devices.length > 0) {

349

const device = devices[0];

350

console.log(`First device: VID:PID = ${device.deviceDescriptor.idVendor.toString(16)}:${device.deviceDescriptor.idProduct.toString(16)}`);

351

}

352

}, index * 2000);

353

});

354

}

355

356

// Windows USBDK backend example

357

function demonstrateUsbDkBackend() {

358

if (process.platform !== 'win32') {

359

console.log('USBDK backend is only available on Windows');

360

return;

361

}

362

363

console.log('Testing USBDK backend on Windows...');

364

365

// Get devices with default WinUSB backend

366

const devicesWinUsb = getDeviceList();

367

console.log(`Devices found with WinUSB: ${devicesWinUsb.length}`);

368

369

// Switch to USBDK backend

370

useUsbDkBackend();

371

console.log('Switched to USBDK backend');

372

373

// Get devices with USBDK backend

374

const devicesUsbDk = getDeviceList();

375

console.log(`Devices found with USBDK: ${devicesUsbDk.length}`);

376

377

// Compare results

378

if (devicesUsbDk.length !== devicesWinUsb.length) {

379

console.log('Different device counts detected between backends');

380

console.log('This might indicate driver compatibility differences');

381

} else {

382

console.log('Same device count with both backends');

383

}

384

}

385

386

// Graceful shutdown pattern

387

function setupGracefulShutdown() {

388

let shutdownInProgress = false;

389

390

// Set up device monitoring

391

usb.on('attach', (device) => {

392

if (!shutdownInProgress) {

393

console.log('Device attached:', device.deviceDescriptor.idVendor.toString(16));

394

}

395

});

396

397

usb.on('detach', (device) => {

398

if (!shutdownInProgress) {

399

console.log('Device detached:', device.deviceDescriptor.idVendor.toString(16));

400

}

401

});

402

403

// Handle shutdown signals

404

const gracefulShutdown = (signal: string) => {

405

if (shutdownInProgress) return;

406

shutdownInProgress = true;

407

408

console.log(`\nReceived ${signal}, shutting down gracefully...`);

409

410

// Remove all USB event listeners

411

usb.removeAllListeners('attach');

412

usb.removeAllListeners('detach');

413

414

// Unreference hotplug events to allow exit

415

unrefHotplugEvents();

416

417

console.log('USB monitoring stopped');

418

process.exit(0);

419

};

420

421

process.on('SIGINT', () => gracefulShutdown('SIGINT'));

422

process.on('SIGTERM', () => gracefulShutdown('SIGTERM'));

423

424

console.log('Graceful shutdown handlers installed');

425

console.log('Press Ctrl+C to shutdown gracefully');

426

}

427

428

// Run demonstrations

429

if (require.main === module) {

430

console.log('USB Utility Functions Demo');

431

console.log('===========================\n');

432

433

demonstrateDebugLevels();

434

435

setTimeout(() => {

436

demonstrateUsbDkBackend();

437

}, 12000);

438

439

setTimeout(() => {

440

setupDeviceMonitoring();

441

}, 15000);

442

443

setTimeout(() => {

444

setupGracefulShutdown();

445

}, 18000);

446

}

447

```