Skip to content

Commit

Permalink
feat: use new KEY-ROTATE message (#60)
Browse files Browse the repository at this point in the history
  • Loading branch information
Julusian authored Oct 31, 2022
1 parent bcc5b0f commit fb8806a
Show file tree
Hide file tree
Showing 5 changed files with 94 additions and 45 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@
"infinitton-idisplay": "^1.1.2",
"meow": "^9.0.0",
"node-hid": "github:julusian/node-hid#v2.1.2-1",
"semver": "^7.3.8",
"sharp": "^0.31.1",
"tslib": "^2.3.1",
"usb": "^2.5.2"
Expand Down
32 changes: 32 additions & 0 deletions src/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { EventEmitter } from 'eventemitter3'
import { Socket } from 'net'
import { DeviceDrawProps, DeviceRegisterProps } from './device-types/api'
import { DEFAULT_PORT } from './lib'
import * as semver from 'semver'

const PING_UNACKED_LIMIT = 5 // Arbitrary number
const PING_IDLE_TIMEOUT = 500 // Pings are allowed to be late if another packet has been received recently
Expand Down Expand Up @@ -100,6 +101,9 @@ export class CompanionSatelliteClient extends EventEmitter<CompanionSatelliteCli
private _retryConnectTimeout: NodeJS.Timer | undefined = undefined
private _host = ''
private _port = DEFAULT_PORT
private _supportsCombinedEncoders = false

public forceSplitEncoders = false

public get host(): string {
return this._host
Expand All @@ -108,6 +112,14 @@ export class CompanionSatelliteClient extends EventEmitter<CompanionSatelliteCli
return this._port
}

/**
* Older versions of Companion do not support rotary encoders.
* For these, we can 'simulate' them by use the press/release actions of a button.
*/
public get useCombinedEncoders(): boolean {
return !this.forceSplitEncoders && this._supportsCombinedEncoders
}

constructor(options: CompanionSatelliteClientOptions = {}) {
super()

Expand Down Expand Up @@ -285,8 +297,10 @@ export class CompanionSatelliteClient extends EventEmitter<CompanionSatelliteCli
break
case 'BEGIN':
console.log(`Connected to Companion: ${body}`)
this.handleBegin(params)
break
case 'KEY-PRESS':
case 'KEY-ROTATE':
// Ignore
break
default:
Expand All @@ -295,6 +309,14 @@ export class CompanionSatelliteClient extends EventEmitter<CompanionSatelliteCli
}
}

private handleBegin(params: Record<string, string | boolean>): void {
const protocolVersion = params.ApiVersion
if (typeof protocolVersion === 'string' && semver.lte('1.3.0', protocolVersion)) {
this._supportsCombinedEncoders = true
console.log('Companion supports combined encoders')
}
}

private handleState(params: Record<string, string | boolean>): void {
if (typeof params.DEVICEID !== 'string') {
console.log('Mising DEVICEID in KEY-DRAW response')
Expand Down Expand Up @@ -372,6 +394,16 @@ export class CompanionSatelliteClient extends EventEmitter<CompanionSatelliteCli
this.socket.write(`KEY-PRESS DEVICEID=${deviceId} KEY=${keyIndex} PRESSED=0\n`)
}
}
public rotateLeft(deviceId: string, keyIndex: number): void {
if (this._connected && this.socket) {
this.socket.write(`KEY-ROTATE DEVICEID=${deviceId} KEY=${keyIndex} DIRECTION=0\n`)
}
}
public rotateRight(deviceId: string, keyIndex: number): void {
if (this._connected && this.socket) {
this.socket.write(`KEY-ROTATE DEVICEID=${deviceId} KEY=${keyIndex} DIRECTION=1\n`)
}
}

public addDevice(deviceId: string, productName: string, props: DeviceRegisterProps): void {
if (this._connected && this.socket) {
Expand Down
86 changes: 45 additions & 41 deletions src/device-types/loupedeck.ts
Original file line number Diff line number Diff line change
Expand Up @@ -106,62 +106,66 @@ export class LoupedeckWrapper implements WrappedDevice {
this.#deck.close()
}
async initDevice(client: CompanionSatelliteClient, status: string): Promise<void> {
const convertButtonId = (type: 'button' | 'rotary', id: number): number => {
const convertButtonId = (type: 'button' | 'rotary', id: number, rotarySecondary: boolean): number => {
if (type === 'button' && id >= 0 && id < 8) {
return 24 + id
} else if (type === 'rotary') {
switch (id) {
case 0:
return 1
case 1:
return 9
case 2:
return 17
case 3:
return 6
case 4:
return 14
case 5:
return 22
if (!client.useCombinedEncoders && rotarySecondary) {
switch (id) {
case 0:
return 1
case 1:
return 9
case 2:
return 17
case 3:
return 6
case 4:
return 14
case 5:
return 22
}
} else {
switch (id) {
case 0:
return 0
case 1:
return 8
case 2:
return 16
case 3:
return 7
case 4:
return 15
case 5:
return 23
}
}
}

// Discard
return 99
}
console.log('Registering key events for ' + this.deviceId)
this.#deck.on('down', (info) => client.keyDown(this.deviceId, convertButtonId(info.type, info.index)))
this.#deck.on('up', (info) => client.keyUp(this.deviceId, convertButtonId(info.type, info.index)))
this.#deck.on('down', (info) => client.keyDown(this.deviceId, convertButtonId(info.type, info.index, true)))
this.#deck.on('up', (info) => client.keyUp(this.deviceId, convertButtonId(info.type, info.index, true)))
this.#deck.on('rotate', (info, delta) => {
if (info.type !== 'rotary') return

let id2
switch (info.index) {
case 0:
id2 = 0
break
case 1:
id2 = 8
break
case 2:
id2 = 16
break
case 3:
id2 = 7
break
case 4:
id2 = 15
break
case 5:
id2 = 23
break
}

if (id2 !== undefined) {
const id2 = convertButtonId(info.type, info.index, false)
if (id2 < 90) {
if (delta < 0) {
client.keyUp(this.deviceId, id2)
if (client.useCombinedEncoders) {
client.rotateLeft(this.deviceId, id2)
} else {
client.keyUp(this.deviceId, id2)
}
} else if (delta > 0) {
client.keyDown(this.deviceId, id2)
if (client.useCombinedEncoders) {
client.rotateRight(this.deviceId, id2)
} else {
client.keyDown(this.deviceId, id2)
}
}
}
})
Expand Down
18 changes: 15 additions & 3 deletions src/device-types/xencelabs-quick-keys.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ function keyToCompanion(k: number): number | null {
return null
}
export class QuickKeysWrapper implements WrappedDevice {
#client: CompanionSatelliteClient | undefined
readonly #surface: XencelabsQuickKeys
readonly #deviceId: string

Expand Down Expand Up @@ -51,6 +52,7 @@ export class QuickKeysWrapper implements WrappedDevice {
await this.#surface.stopData()
}
async initDevice(client: CompanionSatelliteClient, status: string): Promise<void> {
this.#client = client
console.log('Registering key events for ' + this.deviceId)

const handleDown = (key: number) => {
Expand All @@ -68,10 +70,18 @@ export class QuickKeysWrapper implements WrappedDevice {
const handleWheel = (ev: WheelEvent) => {
switch (ev) {
case WheelEvent.Left:
client.keyUp(this.deviceId, 11)
if (client.useCombinedEncoders) {
client.rotateLeft(this.deviceId, 5)
} else {
client.keyUp(this.deviceId, 11)
}
break
case WheelEvent.Right:
client.keyDown(this.deviceId, 11)
if (client.useCombinedEncoders) {
client.rotateRight(this.deviceId, 5)
} else {
client.keyDown(this.deviceId, 11)
}
break
}
}
Expand Down Expand Up @@ -133,7 +143,9 @@ export class QuickKeysWrapper implements WrappedDevice {
await this.#surface.setKeyText(keyIndex, data.text.substr(0, 8))
}
}
if (data.color && data.keyIndex === 11) {

const wheelIndex = this.#client?.useCombinedEncoders ? 5 : 11
if (data.color && data.keyIndex === wheelIndex) {
const r = parseInt(data.color.substr(1, 2), 16)
const g = parseInt(data.color.substr(3, 2), 16)
const b = parseInt(data.color.substr(5, 2), 16)
Expand Down
2 changes: 1 addition & 1 deletion yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -4163,7 +4163,7 @@ semver@^6.0.0, semver@^6.1.0, semver@^6.2.0:
resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d"
integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==

semver@^7.1.1, semver@^7.3.2, semver@^7.3.4, semver@^7.3.5, semver@^7.3.7:
semver@^7.1.1, semver@^7.3.2, semver@^7.3.4, semver@^7.3.5, semver@^7.3.7, semver@^7.3.8:
version "7.3.8"
resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.8.tgz#07a78feafb3f7b32347d725e33de7e2a2df67798"
integrity sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==
Expand Down

0 comments on commit fb8806a

Please sign in to comment.