From 2a5b5a47b9566c9cbdd7dec0b72421f5dd5fe577 Mon Sep 17 00:00:00 2001 From: Nathan Kunicki Date: Thu, 2 Aug 2018 11:41:21 +0100 Subject: [PATCH] Port AB supported on PUPHub, setName on LPF2 hubs --- DOCS.md | 41 ++++++++++++++++++++++++++++++++++++++++- README.md | 41 ++++++++++++++++++++++++++++++++++++++++- lpf2hub.ts | 22 ++++++++++++++++++++++ puphub.ts | 43 ++++++++++++++++++++++++++++++++++++------- wedo2smarthub.ts | 4 ++++ 5 files changed, 142 insertions(+), 9 deletions(-) diff --git a/DOCS.md b/DOCS.md index 4187b49..ab78ac2 100644 --- a/DOCS.md +++ b/DOCS.md @@ -379,6 +379,7 @@ Emits when an attached motor or sensor is detached from the Hub. * [.setLEDColor(color)](#BoostMoveHub+setLEDColor) ⇒ Promise * [.setMotorSpeed(port, speed, [time])](#BoostMoveHub+setMotorSpeed) ⇒ Promise * [.setMotorAngle(port, angle, [speed])](#BoostMoveHub+setMotorAngle) ⇒ Promise + * [.setName(name)](#LPF2Hub+setName) ⇒ Promise * [.connect()](#Hub+connect) ⇒ Promise * [.disconnect()](#Hub+disconnect) ⇒ Promise * [.subscribe(port, [mode])](#Hub+subscribe) ⇒ Promise @@ -493,6 +494,18 @@ Rotate a motor by a given angle. | angle | number | | How much the motor should be rotated (in degrees). | | [speed] | number | 100 | How fast the motor should be rotated. | + + +### boostMoveHub.setName(name) ⇒ Promise +Set the name of the Hub. + +**Kind**: instance method of [BoostMoveHub](#BoostMoveHub) +**Returns**: Promise - Resolved upon successful issuance of command. + +| Param | Type | Description | +| --- | --- | --- | +| name | string | New name of the hub (ASCII characters only). | + ### boostMoveHub.connect() ⇒ Promise @@ -660,6 +673,7 @@ Emits when an attached motor or sensor is detached from the Hub. * [.batteryLevel](#Hub+batteryLevel) * [.setLEDColor(color)](#PUPHub+setLEDColor) ⇒ Promise * [.setMotorSpeed(port, speed, [time])](#PUPHub+setMotorSpeed) ⇒ Promise + * [.setName(name)](#LPF2Hub+setName) ⇒ Promise * [.connect()](#Hub+connect) ⇒ Promise * [.disconnect()](#Hub+disconnect) ⇒ Promise * [.subscribe(port, [mode])](#Hub+subscribe) ⇒ Promise @@ -756,9 +770,21 @@ Set the motor speed on a given port. | Param | Type | Description | | --- | --- | --- | | port | string | | -| speed | number | For forward, a value between 1 - 100 should be set. For reverse, a value between -1 to -100. Stop is 0. | +| speed | number \| Array.<number> | For forward, a value between 1 - 100 should be set. For reverse, a value between -1 to -100. Stop is 0. If you are specifying port AB to control both motors, you can optionally supply a tuple of speeds. | | [time] | number | How long to activate the motor for (in milliseconds). Leave empty to turn the motor on indefinitely. | + + +### pupHub.setName(name) ⇒ Promise +Set the name of the Hub. + +**Kind**: instance method of [PUPHub](#PUPHub) +**Returns**: Promise - Resolved upon successful issuance of command. + +| Param | Type | Description | +| --- | --- | --- | +| name | string | New name of the hub (ASCII characters only). | + ### pupHub.connect() ⇒ Promise @@ -913,6 +939,7 @@ Emits when an attached motor or sensor is detached from the Hub. * [.rssi](#Hub+rssi) * [.batteryLevel](#Hub+batteryLevel) * [.setLEDColor(color)](#PUPRemote+setLEDColor) ⇒ Promise + * [.setName(name)](#LPF2Hub+setName) ⇒ Promise * [.connect()](#Hub+connect) ⇒ Promise * [.disconnect()](#Hub+disconnect) ⇒ Promise * [.subscribe(port, [mode])](#Hub+subscribe) ⇒ Promise @@ -993,6 +1020,18 @@ Set the color of the LED on the Remote via a color value. | --- | --- | --- | | color | number | A number representing one of the LED color consts. | + + +### pupRemote.setName(name) ⇒ Promise +Set the name of the Hub. + +**Kind**: instance method of [PUPRemote](#PUPRemote) +**Returns**: Promise - Resolved upon successful issuance of command. + +| Param | Type | Description | +| --- | --- | --- | +| name | string | New name of the hub (ASCII characters only). | + ### pupRemote.connect() ⇒ Promise diff --git a/README.md b/README.md index e3d96bd..cd9c60b 100644 --- a/README.md +++ b/README.md @@ -429,6 +429,7 @@ Emits when an attached motor or sensor is detached from the Hub. * [.setLEDColor(color)](#BoostMoveHub+setLEDColor) ⇒ Promise * [.setMotorSpeed(port, speed, [time])](#BoostMoveHub+setMotorSpeed) ⇒ Promise * [.setMotorAngle(port, angle, [speed])](#BoostMoveHub+setMotorAngle) ⇒ Promise + * [.setName(name)](#LPF2Hub+setName) ⇒ Promise * [.connect()](#Hub+connect) ⇒ Promise * [.disconnect()](#Hub+disconnect) ⇒ Promise * [.subscribe(port, [mode])](#Hub+subscribe) ⇒ Promise @@ -543,6 +544,18 @@ Rotate a motor by a given angle. | angle | number | | How much the motor should be rotated (in degrees). | | [speed] | number | 100 | How fast the motor should be rotated. | + + +### boostMoveHub.setName(name) ⇒ Promise +Set the name of the Hub. + +**Kind**: instance method of [BoostMoveHub](#BoostMoveHub) +**Returns**: Promise - Resolved upon successful issuance of command. + +| Param | Type | Description | +| --- | --- | --- | +| name | string | New name of the hub (ASCII characters only). | + ### boostMoveHub.connect() ⇒ Promise @@ -710,6 +723,7 @@ Emits when an attached motor or sensor is detached from the Hub. * [.batteryLevel](#Hub+batteryLevel) * [.setLEDColor(color)](#PUPHub+setLEDColor) ⇒ Promise * [.setMotorSpeed(port, speed, [time])](#PUPHub+setMotorSpeed) ⇒ Promise + * [.setName(name)](#LPF2Hub+setName) ⇒ Promise * [.connect()](#Hub+connect) ⇒ Promise * [.disconnect()](#Hub+disconnect) ⇒ Promise * [.subscribe(port, [mode])](#Hub+subscribe) ⇒ Promise @@ -806,9 +820,21 @@ Set the motor speed on a given port. | Param | Type | Description | | --- | --- | --- | | port | string | | -| speed | number | For forward, a value between 1 - 100 should be set. For reverse, a value between -1 to -100. Stop is 0. | +| speed | number \| Array.<number> | For forward, a value between 1 - 100 should be set. For reverse, a value between -1 to -100. Stop is 0. If you are specifying port AB to control both motors, you can optionally supply a tuple of speeds. | | [time] | number | How long to activate the motor for (in milliseconds). Leave empty to turn the motor on indefinitely. | + + +### pupHub.setName(name) ⇒ Promise +Set the name of the Hub. + +**Kind**: instance method of [PUPHub](#PUPHub) +**Returns**: Promise - Resolved upon successful issuance of command. + +| Param | Type | Description | +| --- | --- | --- | +| name | string | New name of the hub (ASCII characters only). | + ### pupHub.connect() ⇒ Promise @@ -963,6 +989,7 @@ Emits when an attached motor or sensor is detached from the Hub. * [.rssi](#Hub+rssi) * [.batteryLevel](#Hub+batteryLevel) * [.setLEDColor(color)](#PUPRemote+setLEDColor) ⇒ Promise + * [.setName(name)](#LPF2Hub+setName) ⇒ Promise * [.connect()](#Hub+connect) ⇒ Promise * [.disconnect()](#Hub+disconnect) ⇒ Promise * [.subscribe(port, [mode])](#Hub+subscribe) ⇒ Promise @@ -1043,6 +1070,18 @@ Set the color of the LED on the Remote via a color value. | --- | --- | --- | | color | number | A number representing one of the LED color consts. | + + +### pupRemote.setName(name) ⇒ Promise +Set the name of the Hub. + +**Kind**: instance method of [PUPRemote](#PUPRemote) +**Returns**: Promise - Resolved upon successful issuance of command. + +| Param | Type | Description | +| --- | --- | --- | +| name | string | New name of the hub (ASCII characters only). | + ### pupRemote.connect() ⇒ Promise diff --git a/lpf2hub.ts b/lpf2hub.ts index 0d86b90..2517a59 100644 --- a/lpf2hub.ts +++ b/lpf2hub.ts @@ -47,6 +47,28 @@ export class LPF2Hub extends Hub { } + /** + * Set the name of the Hub. + * @method LPF2Hub#setName + * @param {string} name New name of the hub (ASCII characters only). + * @returns {Promise} Resolved upon successful issuance of command. + */ + public 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([0x00, 0x00, 0x01, 0x01, 0x01]); + data = Buffer.concat([data, Buffer.from(name, "ascii")]); + data[0] = data.length; + this._writeMessage(Consts.BLECharacteristics.LPF2_ALL, data); + this._writeMessage(Consts.BLECharacteristics.LPF2_ALL, data); + this._name = name; + return resolve(); + }); + } + + protected _activatePortDevice (port: number, type: number, mode: number, format: number, callback?: () => void) { this._writeMessage(Consts.BLECharacteristics.LPF2_ALL, Buffer.from([0x0a, 0x00, 0x41, port, mode, 0x01, 0x00, 0x00, 0x00, 0x01]), callback); } diff --git a/puphub.ts b/puphub.ts index e17b666..2e5551c 100644 --- a/puphub.ts +++ b/puphub.ts @@ -36,7 +36,8 @@ export class PUPHub extends LPF2Hub { this.type = Consts.Hubs.POWERED_UP_HUB; this._ports = { "A": new Port("A", 0), - "B": new Port("B", 1) + "B": new Port("B", 1), + "AB": new Port("AB", 57) }; debug("Discovered Powered Up Hub"); } @@ -74,23 +75,51 @@ export class PUPHub extends LPF2Hub { * Set the motor speed on a given port. * @method PUPHub#setMotorSpeed * @param {string} port - * @param {number} speed For forward, a value between 1 - 100 should be set. For reverse, a value between -1 to -100. Stop is 0. + * @param {number | Array} speed For forward, a value between 1 - 100 should be set. For reverse, a value between -1 to -100. Stop is 0. If you are specifying port AB to control both motors, you can optionally supply a tuple of speeds. * @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 | [number, number], time?: number) { + const portObj = this._portLookup(port); + if (portObj.id !== "AB" && speed instanceof Array) { + throw new Error(`Port ${portObj.id} can only accept a single speed`); + } return new Promise((resolve, reject) => { - const portObj = this._portLookup(port); if (time) { - const data = Buffer.from([0x0a, 0x00, 0x81, portObj.value, 0x11, 0x60, 0x00, this._mapSpeed(speed), 0x00, 0x00]); + let data = null; + if (portObj.id === "AB") { + if (speed instanceof Array) { + data = Buffer.from([0x08, 0x00, 0x81, portObj.value, 0x11, 0x02, this._mapSpeed(speed[0]), this._mapSpeed(speed[1])]); + } else { + data = Buffer.from([0x08, 0x00, 0x81, portObj.value, 0x11, 0x02, this._mapSpeed(speed), this._mapSpeed(speed)]); + } + } else { + // @ts-ignore: The type of speed is properly checked at the start + data = Buffer.from([0x0a, 0x00, 0x81, portObj.value, 0x11, 0x60, 0x00, this._mapSpeed(speed), 0x00, 0x00]); + } this._writeMessage(Consts.BLECharacteristics.LPF2_ALL, data); setTimeout(() => { - const data = Buffer.from([0x0a, 0x00, 0x81, portObj.value, 0x11, 0x60, 0x00, 0x00, 0x00, 0x00]); + let data = null; + if (portObj.id === "AB") { + data = Buffer.from([0x08, 0x00, 0x81, portObj.value, 0x11, 0x02, 0x00]); + } else { + data = Buffer.from([0x0a, 0x00, 0x81, portObj.value, 0x11, 0x60, 0x00, 0x00, 0x00, 0x00]); + } this._writeMessage(Consts.BLECharacteristics.LPF2_ALL, data); return resolve(); }, time); } else { - const data = Buffer.from([0x0a, 0x00, 0x81, portObj.value, 0x11, 0x60, 0x00, this._mapSpeed(speed), 0x00, 0x00]); + let data = null; + if (portObj.id === "AB") { + if (speed instanceof Array) { + data = Buffer.from([0x08, 0x00, 0x81, portObj.value, 0x11, 0x02, this._mapSpeed(speed[0]), this._mapSpeed(speed[1])]); + } else { + data = Buffer.from([0x08, 0x00, 0x81, portObj.value, 0x11, 0x02, this._mapSpeed(speed), this._mapSpeed(speed)]); + } + } else { + // @ts-ignore: The type of speed is properly checked at the start + data = Buffer.from([0x0a, 0x00, 0x81, portObj.value, 0x11, 0x60, 0x00, this._mapSpeed(speed), 0x00, 0x00]); + } this._writeMessage(Consts.BLECharacteristics.LPF2_ALL, data); return resolve(); } diff --git a/wedo2smarthub.ts b/wedo2smarthub.ts index 533ebcc..5cacf23 100644 --- a/wedo2smarthub.ts +++ b/wedo2smarthub.ts @@ -60,9 +60,13 @@ export class WeDo2SmartHub extends Hub { * @returns {Promise} Resolved upon successful issuance of command. */ public setName (name: string) { + if (name.length > 14) { + throw new Error("Name must be 14 characters or less"); + } return new Promise((resolve, reject) => { const data = Buffer.from(name, "ascii"); this._writeMessage(Consts.BLECharacteristics.WEDO2_NAME_ID, data); + this._writeMessage(Consts.BLECharacteristics.WEDO2_NAME_ID, data); this._name = name; return resolve(); });