From 232edb2ffb1c85b041b84318fd0734c88f87beac Mon Sep 17 00:00:00 2001 From: Ben Rogers Date: Tue, 3 Mar 2020 21:29:52 +0000 Subject: [PATCH] Moves away from callbacks, towards more promises Allows more use of await Removed some unnecessary awaits, some unnecessary Promise wrappers --- src/devices/basicmotor.ts | 5 +- src/devices/device.ts | 10 ++-- src/hubs/basehub.ts | 22 ++++----- src/hubs/duplotrainbase.ts | 11 ++--- src/hubs/hub.ts | 11 ++--- src/hubs/lpf2hub.ts | 91 ++++++++++++++++-------------------- src/hubs/movehub.ts | 11 ++--- src/hubs/remotecontrol.ts | 11 ++--- src/hubs/technicmediumhub.ts | 13 ++---- src/hubs/wedo2smarthub.ts | 12 ++--- src/interfaces.ts | 10 ++-- src/nobleabstraction.ts | 24 +++++++--- src/poweredup-node.ts | 12 ++--- src/webbleabstraction.ts | 36 +++++--------- 14 files changed, 120 insertions(+), 159 deletions(-) diff --git a/src/devices/basicmotor.ts b/src/devices/basicmotor.ts index 48881b0..619bce3 100644 --- a/src/devices/basicmotor.ts +++ b/src/devices/basicmotor.ts @@ -28,10 +28,7 @@ export class BasicMotor extends Device { if (interrupt) { this.cancelEventTimer(); } - return new Promise((resolve) => { - this.writeDirect(0x00, Buffer.from([mapSpeed(power)])); - return resolve(); - }); + return this.writeDirect(0x00, Buffer.from([mapSpeed(power)])); } diff --git a/src/devices/device.ts b/src/devices/device.ts index 0b5dfd4..b37ecf4 100644 --- a/src/devices/device.ts +++ b/src/devices/device.ts @@ -126,17 +126,17 @@ export class Device extends EventEmitter { return this._isVirtualPort; } - public writeDirect (mode: number, data: Buffer, callback?: () => void) { + public writeDirect (mode: number, data: Buffer) { if (this.isWeDo2SmartHub) { - this.send(Buffer.concat([Buffer.from([this.portId, 0x01, 0x02]), data]), Consts.BLECharacteristic.WEDO2_MOTOR_VALUE_WRITE); + return this.send(Buffer.concat([Buffer.from([this.portId, 0x01, 0x02]), data]), Consts.BLECharacteristic.WEDO2_MOTOR_VALUE_WRITE); } else { - this.send(Buffer.concat([Buffer.from([0x81, this.portId, 0x11, 0x51, mode]), data]), Consts.BLECharacteristic.LPF2_ALL, callback); + return this.send(Buffer.concat([Buffer.from([0x81, this.portId, 0x11, 0x51, mode]), data]), Consts.BLECharacteristic.LPF2_ALL); } } - public send (data: Buffer, characteristic: string = Consts.BLECharacteristic.LPF2_ALL, callback?: () => void) { + public send (data: Buffer, characteristic: string = Consts.BLECharacteristic.LPF2_ALL) { this._ensureConnected(); - this.hub.send(data, characteristic, callback); + return this.hub.send(data, characteristic); } public subscribe (mode: number) { diff --git a/src/hubs/basehub.ts b/src/hubs/basehub.ts index e6d694b..025b6dc 100644 --- a/src/hubs/basehub.ts +++ b/src/hubs/basehub.ts @@ -165,16 +165,12 @@ export class BaseHub extends EventEmitter { * @returns {Promise} Resolved upon successful connect. */ public connect () { - return new Promise(async (connectResolve, connectReject) => { - if (this._bleDevice.connecting) { - return connectReject("Already connecting"); - } else if (this._bleDevice.connected) { - return connectReject("Already connected"); - } - await this._bleDevice.connect(); - return connectResolve(); - }); - + if (this._bleDevice.connecting) { + throw new Error("Already connecting"); + } else if (this._bleDevice.connected) { + throw new Error("Already connected"); + } + return this._bleDevice.connect(); } @@ -320,10 +316,8 @@ export class BaseHub extends EventEmitter { } - public send (message: Buffer, uuid: string, callback?: () => void) { - if (callback) { - callback(); - } + public send (message: Buffer, uuid: string) { + return Promise.resolve(); } diff --git a/src/hubs/duplotrainbase.ts b/src/hubs/duplotrainbase.ts index 19adfe2..2002f79 100644 --- a/src/hubs/duplotrainbase.ts +++ b/src/hubs/duplotrainbase.ts @@ -36,13 +36,10 @@ export class DuploTrainBase extends LPF2Hub { } - public connect () { - return new Promise(async (resolve, reject) => { - debug("Connecting to Duplo Train Base"); - await super.connect(); - debug("Connect completed"); - return resolve(); - }); + public async connect () { + debug("Connecting to Duplo Train Base"); + await super.connect(); + debug("Connect completed"); } diff --git a/src/hubs/hub.ts b/src/hubs/hub.ts index e2c7a7e..e16ce13 100644 --- a/src/hubs/hub.ts +++ b/src/hubs/hub.ts @@ -39,13 +39,10 @@ export class Hub extends LPF2Hub { } - public connect () { - return new Promise(async (resolve, reject) => { - debug("Connecting to Powered UP Hub"); - await super.connect(); - debug("Connect completed"); - return resolve(); - }); + public async connect () { + debug("Connecting to Powered UP Hub"); + await super.connect(); + debug("Connect completed"); } diff --git a/src/hubs/lpf2hub.ts b/src/hubs/lpf2hub.ts index b6c81ea..7f93ac9 100644 --- a/src/hubs/lpf2hub.ts +++ b/src/hubs/lpf2hub.ts @@ -20,23 +20,19 @@ export class LPF2Hub extends BaseHub { private _propertyRequestCallbacks: {[property: number]: ((data: Buffer) => void)} = {}; - public connect () { - return new Promise(async (resolve, reject) => { - debug("LPF2Hub connecting"); - await super.connect(); - await this._bleDevice.discoverCharacteristicsForService(Consts.BLEService.LPF2_HUB); - this._bleDevice.subscribeToCharacteristic(Consts.BLECharacteristic.LPF2_ALL, this._parseMessage.bind(this)); - await this.sleep(500); - this._requestHubPropertyReports(0x02); // Activate button reports - await this._requestHubPropertyValue(0x03); // Request firmware version - await this._requestHubPropertyValue(0x04); // Request hardware version - this._requestHubPropertyReports(0x05); // Activate RSSI updates - this._requestHubPropertyReports(0x06); // Activate battery level reports - await this._requestHubPropertyValue(0x0d); // Request primary MAC address - this.emit("connect"); - debug("LPF2Hub connected"); - resolve(); - }); + public async connect () { + debug("LPF2Hub connecting"); + await super.connect(); + await this._bleDevice.discoverCharacteristicsForService(Consts.BLEService.LPF2_HUB); + this._bleDevice.subscribeToCharacteristic(Consts.BLECharacteristic.LPF2_ALL, this._parseMessage.bind(this)); + await this._requestHubPropertyReports(0x02); // Activate button reports + await this._requestHubPropertyValue(0x03); // Request firmware version + await this._requestHubPropertyValue(0x04); // Request hardware version + await this._requestHubPropertyReports(0x05); // Activate RSSI updates + await this._requestHubPropertyReports(0x06); // Activate battery level reports + await this._requestHubPropertyValue(0x0d); // Request primary MAC address + this.emit("connect"); + debug("LPF2Hub connected"); } @@ -46,11 +42,7 @@ export class LPF2Hub extends BaseHub { * @returns {Promise} Resolved upon successful disconnect. */ public shutdown () { - return new Promise((resolve, reject) => { - this.send(Buffer.from([0x02, 0x01]), Consts.BLECharacteristic.LPF2_ALL, () => { - return resolve(); - }); - }); + return this.send(Buffer.from([0x02, 0x01]), Consts.BLECharacteristic.LPF2_ALL); } @@ -60,37 +52,34 @@ export class LPF2Hub extends BaseHub { * @param {string} name New name of the hub (14 characters or less, ASCII only). * @returns {Promise} Resolved upon successful issuance of command. */ - public setName (name: string) { + public async setName (name: string) { if (name.length > 14) { throw new Error("Name must be 14 characters or less"); } - return new Promise((resolve, reject) => { - let data = Buffer.from([0x01, 0x01, 0x01]); - data = Buffer.concat([data, Buffer.from(name, "ascii")]); - // Send this twice, as sometimes the first time doesn't take - this.send(data, Consts.BLECharacteristic.LPF2_ALL); - this.send(data, Consts.BLECharacteristic.LPF2_ALL); - this._name = name; - return resolve(); - }); + let data = Buffer.from([0x01, 0x01, 0x01]); + data = Buffer.concat([data, Buffer.from(name, "ascii")]); + // Send this twice, as sometimes the first time doesn't take + await this.send(data, Consts.BLECharacteristic.LPF2_ALL); + await this.send(data, Consts.BLECharacteristic.LPF2_ALL); + this._name = name; } - public send (message: Buffer, uuid: string, callback?: () => void) { + public send (message: Buffer, uuid: string) { message = Buffer.concat([Buffer.alloc(2), message]); message[0] = message.length; debug("Sent Message (LPF2_ALL)", message); - this._bleDevice.writeToCharacteristic(uuid, message, callback); + return this._bleDevice.writeToCharacteristic(uuid, message); } public subscribe (portId: number, deviceType: number, mode: number) { - this.send(Buffer.from([0x41, portId, mode, 0x01, 0x00, 0x00, 0x00, 0x01]), Consts.BLECharacteristic.LPF2_ALL); + return this.send(Buffer.from([0x41, portId, mode, 0x01, 0x00, 0x00, 0x00, 0x01]), Consts.BLECharacteristic.LPF2_ALL); } public unsubscribe (portId: number, mode: number) { - this.send(Buffer.from([0x41, portId, mode, 0x01, 0x00, 0x00, 0x00, 0x00]), Consts.BLECharacteristic.LPF2_ALL); + return this.send(Buffer.from([0x41, portId, mode, 0x01, 0x00, 0x00, 0x00, 0x00]), Consts.BLECharacteristic.LPF2_ALL); } @@ -115,7 +104,7 @@ export class LPF2Hub extends BaseHub { if (firstDevice.type !== secondDevice.type) { throw new Error(`Both devices must be of the same type to create a virtual port`); } - this.send(Buffer.from([0x61, 0x01, firstDevice.portId, secondDevice.portId]), Consts.BLECharacteristic.LPF2_ALL); + return this.send(Buffer.from([0x61, 0x01, firstDevice.portId, secondDevice.portId]), Consts.BLECharacteristic.LPF2_ALL); } @@ -196,7 +185,7 @@ export class LPF2Hub extends BaseHub { private _requestHubPropertyReports (property: number) { - this.send(Buffer.from([0x01, property, 0x02]), Consts.BLECharacteristic.LPF2_ALL); + return this.send(Buffer.from([0x01, property, 0x02]), Consts.BLECharacteristic.LPF2_ALL); } @@ -250,7 +239,7 @@ export class LPF2Hub extends BaseHub { } - private _parsePortMessage (message: Buffer) { + private async _parsePortMessage (message: Buffer) { const portId = message[3]; const event = message[4]; @@ -265,7 +254,7 @@ export class LPF2Hub extends BaseHub { const hwVersion = decodeVersion(message.readInt32LE(7)); const swVersion = decodeVersion(message.readInt32LE(11)); modeInfoDebug(`Port ${toHex(portId)}, hardware version ${hwVersion}, software version ${swVersion}`); - this._sendPortInformationRequest(portId); + await this._sendPortInformationRequest(portId); } const device = this._createDevice(deviceType, portId); @@ -301,13 +290,13 @@ export class LPF2Hub extends BaseHub { } - private _sendPortInformationRequest (port: number) { - this.send(Buffer.from([0x21, port, 0x01]), Consts.BLECharacteristic.LPF2_ALL); - this.send(Buffer.from([0x21, port, 0x02]), Consts.BLECharacteristic.LPF2_ALL); // Mode combinations + private async _sendPortInformationRequest (port: number) { + await this.send(Buffer.from([0x21, port, 0x01]), Consts.BLECharacteristic.LPF2_ALL); + await this.send(Buffer.from([0x21, port, 0x02]), Consts.BLECharacteristic.LPF2_ALL); // Mode combinations } - private _parsePortInformationResponse (message: Buffer) { + private async _parsePortInformationResponse (message: Buffer) { const port = message[3]; if (message[4] === 2) { const modeCombinationMasks: number[] = []; @@ -323,18 +312,18 @@ export class LPF2Hub extends BaseHub { modeInfoDebug(`Port ${toHex(port)}, total modes ${count}, input modes ${input}, output modes ${output}`); for (let i = 0; i < count; i++) { - this._sendModeInformationRequest(port, i, 0x00); // Mode Name - this._sendModeInformationRequest(port, i, 0x01); // RAW Range - this._sendModeInformationRequest(port, i, 0x02); // PCT Range - this._sendModeInformationRequest(port, i, 0x03); // SI Range - this._sendModeInformationRequest(port, i, 0x04); // SI Symbol - this._sendModeInformationRequest(port, i, 0x80); // Value Format + await this._sendModeInformationRequest(port, i, 0x00); // Mode Name + await this._sendModeInformationRequest(port, i, 0x01); // RAW Range + await this._sendModeInformationRequest(port, i, 0x02); // PCT Range + await this._sendModeInformationRequest(port, i, 0x03); // SI Range + await this._sendModeInformationRequest(port, i, 0x04); // SI Symbol + await this._sendModeInformationRequest(port, i, 0x80); // Value Format } } private _sendModeInformationRequest (port: number, mode: number, type: number) { - this.send(Buffer.from([0x22, port, mode, type]), Consts.BLECharacteristic.LPF2_ALL); + return this.send(Buffer.from([0x22, port, mode, type]), Consts.BLECharacteristic.LPF2_ALL); } diff --git a/src/hubs/movehub.ts b/src/hubs/movehub.ts index f769ac4..d290270 100644 --- a/src/hubs/movehub.ts +++ b/src/hubs/movehub.ts @@ -37,13 +37,10 @@ export class MoveHub extends LPF2Hub { } - public connect () { - return new Promise(async (resolve, reject) => { - debug("Connecting to Move Hub"); - await super.connect(); - debug("Connect completed"); - return resolve(); - }); + public async connect () { + debug("Connecting to Move Hub"); + await super.connect(); + debug("Connect completed"); } diff --git a/src/hubs/remotecontrol.ts b/src/hubs/remotecontrol.ts index a40be28..cf01117 100644 --- a/src/hubs/remotecontrol.ts +++ b/src/hubs/remotecontrol.ts @@ -37,13 +37,10 @@ export class RemoteControl extends LPF2Hub { } - public connect () { - return new Promise(async (resolve, reject) => { - debug("Connecting to Powered UP Remote"); - await super.connect(); - debug("Connect completed"); - return resolve(); - }); + public async connect () { + debug("Connecting to Powered UP Remote"); + await super.connect(); + debug("Connect completed"); } diff --git a/src/hubs/technicmediumhub.ts b/src/hubs/technicmediumhub.ts index 966ad03..f7baa84 100644 --- a/src/hubs/technicmediumhub.ts +++ b/src/hubs/technicmediumhub.ts @@ -36,14 +36,11 @@ export class TechnicMediumHub extends LPF2Hub { } - public connect () { - return new Promise(async (resolve, reject) => { - debug("Connecting to Control+ Hub"); - await super.connect(); - this.send(Buffer.from([0x41, 0x3d, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x01]), Consts.BLECharacteristic.LPF2_ALL); // Temperature - debug("Connect completed"); - return resolve(); - }); + public async connect () { + debug("Connecting to Control+ Hub"); + await super.connect(); + await this.send(Buffer.from([0x41, 0x3d, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x01]), Consts.BLECharacteristic.LPF2_ALL); // Temperature + debug("Connect completed"); } diff --git a/src/hubs/wedo2smarthub.ts b/src/hubs/wedo2smarthub.ts index 1b5b14d..9c90a14 100644 --- a/src/hubs/wedo2smarthub.ts +++ b/src/hubs/wedo2smarthub.ts @@ -41,7 +41,7 @@ export class WeDo2SmartHub extends BaseHub { public connect () { - return new Promise(async (resolve, reject) => { + return new Promise(async (resolve, reject) => { debug("Connecting to WeDo 2.0 Smart Hub"); await super.connect(); await this._bleDevice.discoverCharacteristicsForService(Consts.BLEService.WEDO2_SMART_HUB); @@ -99,11 +99,7 @@ export class WeDo2SmartHub extends BaseHub { * @returns {Promise} Resolved upon successful disconnect. */ public shutdown () { - return new Promise((resolve, reject) => { - this.send(Buffer.from([0x00]), Consts.BLECharacteristic.WEDO2_DISCONNECT, () => { - return resolve(); - }); - }); + return this.send(Buffer.from([0x00]), Consts.BLECharacteristic.WEDO2_DISCONNECT); } @@ -128,11 +124,11 @@ export class WeDo2SmartHub extends BaseHub { } - public send (message: Buffer, uuid: string, callback?: () => void) { + public send (message: Buffer, uuid: string) { if (debug.enabled) { debug(`Sent Message (${this._getCharacteristicNameFromUUID(uuid)})`, message); } - this._bleDevice.writeToCharacteristic(uuid, message, callback); + return this._bleDevice.writeToCharacteristic(uuid, message); } diff --git a/src/interfaces.ts b/src/interfaces.ts index 5390575..c06fd8d 100644 --- a/src/interfaces.ts +++ b/src/interfaces.ts @@ -7,19 +7,19 @@ export interface IBLEAbstraction extends EventEmitter { name: string; connecting: boolean; connected: boolean; - connect: () => Promise; - disconnect: () => Promise; - discoverCharacteristicsForService: (uuid: string) => Promise; + connect: () => Promise; + disconnect: () => Promise; + discoverCharacteristicsForService: (uuid: string) => Promise; subscribeToCharacteristic: (uuid: string, callback: (data: Buffer) => void) => void; addToCharacteristicMailbox: (uuid: string, data: Buffer) => void; readFromCharacteristic: (uuid: string, callback: (err: string | null, data: Buffer | null) => void) => void; - writeToCharacteristic: (uuid: string, data: Buffer, callback?: () => void) => void; + writeToCharacteristic: (uuid: string, data: Buffer) => Promise; } export interface IDeviceInterface extends EventEmitter { type: Consts.HubType; getPortNameForPortId: (portId: number) => string | undefined; - send: (message: Buffer, uuid: string, callback?: () => void) => void; + send: (message: Buffer, uuid: string) => Promise; subscribe: (portId: number, deviceType: number, mode: number) => void; isPortVirtual: (portId: number) => boolean; sleep: (delay: number) => Promise; diff --git a/src/nobleabstraction.ts b/src/nobleabstraction.ts index c8bea2d..1d56742 100644 --- a/src/nobleabstraction.ts +++ b/src/nobleabstraction.ts @@ -61,9 +61,13 @@ export class NobleDevice extends EventEmitter implements IBLEAbstraction { public connect () { - return new Promise((resolve, reject) => { + return new Promise((resolve, reject) => { this._connecting = true; this._noblePeripheral.connect((err: string) => { + if(err) { + return reject(err); + } + this._connecting = false; this._connected = true; return resolve(); @@ -73,7 +77,7 @@ export class NobleDevice extends EventEmitter implements IBLEAbstraction { public disconnect () { - return new Promise((resolve, reject) => { + return new Promise((resolve) => { this._noblePeripheral.disconnect(); return resolve(); }); @@ -81,7 +85,7 @@ export class NobleDevice extends EventEmitter implements IBLEAbstraction { public discoverCharacteristicsForService (uuid: string) { - return new Promise(async (discoverResolve, discoverReject) => { + return new Promise(async (discoverResolve, discoverReject) => { uuid = this._sanitizeUUID(uuid); this._noblePeripheral.discoverServices([uuid], (err: string, services: Service[]) => { if (err) { @@ -135,9 +139,17 @@ export class NobleDevice extends EventEmitter implements IBLEAbstraction { } - public writeToCharacteristic (uuid: string, data: Buffer, callback?: () => void) { - uuid = this._sanitizeUUID(uuid); - this._characteristics[uuid].write(data, false, callback); + public writeToCharacteristic (uuid: string, data: Buffer) { + return new Promise((resolve, reject) => { + uuid = this._sanitizeUUID(uuid); + this._characteristics[uuid].write(data, false, (error) => { + if(error) { + return reject(error); + } + + return resolve(); + }); + }) } diff --git a/src/poweredup-node.ts b/src/poweredup-node.ts index 3d8cd2d..e000ade 100644 --- a/src/poweredup-node.ts +++ b/src/poweredup-node.ts @@ -152,17 +152,17 @@ export class PoweredUP extends EventEmitter { let hub: BaseHub; - if (await WeDo2SmartHub.IsWeDo2SmartHub(peripheral)) { + if (WeDo2SmartHub.IsWeDo2SmartHub(peripheral)) { hub = new WeDo2SmartHub(device); - } else if (await MoveHub.IsMoveHub(peripheral)) { + } else if (MoveHub.IsMoveHub(peripheral)) { hub = new MoveHub(device); - } else if (await Hub.IsHub(peripheral)) { + } else if (Hub.IsHub(peripheral)) { hub = new Hub(device); - } else if (await RemoteControl.IsRemoteControl(peripheral)) { + } else if (RemoteControl.IsRemoteControl(peripheral)) { hub = new RemoteControl(device); - } else if (await DuploTrainBase.IsDuploTrainBase(peripheral)) { + } else if (DuploTrainBase.IsDuploTrainBase(peripheral)) { hub = new DuploTrainBase(device); - } else if (await TechnicMediumHub.IsTechnicMediumHub(peripheral)) { + } else if (TechnicMediumHub.IsTechnicMediumHub(peripheral)) { hub = new TechnicMediumHub(device); } else { return; diff --git a/src/webbleabstraction.ts b/src/webbleabstraction.ts index ccfd915..337c86a 100644 --- a/src/webbleabstraction.ts +++ b/src/webbleabstraction.ts @@ -58,7 +58,7 @@ export class WebBLEDevice extends EventEmitter implements IBLEAbstraction { public connect () { - return new Promise((resolve, reject) => { + return new Promise((resolve, reject) => { this._connected = true; return resolve(); }); @@ -66,29 +66,21 @@ export class WebBLEDevice extends EventEmitter implements IBLEAbstraction { public disconnect () { - return new Promise((resolve, reject) => { + return new Promise((resolve, reject) => { this._webBLEServer.device.gatt.disconnect(); return resolve(); }); } - public discoverCharacteristicsForService (uuid: string) { - return new Promise(async (discoverResolve, discoverReject) => { - debug("Service/characteristic discovery started"); - let service; - try { - service = await this._webBLEServer.getPrimaryService(uuid); - } catch (err) { - return discoverReject(err); - } - const characteristics = await service.getCharacteristics(); - for (const characteristic of characteristics) { - this._characteristics[characteristic.uuid] = characteristic; - } - debug("Service/characteristic discovery finished"); - return discoverResolve(); - }); + public async discoverCharacteristicsForService (uuid: string) { + debug("Service/characteristic discovery started"); + const service = await this._webBLEServer.getPrimaryService(uuid); + const characteristics = await service.getCharacteristics(); + for (const characteristic of characteristics) { + this._characteristics[characteristic.uuid] = characteristic; + } + debug("Service/characteristic discovery finished"); } @@ -134,12 +126,8 @@ export class WebBLEDevice extends EventEmitter implements IBLEAbstraction { } - public writeToCharacteristic (uuid: string, data: Buffer, callback?: () => void) { - this._queue = this._queue.then(() => this._characteristics[uuid].writeValue(data)).then(() => { - if (callback) { - callback(); - } - }); + public writeToCharacteristic (uuid: string, data: Buffer) { + return this._queue = this._queue.then(() => this._characteristics[uuid].writeValue(data)); }