From 228f3370604763488bed3b6de1f2e033dd9b8a0d Mon Sep 17 00:00:00 2001 From: Michael Gardner Date: Wed, 4 Jul 2018 18:09:25 -0400 Subject: [PATCH] Abstraction for USB Connection This abstracts the method for getting the USB device. Right now we care about HIDUSB but we could use another library at another time. --- POC/ts/index.ts | 5 +++++ src/keyboard.ts | 27 ++++++++++----------------- src/usb/hid.ts | 18 ++++++++++++------ src/usb/index.ts | 2 ++ src/usb/locator.ts | 9 +++++++++ src/usb/usb.ts | 8 ++++++-- 6 files changed, 44 insertions(+), 25 deletions(-) create mode 100644 src/usb/index.ts create mode 100644 src/usb/locator.ts diff --git a/POC/ts/index.ts b/POC/ts/index.ts index a185a3c..d55a956 100644 --- a/POC/ts/index.ts +++ b/POC/ts/index.ts @@ -9,6 +9,10 @@ const keyboard = new Keyboard(); * Now, this actually finds the keyboard. Internally the keyboard object will track * the device, but if you really want access to the low-level HID device this will * return it. + * + * NOTE: THE FIND METHOD CAN TAKE THE VENDOR AND PRODUCT IDS ALONG WITH A HOST OF USB + * INFO TO MAKE THE CONNECTION. THE DEFAULT CALL USES THE INFO NECESSARY TO CONNECT + * TO THE Q5. */ const hidDevice = keyboard.find(); @@ -19,6 +23,7 @@ const hidDevice = keyboard.find(); keyboard.initialize(); allColor("#FF0000"); +allColor("#00FF00"); allColor("#0000FF"); // sparkle(); diff --git a/src/keyboard.ts b/src/keyboard.ts index 37382b1..c279108 100644 --- a/src/keyboard.ts +++ b/src/keyboard.ts @@ -4,28 +4,21 @@ import { FreezePacket } from "./internal/models/packets/freeze-packet"; import { InitializePacket } from "./internal/models/packets/initialize-packet"; import { TriggerPacket } from "./internal/models/packets/trigger-packet"; import { KeyState } from "./key-state"; -import { USBHID } from "./usb/hid"; -import { Usb } from "./usb/usb"; -export class Keyboard { - private interface: number; - private vendorId: number; - private productId: number; - private usage: number; +import { findUsbDevice, Usb } from "./usb"; +export class Keyboard { private usbDevice: Usb | undefined; private sequence: number = 0; - constructor(vendorId?: number, productId?: number, deviceInterface?: number, usage?: number) { - this.vendorId = vendorId || 0x24f0; - this.productId = productId || 0x2020; - this.interface = deviceInterface || 2; - this.usage = usage || 165; - } + public find(vendorId?: number, productId?: number, deviceInterface?: number, usage?: number): Usb { + this.usbDevice = findUsbDevice(vendorId || 0x24f0, + productId || 0x2020, + deviceInterface || 2, + usage || 165); + + this.usbDevice.connect(); - public find(): Usb { - this.usbDevice = new USBHID(); - this.usbDevice.connect(this.vendorId, this.productId, this.interface, this.usage); return this.usbDevice; } @@ -80,7 +73,7 @@ export class Keyboard { this.featureReports(new FirmwarePacket().buildPacketBytes()); const fwVer = this.readDataFromDevice(); return { - firmware: fwVer[4] + "." + fwVer[5] + "." + fwVer[6] + "." + fwVer[7], + firmware: fwVer[4] + "." + fwVer[5] + "." + fwVer[6] + "." + fwVer[7], packetCount: fwVer[3], }; } diff --git a/src/usb/hid.ts b/src/usb/hid.ts index 2255410..477cf37 100644 --- a/src/usb/hid.ts +++ b/src/usb/hid.ts @@ -1,27 +1,33 @@ import { Device, devices, HID } from "node-hid"; import { Usb } from "./usb"; -export class USBHID extends Usb { +export class UsbHid extends Usb { private hidDevice: HID | undefined; - public connect(vendorId: number, productId: number, usbInterface: number, usage: number) { + constructor(protected vendorId: number, protected productId: number, protected deviceInterface: number, protected usage: number) { + super(vendorId, productId, deviceInterface, usage); + } + + public connect() { const device = devices().find((d: Device) => { - if (d.vendorId === vendorId && d.productId === productId) { + if (d.vendorId === this.vendorId && d.productId === this.productId) { if (process.platform === "darwin") { - return d.usage === usage; + return d.usage === this.usage; } else { - return d.interface === usbInterface; + return d.interface === this.deviceInterface; } } return false; }); + if (device === undefined) { throw new Error("no deviceInfo"); } if (device.path === undefined) { throw new Error("Unable to find device path"); } + this.hidDevice = new HID(device.path); } @@ -52,4 +58,4 @@ export class USBHID extends Usb { this.hidDevice = undefined; } } -} \ No newline at end of file +} diff --git a/src/usb/index.ts b/src/usb/index.ts new file mode 100644 index 0000000..7982fbd --- /dev/null +++ b/src/usb/index.ts @@ -0,0 +1,2 @@ +export * from "./locator"; +export * from "./usb"; diff --git a/src/usb/locator.ts b/src/usb/locator.ts new file mode 100644 index 0000000..f7f8914 --- /dev/null +++ b/src/usb/locator.ts @@ -0,0 +1,9 @@ +import { UsbHid } from "./hid"; +import { Usb } from "./usb"; + +export function findUsbDevice(vendorId: number, productId: number, deviceInterface: number, usage: number): Usb { + // At some point we will have logic to determine which library to use... + // Right now just use the HID one... + + return new UsbHid(vendorId, productId, deviceInterface, usage); +} diff --git a/src/usb/usb.ts b/src/usb/usb.ts index b82e9a9..c8c04a8 100644 --- a/src/usb/usb.ts +++ b/src/usb/usb.ts @@ -1,6 +1,10 @@ export abstract class Usb { - public abstract connect(vendorId: number, productId: number, usbInterface: number, usage: number): void; + constructor(protected vendorId: number, protected productId: number, protected deviceInterface: number, protected usage: number) { + + } + + public abstract connect(): void; public abstract read(): number[]; public abstract write(data: number[]): void; public abstract disconnect(): void; -} \ No newline at end of file +}