From 97e48a8c6a06c2a822e62c6604d6bd5c45451dff Mon Sep 17 00:00:00 2001 From: Nathan Kellenicki Date: Sun, 19 Aug 2018 12:33:56 +0100 Subject: [PATCH 1/4] Missing ramp speed working properly --- boostmovehub.ts | 12 +++++++++--- hub.ts | 3 ++- port.ts | 21 +++++++++++++++------ puphub.ts | 12 +++++++++--- wedo2smarthub.ts | 16 +++++++++++----- 5 files changed, 46 insertions(+), 18 deletions(-) diff --git a/boostmovehub.ts b/boostmovehub.ts index cc03636..3aac515 100644 --- a/boostmovehub.ts +++ b/boostmovehub.ts @@ -61,6 +61,7 @@ export class BoostMoveHub extends LPF2Hub { if (portObj.id !== "AB" && speed instanceof Array) { throw new Error(`Port ${portObj.id} can only accept a single speed`); } + portObj.cancelEventTimer(); return new Promise((resolve, reject) => { if (time) { @@ -82,11 +83,12 @@ export class BoostMoveHub extends LPF2Hub { // @ts-ignore: The type of speed is properly checked at the start const data = Buffer.from([0x81, portObj.value, 0x11, 0x51, 0x00, this._mapSpeed(speed)]); this._writeMessage(Consts.BLECharacteristics.LPF2_ALL, data); - setTimeout(() => { + const timeout = setTimeout(() => { const data = Buffer.from([0x81, portObj.value, 0x11, 0x51, 0x00, 0x00]); this._writeMessage(Consts.BLECharacteristics.LPF2_ALL, data); return resolve(); }, time); + portObj.setEventTimer(timeout); } } else { @@ -125,8 +127,10 @@ export class BoostMoveHub extends LPF2Hub { * @returns {Promise} Resolved upon successful completion of command. */ public rampMotorSpeed (port: string, fromSpeed: number, toSpeed: number, time: number) { + const portObj = this._portLookup(port); + portObj.cancelEventTimer(); return new Promise((resolve, reject) => { - this._calculateRamp(fromSpeed, toSpeed, time) + this._calculateRamp(fromSpeed, toSpeed, time, portObj) .on("changeSpeed", (speed) => { this.setMotorSpeed(port, speed); }) @@ -151,6 +155,7 @@ export class BoostMoveHub extends LPF2Hub { if (portObj.id !== "AB" && speed instanceof Array) { throw new Error(`Port ${portObj.id} can only accept a single speed`); } + portObj.cancelEventTimer(); return new Promise((resolve, reject) => { portObj.busy = true; let data = null; @@ -183,11 +188,12 @@ export class BoostMoveHub extends LPF2Hub { const data = Buffer.from([0x81, portObj.value, 0x11, 0x51, 0x00, brightness]); this._writeMessage(Consts.BLECharacteristics.LPF2_ALL, data); if (time) { - setTimeout(() => { + const timeout = setTimeout(() => { const data = Buffer.from([0x81, portObj.value, 0x11, 0x51, 0x00, 0x00]); this._writeMessage(Consts.BLECharacteristics.LPF2_ALL, data); return resolve(); }, time); + portObj.setEventTimer(timeout); } else { return resolve(); } diff --git a/hub.ts b/hub.ts index 23cd983..c4160bb 100644 --- a/hub.ts +++ b/hub.ts @@ -304,7 +304,7 @@ export class Hub extends EventEmitter { } - protected _calculateRamp (fromSpeed: number, toSpeed: number, time: number) { + protected _calculateRamp (fromSpeed: number, toSpeed: number, time: number, port: Port) { const emitter = new EventEmitter(); const steps = Math.abs(toSpeed - fromSpeed); let delay = time / steps; @@ -330,6 +330,7 @@ export class Hub extends EventEmitter { emitter.emit("finished"); } }, delay); + port.setEventTimer(interval); return emitter; } diff --git a/port.ts b/port.ts index 2f3ae31..508f703 100644 --- a/port.ts +++ b/port.ts @@ -6,19 +6,28 @@ export class Port { public id: string; public value: number; - public connected: boolean; public type: Consts.Devices; - public busy: boolean; - public finished: (() => void) | null; + public connected: boolean = false; + public busy: boolean = false; + public finished: (() => void) | null = null; + private _eventTimer: NodeJS.Timer | null = null; constructor (id: string, value: number) { this.id = id; this.value = value; - this.connected = false; - this.busy = false; - this.finished = null; this.type = Consts.Devices.UNKNOWN; } + public cancelEventTimer () { + if (this._eventTimer) { + clearTimeout(this._eventTimer); + this._eventTimer = null; + } + } + + public setEventTimer (timer: NodeJS.Timer) { + this._eventTimer = timer; + } + } diff --git a/puphub.ts b/puphub.ts index 2f29a66..699f8d0 100644 --- a/puphub.ts +++ b/puphub.ts @@ -74,6 +74,7 @@ export class PUPHub extends LPF2Hub { throw new Error(`Port ${portObj.id} requires both motors be of the same type`); } } + portObj.cancelEventTimer(); return new Promise((resolve, reject) => { if (time) { let data = null; @@ -84,7 +85,7 @@ export class PUPHub extends LPF2Hub { data = Buffer.from([0x81, portObj.value, 0x11, 0x60, 0x00, this._mapSpeed(speed), 0x00, 0x00]); } this._writeMessage(Consts.BLECharacteristics.LPF2_ALL, data); - setTimeout(() => { + const timeout = setTimeout(() => { let data = null; if (portObj.id === "AB") { data = Buffer.from([0x81, portObj.value, 0x11, 0x02, 0x00, 0x00]); @@ -94,6 +95,7 @@ export class PUPHub extends LPF2Hub { this._writeMessage(Consts.BLECharacteristics.LPF2_ALL, data); return resolve(); }, time); + portObj.setEventTimer(timeout); } else { let data = null; if (portObj.id === "AB") { @@ -119,8 +121,10 @@ export class PUPHub extends LPF2Hub { * @returns {Promise} Resolved upon successful completion of command. */ public rampMotorSpeed (port: string, fromSpeed: number, toSpeed: number, time: number) { + const portObj = this._portLookup(port); + portObj.cancelEventTimer(); return new Promise((resolve, reject) => { - this._calculateRamp(fromSpeed, toSpeed, time) + this._calculateRamp(fromSpeed, toSpeed, time, portObj) .on("changeSpeed", (speed) => { this.setMotorSpeed(port, speed); }) @@ -139,15 +143,17 @@ export class PUPHub extends LPF2Hub { */ public setLightBrightness (port: string, brightness: number, time?: number) { const portObj = this._portLookup(port); + portObj.cancelEventTimer(); return new Promise((resolve, reject) => { const data = Buffer.from([0x81, portObj.value, 0x11, 0x51, 0x00, brightness]); this._writeMessage(Consts.BLECharacteristics.LPF2_ALL, data); if (time) { - setTimeout(() => { + const timeout = setTimeout(() => { const data = Buffer.from([0x81, portObj.value, 0x11, 0x51, 0x00, 0x00]); this._writeMessage(Consts.BLECharacteristics.LPF2_ALL, data); return resolve(); }, time); + portObj.setEventTimer(timeout); } else { return resolve(); } diff --git a/wedo2smarthub.ts b/wedo2smarthub.ts index b50a38d..6494871 100644 --- a/wedo2smarthub.ts +++ b/wedo2smarthub.ts @@ -125,13 +125,16 @@ export class WeDo2SmartHub extends Hub { * @returns {Promise} Resolved upon successful completion of command. If time is specified, this is once the motor is finished. */ public setMotorSpeed (port: string, speed: number, time?: number) { + const portObj = this._portLookup(port); + portObj.cancelEventTimer(); return new Promise((resolve, reject) => { - this._writeMessage(Consts.BLECharacteristics.WEDO2_MOTOR_VALUE_WRITE, Buffer.from([this._portLookup(port).value, 0x01, 0x02, this._mapSpeed(speed)])); + this._writeMessage(Consts.BLECharacteristics.WEDO2_MOTOR_VALUE_WRITE, Buffer.from([portObj.value, 0x01, 0x02, this._mapSpeed(speed)])); if (time) { - setTimeout(() => { - this._writeMessage(Consts.BLECharacteristics.WEDO2_MOTOR_VALUE_WRITE, Buffer.from([this._portLookup(port).value, 0x01, 0x02, 0x00])); + const timeout = setTimeout(() => { + this._writeMessage(Consts.BLECharacteristics.WEDO2_MOTOR_VALUE_WRITE, Buffer.from([portObj.value, 0x01, 0x02, 0x00])); return resolve(); }, time); + portObj.setEventTimer(timeout); } else { return resolve(); } @@ -149,8 +152,10 @@ export class WeDo2SmartHub extends Hub { * @returns {Promise} Resolved upon successful completion of command. */ public rampMotorSpeed (port: string, fromSpeed: number, toSpeed: number, time: number) { + const portObj = this._portLookup(port); + portObj.cancelEventTimer(); return new Promise((resolve, reject) => { - this._calculateRamp(fromSpeed, toSpeed, time) + this._calculateRamp(fromSpeed, toSpeed, time, portObj) .on("changeSpeed", (speed) => { this.setMotorSpeed(port, speed); }) @@ -191,11 +196,12 @@ export class WeDo2SmartHub extends Hub { const data = Buffer.from([portObj.value, 0x01, 0x02, brightness]); this._writeMessage(Consts.BLECharacteristics.WEDO2_MOTOR_VALUE_WRITE, data); if (time) { - setTimeout(() => { + const timeout = setTimeout(() => { const data = Buffer.from([portObj.value, 0x01, 0x02, 0x00]); this._writeMessage(Consts.BLECharacteristics.WEDO2_MOTOR_VALUE_WRITE, data); return resolve(); }, time); + portObj.setEventTimer(timeout); } else { return resolve(); } From ef69af5c5f09cc295467f9df3ef042930d57cd8b Mon Sep 17 00:00:00 2001 From: Nathan Kellenicki Date: Tue, 28 Aug 2018 20:28:39 -0700 Subject: [PATCH 2/4] Potentially working? --- boostmovehub.ts | 18 ++++++++++++------ hub.ts | 2 +- puphub.ts | 17 +++++++++++------ wedo2smarthub.ts | 19 ++++++++++++------- 4 files changed, 36 insertions(+), 20 deletions(-) diff --git a/boostmovehub.ts b/boostmovehub.ts index 3aac515..1e7d9be 100644 --- a/boostmovehub.ts +++ b/boostmovehub.ts @@ -56,14 +56,19 @@ export class BoostMoveHub extends LPF2Hub { * @param {number} [time] How long to activate the motor for (in milliseconds). Leave empty to turn the motor on indefinitely. * @returns {Promise} Resolved upon successful completion of command. If time is specified, this is once the motor is finished. */ - public setMotorSpeed (port: string, speed: number | [number, number], time?: number) { + public setMotorSpeed (port: string, speed: number | [number, number], time?: number | boolean) { const portObj = this._portLookup(port); if (portObj.id !== "AB" && speed instanceof Array) { throw new Error(`Port ${portObj.id} can only accept a single speed`); } - portObj.cancelEventTimer(); + if (typeof time === "boolean") { + if (time === true) { + portObj.cancelEventTimer(); + } + time = undefined; + } return new Promise((resolve, reject) => { - if (time) { + if (time && typeof time === "number") { if (portObj.type === Consts.Devices.BOOST_TACHO_MOTOR || portObj.type === Consts.Devices.BOOST_MOVE_HUB_MOTOR) { portObj.busy = true; @@ -83,10 +88,11 @@ export class BoostMoveHub extends LPF2Hub { // @ts-ignore: The type of speed is properly checked at the start const data = Buffer.from([0x81, portObj.value, 0x11, 0x51, 0x00, this._mapSpeed(speed)]); this._writeMessage(Consts.BLECharacteristics.LPF2_ALL, data); - const timeout = setTimeout(() => { + const timeout = global.setTimeout(() => { const data = Buffer.from([0x81, portObj.value, 0x11, 0x51, 0x00, 0x00]); this._writeMessage(Consts.BLECharacteristics.LPF2_ALL, data); return resolve(); + // @ts-ignore: The type of time is properly checked at the start }, time); portObj.setEventTimer(timeout); } @@ -132,7 +138,7 @@ export class BoostMoveHub extends LPF2Hub { return new Promise((resolve, reject) => { this._calculateRamp(fromSpeed, toSpeed, time, portObj) .on("changeSpeed", (speed) => { - this.setMotorSpeed(port, speed); + this.setMotorSpeed(port, speed, true); }) .on("finished", resolve); }); @@ -188,7 +194,7 @@ export class BoostMoveHub extends LPF2Hub { const data = Buffer.from([0x81, portObj.value, 0x11, 0x51, 0x00, brightness]); this._writeMessage(Consts.BLECharacteristics.LPF2_ALL, data); if (time) { - const timeout = setTimeout(() => { + const timeout = global.setTimeout(() => { const data = Buffer.from([0x81, portObj.value, 0x11, 0x51, 0x00, 0x00]); this._writeMessage(Consts.BLECharacteristics.LPF2_ALL, data); return resolve(); diff --git a/hub.ts b/hub.ts index c4160bb..203565f 100644 --- a/hub.ts +++ b/hub.ts @@ -199,7 +199,7 @@ export class Hub extends EventEmitter { */ public sleep (delay: number) { return new Promise((resolve) => { - setTimeout(resolve, delay); + global.setTimeout(resolve, delay); }); } diff --git a/puphub.ts b/puphub.ts index 699f8d0..7ee7b25 100644 --- a/puphub.ts +++ b/puphub.ts @@ -62,7 +62,7 @@ export class PUPHub extends LPF2Hub { * @param {number} [time] How long to activate the motor for (in milliseconds). Leave empty to turn the motor on indefinitely. * @returns {Promise} Resolved upon successful completion of command. If time is specified, this is once the motor is finished. */ - public setMotorSpeed (port: string, speed: number | [number, number], time?: number) { + public setMotorSpeed (port: string, speed: number | [number, number], time?: number | boolean) { const portObj = this._portLookup(port); if (portObj.id !== "AB" && speed instanceof Array) { throw new Error(`Port ${portObj.id} can only accept a single speed`); @@ -74,9 +74,14 @@ export class PUPHub extends LPF2Hub { throw new Error(`Port ${portObj.id} requires both motors be of the same type`); } } - portObj.cancelEventTimer(); + if (typeof time === "boolean") { + if (time === true) { + portObj.cancelEventTimer(); + } + time = undefined; + } return new Promise((resolve, reject) => { - if (time) { + if (time && typeof time === "number") { let data = null; if (portObj.id === "AB") { data = Buffer.from([0x81, portObj.value, 0x11, 0x02, this._mapSpeed(speed instanceof Array ? speed[0] : speed), this._mapSpeed(speed instanceof Array ? speed[1] : speed)]); @@ -85,7 +90,7 @@ export class PUPHub extends LPF2Hub { data = Buffer.from([0x81, portObj.value, 0x11, 0x60, 0x00, this._mapSpeed(speed), 0x00, 0x00]); } this._writeMessage(Consts.BLECharacteristics.LPF2_ALL, data); - const timeout = setTimeout(() => { + const timeout = global.setTimeout(() => { let data = null; if (portObj.id === "AB") { data = Buffer.from([0x81, portObj.value, 0x11, 0x02, 0x00, 0x00]); @@ -126,7 +131,7 @@ export class PUPHub extends LPF2Hub { return new Promise((resolve, reject) => { this._calculateRamp(fromSpeed, toSpeed, time, portObj) .on("changeSpeed", (speed) => { - this.setMotorSpeed(port, speed); + this.setMotorSpeed(port, speed, true); }) .on("finished", resolve); }); @@ -148,7 +153,7 @@ export class PUPHub extends LPF2Hub { const data = Buffer.from([0x81, portObj.value, 0x11, 0x51, 0x00, brightness]); this._writeMessage(Consts.BLECharacteristics.LPF2_ALL, data); if (time) { - const timeout = setTimeout(() => { + const timeout = global.setTimeout(() => { const data = Buffer.from([0x81, portObj.value, 0x11, 0x51, 0x00, 0x00]); this._writeMessage(Consts.BLECharacteristics.LPF2_ALL, data); return resolve(); diff --git a/wedo2smarthub.ts b/wedo2smarthub.ts index 6494871..19a3e11 100644 --- a/wedo2smarthub.ts +++ b/wedo2smarthub.ts @@ -124,13 +124,18 @@ export class WeDo2SmartHub extends Hub { * @param {number} [time] How long to activate the motor for (in milliseconds). Leave empty to turn the motor on indefinitely. * @returns {Promise} Resolved upon successful completion of command. If time is specified, this is once the motor is finished. */ - public setMotorSpeed (port: string, speed: number, time?: number) { + public setMotorSpeed (port: string, speed: number, time?: number | boolean) { const portObj = this._portLookup(port); - portObj.cancelEventTimer(); + if (typeof time === "boolean") { + if (time === true) { + portObj.cancelEventTimer(); + } + time = undefined; + } return new Promise((resolve, reject) => { this._writeMessage(Consts.BLECharacteristics.WEDO2_MOTOR_VALUE_WRITE, Buffer.from([portObj.value, 0x01, 0x02, this._mapSpeed(speed)])); - if (time) { - const timeout = setTimeout(() => { + if (time && typeof time === "number") { + const timeout = global.setTimeout(() => { this._writeMessage(Consts.BLECharacteristics.WEDO2_MOTOR_VALUE_WRITE, Buffer.from([portObj.value, 0x01, 0x02, 0x00])); return resolve(); }, time); @@ -157,7 +162,7 @@ export class WeDo2SmartHub extends Hub { return new Promise((resolve, reject) => { this._calculateRamp(fromSpeed, toSpeed, time, portObj) .on("changeSpeed", (speed) => { - this.setMotorSpeed(port, speed); + this.setMotorSpeed(port, speed, true); }) .on("finished", resolve); }); @@ -177,7 +182,7 @@ export class WeDo2SmartHub extends Hub { data.writeUInt16LE(frequency, 3); data.writeUInt16LE(time, 5); this._writeMessage(Consts.BLECharacteristics.WEDO2_MOTOR_VALUE_WRITE, data); - setTimeout(resolve, time); + global.setTimeout(resolve, time); }); } @@ -196,7 +201,7 @@ export class WeDo2SmartHub extends Hub { const data = Buffer.from([portObj.value, 0x01, 0x02, brightness]); this._writeMessage(Consts.BLECharacteristics.WEDO2_MOTOR_VALUE_WRITE, data); if (time) { - const timeout = setTimeout(() => { + const timeout = global.setTimeout(() => { const data = Buffer.from([portObj.value, 0x01, 0x02, 0x00]); this._writeMessage(Consts.BLECharacteristics.WEDO2_MOTOR_VALUE_WRITE, data); return resolve(); From 52c4accaf5c26bfd318887ea018a80aaaf2735e4 Mon Sep 17 00:00:00 2001 From: Nathan Kellenicki Date: Wed, 29 Aug 2018 10:14:21 -0700 Subject: [PATCH 3/4] Fixes --- boostmovehub.ts | 7 ++++++- puphub.ts | 6 +++++- wedo2smarthub.ts | 7 ++++++- 3 files changed, 17 insertions(+), 3 deletions(-) diff --git a/boostmovehub.ts b/boostmovehub.ts index 1e7d9be..49012ad 100644 --- a/boostmovehub.ts +++ b/boostmovehub.ts @@ -61,12 +61,16 @@ export class BoostMoveHub extends LPF2Hub { if (portObj.id !== "AB" && speed instanceof Array) { throw new Error(`Port ${portObj.id} can only accept a single speed`); } + let cancelEventTimer = true; if (typeof time === "boolean") { if (time === true) { - portObj.cancelEventTimer(); + cancelEventTimer = false; } time = undefined; } + if (cancelEventTimer) { + portObj.cancelEventTimer(); + } return new Promise((resolve, reject) => { if (time && typeof time === "number") { @@ -190,6 +194,7 @@ export class BoostMoveHub extends LPF2Hub { */ public setLightBrightness (port: string, brightness: number, time?: number) { const portObj = this._portLookup(port); + portObj.cancelEventTimer(); return new Promise((resolve, reject) => { const data = Buffer.from([0x81, portObj.value, 0x11, 0x51, 0x00, brightness]); this._writeMessage(Consts.BLECharacteristics.LPF2_ALL, data); diff --git a/puphub.ts b/puphub.ts index 7ee7b25..7f15370 100644 --- a/puphub.ts +++ b/puphub.ts @@ -74,12 +74,16 @@ export class PUPHub extends LPF2Hub { throw new Error(`Port ${portObj.id} requires both motors be of the same type`); } } + let cancelEventTimer = true; if (typeof time === "boolean") { if (time === true) { - portObj.cancelEventTimer(); + cancelEventTimer = false; } time = undefined; } + if (cancelEventTimer) { + portObj.cancelEventTimer(); + } return new Promise((resolve, reject) => { if (time && typeof time === "number") { let data = null; diff --git a/wedo2smarthub.ts b/wedo2smarthub.ts index 19a3e11..1600426 100644 --- a/wedo2smarthub.ts +++ b/wedo2smarthub.ts @@ -126,12 +126,16 @@ export class WeDo2SmartHub extends Hub { */ public setMotorSpeed (port: string, speed: number, time?: number | boolean) { const portObj = this._portLookup(port); + let cancelEventTimer = true; if (typeof time === "boolean") { if (time === true) { - portObj.cancelEventTimer(); + cancelEventTimer = false; } time = undefined; } + if (cancelEventTimer) { + portObj.cancelEventTimer(); + } return new Promise((resolve, reject) => { this._writeMessage(Consts.BLECharacteristics.WEDO2_MOTOR_VALUE_WRITE, Buffer.from([portObj.value, 0x01, 0x02, this._mapSpeed(speed)])); if (time && typeof time === "number") { @@ -197,6 +201,7 @@ export class WeDo2SmartHub extends Hub { */ public setLightBrightness (port: string, brightness: number, time?: number) { const portObj = this._portLookup(port); + portObj.cancelEventTimer(); return new Promise((resolve, reject) => { const data = Buffer.from([portObj.value, 0x01, 0x02, brightness]); this._writeMessage(Consts.BLECharacteristics.WEDO2_MOTOR_VALUE_WRITE, data); From e01ed781090bc32fd6b504ee460c0360e204ca6f Mon Sep 17 00:00:00 2001 From: Nathan Kellenicki Date: Wed, 29 Aug 2018 10:16:19 -0700 Subject: [PATCH 4/4] 1.1.3 - Timer cancellations --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index c029ea8..8665022 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "node-poweredup", - "version": "1.1.2", + "version": "1.1.3", "description": "A Node.js module to interface with LEGO Powered UP components.", "homepage": "https://github.com/nathankellenicki/node-poweredup/", "main": "dist/poweredup.js",