First pass at TypeScript version
This commit is contained in:
parent
f840adb5f0
commit
40a14a602f
2
.gitignore
vendored
2
.gitignore
vendored
@ -1 +1,3 @@
|
||||
node_modules/
|
||||
dist/
|
||||
|
||||
|
@ -1,18 +1,33 @@
|
||||
const debug = require("debug")("lpf2"),
|
||||
EventEmitter = require("events").EventEmitter;
|
||||
import { Peripheral } from "noble";
|
||||
|
||||
const Hub = require("./hub.js"),
|
||||
Port = require("./port.js"),
|
||||
Consts = require("./consts.js");
|
||||
import { Hub } from "./hub.js";
|
||||
import { Port } from "./port.js";
|
||||
|
||||
import Debug = require("debug");
|
||||
const debug = Debug("lpf2");
|
||||
import { Consts } from "./consts.js";
|
||||
|
||||
|
||||
class BoostHub extends Hub {
|
||||
/**
|
||||
* @class BoostHub
|
||||
* @extends Hub
|
||||
*/
|
||||
export class BoostHub extends Hub {
|
||||
|
||||
|
||||
constructor (peripheral, autoSubscribe) {
|
||||
public static IsBoostHub (peripheral: Peripheral) {
|
||||
return (peripheral.advertisement.localName === Consts.BLE.Name.BOOST_MOVE_HUB_NAME && peripheral.advertisement.serviceUuids.indexOf(Consts.BLE.Services.BOOST_MOVE_HUB) >= 0);
|
||||
}
|
||||
|
||||
|
||||
private _lastTiltX: number = 0;
|
||||
private _lastTiltY: number = 0;
|
||||
|
||||
|
||||
constructor (peripheral: Peripheral, autoSubscribe: boolean = true) {
|
||||
super(peripheral, autoSubscribe);
|
||||
this.type = Consts.Hubs.BOOST_MOVE_HUB;
|
||||
this.ports = {
|
||||
this._ports = {
|
||||
"A": new Port("A", 55),
|
||||
"B": new Port("B", 56),
|
||||
"AB": new Port("AB", 57),
|
||||
@ -20,18 +35,11 @@ class BoostHub extends Hub {
|
||||
"C": new Port("C", 1),
|
||||
"D": new Port("D", 2)
|
||||
};
|
||||
this._lastTiltX = 0;
|
||||
this._lastTiltY = 0;
|
||||
debug("Discovered Boost Move Hub");
|
||||
}
|
||||
|
||||
|
||||
static isBoostHub (peripheral) {
|
||||
return (peripheral.advertisement.localName === Consts.BLE.Name.BOOST_MOVE_HUB_NAME && peripheral.advertisement.serviceUuids.indexOf(Consts.BLE.Services.BOOST_MOVE_HUB) >= 0);
|
||||
}
|
||||
|
||||
|
||||
connect (callback) {
|
||||
public connect (callback: () => void) {
|
||||
debug("Connecting to Boost Move Hub");
|
||||
super.connect(() => {
|
||||
const characteristic = this._characteristics[Consts.BLE.Characteristics.Boost.ALL];
|
||||
@ -41,11 +49,16 @@ class BoostHub extends Hub {
|
||||
if (callback) {
|
||||
callback();
|
||||
}
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
setLEDColor (color) {
|
||||
/**
|
||||
* Set the color of the LED on the Hub via a color value.
|
||||
* @method BoostHub#setLEDColor
|
||||
* @param {number} color - A number representing one of the LED color consts.
|
||||
*/
|
||||
public setLEDColor (color: number | boolean) {
|
||||
const characteristic = this._characteristics[Consts.BLE.Characteristics.Boost.ALL];
|
||||
if (characteristic) {
|
||||
let data = Buffer.from([0x05, 0x00, 0x01, 0x02, 0x02]);
|
||||
@ -70,25 +83,39 @@ class BoostHub extends Hub {
|
||||
// }
|
||||
|
||||
|
||||
setMotorSpeed (port, speed, time) {
|
||||
/**
|
||||
* Set the motor speed on a given port.
|
||||
* @method BoostHub#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} [time] - How long to activate the motor for (in milliseconds). Leave empty to turn the motor on indefinitely.
|
||||
*/
|
||||
public setMotorSpeed (port: string, speed: number, time: number) {
|
||||
const characteristic = this._characteristics[Consts.BLE.Characteristics.Boost.ALL];
|
||||
if (characteristic) {
|
||||
if (time) {
|
||||
const data = Buffer.from([0x0c, 0x00, 0x81, this.ports[port].value, 0x11, 0x09, 0x00, 0x00, speed, 0x64, 0x7f, 0x03]);
|
||||
const data = Buffer.from([0x0c, 0x00, 0x81, this._ports[port].value, 0x11, 0x09, 0x00, 0x00, speed, 0x64, 0x7f, 0x03]);
|
||||
data.writeUInt16LE(time > 65535 ? 65535 : time, 6);
|
||||
characteristic.write(data);
|
||||
} else {
|
||||
const data = Buffer.from([0x0a, 0x00, 0x81, this.ports[port].value, 0x11, 0x01, speed, 0x64, 0x7f, 0x03]);
|
||||
const data = Buffer.from([0x0a, 0x00, 0x81, this._ports[port].value, 0x11, 0x01, speed, 0x64, 0x7f, 0x03]);
|
||||
characteristic.write(data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
setMotorAngle (port, angle, speed = 100) {
|
||||
/**
|
||||
* Rotate a motor by a given angle.
|
||||
* @method BoostHub#setMotorAngle
|
||||
* @param {string} port
|
||||
* @param {number} angle - How much the motor should be rotated (in degrees).
|
||||
* @param {number} [speed=100] - How fast the motor should be rotated.
|
||||
*/
|
||||
public setMotorAngle (port: string, angle: number, speed: number = 100) {
|
||||
const characteristic = this._characteristics[Consts.BLE.Characteristics.Boost.ALL];
|
||||
if (characteristic) {
|
||||
const data = Buffer.from([0x0e, 0x00, 0x81, this.ports[port].value, 0x11, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x64, 0x7f, 0x03]);;
|
||||
const data = Buffer.from([0x0e, 0x00, 0x81, this._ports[port].value, 0x11, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x64, 0x7f, 0x03]);
|
||||
data.writeUInt32LE(angle, 6);
|
||||
data.writeInt8(speed, 10);
|
||||
characteristic.write(data);
|
||||
@ -96,22 +123,38 @@ class BoostHub extends Hub {
|
||||
}
|
||||
|
||||
|
||||
_getPortForPortNumber (num) {
|
||||
protected _activatePortDevice (port: number, type: number, mode: number, format: number, callback: () => void) {
|
||||
const characteristic = this._characteristics[Consts.BLE.Characteristics.Boost.ALL];
|
||||
if (characteristic) {
|
||||
characteristic.write(Buffer.from([0x0a, 0x00, 0x41, port, mode, 0x01, 0x00, 0x00, 0x00, 0x01]), callback);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected _deactivatePortDevice (port: number, type: number, mode: number, format: number, callback: () => void) {
|
||||
const characteristic = this._characteristics[Consts.BLE.Characteristics.Boost.ALL];
|
||||
if (characteristic) {
|
||||
characteristic.write(Buffer.from([0x0a, 0x00, 0x41, port, mode, 0x01, 0x00, 0x00, 0x00, 0x00]), callback);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private _getPortForPortNumber (num: number) {
|
||||
|
||||
let port = null;
|
||||
|
||||
if (num === 1) {
|
||||
port = this.ports["C"];
|
||||
port = this._ports["C"];
|
||||
} else if (num === 2) {
|
||||
port = this.ports["D"];
|
||||
port = this._ports["D"];
|
||||
} else if (num === 55) {
|
||||
port = this.ports["A"];
|
||||
port = this._ports["A"];
|
||||
} else if (num === 56) {
|
||||
port = this.ports["B"];
|
||||
port = this._ports["B"];
|
||||
} else if (num === 57) {
|
||||
port = this.ports["AB"];
|
||||
port = this._ports["AB"];
|
||||
} else if (num === 58) {
|
||||
port = this.ports["TILT"];
|
||||
port = this._ports["TILT"];
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
@ -121,7 +164,7 @@ class BoostHub extends Hub {
|
||||
}
|
||||
|
||||
|
||||
_parseMessage (data) {
|
||||
private _parseMessage (data: Buffer) {
|
||||
|
||||
switch (data[2]) {
|
||||
case 0x01:
|
||||
@ -147,10 +190,15 @@ class BoostHub extends Hub {
|
||||
}
|
||||
|
||||
|
||||
_parseDeviceInfo (data) {
|
||||
private _parseDeviceInfo (data: Buffer) {
|
||||
|
||||
if (data[3] === 2) {
|
||||
if (data[5] === 1) {
|
||||
/**
|
||||
* Emits when a button is pressed.
|
||||
* @event BoostHub#button
|
||||
* @param {number} state - A number representing one of the button state consts.
|
||||
*/
|
||||
this.emit("button", Consts.Button.PRESSED);
|
||||
return;
|
||||
} else if (data[5] === 0) {
|
||||
@ -162,9 +210,9 @@ class BoostHub extends Hub {
|
||||
}
|
||||
|
||||
|
||||
_parsePortMessage (data) {
|
||||
private _parsePortMessage (data: Buffer) {
|
||||
|
||||
let port = this._getPortForPortNumber(data[3]);
|
||||
const port = this._getPortForPortNumber(data[3]);
|
||||
|
||||
if (!port) {
|
||||
return;
|
||||
@ -176,9 +224,9 @@ class BoostHub extends Hub {
|
||||
}
|
||||
|
||||
|
||||
_parsePortAction (data) {
|
||||
private _parsePortAction (data: Buffer) {
|
||||
|
||||
let port = this._getPortForPortNumber(data[3]);
|
||||
const port = this._getPortForPortNumber(data[3]);
|
||||
|
||||
if (!port) {
|
||||
return;
|
||||
@ -189,25 +237,9 @@ class BoostHub extends Hub {
|
||||
}
|
||||
|
||||
|
||||
_activatePortDevice (port, type, mode, format, callback) {
|
||||
const characteristic = this._characteristics[Consts.BLE.Characteristics.Boost.ALL];
|
||||
if (characteristic) {
|
||||
characteristic.write(Buffer.from([0x0a, 0x00, 0x41, port, mode, 0x01, 0x00, 0x00, 0x00, 0x01]), callback);
|
||||
}
|
||||
}
|
||||
private _parseSensorMessage (data: Buffer) {
|
||||
|
||||
|
||||
_deactivatePortDevice (port, type, mode, format, callback) {
|
||||
const characteristic = this._characteristics[Consts.BLE.Characteristics.Boost.ALL];
|
||||
if (characteristic) {
|
||||
characteristic.write(Buffer.from([0x0a, 0x00, 0x41, port, mode, 0x01, 0x00, 0x00, 0x00, 0x00]), callback);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
_parseSensorMessage (data) {
|
||||
|
||||
let port = this._getPortForPortNumber(data[3]);
|
||||
const port = this._getPortForPortNumber(data[3]);
|
||||
|
||||
if (!port) {
|
||||
return;
|
||||
@ -221,16 +253,28 @@ class BoostHub extends Hub {
|
||||
if (data[5] === 1) {
|
||||
distance = data[4] + 255;
|
||||
}
|
||||
/**
|
||||
* Emits when a distance sensor is activated.
|
||||
* @event BoostHub#distance
|
||||
* @param {string} port
|
||||
* @param {number} distance - Distance, in millimeters.
|
||||
*/
|
||||
this.emit("distance", port.id, distance * 10);
|
||||
break;
|
||||
}
|
||||
case Consts.Devices.BOOST_DISTANCE:
|
||||
{
|
||||
|
||||
/**
|
||||
* Emits when a color sensor is activated.
|
||||
* @event BoostHub#color
|
||||
* @param {string} port
|
||||
* @param {number} color - A number representing one of the LED color consts.
|
||||
*/
|
||||
this.emit("color", port.id, data[4]);
|
||||
|
||||
let distance = data[5],
|
||||
partial = data[7];
|
||||
let distance = data[5];
|
||||
const partial = data[7];
|
||||
|
||||
if (partial > 0) {
|
||||
distance += 1 / partial;
|
||||
@ -241,23 +285,36 @@ class BoostHub extends Hub {
|
||||
}
|
||||
case Consts.Devices.WEDO2_TILT:
|
||||
{
|
||||
let tiltX = data[4] > 160 ? data[4] - 255 : data[4] - (data[4] * 2);
|
||||
let tiltY = data[5] > 160 ? 255 - data[5] : data[5] - (data[5] * 2);
|
||||
const tiltX = data[4] > 160 ? data[4] - 255 : data[4] - (data[4] * 2);
|
||||
const tiltY = data[5] > 160 ? 255 - data[5] : data[5] - (data[5] * 2);
|
||||
this._lastTiltX = tiltX;
|
||||
this._lastTiltY = tiltY;
|
||||
/**
|
||||
* Emits when a tilt sensor is activated.
|
||||
* @event BoostHub#tilt
|
||||
* @param {string} port
|
||||
* @param {number} x
|
||||
* @param {number} y
|
||||
*/
|
||||
this.emit("tilt", port.id, this._lastTiltX, this._lastTiltY);
|
||||
break;
|
||||
}
|
||||
case Consts.Devices.BOOST_INTERACTIVE_MOTOR:
|
||||
{
|
||||
const rotation = data.readInt32LE(2);
|
||||
/**
|
||||
* Emits when a rotation sensor is activated.
|
||||
* @event BoostHub#rotate
|
||||
* @param {string} port
|
||||
* @param {number} rotation
|
||||
*/
|
||||
this.emit("rotate", port.id, rotation);
|
||||
break;
|
||||
}
|
||||
case Consts.Devices.BOOST_TILT:
|
||||
{
|
||||
let tiltX = data[4] > 160 ? data[4] - 255 : data[4];
|
||||
let tiltY = data[5] > 160 ? 255 - data[5] : data[5] - (data[5] * 2);
|
||||
const tiltX = data[4] > 160 ? data[4] - 255 : data[4];
|
||||
const tiltY = data[5] > 160 ? 255 - data[5] : data[5] - (data[5] * 2);
|
||||
this.emit("tilt", port.id, tiltX, tiltY);
|
||||
break;
|
||||
}
|
||||
@ -268,6 +325,3 @@ class BoostHub extends Hub {
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
module.exports = BoostHub;
|
@ -1,4 +1,6 @@
|
||||
const Consts = {
|
||||
/* tslint:disable */
|
||||
|
||||
export const Consts = {
|
||||
Hubs: {
|
||||
UNKNOWN: 0,
|
||||
WEDO2_SMART_HUB: 1,
|
||||
@ -64,5 +66,3 @@ const Consts = {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = Consts;
|
152
hub.js
152
hub.js
@ -1,152 +0,0 @@
|
||||
const debug = require("debug")("lpf2"),
|
||||
EventEmitter = require("events").EventEmitter;
|
||||
|
||||
const Port = require("./port.js"),
|
||||
Consts = require("./consts.js");
|
||||
|
||||
|
||||
class Hub extends EventEmitter {
|
||||
|
||||
|
||||
constructor (peripheral, autoSubscribe) {
|
||||
super();
|
||||
this.autoSubscribe = !!autoSubscribe;
|
||||
this._peripheral = peripheral;
|
||||
this._characteristics = {};
|
||||
this._batteryLevel = 100;
|
||||
this._rssi = -100; // Initialize as -100 - no signal
|
||||
this._ports = {};
|
||||
this.type = Consts.Hubs.UNKNOWN;
|
||||
this.uuid = peripheral.uuid;
|
||||
}
|
||||
|
||||
|
||||
connect (callback) {
|
||||
|
||||
const self = this;
|
||||
|
||||
this._peripheral.connect((err) => {
|
||||
|
||||
this._rssi = this._peripheral.rssi;
|
||||
|
||||
let rssiUpdateInterval = setInterval(() => {
|
||||
this._peripheral.updateRssi((err, rssi) => {
|
||||
if (!err) {
|
||||
if (this._rssi != rssi) {
|
||||
this._rssi = rssi;
|
||||
debug(`RSSI change ${rssi}`)
|
||||
self.emit("rssiChange", rssi);
|
||||
}
|
||||
}
|
||||
});
|
||||
}, 2000);
|
||||
|
||||
self._peripheral.on("disconnect", () => {
|
||||
clearInterval(rssiUpdateInterval);
|
||||
});
|
||||
|
||||
self._peripheral.discoverServices([], (err, services) => {
|
||||
|
||||
if (err) {
|
||||
this.emit("error", err);
|
||||
return;
|
||||
}
|
||||
|
||||
debug("Service/characteristic discovery started");
|
||||
|
||||
const servicePromises = [];
|
||||
|
||||
services.forEach((service) => {
|
||||
|
||||
servicePromises.push(new Promise((resolve, reject) => {
|
||||
|
||||
service.discoverCharacteristics([], (err, characteristics) => {
|
||||
characteristics.forEach((characteristic) => {
|
||||
this._characteristics[characteristic.uuid] = characteristic;
|
||||
});
|
||||
return resolve();
|
||||
});
|
||||
|
||||
}));
|
||||
|
||||
});
|
||||
|
||||
Promise.all(servicePromises).then(() => {
|
||||
debug("Service/characteristic discovery finished");
|
||||
if (callback) {
|
||||
callback();
|
||||
}
|
||||
})
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
||||
subscribe (port, mode = false) {
|
||||
if (!mode) {
|
||||
mode = this._getModeForDeviceType(this.ports[port].type);
|
||||
}
|
||||
this._activatePortDevice(this.ports[port].value, this.ports[port].type, mode, 0x00);
|
||||
}
|
||||
|
||||
|
||||
unsubscribe (port, mode = false) {
|
||||
if (!mode) {
|
||||
mode = this._getModeForDeviceType(this.ports[port].type);
|
||||
}
|
||||
this._deactivatePortDevice(this.ports[port].value, this.ports[port].type, mode, 0x00);
|
||||
}
|
||||
|
||||
|
||||
_getModeForDeviceType (type) {
|
||||
switch (type) {
|
||||
case Consts.Devices.BASIC_MOTOR:
|
||||
return 0x02;
|
||||
case Consts.Devices.BOOST_INTERACTIVE_MOTOR:
|
||||
return 0x02;
|
||||
case Consts.Devices.BOOST_MOVE_HUB_MOTOR:
|
||||
return 0x02;
|
||||
case Consts.Devices.BOOST_DISTANCE:
|
||||
return (this.type == Consts.Hubs.WEDO2_SMART_HUB ? 0x00 : 0x08);
|
||||
case Consts.Devices.BOOST_TILT:
|
||||
return 0x04;
|
||||
default:
|
||||
return 0x00;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
_subscribeToCharacteristic (characteristic, callback) {
|
||||
characteristic.on("data", (data, isNotification) => {
|
||||
return callback(data);
|
||||
});
|
||||
characteristic.subscribe((err) => {
|
||||
if (err) {
|
||||
this.emit("error", err);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
_registerDeviceAttachment (port, type) {
|
||||
|
||||
if (port.connected) {
|
||||
port.type = type;
|
||||
if (this.autoSubscribe) {
|
||||
this._activatePortDevice(port.value, type, this._getModeForDeviceType(type), 0x00);
|
||||
}
|
||||
} else {
|
||||
port.type = null;
|
||||
debug(`Port ${port.id} disconnected`);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
module.exports = Hub;
|
192
hub.ts
Normal file
192
hub.ts
Normal file
@ -0,0 +1,192 @@
|
||||
import { EventEmitter } from "events";
|
||||
|
||||
import { Characteristic, Peripheral, Service } from "noble";
|
||||
import { Port } from "./port";
|
||||
|
||||
import Debug = require("debug");
|
||||
const debug = Debug("lpf2");
|
||||
import { Consts } from "./consts.js";
|
||||
|
||||
|
||||
/**
|
||||
* @class Hub
|
||||
* @extends EventEmitter
|
||||
*/
|
||||
export class Hub extends EventEmitter {
|
||||
|
||||
|
||||
public autoSubscribe: boolean;
|
||||
public type: number = Consts.Hubs.UNKNOWN;
|
||||
public uuid: string;
|
||||
|
||||
protected _ports: any = {};
|
||||
protected _characteristics: any = {};
|
||||
|
||||
private _peripheral: Peripheral;
|
||||
private _rssi: number = -100;
|
||||
private _batteryLevel: number = 100;
|
||||
|
||||
constructor (peripheral: Peripheral, autoSubscribe: boolean = true) {
|
||||
super();
|
||||
this.autoSubscribe = !!autoSubscribe;
|
||||
this._peripheral = peripheral;
|
||||
this.uuid = peripheral.uuid;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Connect to the Hub.
|
||||
* @method Hub#connect
|
||||
* @param {function} [callback]
|
||||
*/
|
||||
public connect (callback: () => void) {
|
||||
|
||||
const self = this;
|
||||
|
||||
this._peripheral.connect((err: string) => {
|
||||
|
||||
this._rssi = this._peripheral.rssi;
|
||||
|
||||
const rssiUpdateInterval = setInterval(() => {
|
||||
this._peripheral.updateRssi((err: string, rssi: number) => {
|
||||
if (!err) {
|
||||
if (this._rssi !== rssi) {
|
||||
this._rssi = rssi;
|
||||
debug(`RSSI change ${rssi}`);
|
||||
self.emit("rssiChange", rssi);
|
||||
}
|
||||
}
|
||||
});
|
||||
}, 2000);
|
||||
|
||||
self._peripheral.on("disconnect", () => {
|
||||
clearInterval(rssiUpdateInterval);
|
||||
this.emit("disconnect");
|
||||
});
|
||||
|
||||
self._peripheral.discoverServices([], (err: string, services: Service[]) => {
|
||||
|
||||
if (err) {
|
||||
this.emit("error", err);
|
||||
return;
|
||||
}
|
||||
|
||||
debug("Service/characteristic discovery started");
|
||||
|
||||
const servicePromises: Array<Promise<null>> = [];
|
||||
|
||||
services.forEach((service) => {
|
||||
|
||||
servicePromises.push(new Promise((resolve, reject) => {
|
||||
|
||||
service.discoverCharacteristics([], (err, characteristics) => {
|
||||
characteristics.forEach((characteristic) => {
|
||||
this._characteristics[characteristic.uuid] = characteristic;
|
||||
});
|
||||
return resolve();
|
||||
});
|
||||
|
||||
}));
|
||||
|
||||
});
|
||||
|
||||
Promise.all(servicePromises).then(() => {
|
||||
debug("Service/characteristic discovery finished");
|
||||
this.emit("connect");
|
||||
if (callback) {
|
||||
callback();
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Subscribe to sensor notifications on a given port.
|
||||
* @method Hub#subscribe
|
||||
* @param {string} port
|
||||
* @param {number|boolean} [mode=false] - The sensor mode to activate. If no mode is provided, the default for that sensor will be chosen.
|
||||
*/
|
||||
public subscribe (port: string, mode: number | boolean = false, callback?: () => void) {
|
||||
let newMode = 0x00;
|
||||
if (!mode) {
|
||||
newMode = this._getModeForDeviceType(this._ports[port].type);
|
||||
}
|
||||
this._activatePortDevice(this._ports[port].value, this._ports[port].type, newMode, 0x00, callback);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unsubscribe to sensor notifications on a given port.
|
||||
* @method Hub#unsubscribe
|
||||
* @param {string} port
|
||||
*/
|
||||
public unsubscribe (port: string, callback?: () => void) {
|
||||
const mode = this._getModeForDeviceType(this._ports[port].type);
|
||||
this._deactivatePortDevice(this._ports[port].value, this._ports[port].type, mode, 0x00, callback);
|
||||
}
|
||||
|
||||
|
||||
protected _subscribeToCharacteristic (characteristic: Characteristic, callback: (data: Buffer) => void) {
|
||||
characteristic.on("data", (data: Buffer) => {
|
||||
return callback(data);
|
||||
});
|
||||
characteristic.subscribe((err) => {
|
||||
if (err) {
|
||||
this.emit("error", err);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
protected _activatePortDevice (port: number, type: number, mode: number, format: number, callback?: () => void) {
|
||||
if (callback) {
|
||||
callback();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected _deactivatePortDevice (port: number, type: number, mode: number, format: number, callback?: () => void) {
|
||||
if (callback) {
|
||||
callback();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected _registerDeviceAttachment (port: Port, type: number) {
|
||||
|
||||
if (port.connected) {
|
||||
port.type = type;
|
||||
if (this.autoSubscribe) {
|
||||
this._activatePortDevice(port.value, type, this._getModeForDeviceType(type), 0x00);
|
||||
}
|
||||
} else {
|
||||
port.type = null;
|
||||
debug(`Port ${port.id} disconnected`);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
private _getModeForDeviceType (type: number) {
|
||||
switch (type) {
|
||||
case Consts.Devices.BASIC_MOTOR:
|
||||
return 0x02;
|
||||
case Consts.Devices.BOOST_INTERACTIVE_MOTOR:
|
||||
return 0x02;
|
||||
case Consts.Devices.BOOST_MOVE_HUB_MOTOR:
|
||||
return 0x02;
|
||||
case Consts.Devices.BOOST_DISTANCE:
|
||||
return (this.type === Consts.Hubs.WEDO2_SMART_HUB ? 0x00 : 0x08);
|
||||
case Consts.Devices.BOOST_TILT:
|
||||
return 0x04;
|
||||
default:
|
||||
return 0x00;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -1,15 +1,19 @@
|
||||
const noble = require("noble"),
|
||||
debug = require("debug")("lpf2"),
|
||||
EventEmitter = require("events").EventEmitter;
|
||||
import { Peripheral } from "noble";
|
||||
|
||||
const WeDo2Hub = require("./wedo2hub.js"),
|
||||
BoostHub = require("./boosthub.js"),
|
||||
Consts = require("./consts.js");
|
||||
import { BoostHub } from "./boosthub";
|
||||
import { Hub } from "./hub";
|
||||
import { WeDo2Hub } from "./wedo2hub";
|
||||
|
||||
let ready = false,
|
||||
wantScan = false;
|
||||
import { EventEmitter} from "events";
|
||||
|
||||
noble.on("stateChange", (state) => {
|
||||
import Debug = require("debug");
|
||||
const debug = Debug("lpf2");
|
||||
import noble = require("noble");
|
||||
|
||||
let ready = false;
|
||||
let wantScan = false;
|
||||
|
||||
noble.on("stateChange", (state: string) => {
|
||||
ready = (state === "poweredOn");
|
||||
if (ready) {
|
||||
if (wantScan) {
|
||||
@ -21,26 +25,38 @@ noble.on("stateChange", (state) => {
|
||||
}
|
||||
});
|
||||
|
||||
class LPF2 extends EventEmitter {
|
||||
/**
|
||||
* @class LPF2
|
||||
* @extends EventEmitter
|
||||
*/
|
||||
export class LPF2 extends EventEmitter {
|
||||
|
||||
|
||||
public autoSubscribe: boolean = true;
|
||||
|
||||
|
||||
private _connectedDevices: any = {};
|
||||
|
||||
|
||||
constructor () {
|
||||
super();
|
||||
this.autoSubscribe = true;
|
||||
this._connectedDevices = {};
|
||||
}
|
||||
|
||||
|
||||
scan () {
|
||||
/**
|
||||
* Begin scanning for LPF2 Hub devices.
|
||||
* @method LPF2#scan
|
||||
*/
|
||||
public scan () {
|
||||
wantScan = true;
|
||||
|
||||
noble.on("discover", (peripheral) => {
|
||||
noble.on("discover", (peripheral: Peripheral) => {
|
||||
|
||||
let hub = null;
|
||||
let hub: Hub;
|
||||
|
||||
if (WeDo2Hub.isWeDo2Hub(peripheral)) {
|
||||
if (WeDo2Hub.IsWeDo2Hub(peripheral)) {
|
||||
hub = new WeDo2Hub(peripheral, this.autoSubscribe);
|
||||
} else if (BoostHub.isBoostHub(peripheral)) {
|
||||
} else if (BoostHub.IsBoostHub(peripheral)) {
|
||||
hub = new BoostHub(peripheral, this.autoSubscribe);
|
||||
} else {
|
||||
return;
|
||||
@ -50,12 +66,12 @@ class LPF2 extends EventEmitter {
|
||||
noble.stopScanning();
|
||||
noble.startScanning();
|
||||
|
||||
hub._peripheral.on("connect", () => {
|
||||
hub.on("connect", () => {
|
||||
debug(`Hub ${hub.uuid} connected`);
|
||||
this._connectedDevices[hub.uuid] = hub;
|
||||
});
|
||||
|
||||
hub._peripheral.on("disconnect", () => {
|
||||
hub.on("disconnect", () => {
|
||||
debug(`Hub ${hub.uuid} disconnected`);
|
||||
delete this._connectedDevices[hub.uuid];
|
||||
|
||||
@ -67,6 +83,11 @@ class LPF2 extends EventEmitter {
|
||||
});
|
||||
|
||||
debug(`Hub ${hub.uuid} discovered`);
|
||||
/**
|
||||
* Emits when a LPF2 Hub device is found.
|
||||
* @event LPF2#discover
|
||||
* @param {Hub} hub
|
||||
*/
|
||||
this.emit("discover", hub);
|
||||
|
||||
});
|
||||
@ -79,6 +100,3 @@ class LPF2 extends EventEmitter {
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
module.exports = LPF2;
|
998
package-lock.json
generated
998
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
15
package.json
15
package.json
@ -2,13 +2,22 @@
|
||||
"name": "node-lpf2",
|
||||
"version": "1.0.0",
|
||||
"description": "A Node.js module to interface with Lego Power Functions 2.0 components.",
|
||||
"main": "lpf2.js",
|
||||
"main": "dist/lpf2.js",
|
||||
"types": "dist/lpf2.d.ts",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
"build": "tslint -c tslint.json \"*.ts\" && tsc"
|
||||
},
|
||||
"author": "Nathan Kunicki <me@nathankunicki.com>",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"noble": "^1.9.1"
|
||||
"@types/debug": "0.0.30",
|
||||
"@types/noble": "0.0.37",
|
||||
"@types/node": "^10.3.4",
|
||||
"noble": "^1.9.1",
|
||||
"typescript": "^2.9.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"jsdoc-to-markdown": "^4.0.1",
|
||||
"tslint": "^5.10.0"
|
||||
}
|
||||
}
|
||||
|
12
port.js
12
port.js
@ -1,12 +0,0 @@
|
||||
class Port {
|
||||
|
||||
constructor (id, value) {
|
||||
this.id = id;
|
||||
this.value = value;
|
||||
this.connected = false;
|
||||
this.type = null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
module.exports = Port;
|
17
port.ts
Normal file
17
port.ts
Normal file
@ -0,0 +1,17 @@
|
||||
export class Port {
|
||||
|
||||
|
||||
public id: string;
|
||||
public value: number;
|
||||
public connected: boolean;
|
||||
public type: number | null;
|
||||
|
||||
|
||||
constructor (id: string, value: number) {
|
||||
this.id = id;
|
||||
this.value = value;
|
||||
this.connected = false;
|
||||
this.type = null;
|
||||
}
|
||||
|
||||
}
|
59
tsconfig.json
Normal file
59
tsconfig.json
Normal file
@ -0,0 +1,59 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
/* Basic Options */
|
||||
"target": "es2017", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017','ES2018' or 'ESNEXT'. */
|
||||
"module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */
|
||||
// "lib": [], /* Specify library files to be included in the compilation. */
|
||||
// "allowJs": true, /* Allow javascript files to be compiled. */
|
||||
// "checkJs": true, /* Report errors in .js files. */
|
||||
// "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */
|
||||
"declaration": true, /* Generates corresponding '.d.ts' file. */
|
||||
// "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */
|
||||
// "sourceMap": true, /* Generates corresponding '.map' file. */
|
||||
// "outFile": "./", /* Concatenate and emit output to single file. */
|
||||
"outDir": "./dist", /* Redirect output structure to the directory. */
|
||||
// "rootDir": "./", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */
|
||||
// "composite": true, /* Enable project compilation */
|
||||
// "removeComments": true, /* Do not emit comments to output. */
|
||||
// "noEmit": true, /* Do not emit outputs. */
|
||||
// "importHelpers": true, /* Import emit helpers from 'tslib'. */
|
||||
// "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */
|
||||
// "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */
|
||||
|
||||
/* Strict Type-Checking Options */
|
||||
"strict": true, /* Enable all strict type-checking options. */
|
||||
// "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */
|
||||
// "strictNullChecks": true, /* Enable strict null checks. */
|
||||
// "strictFunctionTypes": true, /* Enable strict checking of function types. */
|
||||
// "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */
|
||||
// "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */
|
||||
// "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */
|
||||
|
||||
/* Additional Checks */
|
||||
// "noUnusedLocals": true, /* Report errors on unused locals. */
|
||||
// "noUnusedParameters": true, /* Report errors on unused parameters. */
|
||||
// "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */
|
||||
// "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */
|
||||
|
||||
/* Module Resolution Options */
|
||||
// "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */
|
||||
// "baseUrl": "./", /* Base directory to resolve non-absolute module names. */
|
||||
// "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */
|
||||
// "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */
|
||||
// "typeRoots": [], /* List of folders to include type definitions from. */
|
||||
// "types": [], /* Type declaration files to be included in compilation. */
|
||||
// "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */
|
||||
"esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */
|
||||
// "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */
|
||||
|
||||
/* Source Map Options */
|
||||
// "sourceRoot": "./", /* Specify the location where debugger should locate TypeScript files instead of source locations. */
|
||||
// "mapRoot": "./", /* Specify the location where debugger should locate map files instead of generated locations. */
|
||||
// "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */
|
||||
// "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */
|
||||
|
||||
/* Experimental Options */
|
||||
// "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */
|
||||
// "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */
|
||||
}
|
||||
}
|
23
tslint.json
Normal file
23
tslint.json
Normal file
@ -0,0 +1,23 @@
|
||||
{
|
||||
"defaultSeverity": "error",
|
||||
"extends": [
|
||||
"tslint:recommended"
|
||||
],
|
||||
"jsRules": {},
|
||||
"rules": {
|
||||
"no-consecutive-blank-lines": false,
|
||||
"space-before-function-paren": false,
|
||||
"no-bitwise": false,
|
||||
"trailing-comma": false,
|
||||
"max-line-length": false,
|
||||
"prefer-for-of": false,
|
||||
"typedef": true,
|
||||
"no-console": false,
|
||||
"variable-name": [true, "ban-keywords", "check-format", "allow-leading-underscore"],
|
||||
"object-literal-key-quotes": "consistent",
|
||||
"object-literal-sort-keys": false,
|
||||
"no-string-literal": false,
|
||||
"no-shadowed-variable": [false]
|
||||
},
|
||||
"rulesDirectory": []
|
||||
}
|
@ -1,33 +1,41 @@
|
||||
const debug = require("debug")("lpf2"),
|
||||
EventEmitter = require("events").EventEmitter;
|
||||
import { Peripheral } from "noble";
|
||||
|
||||
const Hub = require("./hub.js"),
|
||||
Port = require("./port.js"),
|
||||
Consts = require("./consts.js");
|
||||
import { Hub } from "./hub.js";
|
||||
import { Port } from "./port.js";
|
||||
|
||||
import Debug = require("debug");
|
||||
const debug = Debug("lpf2");
|
||||
import { Consts } from "./consts.js";
|
||||
|
||||
|
||||
class WeDo2Hub extends Hub {
|
||||
/**
|
||||
* @class WeDo2Hub
|
||||
* @extends Hub
|
||||
*/
|
||||
export class WeDo2Hub extends Hub {
|
||||
|
||||
|
||||
constructor (peripheral, autoSubscribe) {
|
||||
super(peripheral, autoSubscribe);
|
||||
this.type = Consts.Hubs.WEDO2_SMART_HUB;
|
||||
this.ports = {
|
||||
"A": new Port("A", 1),
|
||||
"B": new Port("B", 2)
|
||||
};
|
||||
this._lastTiltX = 0;
|
||||
this._lastTiltY = 0;
|
||||
debug("Discovered WeDo 2.0 Smart Hub");
|
||||
}
|
||||
|
||||
|
||||
static isWeDo2Hub (peripheral) {
|
||||
public static IsWeDo2Hub (peripheral: Peripheral) {
|
||||
return (peripheral.advertisement.localName === Consts.BLE.Name.WEDO2_SMART_HUB_NAME && peripheral.advertisement.serviceUuids.indexOf(Consts.BLE.Services.WEDO2_SMART_HUB) >= 0);
|
||||
}
|
||||
|
||||
|
||||
connect (callback) {
|
||||
private _lastTiltX: number = 0;
|
||||
private _lastTiltY: number = 0;
|
||||
|
||||
|
||||
constructor (peripheral: Peripheral, autoSubscribe: boolean = true) {
|
||||
super(peripheral, autoSubscribe);
|
||||
this.type = Consts.Hubs.WEDO2_SMART_HUB;
|
||||
this._ports = {
|
||||
"A": new Port("A", 1),
|
||||
"B": new Port("B", 2)
|
||||
};
|
||||
debug("Discovered WeDo 2.0 Smart Hub");
|
||||
}
|
||||
|
||||
|
||||
public connect (callback: () => void) {
|
||||
debug("Connecting to WeDo 2.0 Smart Hub");
|
||||
super.connect(() => {
|
||||
this._subscribeToCharacteristic(this._characteristics[Consts.BLE.Characteristics.WeDo2.PORT_TYPE], this._parsePortMessage.bind(this));
|
||||
@ -37,11 +45,16 @@ class WeDo2Hub extends Hub {
|
||||
if (callback) {
|
||||
callback();
|
||||
}
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
setLEDColor (color) {
|
||||
/**
|
||||
* Set the color of the LED on the Hub via a color value.
|
||||
* @method WeDo2Hub#setLEDColor
|
||||
* @param {number} color - A number representing one of the LED color consts.
|
||||
*/
|
||||
public setLEDColor (color: number | boolean) {
|
||||
const motorCharacteristic = this._characteristics[Consts.BLE.Characteristics.WeDo2.MOTOR_VALUE_WRITE];
|
||||
const portCharacteristic = this._characteristics[Consts.BLE.Characteristics.WeDo2.PORT_TYPE_WRITE];
|
||||
if (motorCharacteristic && portCharacteristic) {
|
||||
@ -56,35 +69,63 @@ class WeDo2Hub extends Hub {
|
||||
}
|
||||
|
||||
|
||||
setLEDRGB (red, green, blue) {
|
||||
/**
|
||||
* Set the color of the LED on the Hub via RGB values.
|
||||
* @method WeDo2Hub#setLEDRGB
|
||||
* @param {number} red
|
||||
* @param {number} green
|
||||
* @param {number} blue
|
||||
*/
|
||||
public setLEDRGB (red: number, green: number, blue: number) {
|
||||
const motorCharacteristic = this._characteristics[Consts.BLE.Characteristics.WeDo2.MOTOR_VALUE_WRITE];
|
||||
const portCharacteristic = this._characteristics[Consts.BLE.Characteristics.WeDo2.PORT_TYPE_WRITE];
|
||||
if (motorCharacteristic && portCharacteristic) {
|
||||
let data1 = Buffer.from([0x01, 0x02, 0x06, 0x17, 0x01, 0x02]);
|
||||
const data1 = Buffer.from([0x01, 0x02, 0x06, 0x17, 0x01, 0x02]);
|
||||
portCharacteristic.write(data1);
|
||||
let data2 = Buffer.from([0x06, 0x04, 0x03, red, green, blue]);
|
||||
console.log(data2);
|
||||
const data2 = Buffer.from([0x06, 0x04, 0x03, red, green, blue]);
|
||||
motorCharacteristic.write(data2);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
setMotorSpeed (port, speed) {
|
||||
/**
|
||||
* Set the motor speed on a given port.
|
||||
* @method WeDo2Hub#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.
|
||||
*/
|
||||
public setMotorSpeed (port: string, speed: number) {
|
||||
const characteristic = this._characteristics[Consts.BLE.Characteristics.WeDo2.MOTOR_VALUE_WRITE];
|
||||
if (characteristic) {
|
||||
characteristic.write(Buffer.from([this.ports[port].value, 0x01, 0x02, speed]));
|
||||
characteristic.write(Buffer.from([this._ports[port].value, 0x01, 0x02, speed]));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
_getPortForPortNumber (num) {
|
||||
protected _activatePortDevice (port: number, type: number, mode: number, format: number, callback: () => void) {
|
||||
const characteristic = this._characteristics[Consts.BLE.Characteristics.WeDo2.PORT_TYPE_WRITE];
|
||||
if (characteristic) {
|
||||
characteristic.write(Buffer.from([0x01, 0x02, port, type, mode, 0x01, 0x00, 0x00, 0x00, format, 0x01]), callback);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected _deactivatePortDevice (port: number, type: number, mode: number, format: number, callback: () => void) {
|
||||
const characteristic = this._characteristics[Consts.BLE.Characteristics.WeDo2.PORT_TYPE_WRITE];
|
||||
if (characteristic) {
|
||||
characteristic.write(Buffer.from([0x01, 0x02, port, type, mode, 0x01, 0x00, 0x00, 0x00, format, 0x00]), callback);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private _getPortForPortNumber (num: number) {
|
||||
|
||||
let port = null;
|
||||
|
||||
if (num === 1) {
|
||||
port = this.ports["A"];
|
||||
port = this._ports["A"];
|
||||
} else if (num === 2) {
|
||||
port = this.ports["B"];
|
||||
port = this._ports["B"];
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
@ -94,9 +135,9 @@ class WeDo2Hub extends Hub {
|
||||
}
|
||||
|
||||
|
||||
_parsePortMessage (data) {
|
||||
private _parsePortMessage (data: Buffer) {
|
||||
|
||||
let port = this._getPortForPortNumber(data[0]);
|
||||
const port = this._getPortForPortNumber(data[0]);
|
||||
|
||||
if (!port) {
|
||||
return;
|
||||
@ -108,26 +149,15 @@ class WeDo2Hub extends Hub {
|
||||
}
|
||||
|
||||
|
||||
_activatePortDevice (port, type, mode, format, callback) {
|
||||
const characteristic = this._characteristics[Consts.BLE.Characteristics.WeDo2.PORT_TYPE_WRITE];
|
||||
if (characteristic) {
|
||||
characteristic.write(Buffer.from([0x01, 0x02, port, type, mode, 0x01, 0x00, 0x00, 0x00, format, 0x01]), callback);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
_deactivatePortDevice (port, type, mode, format, callback) {
|
||||
const characteristic = this._characteristics[Consts.BLE.Characteristics.WeDo2.PORT_TYPE_WRITE];
|
||||
if (characteristic) {
|
||||
characteristic.write(Buffer.from([0x01, 0x02, port, type, mode, 0x01, 0x00, 0x00, 0x00, format, 0x00]), callback);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
_parseSensorMessage (data) {
|
||||
private _parseSensorMessage (data: Buffer) {
|
||||
|
||||
|
||||
if (data[0] === 1) {
|
||||
/**
|
||||
* Emits when a button is pressed.
|
||||
* @event WeDo2Hub#button
|
||||
* @param {number} state - A number representing one of the button state consts.
|
||||
*/
|
||||
this.emit("button", Consts.Button.PRESSED);
|
||||
return;
|
||||
} else if (data[0] === 0) {
|
||||
@ -135,7 +165,7 @@ class WeDo2Hub extends Hub {
|
||||
return;
|
||||
}
|
||||
|
||||
let port = this._getPortForPortNumber(data[1]);
|
||||
const port = this._getPortForPortNumber(data[1]);
|
||||
|
||||
if (!port) {
|
||||
return;
|
||||
@ -149,12 +179,24 @@ class WeDo2Hub extends Hub {
|
||||
if (data[3] === 1) {
|
||||
distance = data[2] + 255;
|
||||
}
|
||||
/**
|
||||
* Emits when a distance sensor is activated.
|
||||
* @event WeDo2Hub#distance
|
||||
* @param {string} port
|
||||
* @param {number} distance - Distance, in millimeters.
|
||||
*/
|
||||
this.emit("distance", port.id, distance * 10);
|
||||
break;
|
||||
}
|
||||
case Consts.Devices.BOOST_DISTANCE:
|
||||
{
|
||||
let distance = data[2];
|
||||
const distance = data[2];
|
||||
/**
|
||||
* Emits when a color sensor is activated.
|
||||
* @event WeDo2Hub#color
|
||||
* @param {string} port
|
||||
* @param {number} color - A number representing one of the LED color consts.
|
||||
*/
|
||||
this.emit("color", port.id, distance);
|
||||
break;
|
||||
}
|
||||
@ -168,12 +210,25 @@ class WeDo2Hub extends Hub {
|
||||
if (this._lastTiltY > 100) {
|
||||
this._lastTiltY = -(255 - this._lastTiltY);
|
||||
}
|
||||
/**
|
||||
* Emits when a tilt sensor is activated.
|
||||
* @event WeDo2Hub#tilt
|
||||
* @param {string} port
|
||||
* @param {number} x
|
||||
* @param {number} y
|
||||
*/
|
||||
this.emit("tilt", port.id, this._lastTiltX, this._lastTiltY);
|
||||
break;
|
||||
}
|
||||
case Consts.Devices.BOOST_INTERACTIVE_MOTOR:
|
||||
{
|
||||
const rotation = data.readInt32LE(2);
|
||||
/**
|
||||
* Emits when a rotation sensor is activated.
|
||||
* @event WeDo2Hub#rotate
|
||||
* @param {string} port
|
||||
* @param {number} rotation
|
||||
*/
|
||||
this.emit("rotate", port.id, rotation);
|
||||
}
|
||||
}
|
||||
@ -183,6 +238,3 @@ class WeDo2Hub extends Hub {
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
module.exports = WeDo2Hub;
|
Loading…
x
Reference in New Issue
Block a user