diff --git a/src/consts.ts b/src/consts.ts index f9cabba..0c66aba 100644 --- a/src/consts.ts +++ b/src/consts.ts @@ -57,7 +57,7 @@ export enum DeviceType { LIGHT = 8, VOLTAGE_SENSOR = 20, CURRENT_SENSOR = 21, - PIEZO_TONE = 22, + PIEZO_BUZZER = 22, HUB_LED = 23, TILT_SENSOR = 34, MOTION_SENSOR = 35, diff --git a/src/devices/currentsensor.ts b/src/devices/currentsensor.ts index efa11c8..e68dbea 100644 --- a/src/devices/currentsensor.ts +++ b/src/devices/currentsensor.ts @@ -11,25 +11,30 @@ export class CurrentSensor extends Device { } public receive (message: Buffer) { - const mode = this._mode; + const mode = this.mode; switch (mode) { case CurrentSensor.Mode.CURRENT: - let maxCurrentValue = CurrentSensor.MaxCurrentValue[this.hub.type]; - if (maxCurrentValue === undefined) { - maxCurrentValue = CurrentSensor.MaxCurrentValue[Consts.HubType.UNKNOWN]; + if (this.isWeDo2SmartHub) { + const current = message.readInt16LE(2) / 1000; + this.emit("current", current); + } else { + let maxCurrentValue = CurrentSensor.MaxCurrentValue[this.hub.type]; + if (maxCurrentValue === undefined) { + maxCurrentValue = CurrentSensor.MaxCurrentValue[Consts.HubType.UNKNOWN]; + } + let maxCurrentRaw = CurrentSensor.MaxCurrentRaw[this.hub.type]; + if (maxCurrentRaw === undefined) { + maxCurrentRaw = CurrentSensor.MaxCurrentRaw[Consts.HubType.UNKNOWN]; + } + const current = message.readUInt16LE(4) * maxCurrentValue / maxCurrentRaw; + /** + * Emits when a current change is detected. + * @event CurrentSensor#current + * @param {number} current + */ + this.emit("current", current); } - let maxCurrentRaw = CurrentSensor.MaxCurrentRaw[this.hub.type]; - if (maxCurrentRaw === undefined) { - maxCurrentRaw = CurrentSensor.MaxCurrentRaw[Consts.HubType.UNKNOWN]; - } - const current = message.readUInt16LE(4) * maxCurrentValue / maxCurrentRaw; - /** - * Emits when a current change is detected. - * @event CurrentSensor#current - * @param {number} current - */ - this.emit("current", current); break; } } diff --git a/src/devices/hubled.ts b/src/devices/hubled.ts index 6aee4e3..807ba1f 100644 --- a/src/devices/hubled.ts +++ b/src/devices/hubled.ts @@ -23,8 +23,13 @@ export class HubLED extends Device { if (typeof color === "boolean") { color = 0; } - this.subscribe(HubLED.Mode.COLOR); - this.writeDirect(0x00, Buffer.from([color])); + if (this.isWeDo2SmartHub) { + this.send(Buffer.from([0x06, 0x17, 0x01, 0x01]), Consts.BLECharacteristic.WEDO2_PORT_TYPE_WRITE); + this.send(Buffer.from([0x06, 0x04, 0x01, color]), Consts.BLECharacteristic.WEDO2_MOTOR_VALUE_WRITE); + } else { + this.subscribe(HubLED.Mode.COLOR); + this.writeDirect(0x00, Buffer.from([color])); + } return resolve(); }); } @@ -40,8 +45,13 @@ export class HubLED extends Device { */ public setRGB (red: number, green: number, blue: number) { return new Promise((resolve, reject) => { - this.subscribe(HubLED.Mode.RGB); - this.writeDirect(0x01, Buffer.from([red, green, blue])); + if (this.isWeDo2SmartHub) { + this.send(Buffer.from([0x06, 0x17, 0x01, 0x02]), Consts.BLECharacteristic.WEDO2_PORT_TYPE_WRITE); + this.send(Buffer.from([0x06, 0x04, 0x03, red, green, blue]), Consts.BLECharacteristic.WEDO2_MOTOR_VALUE_WRITE); + } else { + this.subscribe(HubLED.Mode.RGB); + this.writeDirect(0x01, Buffer.from([red, green, blue])); + } return resolve(); }); } diff --git a/src/devices/piezobuzzer.ts b/src/devices/piezobuzzer.ts new file mode 100644 index 0000000..4c7eb02 --- /dev/null +++ b/src/devices/piezobuzzer.ts @@ -0,0 +1,33 @@ +import { Device } from "./device"; + +import { IDeviceInterface } from "../interfaces"; + +import * as Consts from "../consts"; + +export class PiezoBuzzer extends Device { + + + constructor (hub: IDeviceInterface, portId: number) { + super(hub, portId, {}, Consts.DeviceType.PIEZO_BUZZER); + } + + + /** + * Play a tone on the Hub's in-built buzzer + * @method PiezoBuzzer#playTone + * @param {number} frequency + * @param {number} time How long the tone should play for (in milliseconds). + * @returns {Promise} Resolved upon successful completion of command (ie. once the tone has finished playing). + */ + public playTone (frequency: number, time: number) { + return new Promise((resolve) => { + const data = Buffer.from([0x05, 0x02, 0x04, 0x00, 0x00, 0x00, 0x00]); + data.writeUInt16LE(frequency, 3); + data.writeUInt16LE(time, 5); + this.send(data, Consts.BLECharacteristic.WEDO2_MOTOR_VALUE_WRITE); + global.setTimeout(resolve, time); + }); + } + + +} diff --git a/src/devices/voltagesensor.ts b/src/devices/voltagesensor.ts index aadf7c5..45ecc91 100644 --- a/src/devices/voltagesensor.ts +++ b/src/devices/voltagesensor.ts @@ -15,21 +15,26 @@ export class VoltageSensor extends Device { switch (mode) { case VoltageSensor.Mode.VOLTAGE: - let maxVoltageValue = VoltageSensor.MaxVoltageValue[this.hub.type]; - if (maxVoltageValue === undefined) { - maxVoltageValue = VoltageSensor.MaxVoltageValue[Consts.HubType.UNKNOWN]; + if (this.isWeDo2SmartHub) { + const voltage = message.readInt16LE(2) / 40; + this.emit("voltage", voltage); + } else { + let maxVoltageValue = VoltageSensor.MaxVoltageValue[this.hub.type]; + if (maxVoltageValue === undefined) { + maxVoltageValue = VoltageSensor.MaxVoltageValue[Consts.HubType.UNKNOWN]; + } + let maxVoltageRaw = VoltageSensor.MaxVoltageRaw[this.hub.type]; + if (maxVoltageRaw === undefined) { + maxVoltageRaw = VoltageSensor.MaxVoltageRaw[Consts.HubType.UNKNOWN]; + } + const voltage = message.readUInt16LE(4) * maxVoltageValue / maxVoltageRaw; + /** + * Emits when a voltage change is detected. + * @event VoltageSensor#voltage + * @param {number} voltage + */ + this.emit("voltage", voltage); } - let maxVoltageRaw = VoltageSensor.MaxVoltageRaw[this.hub.type]; - if (maxVoltageRaw === undefined) { - maxVoltageRaw = VoltageSensor.MaxVoltageRaw[Consts.HubType.UNKNOWN]; - } - const voltage = message.readUInt16LE(4) * maxVoltageValue / maxVoltageRaw; - /** - * Emits when a voltage change is detected. - * @event VoltageSensor#voltage - * @param {number} voltage - */ - this.emit("voltage", voltage); break; } } diff --git a/src/hubs/basehub.ts b/src/hubs/basehub.ts index dfa7895..fe2f4d3 100644 --- a/src/hubs/basehub.ts +++ b/src/hubs/basehub.ts @@ -19,6 +19,7 @@ import { MoveHubMediumLinearMotor } from "../devices/movehubmediumlinearmotor"; import { MoveHubTiltSensor } from "../devices/movehubtiltsensor"; import { RemoteControlButton } from "../devices/remotecontrolbutton"; import { SimpleMediumLinearMotor } from "../devices/simplemediumlinearmotor"; +import { PiezoBuzzer } from "../devices/piezobuzzer"; import { TechnicLargeLinearMotor } from "../devices/techniclargelinearmotor"; import { TechnicMediumHubAccelerometerSensor } from "../devices/technicmediumhubaccelerometersensor"; import { TechnicMediumHubGyroSensor } from "../devices/technicmediumhubgyrosensor"; @@ -336,6 +337,9 @@ export class BaseHub extends EventEmitter { case Consts.DeviceType.MOVE_HUB_MEDIUM_LINEAR_MOTOR: device = new MoveHubMediumLinearMotor(this, portId); break; + case Consts.DeviceType.PIEZO_BUZZER: + device = new PiezoBuzzer(this, portId); + break; case Consts.DeviceType.MOTION_SENSOR: device = new MotionSensor(this, portId); break; diff --git a/src/hubs/lpf2hub.ts b/src/hubs/lpf2hub.ts index 703f22e..9d27ae7 100644 --- a/src/hubs/lpf2hub.ts +++ b/src/hubs/lpf2hub.ts @@ -230,7 +230,11 @@ export class LPF2Hub extends BaseHub { // Battery level reports } else if (message[3] === 0x06) { - this._batteryLevel = message[5]; + const batteryLevel = message[5]; + if (batteryLevel !== this._batteryLevel) { + this._batteryLevel = batteryLevel; + this.emit("batteryLevel", batteryLevel); + } } } diff --git a/src/hubs/wedo2smarthub.ts b/src/hubs/wedo2smarthub.ts index c6791da..74f5868 100644 --- a/src/hubs/wedo2smarthub.ts +++ b/src/hubs/wedo2smarthub.ts @@ -9,6 +9,7 @@ import * as Consts from "../consts"; import { isWebBluetooth } from "../utils"; import Debug = require("debug"); +import { HubLED } from "../devices/hubled"; const debug = Debug("wedo2smarthub"); @@ -53,8 +54,6 @@ export class WeDo2SmartHub extends BaseHub { await this._bleDevice.discoverCharacteristicsForService("battery_service"); await this._bleDevice.discoverCharacteristicsForService("device_information"); } - this.subscribe(0x03, 0x15, 0x00); // Activate voltage reports - this.subscribe(0x04, 0x14, 0x00); // Activate current reports debug("Connect completed"); this.emit("connect"); resolve(); @@ -129,85 +128,6 @@ export class WeDo2SmartHub extends BaseHub { } - /** - * Set the color of the LED on the Hub via a color value. - * @method WeDo2SmartHub#setLEDColor - * @param {Color} color - * @returns {Promise} Resolved upon successful issuance of command. - */ - public setLEDColor (color: number | boolean) { - return new Promise((resolve, reject) => { - let data = Buffer.from([0x06, 0x17, 0x01, 0x01]); - this.send(data, Consts.BLECharacteristic.WEDO2_PORT_TYPE_WRITE); - if (typeof color === "boolean") { - color = 0; - } - data = Buffer.from([0x06, 0x04, 0x01, color]); - this.send(data, Consts.BLECharacteristic.WEDO2_MOTOR_VALUE_WRITE); - return resolve(); - }); - } - - - /** - * Set the color of the LED on the Hub via RGB values. - * @method WeDo2SmartHub#setLEDRGB - * @param {number} red - * @param {number} green - * @param {number} blue - * @returns {Promise} Resolved upon successful issuance of command. - */ - public setLEDRGB (red: number, green: number, blue: number) { - return new Promise((resolve, reject) => { - let data = Buffer.from([0x06, 0x17, 0x01, 0x02]); - this.send(data, Consts.BLECharacteristic.WEDO2_PORT_TYPE_WRITE); - data = Buffer.from([0x06, 0x04, 0x03, red, green, blue]); - this.send(data, Consts.BLECharacteristic.WEDO2_MOTOR_VALUE_WRITE); - return resolve(); - }); - } - - - // /** - // * Ramp the motor speed on a given port. - // * @method WeDo2SmartHub#rampMotorSpeed - // * @param {string} port - // * @param {number} fromSpeed For forward, a value between 1 - 100 should be set. For reverse, a value between -1 to -100. Stop is 0. - // * @param {number} toSpeed For forward, a value between 1 - 100 should be set. For reverse, a value between -1 to -100. Stop is 0. - // * @param {number} time How long the ramp should last (in milliseconds). - // * @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, portObj) - // .on("changeSpeed", (speed) => { - // this.setMotorSpeed(port, speed, true); - // }) - // .on("finished", resolve); - // }); - // } - - - /** - * Play a tone on the Hub's in-built buzzer - * @method WeDo2SmartHub#playTone - * @param {number} frequency - * @param {number} time How long the tone should play for (in milliseconds). - * @returns {Promise} Resolved upon successful completion of command (ie. once the tone has finished playing). - */ - public playTone (frequency: number, time: number) { - return new Promise((resolve, reject) => { - const data = Buffer.from([0x05, 0x02, 0x04, 0x00, 0x00, 0x00, 0x00]); - data.writeUInt16LE(frequency, 3); - data.writeUInt16LE(time, 5); - this.send(data, Consts.BLECharacteristic.WEDO2_MOTOR_VALUE_WRITE); - global.setTimeout(resolve, time); - }); - } - - public send (message: Buffer, uuid: string, callback?: () => void) { if (debug.enabled) { debug(`Sent Message (${this._getCharacteristicNameFromUUID(uuid)})`, message); @@ -245,7 +165,11 @@ export class WeDo2SmartHub extends BaseHub { private _parseBatteryMessage (data: Buffer) { debug("Received Message (WEDO2_BATTERY)", data); - this._batteryLevel = data[0]; + const batteryLevel = data[0]; + if (batteryLevel !== this._batteryLevel) { + this._batteryLevel = batteryLevel; + this.emit("batteryLevel", batteryLevel); + } } @@ -299,52 +223,6 @@ export class WeDo2SmartHub extends BaseHub { device.receive(message); } - // if (data[0] === 0x01) { - // /** - // * Emits when a button is pressed. - // * @event WeDo2SmartHub#button - // * @param {string} button - // * @param {ButtonState} state - // */ - // this.emit("button", "GREEN", Consts.ButtonState.PRESSED); - // return; - // } else if (data[0] === 0x00) { - // this.emit("button", "GREEN", Consts.ButtonState.RELEASED); - // return; - // } - - // // Voltage - // if (data[1] === 0x03) { - // const voltage = data.readInt16LE(2); - // this._voltage = voltage / 40; - // // Current - // } else if (data[1] === 0x04) { - // const current = data.readInt16LE(2); - // this._current = current / 1000; - // } - - // const port = this._getPortForPortNumber(data[1]); - - // if (!port) { - // return; - // } - - // if (port && port.connected) { - // switch (port.type) { - // case Consts.DeviceType.COLOR_DISTANCE_SENSOR: { - // const distance = data[2]; - // /** - // * Emits when a color sensor is activated. - // * @event WeDo2SmartHub#color - // * @param {string} port - // * @param {Color} color - // */ - // this.emit("color", port.id, distance); - // break; - // } - // } - // } - } diff --git a/src/index-browser.ts b/src/index-browser.ts index 622f4e0..284b682 100644 --- a/src/index-browser.ts +++ b/src/index-browser.ts @@ -23,6 +23,7 @@ import { MediumLinearMotor } from "./devices/mediumlinearmotor"; import { MotionSensor } from "./devices/motionsensor"; import { MoveHubMediumLinearMotor } from "./devices/movehubmediumlinearmotor"; import { MoveHubTiltSensor } from "./devices/movehubtiltsensor"; +import { PiezoBuzzer } from "./devices/piezobuzzer"; import { RemoteControlButton } from "./devices/remotecontrolbutton"; import { SimpleMediumLinearMotor } from "./devices/simplemediumlinearmotor"; import { TechnicLargeLinearMotor } from "./devices/techniclargelinearmotor"; @@ -59,6 +60,7 @@ window.PoweredUP = { MoveHub, MoveHubMediumLinearMotor, MoveHubTiltSensor, + PiezoBuzzer, RemoteControlButton, SimpleMediumLinearMotor, TechnicMediumHubAccelerometerSensor, diff --git a/src/index-node.ts b/src/index-node.ts index 54d5a1b..edf4f85 100644 --- a/src/index-node.ts +++ b/src/index-node.ts @@ -23,6 +23,7 @@ import { MediumLinearMotor } from "./devices/mediumlinearmotor"; import { MotionSensor } from "./devices/motionsensor"; import { MoveHubMediumLinearMotor } from "./devices/movehubmediumlinearmotor"; import { MoveHubTiltSensor } from "./devices/movehubtiltsensor"; +import { PiezoBuzzer } from "./devices/piezobuzzer"; import { RemoteControlButton } from "./devices/remotecontrolbutton"; import { SimpleMediumLinearMotor } from "./devices/simplemediumlinearmotor"; import { TechnicLargeLinearMotor } from "./devices/techniclargelinearmotor"; @@ -59,6 +60,7 @@ export { MoveHub, MoveHubMediumLinearMotor, MoveHubTiltSensor, + PiezoBuzzer, RemoteControlButton, SimpleMediumLinearMotor, TechnicMediumHubAccelerometerSensor,