From a3e975b0c3a1b35f87ac3e810188266b3fa9c027 Mon Sep 17 00:00:00 2001 From: David Idol Date: Mon, 22 Apr 2019 12:43:23 -0700 Subject: [PATCH 1/3] Add a long touch event --- src/CraftPlugin.ts | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/CraftPlugin.ts b/src/CraftPlugin.ts index ee95a9d..bf08a61 100644 --- a/src/CraftPlugin.ts +++ b/src/CraftPlugin.ts @@ -82,6 +82,7 @@ export default class CraftPlugin { private emitter: EventEmitter; private sessionId: string | undefined; private opts: CraftPluginOptions; + private touchTimer: any | undefined; constructor({ pluginGuid, reconnect = true }: CraftPluginOptions) { this.opts = { pluginGuid, reconnect }; @@ -97,6 +98,8 @@ export default class CraftPlugin { if (this.ws) { // We are reconnecting so clean up the old instance this.ws.removeAllListeners(); + clearTimeout(this.touchTimer); + this.touchTimer = undefined; } this.ws = new WebSocket(LOGITECH_OPTIONS_URL); this.emitter.emit('connect:begin'); @@ -150,14 +153,22 @@ export default class CraftPlugin { } else if (message.ratchet_delta < 0) { this.emitter.emit('crown:turn:negative', message); } + clearTimeout(this.touchTimer); + this.touchTimer = undefined; } private handleCrownTouch(message: CrownTouchMessage) { this.emitter.emit('crown:touch', message); if (message.touch_state === 0) { this.emitter.emit('crown:touch:released', message); + clearTimeout(this.touchTimer); + this.touchTimer = undefined; } else if (message.touch_state === 1) { this.emitter.emit('crown:touch:touched', message); + this.touchTimer = setTimeout(() => { + this.emitter.emit('crown:touch:longTouch', message); + this.touchTimer = undefined; + }, 1000); } } From d7f9122eecf13bbd658921e2561a1147aee21264 Mon Sep 17 00:00:00 2001 From: David Idol Date: Mon, 22 Apr 2019 12:48:42 -0700 Subject: [PATCH 2/3] Update CraftPlugin.ts --- src/CraftPlugin.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/CraftPlugin.ts b/src/CraftPlugin.ts index bf08a61..5f93550 100644 --- a/src/CraftPlugin.ts +++ b/src/CraftPlugin.ts @@ -189,6 +189,8 @@ export default class CraftPlugin { } public close() { + clearTimeout(this.touchTimer); + this.touchTimer = undefined; this.emitter.removeAllListeners(); this.ws.close(); } From 70041b1ae7c45fd6cec1f749a21b2dcf81f32ef6 Mon Sep 17 00:00:00 2001 From: David Idol Date: Wed, 8 May 2019 21:30:31 -0700 Subject: [PATCH 3/3] Improvements --- src/CraftPlugin.ts | 35 +++++++++++++++++++++++++++-------- 1 file changed, 27 insertions(+), 8 deletions(-) diff --git a/src/CraftPlugin.ts b/src/CraftPlugin.ts index 5f93550..4448c39 100644 --- a/src/CraftPlugin.ts +++ b/src/CraftPlugin.ts @@ -6,7 +6,7 @@ const LOGITECH_OPTIONS_URL = 'ws://localhost:10134'; const stringify = (obj: any) => JSON.stringify(obj); -const sendRegister = (pluginGuid: string) => stringify({ +const registerOutgoingMessage = (pluginGuid: string) => stringify({ PID: process.pid, application_version: '1.0', execName: process.title, @@ -14,7 +14,7 @@ const sendRegister = (pluginGuid: string) => stringify({ plugin_guid: pluginGuid, }); -const sendToolChange = (sessionId: string, toolId: string) => stringify({ +const toolChangeOutgoingMessage = (sessionId: string, toolId: string) => stringify({ message_type: 'tool_change', reset_options: true, session_id: sessionId, @@ -74,25 +74,34 @@ export type CraftPluginEventType = interface CraftPluginOptions { pluginGuid: string; reconnect?: boolean; + crownTurnCancelsRelease?: boolean; } // https://github.com/Logitech/logi_craft_sdk/blob/master/documentation/Craft_Crown_SDK.md export default class CraftPlugin { + public static log: boolean = true; private ws!: WebSocket; private emitter: EventEmitter; private sessionId: string | undefined; private opts: CraftPluginOptions; private touchTimer: any | undefined; + private touchingCrown: boolean = false; - constructor({ pluginGuid, reconnect = true }: CraftPluginOptions) { - this.opts = { pluginGuid, reconnect }; + constructor({ pluginGuid, reconnect = true, crownTurnCancelsRelease = false }: CraftPluginOptions) { + this.opts = { pluginGuid, reconnect, crownTurnCancelsRelease }; this.emitter = new EventEmitter(); this.connectWithManager(); } + private static logToConsole(message: string) { + if (CraftPlugin.log) { + console.log(`[logitech-craft-plugin] ${message}`); + } + } + private connectWithManager() { if (this.ws && this.ws.readyState !== this.ws.CONNECTING && this.ws.readyState !== this.ws.CLOSED) { - console.log('Already connected'); + CraftPlugin.logToConsole('Already connected'); return; } if (this.ws) { @@ -100,12 +109,13 @@ export default class CraftPlugin { this.ws.removeAllListeners(); clearTimeout(this.touchTimer); this.touchTimer = undefined; + this.touchingCrown = false; } this.ws = new WebSocket(LOGITECH_OPTIONS_URL); this.emitter.emit('connect:begin'); this.ws.once('open', () => { this.sessionId = undefined; - this.ws.send(sendRegister(this.opts.pluginGuid)); + this.ws.send(registerOutgoingMessage(this.opts.pluginGuid)); this.ws.on('message', (data: string) => { // route the message let message: ReceiveMessage; @@ -130,7 +140,7 @@ export default class CraftPlugin { }); this.ws.on('error', (err) => { this.emitter.emit('connect:failed', err); - console.error('Failed to connect to Logitech Options', err.message); + CraftPlugin.logToConsole('Failed to connect to Logitech Options ' + err.message); if (this.opts.reconnect) { setTimeout(() => { this.connectWithManager(); @@ -155,6 +165,9 @@ export default class CraftPlugin { } clearTimeout(this.touchTimer); this.touchTimer = undefined; + if (this.opts.crownTurnCancelsRelease) { + this.touchingCrown = false; + } } private handleCrownTouch(message: CrownTouchMessage) { @@ -163,6 +176,7 @@ export default class CraftPlugin { this.emitter.emit('crown:touch:released', message); clearTimeout(this.touchTimer); this.touchTimer = undefined; + this.touchingCrown = false; } else if (message.touch_state === 1) { this.emitter.emit('crown:touch:touched', message); this.touchTimer = setTimeout(() => { @@ -172,9 +186,13 @@ export default class CraftPlugin { } } + public get isTouchingCrown(): boolean { + return this.touchingCrown; + } + public changeTool(toolId: string) { if (this.sessionId) { - this.ws.send(sendToolChange(this.sessionId, toolId)); + this.ws.send(toolChangeOutgoingMessage(this.sessionId, toolId)); } else { throw new Error('Not connected yet. Make sure to only send this once the "connect:done" event has occurred'); } @@ -191,6 +209,7 @@ export default class CraftPlugin { public close() { clearTimeout(this.touchTimer); this.touchTimer = undefined; + this.touchingCrown = false; this.emitter.removeAllListeners(); this.ws.close(); }