From a45ee1fd7982d40ef9b3f97f0ffa6c2a7d928d71 Mon Sep 17 00:00:00 2001 From: Johan Nyman Date: Wed, 7 Apr 2021 08:46:13 +0200 Subject: [PATCH] fix: the emitted timestamp is undefined for some products --- src/api.ts | 6 ++++-- src/products.ts | 49 +++++++++++++++++++++++++------------------------ src/xkeys.ts | 7 ++++--- 3 files changed, 33 insertions(+), 29 deletions(-) diff --git a/src/api.ts b/src/api.ts index 7927cd7..e038f4e 100644 --- a/src/api.ts +++ b/src/api.ts @@ -44,7 +44,7 @@ export interface EventMetadata { * Timestamp of the event. Measured in milliseconds from when the device was last powered on. * The timestamp can be used as a more trustworthy source of time than the computer clock, as it's not affected by delays in the USB data handling. */ - timestamp: number + timestamp: number | undefined } export interface ButtonEventMetadata extends EventMetadata { /** Row of the button location*/ @@ -105,9 +105,11 @@ export interface XKeysInfo { endCol: number }[] + /** If the X-keys panel emits timestamps (if not, timestamp will be undefined) */ + emitsTimestamp: boolean + /** If the product has the Program Switch button, this is a special switch not in the normal switch matrix. If exsists, only one per X-keys. */ hasPS: boolean - /** The number of joysticks available on the device */ hasJoystick: number /** The number of jog wheels available on the device */ diff --git a/src/products.ts b/src/products.ts index c93ed81..851ee16 100644 --- a/src/products.ts +++ b/src/products.ts @@ -36,7 +36,8 @@ export interface Product { /** Maps the (internal) btnIndex to a [Row, Column] */ btnLocation?: [number, number][] - timestamp?: number // the index of the start to the 4 byte time stamp + /** The index of the start to the 4 byte time stamp. */ + timestampByte?: number hasJoystick?: { joyXbyte: number @@ -91,7 +92,7 @@ export const PRODUCTS: { [name: string]: Product } = { hasPS: true, backLightType: BackLightType.LEGACY, backLight2offset: 32, - timestamp: 6, // index of first of 4 bytes, ms time since device boot, 4 byte BE + timestampByte: 6, // index of first of 4 bytes, ms time since device boot, 4 byte BE }), XK24RGB: literal({ name: 'XK-24M-RGB', // prototype XK24 with RGB backLight LEDs and mechanical @@ -103,7 +104,7 @@ export const PRODUCTS: { [name: string]: Product } = { hasPS: true, backLightType: BackLightType.REMAP_24, //RGB Standard Index backLight2offset: 0, // RGBs have no offset. - timestamp: 6, // index of first of 4 bytes, ms time since device boot, 4 byte BE + timestampByte: 6, // index of first of 4 bytes, ms time since device boot, 4 byte BE }), XK4: literal({ name: 'XK-4 Stick', @@ -118,7 +119,7 @@ export const PRODUCTS: { [name: string]: Product } = { hasPS: true, // slide switch on end backLightType: BackLightType.STICK_BUTTONS, // only has blue light backLight2offset: 0, // - timestamp: 6, // ms time since device boot 4 byte BE + timestampByte: 6, // ms time since device boot 4 byte BE }), XK8: literal({ name: 'XK-8 Stick', @@ -133,7 +134,7 @@ export const PRODUCTS: { [name: string]: Product } = { hasPS: true, // slide switch on end backLightType: BackLightType.STICK_BUTTONS, // only has blue light backLight2offset: 0, // - timestamp: 6, // ms time since device boot 4 byte BE + timestampByte: 6, // ms time since device boot 4 byte BE btnLocation: [ [0, 0], [1, 1], @@ -161,7 +162,7 @@ export const PRODUCTS: { [name: string]: Product } = { hasPS: true, // slide switch on end backLightType: BackLightType.STICK_BUTTONS, // only has blue backlight backLight2offset: 0, // only one set of LEDs under the buttons - timestamp: 6, // ms time since device boot 4 byte BE + timestampByte: 6, // ms time since device boot 4 byte BE btnLocation: [ [0, 0], [1, 1], @@ -197,7 +198,7 @@ export const PRODUCTS: { [name: string]: Product } = { hasShuttle: [{ shuttleByte: 7 }], backLightType: BackLightType.LEGACY, backLight2offset: 32, - timestamp: 8, // ms time since device boot 4 byte BE + timestampByte: 8, // ms time since device boot 4 byte BE }), XK12JOYSTICK: literal({ name: 'XK-12 Joystick', @@ -220,7 +221,7 @@ export const PRODUCTS: { [name: string]: Product } = { backLightType: BackLightType.LEGACY, backLight2offset: 32, // offset used to access second bank of LEDs, usually the red is on bank 2 - timestamp: 12, + timestampByte: 12, }), XK68JOYSTICK: literal({ name: 'XK-68 Joystick', @@ -247,7 +248,7 @@ export const PRODUCTS: { [name: string]: Product } = { backLightType: BackLightType.LEGACY, backLight2offset: 80, // offset used to access second bank of LEDs, usually the red is on bank 2 - timestamp: 18, // ms time since device boot 4 byte BE + timestampByte: 18, // ms time since device boot 4 byte BE disableButtons: [28, 29, 30, 36, 37, 38, 44, 45, 46, 52, 53, 54], // these are the index of the "hole" created by the joystick in the center, they will always be 0 }), XKR32: literal({ @@ -264,7 +265,7 @@ export const PRODUCTS: { [name: string]: Product } = { hasPS: false, // unknown backLightType: BackLightType.LEGACY, backLight2offset: 32, - timestamp: 31, // ms time since device boot 4 byte BE + timestampByte: 31, // ms time since device boot 4 byte BE }), XKE40: literal({ name: 'XKE-40', @@ -284,7 +285,7 @@ export const PRODUCTS: { [name: string]: Product } = { hasPS: true, // behind small hole on right side. backLightType: BackLightType.LINEAR, // map btnIndex-1 to ledIndex backLight2offset: 40, // off set to control second led bank. - timestamp: 31, // ms time since device boot 4 byte BE + timestampByte: 31, // ms time since device boot 4 byte BE btnLocation: [ [0, 0], [1, 1], @@ -350,7 +351,7 @@ export const PRODUCTS: { [name: string]: Product } = { hasPS: true, backLightType: BackLightType.LEGACY, backLight2offset: 80, - timestamp: 12, // ms time since device boot 4 byte BE + timestampByte: 12, // ms time since device boot 4 byte BE //disableButtons: [2,10,18,26,34,42,50,58,66,74,19,20,21,22,23,59,60,61,] // these buttons are not installed on the 60 button unit, these bytes will always be 0. }), XK80: literal({ @@ -368,7 +369,7 @@ export const PRODUCTS: { [name: string]: Product } = { hasPS: true, backLightType: BackLightType.LEGACY, backLight2offset: 80, - timestamp: 12, // ms time since device boot 4 byte BE + timestampByte: 12, // ms time since device boot 4 byte BE }), XKE124TBAR: literal({ name: 'XKE-124 T-bar', @@ -410,7 +411,7 @@ export const PRODUCTS: { [name: string]: Product } = { hasPS: false, backLightType: BackLightType.LEGACY, backLight2offset: 128, - timestamp: 31, // ms time since device boot 4 byte BE + timestampByte: 31, // ms time since device boot 4 byte BE }), XKMatrix: literal({ name: 'XK-128 Matrix', // this is a bare encoder board that can encode a 8x16 switch matrix @@ -425,7 +426,7 @@ export const PRODUCTS: { [name: string]: Product } = { hasPS: true, // slide switch on board backLightType: BackLightType.NONE, // no back light, only the 2 standard indicator LEDs, also availe on header, see documentation backLight2offset: 0, - timestamp: 18, // ms time since device boot 4 byte BE + timestampByte: 18, // ms time since device boot 4 byte BE // many buttons may be disabled or not as the custom wiring determines this. // to prevent phantom buttons, external diodes may be required, if diodes not used the board may be set by write command 215, see documentation }), @@ -450,7 +451,7 @@ export const PRODUCTS: { [name: string]: Product } = { backLightType: BackLightType.LEGACY, backLight2offset: 80, - timestamp: 18, // ms time since device boot 4 byte BE + timestampByte: 18, // ms time since device boot 4 byte BE disableButtons: [30, 31, 32, 38, 39, 40, 46, 47, 48, 54, 55, 56], }), XK3FOOT: literal({ @@ -466,7 +467,7 @@ export const PRODUCTS: { [name: string]: Product } = { hasPS: true, // inside unit and not very accessible backLightType: BackLightType.NONE, // no back light LEDs backLight2offset: 0, - timestamp: 18, // ms time since device boot 4 byte BE + timestampByte: 18, // ms time since device boot 4 byte BE btnLocation: [ [0, 0], [0, 0], // the keyIndex of 1 on this panel does not exsit @@ -489,7 +490,7 @@ export const PRODUCTS: { [name: string]: Product } = { hasPS: false, // none backLightType: BackLightType.NONE, // no back light LEDs backLight2offset: 0, - timestamp: 31, // ms time since device boot 4 byte BE + timestampByte: 31, // ms time since device boot 4 byte BE btnLocation: [ [0, 0], [1, 1], @@ -517,7 +518,7 @@ export const PRODUCTS: { [name: string]: Product } = { hasPS: false, // none backLightType: BackLightType.NONE, // no back light LEDs backLight2offset: 0, - timestamp: 31, // ms time since device boot 4 byte BE + timestampByte: 31, // ms time since device boot 4 byte BE btnLocation: [ [0, 0], [2, 1], @@ -548,7 +549,7 @@ export const PRODUCTS: { [name: string]: Product } = { hasPS: false, // none backLightType: BackLightType.NONE, // no back light LEDs but has 2 digital outputs on the HD 15 wire. See documentation backLight2offset: 0, - timestamp: 31, // ms time since device boot 4 byte BE + timestampByte: 31, // ms time since device boot 4 byte BE }), XKHD15GPIO: literal({ name: 'XK-HD15 GPIO', // HD15 connector for 10 digital outputs or can be configured to inputs, and two 3.5 mm ports, contacts for a stereo Plug @@ -564,7 +565,7 @@ export const PRODUCTS: { [name: string]: Product } = { backLightType: BackLightType.NONE, // no back light LEDs but has 2 or more digital outputs on the HD 15 wire. See documentation backLight2offset: 0, hasGPIO: true, - timestamp: 31, // ms time since device boot 4 byte BE + timestampByte: 31, // ms time since device boot 4 byte BE //The input data will always be in the 2 data bytes described, but this device may be configured in several ways // it is best to Qwery the device and get its current setup data, using GetIoConfiguration function }), @@ -663,7 +664,7 @@ export const PRODUCTS: { [name: string]: Product } = { hasLCD: true, backLightType: BackLightType.LEGACY, // back light LEDs backLight2offset: 32, - timestamp: 31, // ms time since device boot 4 byte BE + timestampByte: 31, // ms time since device boot 4 byte BE }), XKE180BROAD: literal({ name: 'XKE-180 Broadcast Keyboard', // @@ -682,7 +683,7 @@ export const PRODUCTS: { [name: string]: Product } = { hasPS: true, // at top right behind hole in end backLightType: BackLightType.NONE, // back light LEDs backLight2offset: 0, - timestamp: 36, // ms time since device boot 4 byte BE + timestampByte: 36, // ms time since device boot 4 byte BE }), XK64JOGTBAR: literal({ @@ -718,7 +719,7 @@ export const PRODUCTS: { [name: string]: Product } = { ], backLightType: BackLightType.LEGACY, backLight2offset: 80, - timestamp: 31, // ms time since device boot 4 byte BE + timestampByte: 31, // ms time since device boot 4 byte BE disableButtons: [6, 7, 8, 14, 15, 16, 22, 23, 24, 30, 31, 32, 73, 74, 75, 73], // These bits are messy, better to ignore them }), } diff --git a/src/xkeys.ts b/src/xkeys.ts index 369b221..bd2b681 100644 --- a/src/xkeys.ts +++ b/src/xkeys.ts @@ -217,9 +217,9 @@ export class XKeys extends EventEmitter { const UID = data.readUInt8(0) // the unit ID is the first byte, index 0, used to tell between 2 identical X-keys, UID is set by user // const PID = deviceInfo.productId // from USB hardware ID - let timestamp = 0 - if (this.product.timestamp !== undefined) { - timestamp = data.readUInt32BE(this.product.timestamp) // Time stamp is 4 bytes, use UInt32BE + let timestamp: number | undefined = undefined + if (this.product.timestampByte !== undefined) { + timestamp = data.readUInt32BE(this.product.timestampByte) // Time stamp is 4 bytes, use UInt32BE } const dd = data.readUInt8(1) @@ -417,6 +417,7 @@ export class XKeys extends EventEmitter { }) }) || [], + emitsTimestamp: this.product.timestampByte !== undefined, hasPS: this.product.hasPS, hasJoystick: this.product.hasJoystick?.length || 0, hasJog: this.product.hasJog?.length || 0,