Basic implementation of BasicMotor types
This commit is contained in:
parent
eb6b20adbb
commit
d453fe52fb
39
src/basicmotor.ts
Normal file
39
src/basicmotor.ts
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
import { Device } from "./device";
|
||||||
|
import { Hub } from "./hub";
|
||||||
|
|
||||||
|
import * as Consts from "./consts";
|
||||||
|
|
||||||
|
export class BasicMotor extends Device {
|
||||||
|
|
||||||
|
|
||||||
|
constructor (hub: Hub, portId: number, type: number = Consts.DeviceType.UNKNOWN) {
|
||||||
|
super(hub, portId, type);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the motor speed.
|
||||||
|
* @method BasicMotor#setSpeed
|
||||||
|
* @param {number} speed For forward, a value between 1 - 100 should be set. For reverse, a value between -1 to -100. Stop is 0.
|
||||||
|
* @returns {Promise} Resolved upon successful completion of command.
|
||||||
|
*/
|
||||||
|
public setSpeed (speed: number) {
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
const data = Buffer.from([0x81, this.portId, 0x11, 0x51, 0x00, speed]);
|
||||||
|
this.send(data);
|
||||||
|
return resolve();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fully (hard) stop the motor.
|
||||||
|
* @method BasicMotor#brake
|
||||||
|
* @returns {Promise} Resolved upon successful completion of command.
|
||||||
|
*/
|
||||||
|
public brake () {
|
||||||
|
return this.setSpeed(127);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -7,7 +7,7 @@ import { Port } from "./port";
|
|||||||
import * as Consts from "./consts";
|
import * as Consts from "./consts";
|
||||||
|
|
||||||
import Debug = require("debug");
|
import Debug = require("debug");
|
||||||
import { IBLEDevice } from "./interfaces";
|
import { IBLEAbstraction } from "./interfaces";
|
||||||
const debug = Debug("boostmovehub");
|
const debug = Debug("boostmovehub");
|
||||||
|
|
||||||
|
|
||||||
@ -34,7 +34,7 @@ export class BoostMoveHub extends LPF2Hub {
|
|||||||
protected _currentPort = 0x3b;
|
protected _currentPort = 0x3b;
|
||||||
protected _voltagePort = 0x3c;
|
protected _voltagePort = 0x3c;
|
||||||
|
|
||||||
constructor (device: IBLEDevice, autoSubscribe: boolean = true) {
|
constructor (device: IBLEAbstraction, autoSubscribe: boolean = true) {
|
||||||
super(device, autoSubscribe);
|
super(device, autoSubscribe);
|
||||||
this.type = Consts.HubType.BOOST_MOVE_HUB;
|
this.type = Consts.HubType.BOOST_MOVE_HUB;
|
||||||
this._ports = {
|
this._ports = {
|
||||||
@ -102,17 +102,17 @@ export class BoostMoveHub extends LPF2Hub {
|
|||||||
data = Buffer.from([0x81, portObj.value, 0x11, 0x09, 0x00, 0x00, this._mapSpeed(speed), 0x64, 0x7f, 0x03]);
|
data = Buffer.from([0x81, portObj.value, 0x11, 0x09, 0x00, 0x00, this._mapSpeed(speed), 0x64, 0x7f, 0x03]);
|
||||||
}
|
}
|
||||||
data.writeUInt16LE(time > 65535 ? 65535 : time, 4);
|
data.writeUInt16LE(time > 65535 ? 65535 : time, 4);
|
||||||
this._writeMessage(Consts.BLECharacteristic.LPF2_ALL, data);
|
this.send(Consts.BLECharacteristic.LPF2_ALL, data);
|
||||||
portObj.finished = () => {
|
portObj.finished = () => {
|
||||||
return resolve();
|
return resolve();
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
// @ts-ignore: The type of speed is properly checked at the start
|
// @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)]);
|
const data = Buffer.from([0x81, portObj.value, 0x11, 0x51, 0x00, this._mapSpeed(speed)]);
|
||||||
this._writeMessage(Consts.BLECharacteristic.LPF2_ALL, data);
|
this.send(Consts.BLECharacteristic.LPF2_ALL, data);
|
||||||
const timeout = global.setTimeout(() => {
|
const timeout = global.setTimeout(() => {
|
||||||
const data = Buffer.from([0x81, portObj.value, 0x11, 0x51, 0x00, 0x00]);
|
const data = Buffer.from([0x81, portObj.value, 0x11, 0x51, 0x00, 0x00]);
|
||||||
this._writeMessage(Consts.BLECharacteristic.LPF2_ALL, data);
|
this.send(Consts.BLECharacteristic.LPF2_ALL, data);
|
||||||
return resolve();
|
return resolve();
|
||||||
// @ts-ignore: The type of time is properly checked at the start
|
// @ts-ignore: The type of time is properly checked at the start
|
||||||
}, time);
|
}, time);
|
||||||
@ -135,14 +135,14 @@ export class BoostMoveHub extends LPF2Hub {
|
|||||||
// @ts-ignore: The type of speed is properly checked at the start
|
// @ts-ignore: The type of speed is properly checked at the start
|
||||||
data = Buffer.from([0x81, portObj.value, 0x11, 0x01, this._mapSpeed(speed), 0x64, 0x7f, 0x03]);
|
data = Buffer.from([0x81, portObj.value, 0x11, 0x01, this._mapSpeed(speed), 0x64, 0x7f, 0x03]);
|
||||||
}
|
}
|
||||||
this._writeMessage(Consts.BLECharacteristic.LPF2_ALL, data);
|
this.send(Consts.BLECharacteristic.LPF2_ALL, data);
|
||||||
portObj.finished = () => {
|
portObj.finished = () => {
|
||||||
return resolve();
|
return resolve();
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
// @ts-ignore: The type of speed is properly checked at the start
|
// @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)]);
|
const data = Buffer.from([0x81, portObj.value, 0x11, 0x51, 0x00, this._mapSpeed(speed)]);
|
||||||
this._writeMessage(Consts.BLECharacteristic.LPF2_ALL, data);
|
this.send(Consts.BLECharacteristic.LPF2_ALL, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -204,7 +204,7 @@ export class BoostMoveHub extends LPF2Hub {
|
|||||||
data = Buffer.from([0x81, portObj.value, 0x11, 0x0b, 0x00, 0x00, 0x00, 0x00, this._mapSpeed(speed), 0x64, 0x7f, 0x03]);
|
data = Buffer.from([0x81, portObj.value, 0x11, 0x0b, 0x00, 0x00, 0x00, 0x00, this._mapSpeed(speed), 0x64, 0x7f, 0x03]);
|
||||||
}
|
}
|
||||||
data.writeUInt32LE(angle, 4);
|
data.writeUInt32LE(angle, 4);
|
||||||
this._writeMessage(Consts.BLECharacteristic.LPF2_ALL, data);
|
this.send(Consts.BLECharacteristic.LPF2_ALL, data);
|
||||||
portObj.finished = () => {
|
portObj.finished = () => {
|
||||||
return resolve();
|
return resolve();
|
||||||
};
|
};
|
||||||
@ -241,7 +241,7 @@ export class BoostMoveHub extends LPF2Hub {
|
|||||||
data = Buffer.from([0x81, portObj.value, 0x11, 0x0d, 0x00, 0x00, 0x00, 0x00, this._mapSpeed(speed), 0x64, 0x7f, 0x03]);
|
data = Buffer.from([0x81, portObj.value, 0x11, 0x0d, 0x00, 0x00, 0x00, 0x00, this._mapSpeed(speed), 0x64, 0x7f, 0x03]);
|
||||||
data.writeInt32LE(pos, 4);
|
data.writeInt32LE(pos, 4);
|
||||||
}
|
}
|
||||||
this._writeMessage(Consts.BLECharacteristic.LPF2_ALL, data);
|
this.send(Consts.BLECharacteristic.LPF2_ALL, data);
|
||||||
portObj.finished = () => {
|
portObj.finished = () => {
|
||||||
return resolve();
|
return resolve();
|
||||||
};
|
};
|
||||||
@ -265,7 +265,7 @@ export class BoostMoveHub extends LPF2Hub {
|
|||||||
}
|
}
|
||||||
return new Promise((resolve) => {
|
return new Promise((resolve) => {
|
||||||
const data = Buffer.from([0x81, portObj.value, 0x11, 0x51, 0x02, 0x00, 0x00, 0x00, 0x00]);
|
const data = Buffer.from([0x81, portObj.value, 0x11, 0x51, 0x02, 0x00, 0x00, 0x00, 0x00]);
|
||||||
this._writeMessage(Consts.BLECharacteristic.LPF2_ALL, data);
|
this.send(Consts.BLECharacteristic.LPF2_ALL, data);
|
||||||
return resolve();
|
return resolve();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -295,11 +295,11 @@ export class BoostMoveHub extends LPF2Hub {
|
|||||||
portObj.cancelEventTimer();
|
portObj.cancelEventTimer();
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
const data = Buffer.from([0x81, portObj.value, 0x11, 0x51, 0x00, brightness]);
|
const data = Buffer.from([0x81, portObj.value, 0x11, 0x51, 0x00, brightness]);
|
||||||
this._writeMessage(Consts.BLECharacteristic.LPF2_ALL, data);
|
this.send(Consts.BLECharacteristic.LPF2_ALL, data);
|
||||||
if (time) {
|
if (time) {
|
||||||
const timeout = global.setTimeout(() => {
|
const timeout = global.setTimeout(() => {
|
||||||
const data = Buffer.from([0x81, portObj.value, 0x11, 0x51, 0x00, 0x00]);
|
const data = Buffer.from([0x81, portObj.value, 0x11, 0x51, 0x00, 0x00]);
|
||||||
this._writeMessage(Consts.BLECharacteristic.LPF2_ALL, data);
|
this.send(Consts.BLECharacteristic.LPF2_ALL, data);
|
||||||
return resolve();
|
return resolve();
|
||||||
}, time);
|
}, time);
|
||||||
portObj.setEventTimer(timeout);
|
portObj.setEventTimer(timeout);
|
||||||
|
12
src/colordistancesensor.ts
Normal file
12
src/colordistancesensor.ts
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
import { Device } from "./device";
|
||||||
|
import { Hub } from "./hub";
|
||||||
|
|
||||||
|
import * as Consts from "./consts";
|
||||||
|
|
||||||
|
export class ColorDistanceSensor extends Device {
|
||||||
|
|
||||||
|
constructor (hub: Hub, portId: number) {
|
||||||
|
super(hub, portId, Consts.DeviceType.COLOR_DISTANCE_SENSOR);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -52,7 +52,7 @@ export const HubTypeNames = HubType;
|
|||||||
*/
|
*/
|
||||||
export enum DeviceType {
|
export enum DeviceType {
|
||||||
UNKNOWN = 0,
|
UNKNOWN = 0,
|
||||||
BASIC_MOTOR = 1,
|
SIMPLE_MEDIUM_LINEAR_MOTOR = 1,
|
||||||
TRAIN_MOTOR = 2,
|
TRAIN_MOTOR = 2,
|
||||||
LED_LIGHTS = 8,
|
LED_LIGHTS = 8,
|
||||||
VOLTAGE = 20,
|
VOLTAGE = 20,
|
||||||
@ -61,7 +61,7 @@ export enum DeviceType {
|
|||||||
RGB_LIGHT = 23,
|
RGB_LIGHT = 23,
|
||||||
WEDO2_TILT = 34,
|
WEDO2_TILT = 34,
|
||||||
WEDO2_DISTANCE = 35,
|
WEDO2_DISTANCE = 35,
|
||||||
BOOST_DISTANCE = 37,
|
COLOR_DISTANCE_SENSOR = 37,
|
||||||
BOOST_TACHO_MOTOR = 38,
|
BOOST_TACHO_MOTOR = 38,
|
||||||
BOOST_MOVE_HUB_MOTOR = 39,
|
BOOST_MOVE_HUB_MOTOR = 39,
|
||||||
BOOST_TILT = 40,
|
BOOST_TILT = 40,
|
||||||
|
@ -6,7 +6,7 @@ import { Port } from "./port";
|
|||||||
import * as Consts from "./consts";
|
import * as Consts from "./consts";
|
||||||
|
|
||||||
import Debug = require("debug");
|
import Debug = require("debug");
|
||||||
import { IBLEDevice } from "./interfaces";
|
import { IBLEAbstraction } from "./interfaces";
|
||||||
const debug = Debug("ControlPlusHub");
|
const debug = Debug("ControlPlusHub");
|
||||||
|
|
||||||
|
|
||||||
@ -36,7 +36,7 @@ export class ControlPlusHub extends LPF2Hub {
|
|||||||
protected _voltageMaxRaw = 4095;
|
protected _voltageMaxRaw = 4095;
|
||||||
protected _voltageMaxV = 9.615;
|
protected _voltageMaxV = 9.615;
|
||||||
|
|
||||||
constructor (device: IBLEDevice, autoSubscribe: boolean = true) {
|
constructor (device: IBLEAbstraction, autoSubscribe: boolean = true) {
|
||||||
super(device, autoSubscribe);
|
super(device, autoSubscribe);
|
||||||
this.type = Consts.HubType.CONTROL_PLUS_HUB;
|
this.type = Consts.HubType.CONTROL_PLUS_HUB;
|
||||||
this._ports = {
|
this._ports = {
|
||||||
@ -59,7 +59,7 @@ export class ControlPlusHub extends LPF2Hub {
|
|||||||
return new Promise(async (resolve, reject) => {
|
return new Promise(async (resolve, reject) => {
|
||||||
debug("Connecting to Control+ Hub");
|
debug("Connecting to Control+ Hub");
|
||||||
await super.connect();
|
await super.connect();
|
||||||
this._writeMessage(Consts.BLECharacteristic.LPF2_ALL, Buffer.from([0x41, 0x3d, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x01])); // Temperature
|
this.send(Consts.BLECharacteristic.LPF2_ALL, Buffer.from([0x41, 0x3d, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x01])); // Temperature
|
||||||
debug("Connect completed");
|
debug("Connect completed");
|
||||||
return resolve();
|
return resolve();
|
||||||
});
|
});
|
||||||
@ -107,17 +107,17 @@ export class ControlPlusHub extends LPF2Hub {
|
|||||||
data = Buffer.from([0x81, portObj.value, 0x11, 0x09, 0x00, 0x00, this._mapSpeed(speed), 0x64, 0x7f, 0x03]);
|
data = Buffer.from([0x81, portObj.value, 0x11, 0x09, 0x00, 0x00, this._mapSpeed(speed), 0x64, 0x7f, 0x03]);
|
||||||
}
|
}
|
||||||
data.writeUInt16LE(time > 65535 ? 65535 : time, 4);
|
data.writeUInt16LE(time > 65535 ? 65535 : time, 4);
|
||||||
this._writeMessage(Consts.BLECharacteristic.LPF2_ALL, data);
|
this.send(Consts.BLECharacteristic.LPF2_ALL, data);
|
||||||
portObj.finished = () => {
|
portObj.finished = () => {
|
||||||
return resolve();
|
return resolve();
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
// @ts-ignore: The type of speed is properly checked at the start
|
// @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)]);
|
const data = Buffer.from([0x81, portObj.value, 0x11, 0x51, 0x00, this._mapSpeed(speed)]);
|
||||||
this._writeMessage(Consts.BLECharacteristic.LPF2_ALL, data);
|
this.send(Consts.BLECharacteristic.LPF2_ALL, data);
|
||||||
const timeout = global.setTimeout(() => {
|
const timeout = global.setTimeout(() => {
|
||||||
const data = Buffer.from([0x81, portObj.value, 0x11, 0x51, 0x00, 0x00]);
|
const data = Buffer.from([0x81, portObj.value, 0x11, 0x51, 0x00, 0x00]);
|
||||||
this._writeMessage(Consts.BLECharacteristic.LPF2_ALL, data);
|
this.send(Consts.BLECharacteristic.LPF2_ALL, data);
|
||||||
return resolve();
|
return resolve();
|
||||||
// @ts-ignore: The type of time is properly checked at the start
|
// @ts-ignore: The type of time is properly checked at the start
|
||||||
}, time);
|
}, time);
|
||||||
@ -135,14 +135,14 @@ export class ControlPlusHub extends LPF2Hub {
|
|||||||
// @ts-ignore: The type of speed is properly checked at the start
|
// @ts-ignore: The type of speed is properly checked at the start
|
||||||
data = Buffer.from([0x81, portObj.value, 0x11, 0x01, this._mapSpeed(speed), 0x64, 0x7f, 0x03]);
|
data = Buffer.from([0x81, portObj.value, 0x11, 0x01, this._mapSpeed(speed), 0x64, 0x7f, 0x03]);
|
||||||
}
|
}
|
||||||
this._writeMessage(Consts.BLECharacteristic.LPF2_ALL, data);
|
this.send(Consts.BLECharacteristic.LPF2_ALL, data);
|
||||||
portObj.finished = () => {
|
portObj.finished = () => {
|
||||||
return resolve();
|
return resolve();
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
// @ts-ignore: The type of speed is properly checked at the start
|
// @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)]);
|
const data = Buffer.from([0x81, portObj.value, 0x11, 0x51, 0x00, this._mapSpeed(speed)]);
|
||||||
this._writeMessage(Consts.BLECharacteristic.LPF2_ALL, data);
|
this.send(Consts.BLECharacteristic.LPF2_ALL, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -204,7 +204,7 @@ export class ControlPlusHub extends LPF2Hub {
|
|||||||
data = Buffer.from([0x81, portObj.value, 0x11, 0x0b, 0x00, 0x00, 0x00, 0x00, this._mapSpeed(speed), 0x64, 0x7f, 0x03]);
|
data = Buffer.from([0x81, portObj.value, 0x11, 0x0b, 0x00, 0x00, 0x00, 0x00, this._mapSpeed(speed), 0x64, 0x7f, 0x03]);
|
||||||
}
|
}
|
||||||
data.writeUInt32LE(angle, 4);
|
data.writeUInt32LE(angle, 4);
|
||||||
this._writeMessage(Consts.BLECharacteristic.LPF2_ALL, data);
|
this.send(Consts.BLECharacteristic.LPF2_ALL, data);
|
||||||
portObj.finished = () => {
|
portObj.finished = () => {
|
||||||
return resolve();
|
return resolve();
|
||||||
};
|
};
|
||||||
@ -241,7 +241,7 @@ export class ControlPlusHub extends LPF2Hub {
|
|||||||
data = Buffer.from([0x81, portObj.value, 0x11, 0x0d, 0x00, 0x00, 0x00, 0x00, this._mapSpeed(speed), 0x64, 0x7f, 0x03]);
|
data = Buffer.from([0x81, portObj.value, 0x11, 0x0d, 0x00, 0x00, 0x00, 0x00, this._mapSpeed(speed), 0x64, 0x7f, 0x03]);
|
||||||
data.writeInt32LE(pos, 4);
|
data.writeInt32LE(pos, 4);
|
||||||
}
|
}
|
||||||
this._writeMessage(Consts.BLECharacteristic.LPF2_ALL, data);
|
this.send(Consts.BLECharacteristic.LPF2_ALL, data);
|
||||||
portObj.finished = () => {
|
portObj.finished = () => {
|
||||||
return resolve();
|
return resolve();
|
||||||
};
|
};
|
||||||
@ -265,7 +265,7 @@ export class ControlPlusHub extends LPF2Hub {
|
|||||||
}
|
}
|
||||||
return new Promise((resolve) => {
|
return new Promise((resolve) => {
|
||||||
const data = Buffer.from([0x81, portObj.value, 0x11, 0x51, 0x02, 0x00, 0x00, 0x00, 0x00]);
|
const data = Buffer.from([0x81, portObj.value, 0x11, 0x51, 0x02, 0x00, 0x00, 0x00, 0x00]);
|
||||||
this._writeMessage(Consts.BLECharacteristic.LPF2_ALL, data);
|
this.send(Consts.BLECharacteristic.LPF2_ALL, data);
|
||||||
return resolve();
|
return resolve();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -295,11 +295,11 @@ export class ControlPlusHub extends LPF2Hub {
|
|||||||
portObj.cancelEventTimer();
|
portObj.cancelEventTimer();
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
const data = Buffer.from([0x81, portObj.value, 0x11, 0x51, 0x00, brightness]);
|
const data = Buffer.from([0x81, portObj.value, 0x11, 0x51, 0x00, brightness]);
|
||||||
this._writeMessage(Consts.BLECharacteristic.LPF2_ALL, data);
|
this.send(Consts.BLECharacteristic.LPF2_ALL, data);
|
||||||
if (time) {
|
if (time) {
|
||||||
const timeout = global.setTimeout(() => {
|
const timeout = global.setTimeout(() => {
|
||||||
const data = Buffer.from([0x81, portObj.value, 0x11, 0x51, 0x00, 0x00]);
|
const data = Buffer.from([0x81, portObj.value, 0x11, 0x51, 0x00, 0x00]);
|
||||||
this._writeMessage(Consts.BLECharacteristic.LPF2_ALL, data);
|
this.send(Consts.BLECharacteristic.LPF2_ALL, data);
|
||||||
return resolve();
|
return resolve();
|
||||||
}, time);
|
}, time);
|
||||||
portObj.setEventTimer(timeout);
|
portObj.setEventTimer(timeout);
|
||||||
|
12
src/controlpluslargemotor.ts
Normal file
12
src/controlpluslargemotor.ts
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
import { BasicMotor } from "./basicmotor";
|
||||||
|
import { Hub } from "./hub";
|
||||||
|
|
||||||
|
import * as Consts from "./consts";
|
||||||
|
|
||||||
|
export class ControlPlusLargeMotor extends BasicMotor {
|
||||||
|
|
||||||
|
constructor (hub: Hub, portId: number) {
|
||||||
|
super(hub, portId, Consts.DeviceType.CONTROL_PLUS_LARGE_MOTOR);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
45
src/device.ts
Normal file
45
src/device.ts
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
import { EventEmitter } from "events";
|
||||||
|
import { Hub } from "./hub";
|
||||||
|
|
||||||
|
import * as Consts from "./consts";
|
||||||
|
|
||||||
|
export class Device extends EventEmitter {
|
||||||
|
|
||||||
|
private _hub: Hub;
|
||||||
|
private _portId: number;
|
||||||
|
private _connected: boolean = true;
|
||||||
|
private _type: number;
|
||||||
|
|
||||||
|
constructor (hub: Hub, portId: number, type: number = Consts.DeviceType.UNKNOWN) {
|
||||||
|
super();
|
||||||
|
this._hub = hub;
|
||||||
|
this._portId = portId;
|
||||||
|
this._type = type;
|
||||||
|
console.log(`New device on ${this._portId} - ${this._type}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
public get connected () {
|
||||||
|
return this._connected;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get hub () {
|
||||||
|
return this._hub;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get portId () {
|
||||||
|
return this._portId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get port () {
|
||||||
|
return "A"; // TODO NK: Look up the port name from the relevant hub
|
||||||
|
}
|
||||||
|
|
||||||
|
public get type () {
|
||||||
|
return this._type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public send (data: Buffer, characteristic: string = Consts.BLECharacteristic.LPF2_ALL, callback?: () => void) {
|
||||||
|
this.hub.send(characteristic, data, callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -6,7 +6,7 @@ import { Port } from "./port";
|
|||||||
import * as Consts from "./consts";
|
import * as Consts from "./consts";
|
||||||
|
|
||||||
import Debug = require("debug");
|
import Debug = require("debug");
|
||||||
import { IBLEDevice } from "./interfaces";
|
import { IBLEAbstraction } from "./interfaces";
|
||||||
const debug = Debug("duplotrainbase");
|
const debug = Debug("duplotrainbase");
|
||||||
|
|
||||||
|
|
||||||
@ -36,7 +36,7 @@ export class DuploTrainBase extends LPF2Hub {
|
|||||||
protected _voltageMaxV = 6.4;
|
protected _voltageMaxV = 6.4;
|
||||||
protected _voltageMaxRaw = 3047;
|
protected _voltageMaxRaw = 3047;
|
||||||
|
|
||||||
constructor (device: IBLEDevice, autoSubscribe: boolean = true) {
|
constructor (device: IBLEAbstraction, autoSubscribe: boolean = true) {
|
||||||
super(device, autoSubscribe);
|
super(device, autoSubscribe);
|
||||||
this.type = Consts.HubType.DUPLO_TRAIN_HUB;
|
this.type = Consts.HubType.DUPLO_TRAIN_HUB;
|
||||||
this._ports = {
|
this._ports = {
|
||||||
@ -80,16 +80,16 @@ export class DuploTrainBase extends LPF2Hub {
|
|||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
if (time && typeof time === "number") {
|
if (time && typeof time === "number") {
|
||||||
const data = Buffer.from([0x81, portObj.value, 0x11, 0x51, 0x00, this._mapSpeed(speed)]);
|
const data = Buffer.from([0x81, portObj.value, 0x11, 0x51, 0x00, this._mapSpeed(speed)]);
|
||||||
this._writeMessage(Consts.BLECharacteristic.LPF2_ALL, data);
|
this.send(Consts.BLECharacteristic.LPF2_ALL, data);
|
||||||
const timeout = global.setTimeout(() => {
|
const timeout = global.setTimeout(() => {
|
||||||
const data = Buffer.from([0x81, portObj.value, 0x11, 0x51, 0x00, 0x00]);
|
const data = Buffer.from([0x81, portObj.value, 0x11, 0x51, 0x00, 0x00]);
|
||||||
this._writeMessage(Consts.BLECharacteristic.LPF2_ALL, data);
|
this.send(Consts.BLECharacteristic.LPF2_ALL, data);
|
||||||
return resolve();
|
return resolve();
|
||||||
}, time);
|
}, time);
|
||||||
portObj.setEventTimer(timeout);
|
portObj.setEventTimer(timeout);
|
||||||
} else {
|
} else {
|
||||||
const data = Buffer.from([0x81, portObj.value, 0x11, 0x51, 0x00, this._mapSpeed(speed)]);
|
const data = Buffer.from([0x81, portObj.value, 0x11, 0x51, 0x00, this._mapSpeed(speed)]);
|
||||||
this._writeMessage(Consts.BLECharacteristic.LPF2_ALL, data);
|
this.send(Consts.BLECharacteristic.LPF2_ALL, data);
|
||||||
return resolve();
|
return resolve();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -138,7 +138,7 @@ export class DuploTrainBase extends LPF2Hub {
|
|||||||
public playSound (sound: number) {
|
public playSound (sound: number) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
const data = Buffer.from([0x81, 0x01, 0x11, 0x51, 0x01, sound]);
|
const data = Buffer.from([0x81, 0x01, 0x11, 0x51, 0x01, sound]);
|
||||||
this._writeMessage(Consts.BLECharacteristic.LPF2_ALL, data);
|
this.send(Consts.BLECharacteristic.LPF2_ALL, data);
|
||||||
return resolve();
|
return resolve();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
81
src/hub.ts
81
src/hub.ts
@ -1,11 +1,12 @@
|
|||||||
import { EventEmitter } from "events";
|
import { EventEmitter } from "events";
|
||||||
|
|
||||||
import { IBLEDevice } from "./interfaces";
|
import { IBLEAbstraction } from "./interfaces";
|
||||||
import { Port } from "./port";
|
import { Port } from "./port";
|
||||||
|
|
||||||
import * as Consts from "./consts";
|
import * as Consts from "./consts";
|
||||||
|
|
||||||
import Debug = require("debug");
|
import Debug = require("debug");
|
||||||
|
import { Device } from "./device";
|
||||||
const debug = Debug("hub");
|
const debug = Debug("hub");
|
||||||
|
|
||||||
|
|
||||||
@ -20,6 +21,8 @@ export class Hub extends EventEmitter {
|
|||||||
public useSpeedMap: boolean = true;
|
public useSpeedMap: boolean = true;
|
||||||
public type: Consts.HubType = Consts.HubType.UNKNOWN;
|
public type: Consts.HubType = Consts.HubType.UNKNOWN;
|
||||||
|
|
||||||
|
protected _attachedDevices: Device[] = [];
|
||||||
|
|
||||||
protected _ports: {[port: string]: Port} = {};
|
protected _ports: {[port: string]: Port} = {};
|
||||||
protected _virtualPorts: {[port: string]: Port} = {};
|
protected _virtualPorts: {[port: string]: Port} = {};
|
||||||
|
|
||||||
@ -32,12 +35,12 @@ export class Hub extends EventEmitter {
|
|||||||
protected _current: number = 0;
|
protected _current: number = 0;
|
||||||
protected _rssi: number = -60;
|
protected _rssi: number = -60;
|
||||||
|
|
||||||
protected _bleDevice: IBLEDevice;
|
protected _bleDevice: IBLEAbstraction;
|
||||||
|
|
||||||
private _isConnecting = false;
|
private _isConnecting = false;
|
||||||
private _isConnected = false;
|
private _isConnected = false;
|
||||||
|
|
||||||
constructor (device: IBLEDevice, autoSubscribe: boolean = true) {
|
constructor (device: IBLEAbstraction, autoSubscribe: boolean = true) {
|
||||||
super();
|
super();
|
||||||
this.autoSubscribe = !!autoSubscribe;
|
this.autoSubscribe = !!autoSubscribe;
|
||||||
this._bleDevice = device;
|
this._bleDevice = device;
|
||||||
@ -246,6 +249,13 @@ export class Hub extends EventEmitter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public send (uuid: string, message: Buffer, callback?: () => void) {
|
||||||
|
if (callback) {
|
||||||
|
callback();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// protected _getCharacteristic (uuid: string) {
|
// protected _getCharacteristic (uuid: string) {
|
||||||
// return this._characteristics[uuid.replace(/-/g, "")];
|
// return this._characteristics[uuid.replace(/-/g, "")];
|
||||||
// }
|
// }
|
||||||
@ -277,33 +287,48 @@ export class Hub extends EventEmitter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
protected _registerDeviceAttachment (port: Port, type: number) {
|
protected _registerDeviceAttachment (device: Device) {
|
||||||
|
|
||||||
if (port.connected) {
|
const exists = this._attachedDevices.find((attachedDevice) => attachedDevice.portId === device.portId);
|
||||||
port.type = type;
|
|
||||||
if (this.autoSubscribe) {
|
if (exists) {
|
||||||
this._activatePortDevice(port.value, type, this._getModeForDeviceType(type), 0x00);
|
// TODO NK: Remove existing zombie device
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Emits when a motor or sensor is attached to the Hub.
|
|
||||||
* @event Hub#attach
|
|
||||||
* @param {string} port
|
|
||||||
* @param {DeviceType} type
|
|
||||||
*/
|
|
||||||
this.emit("attach", port.id, type);
|
|
||||||
} else {
|
} else {
|
||||||
port.type = Consts.DeviceType.UNKNOWN;
|
this._attachedDevices.push(device);
|
||||||
debug(`Port ${port.id} disconnected`);
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Emits when an attached motor or sensor is detached from the Hub.
|
* Emits when a device is attached to the Hub.
|
||||||
* @event Hub#detach
|
* @event Hub#attach
|
||||||
* @param {string} port
|
* @param {Device} device
|
||||||
*/
|
*/
|
||||||
if (this._virtualPorts[port.id]) {
|
this.emit("attach", device);
|
||||||
delete this._virtualPorts[port.id];
|
|
||||||
}
|
// if (port.connected) {
|
||||||
this.emit("detach", port.id);
|
// port.type = type;
|
||||||
}
|
// if (this.autoSubscribe) {
|
||||||
|
// this._activatePortDevice(port.value, type, this._getModeForDeviceType(type), 0x00);
|
||||||
|
// }
|
||||||
|
// /**
|
||||||
|
// * Emits when a motor or sensor is attached to the Hub.
|
||||||
|
// * @event Hub#attach
|
||||||
|
// * @param {string} port
|
||||||
|
// * @param {DeviceType} type
|
||||||
|
// */
|
||||||
|
// this.emit("attach", port.id, type);
|
||||||
|
// } else {
|
||||||
|
// port.type = Consts.DeviceType.UNKNOWN;
|
||||||
|
// debug(`Port ${port.id} disconnected`);
|
||||||
|
// /**
|
||||||
|
// * Emits when an attached motor or sensor is detached from the Hub.
|
||||||
|
// * @event Hub#detach
|
||||||
|
// * @param {string} port
|
||||||
|
// */
|
||||||
|
// if (this._virtualPorts[port.id]) {
|
||||||
|
// delete this._virtualPorts[port.id];
|
||||||
|
// }
|
||||||
|
// this.emit("detach", port.id);
|
||||||
|
// }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -388,7 +413,7 @@ export class Hub extends EventEmitter {
|
|||||||
|
|
||||||
private _getModeForDeviceType (type: Consts.DeviceType) {
|
private _getModeForDeviceType (type: Consts.DeviceType) {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case Consts.DeviceType.BASIC_MOTOR:
|
case Consts.DeviceType.SIMPLE_MEDIUM_LINEAR_MOTOR:
|
||||||
return 0x02;
|
return 0x02;
|
||||||
case Consts.DeviceType.TRAIN_MOTOR:
|
case Consts.DeviceType.TRAIN_MOTOR:
|
||||||
return 0x02;
|
return 0x02;
|
||||||
@ -404,7 +429,7 @@ export class Hub extends EventEmitter {
|
|||||||
return 0x00;
|
return 0x00;
|
||||||
case Consts.DeviceType.CONTROL_PLUS_ACCELEROMETER:
|
case Consts.DeviceType.CONTROL_PLUS_ACCELEROMETER:
|
||||||
return 0x00;
|
return 0x00;
|
||||||
case Consts.DeviceType.BOOST_DISTANCE:
|
case Consts.DeviceType.COLOR_DISTANCE_SENSOR:
|
||||||
return (this.type === Consts.HubType.WEDO2_SMART_HUB ? 0x00 : 0x08);
|
return (this.type === Consts.HubType.WEDO2_SMART_HUB ? 0x00 : 0x08);
|
||||||
case Consts.DeviceType.BOOST_TILT:
|
case Consts.DeviceType.BOOST_TILT:
|
||||||
return 0x04;
|
return 0x04;
|
||||||
|
@ -1,15 +1,35 @@
|
|||||||
import * as Consts from "./consts";
|
import * as Consts from "./consts";
|
||||||
|
|
||||||
|
import { PoweredUP } from "./poweredup-browser";
|
||||||
|
|
||||||
import { BoostMoveHub } from "./boostmovehub";
|
import { BoostMoveHub } from "./boostmovehub";
|
||||||
import { ControlPlusHub } from "./controlplushub";
|
import { ControlPlusHub } from "./controlplushub";
|
||||||
import { DuploTrainBase } from "./duplotrainbase";
|
import { DuploTrainBase } from "./duplotrainbase";
|
||||||
import { Hub } from "./hub";
|
import { Hub } from "./hub";
|
||||||
import { PoweredUP } from "./poweredup-browser";
|
|
||||||
import { PUPHub } from "./puphub";
|
import { PUPHub } from "./puphub";
|
||||||
import { PUPRemote } from "./pupremote";
|
import { PUPRemote } from "./pupremote";
|
||||||
import { WeDo2SmartHub } from "./wedo2smarthub";
|
import { WeDo2SmartHub } from "./wedo2smarthub";
|
||||||
|
|
||||||
|
import { ColorDistanceSensor } from "./colordistancesensor";
|
||||||
|
import { ControlPlusLargeMotor } from "./controlpluslargemotor";
|
||||||
|
import { Device } from "./device";
|
||||||
|
|
||||||
import { isWebBluetooth } from "./utils";
|
import { isWebBluetooth } from "./utils";
|
||||||
|
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
window.PoweredUP = { PoweredUP, Hub, WeDo2SmartHub, BoostMoveHub, ControlPlusHub, PUPHub, PUPRemote, DuploTrainBase, Consts, isWebBluetooth };
|
window.PoweredUP = {
|
||||||
|
PoweredUP,
|
||||||
|
Hub,
|
||||||
|
WeDo2SmartHub,
|
||||||
|
BoostMoveHub,
|
||||||
|
ControlPlusHub,
|
||||||
|
PUPHub,
|
||||||
|
PUPRemote,
|
||||||
|
DuploTrainBase,
|
||||||
|
Consts,
|
||||||
|
Device,
|
||||||
|
ColorDistanceSensor,
|
||||||
|
ControlPlusLargeMotor,
|
||||||
|
isWebBluetooth
|
||||||
|
};
|
||||||
|
|
||||||
|
@ -1,15 +1,34 @@
|
|||||||
import * as Consts from "./consts";
|
import * as Consts from "./consts";
|
||||||
|
|
||||||
|
import { PoweredUP } from "./poweredup-node";
|
||||||
|
|
||||||
import { BoostMoveHub } from "./boostmovehub";
|
import { BoostMoveHub } from "./boostmovehub";
|
||||||
import { ControlPlusHub } from "./controlplushub";
|
import { ControlPlusHub } from "./controlplushub";
|
||||||
import { DuploTrainBase } from "./duplotrainbase";
|
import { DuploTrainBase } from "./duplotrainbase";
|
||||||
import { Hub } from "./hub";
|
import { Hub } from "./hub";
|
||||||
import { PoweredUP } from "./poweredup-node";
|
|
||||||
import { PUPHub } from "./puphub";
|
import { PUPHub } from "./puphub";
|
||||||
import { PUPRemote } from "./pupremote";
|
import { PUPRemote } from "./pupremote";
|
||||||
import { WeDo2SmartHub } from "./wedo2smarthub";
|
import { WeDo2SmartHub } from "./wedo2smarthub";
|
||||||
|
|
||||||
|
import { ColorDistanceSensor } from "./colordistancesensor";
|
||||||
|
import { ControlPlusLargeMotor } from "./controlpluslargemotor";
|
||||||
|
import { Device } from "./device";
|
||||||
|
|
||||||
import { isWebBluetooth } from "./utils";
|
import { isWebBluetooth } from "./utils";
|
||||||
|
|
||||||
export default PoweredUP;
|
export default PoweredUP;
|
||||||
export { PoweredUP, Hub, WeDo2SmartHub, BoostMoveHub, ControlPlusHub, PUPHub, PUPRemote, DuploTrainBase, Consts, isWebBluetooth };
|
export {
|
||||||
|
PoweredUP,
|
||||||
|
Hub,
|
||||||
|
WeDo2SmartHub,
|
||||||
|
BoostMoveHub,
|
||||||
|
ControlPlusHub,
|
||||||
|
PUPHub,
|
||||||
|
PUPRemote,
|
||||||
|
DuploTrainBase,
|
||||||
|
Consts,
|
||||||
|
Device,
|
||||||
|
ColorDistanceSensor,
|
||||||
|
ControlPlusLargeMotor,
|
||||||
|
isWebBluetooth
|
||||||
|
};
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { EventEmitter } from "events";
|
import { EventEmitter } from "events";
|
||||||
|
|
||||||
export interface IBLEDevice extends EventEmitter {
|
export interface IBLEAbstraction extends EventEmitter {
|
||||||
uuid: string;
|
uuid: string;
|
||||||
name: string;
|
name: string;
|
||||||
connecting: boolean;
|
connecting: boolean;
|
||||||
|
159
src/lpf2hub.ts
159
src/lpf2hub.ts
@ -1,8 +1,10 @@
|
|||||||
import { Peripheral } from "@abandonware/noble";
|
import { Device } from "./device";
|
||||||
|
|
||||||
import { Hub } from "./hub";
|
import { Hub } from "./hub";
|
||||||
import { Port } from "./port";
|
import { Port } from "./port";
|
||||||
|
|
||||||
|
import { ColorDistanceSensor } from "./colordistancesensor";
|
||||||
|
import { ControlPlusLargeMotor } from "./controlpluslargemotor";
|
||||||
|
|
||||||
import * as Consts from "./consts";
|
import * as Consts from "./consts";
|
||||||
import { toBin, toHex } from "./utils";
|
import { toBin, toHex } from "./utils";
|
||||||
|
|
||||||
@ -46,21 +48,21 @@ export class LPF2Hub extends Hub {
|
|||||||
await this._bleDevice.discoverCharacteristicsForService(Consts.BLEService.LPF2_HUB);
|
await this._bleDevice.discoverCharacteristicsForService(Consts.BLEService.LPF2_HUB);
|
||||||
this._bleDevice.subscribeToCharacteristic(Consts.BLECharacteristic.LPF2_ALL, this._parseMessage.bind(this));
|
this._bleDevice.subscribeToCharacteristic(Consts.BLECharacteristic.LPF2_ALL, this._parseMessage.bind(this));
|
||||||
if (this._voltagePort !== undefined) {
|
if (this._voltagePort !== undefined) {
|
||||||
this._writeMessage(Consts.BLECharacteristic.LPF2_ALL, Buffer.from([0x41, this._voltagePort, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01])); // Activate voltage reports
|
this.send(Consts.BLECharacteristic.LPF2_ALL, Buffer.from([0x41, this._voltagePort, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01])); // Activate voltage reports
|
||||||
}
|
}
|
||||||
if (this._currentPort !== undefined) {
|
if (this._currentPort !== undefined) {
|
||||||
this._writeMessage(Consts.BLECharacteristic.LPF2_ALL, Buffer.from([0x41, this._currentPort, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01])); // Activate current reports
|
this.send(Consts.BLECharacteristic.LPF2_ALL, Buffer.from([0x41, this._currentPort, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01])); // Activate current reports
|
||||||
}
|
}
|
||||||
if (this.type === Consts.HubType.DUPLO_TRAIN_HUB) {
|
if (this.type === Consts.HubType.DUPLO_TRAIN_HUB) {
|
||||||
this._writeMessage(Consts.BLECharacteristic.LPF2_ALL, Buffer.from([0x41, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01]));
|
this.send(Consts.BLECharacteristic.LPF2_ALL, Buffer.from([0x41, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01]));
|
||||||
}
|
}
|
||||||
await this.sleep(100);
|
await this.sleep(100);
|
||||||
this._writeMessage(Consts.BLECharacteristic.LPF2_ALL, Buffer.from([0x01, 0x02, 0x02])); // Activate button reports
|
this.send(Consts.BLECharacteristic.LPF2_ALL, Buffer.from([0x01, 0x02, 0x02])); // Activate button reports
|
||||||
this._writeMessage(Consts.BLECharacteristic.LPF2_ALL, Buffer.from([0x01, 0x03, 0x05])); // Request firmware version
|
this.send(Consts.BLECharacteristic.LPF2_ALL, Buffer.from([0x01, 0x03, 0x05])); // Request firmware version
|
||||||
this._writeMessage(Consts.BLECharacteristic.LPF2_ALL, Buffer.from([0x01, 0x04, 0x05])); // Request hardware version
|
this.send(Consts.BLECharacteristic.LPF2_ALL, Buffer.from([0x01, 0x04, 0x05])); // Request hardware version
|
||||||
this._writeMessage(Consts.BLECharacteristic.LPF2_ALL, Buffer.from([0x01, 0x05, 0x02])); // Activate RSSI updates
|
this.send(Consts.BLECharacteristic.LPF2_ALL, Buffer.from([0x01, 0x05, 0x02])); // Activate RSSI updates
|
||||||
this._writeMessage(Consts.BLECharacteristic.LPF2_ALL, Buffer.from([0x01, 0x06, 0x02])); // Activate battery level reports
|
this.send(Consts.BLECharacteristic.LPF2_ALL, Buffer.from([0x01, 0x06, 0x02])); // Activate battery level reports
|
||||||
this._writeMessage(Consts.BLECharacteristic.LPF2_ALL, Buffer.from([0x01, 0x0d, 0x05])); // Request primary MAC address
|
this.send(Consts.BLECharacteristic.LPF2_ALL, Buffer.from([0x01, 0x0d, 0x05])); // Request primary MAC address
|
||||||
this.emit("connect");
|
this.emit("connect");
|
||||||
resolve();
|
resolve();
|
||||||
});
|
});
|
||||||
@ -74,7 +76,7 @@ export class LPF2Hub extends Hub {
|
|||||||
*/
|
*/
|
||||||
public shutdown () {
|
public shutdown () {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
this._writeMessage(Consts.BLECharacteristic.LPF2_ALL, Buffer.from([0x02, 0x01]), () => {
|
this.send(Consts.BLECharacteristic.LPF2_ALL, Buffer.from([0x02, 0x01]), () => {
|
||||||
return resolve();
|
return resolve();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -95,8 +97,8 @@ export class LPF2Hub extends Hub {
|
|||||||
let data = Buffer.from([0x01, 0x01, 0x01]);
|
let data = Buffer.from([0x01, 0x01, 0x01]);
|
||||||
data = Buffer.concat([data, Buffer.from(name, "ascii")]);
|
data = Buffer.concat([data, Buffer.from(name, "ascii")]);
|
||||||
// Send this twice, as sometimes the first time doesn't take
|
// Send this twice, as sometimes the first time doesn't take
|
||||||
this._writeMessage(Consts.BLECharacteristic.LPF2_ALL, data);
|
this.send(Consts.BLECharacteristic.LPF2_ALL, data);
|
||||||
this._writeMessage(Consts.BLECharacteristic.LPF2_ALL, data);
|
this.send(Consts.BLECharacteristic.LPF2_ALL, data);
|
||||||
this._name = name;
|
this._name = name;
|
||||||
return resolve();
|
return resolve();
|
||||||
});
|
});
|
||||||
@ -112,12 +114,12 @@ export class LPF2Hub extends Hub {
|
|||||||
public setLEDColor (color: number | boolean) {
|
public setLEDColor (color: number | boolean) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
let data = Buffer.from([0x41, this._ledPort, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00]);
|
let data = Buffer.from([0x41, this._ledPort, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00]);
|
||||||
this._writeMessage(Consts.BLECharacteristic.LPF2_ALL, data);
|
this.send(Consts.BLECharacteristic.LPF2_ALL, data);
|
||||||
if (typeof color === "boolean") {
|
if (typeof color === "boolean") {
|
||||||
color = 0;
|
color = 0;
|
||||||
}
|
}
|
||||||
data = Buffer.from([0x81, this._ledPort, 0x11, 0x51, 0x00, color]);
|
data = Buffer.from([0x81, this._ledPort, 0x11, 0x51, 0x00, color]);
|
||||||
this._writeMessage(Consts.BLECharacteristic.LPF2_ALL, data);
|
this.send(Consts.BLECharacteristic.LPF2_ALL, data);
|
||||||
return resolve();
|
return resolve();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -134,9 +136,9 @@ export class LPF2Hub extends Hub {
|
|||||||
public setLEDRGB (red: number, green: number, blue: number) {
|
public setLEDRGB (red: number, green: number, blue: number) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
let data = Buffer.from([0x41, this._ledPort, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00]);
|
let data = Buffer.from([0x41, this._ledPort, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00]);
|
||||||
this._writeMessage(Consts.BLECharacteristic.LPF2_ALL, data);
|
this.send(Consts.BLECharacteristic.LPF2_ALL, data);
|
||||||
data = Buffer.from([0x81, this._ledPort, 0x11, 0x51, 0x01, red, green, blue]);
|
data = Buffer.from([0x81, this._ledPort, 0x11, 0x51, 0x01, red, green, blue]);
|
||||||
this._writeMessage(Consts.BLECharacteristic.LPF2_ALL, data);
|
this.send(Consts.BLECharacteristic.LPF2_ALL, data);
|
||||||
return resolve();
|
return resolve();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -144,24 +146,14 @@ export class LPF2Hub extends Hub {
|
|||||||
|
|
||||||
public sendRaw (message: Buffer) {
|
public sendRaw (message: Buffer) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
this._writeMessage(Consts.BLECharacteristic.LPF2_ALL, message, () => {
|
this.send(Consts.BLECharacteristic.LPF2_ALL, message, () => {
|
||||||
return resolve();
|
return resolve();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
protected _activatePortDevice (port: number, type: number, mode: number, format: number, callback?: () => void) {
|
public send (uuid: string, message: Buffer, callback?: () => void) {
|
||||||
this._writeMessage(Consts.BLECharacteristic.LPF2_ALL, Buffer.from([0x41, port, mode, 0x01, 0x00, 0x00, 0x00, 0x01]), callback);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
protected _deactivatePortDevice (port: number, type: number, mode: number, format: number, callback?: () => void) {
|
|
||||||
this._writeMessage(Consts.BLECharacteristic.LPF2_ALL, Buffer.from([0x41, port, mode, 0x01, 0x00, 0x00, 0x00, 0x00]), callback);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
protected _writeMessage (uuid: string, message: Buffer, callback?: () => void) {
|
|
||||||
message = Buffer.concat([Buffer.alloc(2), message]);
|
message = Buffer.concat([Buffer.alloc(2), message]);
|
||||||
message[0] = message.length;
|
message[0] = message.length;
|
||||||
debug("Sent Message (LPF2_ALL)", message);
|
debug("Sent Message (LPF2_ALL)", message);
|
||||||
@ -169,6 +161,16 @@ export class LPF2Hub extends Hub {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
protected _activatePortDevice (port: number, type: number, mode: number, format: number, callback?: () => void) {
|
||||||
|
this.send(Consts.BLECharacteristic.LPF2_ALL, Buffer.from([0x41, port, mode, 0x01, 0x00, 0x00, 0x00, 0x01]), callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
protected _deactivatePortDevice (port: number, type: number, mode: number, format: number, callback?: () => void) {
|
||||||
|
this.send(Consts.BLECharacteristic.LPF2_ALL, Buffer.from([0x41, port, mode, 0x01, 0x00, 0x00, 0x00, 0x00]), callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
protected _combinePorts (port: string, type: number) {
|
protected _combinePorts (port: string, type: number) {
|
||||||
if (!this._ports[port]) {
|
if (!this._ports[port]) {
|
||||||
return;
|
return;
|
||||||
@ -178,7 +180,7 @@ export class LPF2Hub extends Hub {
|
|||||||
Object.keys(this._ports).forEach((id) => {
|
Object.keys(this._ports).forEach((id) => {
|
||||||
if (this._ports[id].type === type && this._ports[id].value !== portObj.value && !this._virtualPorts[`${portObj.value < this._ports[id].value ? portObj.id : this._ports[id].id}${portObj.value > this._ports[id].value ? portObj.id : this._ports[id].id}`]) {
|
if (this._ports[id].type === type && this._ports[id].value !== portObj.value && !this._virtualPorts[`${portObj.value < this._ports[id].value ? portObj.id : this._ports[id].id}${portObj.value > this._ports[id].value ? portObj.id : this._ports[id].id}`]) {
|
||||||
debug("Combining ports", portObj.value < this._ports[id].value ? portObj.id : id, portObj.value > this._ports[id].value ? portObj.id : id);
|
debug("Combining ports", portObj.value < this._ports[id].value ? portObj.id : id, portObj.value > this._ports[id].value ? portObj.id : id);
|
||||||
this._writeMessage(Consts.BLECharacteristic.LPF2_ALL, Buffer.from([0x61, 0x01, portObj.value < this._ports[id].value ? portObj.value : this._ports[id].value, portObj.value > this._ports[id].value ? portObj.value : this._ports[id].value]));
|
this.send(Consts.BLECharacteristic.LPF2_ALL, Buffer.from([0x61, 0x01, portObj.value < this._ports[id].value ? portObj.value : this._ports[id].value, portObj.value > this._ports[id].value ? portObj.value : this._ports[id].value]));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -291,48 +293,73 @@ export class LPF2Hub extends Hub {
|
|||||||
|
|
||||||
private _parsePortMessage (data: Buffer) {
|
private _parsePortMessage (data: Buffer) {
|
||||||
|
|
||||||
let port = this._getPortForPortNumber(data[3]);
|
const portId = data[3];
|
||||||
const type = data[4] ? data.readUInt16LE(5) : 0;
|
const event = data[4];
|
||||||
|
const deviceType = event ? data.readUInt16LE(5) : 0;
|
||||||
|
|
||||||
if (data[4] === 0x01 && modeInfoDebug.enabled) {
|
if (event === 0x01) {
|
||||||
const typeName = Consts.DeviceTypeNames[data[5]] || "unknown";
|
|
||||||
modeInfoDebug(`Port ${toHex(data[3])}, type ${toHex(type, 4)} (${typeName})`);
|
let device;
|
||||||
const hwVersion = LPF2Hub.decodeVersion(data.readInt32LE(7));
|
|
||||||
const swVersion = LPF2Hub.decodeVersion(data.readInt32LE(11));
|
switch (deviceType) {
|
||||||
modeInfoDebug(`Port ${toHex(data[3])}, hardware version ${hwVersion}, software version ${swVersion}`);
|
case Consts.DeviceType.CONTROL_PLUS_LARGE_MOTOR:
|
||||||
this._sendPortInformationRequest(data[3]);
|
device = new ControlPlusLargeMotor(this, portId);
|
||||||
|
break;
|
||||||
|
case Consts.DeviceType.COLOR_DISTANCE_SENSOR:
|
||||||
|
device = new ColorDistanceSensor(this, portId);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
device = new Device(this, portId, deviceType);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!port) {
|
this._registerDeviceAttachment(device);
|
||||||
if (data[4] === 0x02) {
|
|
||||||
const portA = this._getPortForPortNumber(data[7]);
|
|
||||||
const portB = this._getPortForPortNumber(data[8]);
|
|
||||||
if (portA && portB) {
|
|
||||||
this._virtualPorts[`${portA.id}${portB.id}`] = new Port(`${portA.id}${portB.id}`, data[3]);
|
|
||||||
port = this._getPortForPortNumber(data[3]);
|
|
||||||
if (port) {
|
|
||||||
port.connected = true;
|
|
||||||
this._registerDeviceAttachment(port, type);
|
|
||||||
} else {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
port.connected = (data[4] === 0x01 || data[4] === 0x02) ? true : false;
|
|
||||||
this._registerDeviceAttachment(port, type);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// let port = this._getPortForPortNumber(data[3]);
|
||||||
|
|
||||||
|
// if (data[4] === 0x01 && modeInfoDebug.enabled) {
|
||||||
|
// const typeName = Consts.DeviceTypeNames[data[5]] || "unknown";
|
||||||
|
// modeInfoDebug(`Port ${toHex(data[3])}, type ${toHex(deviceType, 4)} (${typeName})`);
|
||||||
|
// const hwVersion = LPF2Hub.decodeVersion(data.readInt32LE(7));
|
||||||
|
// const swVersion = LPF2Hub.decodeVersion(data.readInt32LE(11));
|
||||||
|
// modeInfoDebug(`Port ${toHex(data[3])}, hardware version ${hwVersion}, software version ${swVersion}`);
|
||||||
|
// this._sendPortInformationRequest(data[3]);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// if (!port) {
|
||||||
|
// if (data[4] === 0x02) {
|
||||||
|
// const portA = this._getPortForPortNumber(data[7]);
|
||||||
|
// const portB = this._getPortForPortNumber(data[8]);
|
||||||
|
// if (portA && portB) {
|
||||||
|
// this._virtualPorts[`${portA.id}${portB.id}`] = new Port(`${portA.id}${portB.id}`, data[3]);
|
||||||
|
// port = this._getPortForPortNumber(data[3]);
|
||||||
|
// if (port) {
|
||||||
|
// port.connected = true;
|
||||||
|
// this._registerDeviceAttachment(port, deviceType);
|
||||||
|
// } else {
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
// } else {
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
// } else {
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
// } else {
|
||||||
|
// port.connected = (data[4] === 0x01 || data[4] === 0x02) ? true : false;
|
||||||
|
// this._registerDeviceAttachment(port, deviceType);
|
||||||
|
// }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private _sendPortInformationRequest (port: number) {
|
private _sendPortInformationRequest (port: number) {
|
||||||
this._writeMessage(Consts.BLECharacteristic.LPF2_ALL, Buffer.from([0x21, port, 0x01]));
|
this.send(Consts.BLECharacteristic.LPF2_ALL, Buffer.from([0x21, port, 0x01]));
|
||||||
this._writeMessage(Consts.BLECharacteristic.LPF2_ALL, Buffer.from([0x21, port, 0x02])); // Mode combinations
|
this.send(Consts.BLECharacteristic.LPF2_ALL, Buffer.from([0x21, port, 0x02])); // Mode combinations
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -363,7 +390,7 @@ export class LPF2Hub extends Hub {
|
|||||||
|
|
||||||
|
|
||||||
private _sendModeInformationRequest (port: number, mode: number, type: number) {
|
private _sendModeInformationRequest (port: number, mode: number, type: number) {
|
||||||
this._writeMessage(Consts.BLECharacteristic.LPF2_ALL, Buffer.from([0x22, port, mode, type]));
|
this.send(Consts.BLECharacteristic.LPF2_ALL, Buffer.from([0x22, port, mode, type]));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -461,7 +488,7 @@ export class LPF2Hub extends Hub {
|
|||||||
this.emit("distance", port.id, distance * 10);
|
this.emit("distance", port.id, distance * 10);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Consts.DeviceType.BOOST_DISTANCE: {
|
case Consts.DeviceType.COLOR_DISTANCE_SENSOR: {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Emits when a color sensor is activated.
|
* Emits when a color sensor is activated.
|
||||||
|
@ -2,11 +2,11 @@ import { Characteristic, Peripheral, Service } from "@abandonware/noble";
|
|||||||
|
|
||||||
import Debug = require("debug");
|
import Debug = require("debug");
|
||||||
import { EventEmitter } from "events";
|
import { EventEmitter } from "events";
|
||||||
import { IBLEDevice } from "./interfaces";
|
import { IBLEAbstraction } from "./interfaces";
|
||||||
const debug = Debug("bledevice");
|
const debug = Debug("bledevice");
|
||||||
|
|
||||||
|
|
||||||
export class NobleDevice extends EventEmitter implements IBLEDevice {
|
export class NobleDevice extends EventEmitter implements IBLEAbstraction {
|
||||||
|
|
||||||
private _noblePeripheral: Peripheral;
|
private _noblePeripheral: Peripheral;
|
||||||
|
|
@ -4,7 +4,7 @@ import { DuploTrainBase } from "./duplotrainbase";
|
|||||||
import { Hub } from "./hub";
|
import { Hub } from "./hub";
|
||||||
import { PUPHub } from "./puphub";
|
import { PUPHub } from "./puphub";
|
||||||
import { PUPRemote } from "./pupremote";
|
import { PUPRemote } from "./pupremote";
|
||||||
import { WebBLEDevice } from "./webbledevice";
|
import { WebBLEDevice } from "./webbleabstraction";
|
||||||
import { WeDo2SmartHub } from "./wedo2smarthub";
|
import { WeDo2SmartHub } from "./wedo2smarthub";
|
||||||
|
|
||||||
import * as Consts from "./consts";
|
import * as Consts from "./consts";
|
||||||
@ -12,7 +12,7 @@ import * as Consts from "./consts";
|
|||||||
import { EventEmitter } from "events";
|
import { EventEmitter } from "events";
|
||||||
|
|
||||||
import Debug = require("debug");
|
import Debug = require("debug");
|
||||||
import { IBLEDevice } from "./interfaces";
|
import { IBLEAbstraction } from "./interfaces";
|
||||||
const debug = Debug("poweredup");
|
const debug = Debug("poweredup");
|
||||||
|
|
||||||
|
|
||||||
@ -118,7 +118,7 @@ export class PoweredUP extends EventEmitter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private _determineLPF2HubType (device: IBLEDevice): Promise<Consts.HubType> {
|
private _determineLPF2HubType (device: IBLEAbstraction): Promise<Consts.HubType> {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
let buf: Buffer = Buffer.alloc(0);
|
let buf: Buffer = Buffer.alloc(0);
|
||||||
device.subscribeToCharacteristic(Consts.BLECharacteristic.LPF2_ALL, (data: Buffer) => {
|
device.subscribeToCharacteristic(Consts.BLECharacteristic.LPF2_ALL, (data: Buffer) => {
|
||||||
|
@ -4,7 +4,7 @@ import { BoostMoveHub } from "./boostmovehub";
|
|||||||
import { ControlPlusHub } from "./controlplushub";
|
import { ControlPlusHub } from "./controlplushub";
|
||||||
import { DuploTrainBase } from "./duplotrainbase";
|
import { DuploTrainBase } from "./duplotrainbase";
|
||||||
import { Hub } from "./hub";
|
import { Hub } from "./hub";
|
||||||
import { NobleDevice } from "./nobledevice";
|
import { NobleDevice } from "./nobleabstraction";
|
||||||
import { PUPHub } from "./puphub";
|
import { PUPHub } from "./puphub";
|
||||||
import { PUPRemote } from "./pupremote";
|
import { PUPRemote } from "./pupremote";
|
||||||
import { WeDo2SmartHub } from "./wedo2smarthub";
|
import { WeDo2SmartHub } from "./wedo2smarthub";
|
||||||
|
@ -7,7 +7,7 @@ import { Port } from "./port";
|
|||||||
import * as Consts from "./consts";
|
import * as Consts from "./consts";
|
||||||
|
|
||||||
import Debug = require("debug");
|
import Debug = require("debug");
|
||||||
import { IBLEDevice } from "./interfaces";
|
import { IBLEAbstraction } from "./interfaces";
|
||||||
const debug = Debug("puphub");
|
const debug = Debug("puphub");
|
||||||
|
|
||||||
|
|
||||||
@ -34,7 +34,7 @@ export class PUPHub extends LPF2Hub {
|
|||||||
protected _currentPort = 0x3b;
|
protected _currentPort = 0x3b;
|
||||||
protected _voltagePort = 0x3c;
|
protected _voltagePort = 0x3c;
|
||||||
|
|
||||||
constructor (device: IBLEDevice, autoSubscribe: boolean = true) {
|
constructor (device: IBLEAbstraction, autoSubscribe: boolean = true) {
|
||||||
super(device, autoSubscribe);
|
super(device, autoSubscribe);
|
||||||
this.type = Consts.HubType.POWERED_UP_HUB;
|
this.type = Consts.HubType.POWERED_UP_HUB;
|
||||||
this._ports = {
|
this._ports = {
|
||||||
@ -99,17 +99,17 @@ export class PUPHub extends LPF2Hub {
|
|||||||
data = Buffer.from([0x81, portObj.value, 0x11, 0x09, 0x00, 0x00, this._mapSpeed(speed), 0x64, 0x7f, 0x03]);
|
data = Buffer.from([0x81, portObj.value, 0x11, 0x09, 0x00, 0x00, this._mapSpeed(speed), 0x64, 0x7f, 0x03]);
|
||||||
}
|
}
|
||||||
data.writeUInt16LE(time > 65535 ? 65535 : time, 4);
|
data.writeUInt16LE(time > 65535 ? 65535 : time, 4);
|
||||||
this._writeMessage(Consts.BLECharacteristic.LPF2_ALL, data);
|
this.send(Consts.BLECharacteristic.LPF2_ALL, data);
|
||||||
portObj.finished = () => {
|
portObj.finished = () => {
|
||||||
return resolve();
|
return resolve();
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
// @ts-ignore: The type of speed is properly checked at the start
|
// @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)]);
|
const data = Buffer.from([0x81, portObj.value, 0x11, 0x51, 0x00, this._mapSpeed(speed)]);
|
||||||
this._writeMessage(Consts.BLECharacteristic.LPF2_ALL, data);
|
this.send(Consts.BLECharacteristic.LPF2_ALL, data);
|
||||||
const timeout = global.setTimeout(() => {
|
const timeout = global.setTimeout(() => {
|
||||||
const data = Buffer.from([0x81, portObj.value, 0x11, 0x51, 0x00, 0x00]);
|
const data = Buffer.from([0x81, portObj.value, 0x11, 0x51, 0x00, 0x00]);
|
||||||
this._writeMessage(Consts.BLECharacteristic.LPF2_ALL, data);
|
this.send(Consts.BLECharacteristic.LPF2_ALL, data);
|
||||||
return resolve();
|
return resolve();
|
||||||
// @ts-ignore: The type of time is properly checked at the start
|
// @ts-ignore: The type of time is properly checked at the start
|
||||||
}, time);
|
}, time);
|
||||||
@ -127,14 +127,14 @@ export class PUPHub extends LPF2Hub {
|
|||||||
// @ts-ignore: The type of speed is properly checked at the start
|
// @ts-ignore: The type of speed is properly checked at the start
|
||||||
data = Buffer.from([0x81, portObj.value, 0x11, 0x01, this._mapSpeed(speed), 0x64, 0x7f, 0x03]);
|
data = Buffer.from([0x81, portObj.value, 0x11, 0x01, this._mapSpeed(speed), 0x64, 0x7f, 0x03]);
|
||||||
}
|
}
|
||||||
this._writeMessage(Consts.BLECharacteristic.LPF2_ALL, data);
|
this.send(Consts.BLECharacteristic.LPF2_ALL, data);
|
||||||
portObj.finished = () => {
|
portObj.finished = () => {
|
||||||
return resolve();
|
return resolve();
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
// @ts-ignore: The type of speed is properly checked at the start
|
// @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)]);
|
const data = Buffer.from([0x81, portObj.value, 0x11, 0x51, 0x00, this._mapSpeed(speed)]);
|
||||||
this._writeMessage(Consts.BLECharacteristic.LPF2_ALL, data);
|
this.send(Consts.BLECharacteristic.LPF2_ALL, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -196,7 +196,7 @@ export class PUPHub extends LPF2Hub {
|
|||||||
data = Buffer.from([0x81, portObj.value, 0x11, 0x0b, 0x00, 0x00, 0x00, 0x00, this._mapSpeed(speed), 0x64, 0x7f, 0x03]);
|
data = Buffer.from([0x81, portObj.value, 0x11, 0x0b, 0x00, 0x00, 0x00, 0x00, this._mapSpeed(speed), 0x64, 0x7f, 0x03]);
|
||||||
}
|
}
|
||||||
data.writeUInt32LE(angle, 4);
|
data.writeUInt32LE(angle, 4);
|
||||||
this._writeMessage(Consts.BLECharacteristic.LPF2_ALL, data);
|
this.send(Consts.BLECharacteristic.LPF2_ALL, data);
|
||||||
portObj.finished = () => {
|
portObj.finished = () => {
|
||||||
return resolve();
|
return resolve();
|
||||||
};
|
};
|
||||||
@ -233,7 +233,7 @@ export class PUPHub extends LPF2Hub {
|
|||||||
data = Buffer.from([0x81, portObj.value, 0x11, 0x0d, 0x00, 0x00, 0x00, 0x00, this._mapSpeed(speed), 0x64, 0x7f, 0x03]);
|
data = Buffer.from([0x81, portObj.value, 0x11, 0x0d, 0x00, 0x00, 0x00, 0x00, this._mapSpeed(speed), 0x64, 0x7f, 0x03]);
|
||||||
data.writeInt32LE(pos, 4);
|
data.writeInt32LE(pos, 4);
|
||||||
}
|
}
|
||||||
this._writeMessage(Consts.BLECharacteristic.LPF2_ALL, data);
|
this.send(Consts.BLECharacteristic.LPF2_ALL, data);
|
||||||
portObj.finished = () => {
|
portObj.finished = () => {
|
||||||
return resolve();
|
return resolve();
|
||||||
};
|
};
|
||||||
@ -257,23 +257,12 @@ export class PUPHub extends LPF2Hub {
|
|||||||
}
|
}
|
||||||
return new Promise((resolve) => {
|
return new Promise((resolve) => {
|
||||||
const data = Buffer.from([0x81, portObj.value, 0x11, 0x51, 0x02, 0x00, 0x00, 0x00, 0x00]);
|
const data = Buffer.from([0x81, portObj.value, 0x11, 0x51, 0x02, 0x00, 0x00, 0x00, 0x00]);
|
||||||
this._writeMessage(Consts.BLECharacteristic.LPF2_ALL, data);
|
this.send(Consts.BLECharacteristic.LPF2_ALL, data);
|
||||||
return resolve();
|
return resolve();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Fully (hard) stop the motor on a given port.
|
|
||||||
* @method PUPHub#brakeMotor
|
|
||||||
* @param {string} port
|
|
||||||
* @returns {Promise} Resolved upon successful completion of command.
|
|
||||||
*/
|
|
||||||
public brakeMotor (port: string) {
|
|
||||||
return this.setMotorSpeed(port, 127);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the light brightness on a given port.
|
* Set the light brightness on a given port.
|
||||||
* @method PUPHub#setLightBrightness
|
* @method PUPHub#setLightBrightness
|
||||||
@ -287,11 +276,11 @@ export class PUPHub extends LPF2Hub {
|
|||||||
portObj.cancelEventTimer();
|
portObj.cancelEventTimer();
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
const data = Buffer.from([0x81, portObj.value, 0x11, 0x51, 0x00, brightness]);
|
const data = Buffer.from([0x81, portObj.value, 0x11, 0x51, 0x00, brightness]);
|
||||||
this._writeMessage(Consts.BLECharacteristic.LPF2_ALL, data);
|
this.send(Consts.BLECharacteristic.LPF2_ALL, data);
|
||||||
if (time) {
|
if (time) {
|
||||||
const timeout = global.setTimeout(() => {
|
const timeout = global.setTimeout(() => {
|
||||||
const data = Buffer.from([0x81, portObj.value, 0x11, 0x51, 0x00, 0x00]);
|
const data = Buffer.from([0x81, portObj.value, 0x11, 0x51, 0x00, 0x00]);
|
||||||
this._writeMessage(Consts.BLECharacteristic.LPF2_ALL, data);
|
this.send(Consts.BLECharacteristic.LPF2_ALL, data);
|
||||||
return resolve();
|
return resolve();
|
||||||
}, time);
|
}, time);
|
||||||
portObj.setEventTimer(timeout);
|
portObj.setEventTimer(timeout);
|
||||||
|
@ -6,7 +6,7 @@ import { Port } from "./port";
|
|||||||
import * as Consts from "./consts";
|
import * as Consts from "./consts";
|
||||||
|
|
||||||
import Debug = require("debug");
|
import Debug = require("debug");
|
||||||
import { IBLEDevice } from "./interfaces";
|
import { IBLEAbstraction } from "./interfaces";
|
||||||
const debug = Debug("pupremote");
|
const debug = Debug("pupremote");
|
||||||
|
|
||||||
|
|
||||||
@ -37,7 +37,7 @@ export class PUPRemote extends LPF2Hub {
|
|||||||
protected _voltageMaxRaw = 3200;
|
protected _voltageMaxRaw = 3200;
|
||||||
|
|
||||||
|
|
||||||
constructor (device: IBLEDevice, autoSubscribe: boolean = true) {
|
constructor (device: IBLEAbstraction, autoSubscribe: boolean = true) {
|
||||||
super(device, autoSubscribe);
|
super(device, autoSubscribe);
|
||||||
this.type = Consts.HubType.POWERED_UP_REMOTE;
|
this.type = Consts.HubType.POWERED_UP_REMOTE;
|
||||||
this._ports = {
|
this._ports = {
|
||||||
|
12
src/simplemediumlinearmotor.ts
Normal file
12
src/simplemediumlinearmotor.ts
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
import { BasicMotor } from "./basicmotor";
|
||||||
|
import { Hub } from "./hub";
|
||||||
|
|
||||||
|
import * as Consts from "./consts";
|
||||||
|
|
||||||
|
export class SimpleMediumLinearMotor extends BasicMotor {
|
||||||
|
|
||||||
|
constructor (hub: Hub, portId: number) {
|
||||||
|
super(hub, portId, Consts.DeviceType.SIMPLE_MEDIUM_LINEAR_MOTOR);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
12
src/trainmotor.ts
Normal file
12
src/trainmotor.ts
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
import { BasicMotor } from "./basicmotor";
|
||||||
|
import { Hub } from "./hub";
|
||||||
|
|
||||||
|
import * as Consts from "./consts";
|
||||||
|
|
||||||
|
export class TrainMotor extends BasicMotor {
|
||||||
|
|
||||||
|
constructor (hub: Hub, portId: number) {
|
||||||
|
super(hub, portId, Consts.DeviceType.TRAIN_MOTOR);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,10 +1,10 @@
|
|||||||
import Debug = require("debug");
|
import Debug = require("debug");
|
||||||
import { EventEmitter } from "events";
|
import { EventEmitter } from "events";
|
||||||
import { IBLEDevice } from "./interfaces";
|
import { IBLEAbstraction } from "./interfaces";
|
||||||
const debug = Debug("bledevice");
|
const debug = Debug("bledevice");
|
||||||
|
|
||||||
|
|
||||||
export class WebBLEDevice extends EventEmitter implements IBLEDevice {
|
export class WebBLEDevice extends EventEmitter implements IBLEAbstraction {
|
||||||
|
|
||||||
private _webBLEServer: any;
|
private _webBLEServer: any;
|
||||||
|
|
@ -1,12 +1,16 @@
|
|||||||
import { Peripheral } from "@abandonware/noble";
|
import { Peripheral } from "@abandonware/noble";
|
||||||
|
|
||||||
|
import { Device } from "./device";
|
||||||
import { Hub } from "./hub";
|
import { Hub } from "./hub";
|
||||||
import { Port } from "./port";
|
import { Port } from "./port";
|
||||||
|
|
||||||
|
import { ColorDistanceSensor } from "./colordistancesensor";
|
||||||
|
import { ControlPlusLargeMotor } from "./controlpluslargemotor";
|
||||||
|
|
||||||
import * as Consts from "./consts";
|
import * as Consts from "./consts";
|
||||||
|
|
||||||
import Debug = require("debug");
|
import Debug = require("debug");
|
||||||
import { IBLEDevice } from "./interfaces";
|
import { IBLEAbstraction } from "./interfaces";
|
||||||
import { isWebBluetooth } from "./utils";
|
import { isWebBluetooth } from "./utils";
|
||||||
const debug = Debug("wedo2smarthub");
|
const debug = Debug("wedo2smarthub");
|
||||||
|
|
||||||
@ -32,7 +36,7 @@ export class WeDo2SmartHub extends Hub {
|
|||||||
private _lastTiltY: number = 0;
|
private _lastTiltY: number = 0;
|
||||||
|
|
||||||
|
|
||||||
constructor (device: IBLEDevice, autoSubscribe: boolean = true) {
|
constructor (device: IBLEAbstraction, autoSubscribe: boolean = true) {
|
||||||
super(device, autoSubscribe);
|
super(device, autoSubscribe);
|
||||||
this.type = Consts.HubType.WEDO2_SMART_HUB;
|
this.type = Consts.HubType.WEDO2_SMART_HUB;
|
||||||
this._ports = {
|
this._ports = {
|
||||||
@ -111,8 +115,8 @@ export class WeDo2SmartHub extends Hub {
|
|||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
const data = Buffer.from(name, "ascii");
|
const data = Buffer.from(name, "ascii");
|
||||||
// Send this twice, as sometimes the first time doesn't take
|
// Send this twice, as sometimes the first time doesn't take
|
||||||
this._writeMessage(Consts.BLECharacteristic.WEDO2_NAME_ID, data);
|
this.send(Consts.BLECharacteristic.WEDO2_NAME_ID, data);
|
||||||
this._writeMessage(Consts.BLECharacteristic.WEDO2_NAME_ID, data);
|
this.send(Consts.BLECharacteristic.WEDO2_NAME_ID, data);
|
||||||
this._name = name;
|
this._name = name;
|
||||||
return resolve();
|
return resolve();
|
||||||
});
|
});
|
||||||
@ -128,12 +132,12 @@ export class WeDo2SmartHub extends Hub {
|
|||||||
public setLEDColor (color: number | boolean) {
|
public setLEDColor (color: number | boolean) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
let data = Buffer.from([0x06, 0x17, 0x01, 0x01]);
|
let data = Buffer.from([0x06, 0x17, 0x01, 0x01]);
|
||||||
this._writeMessage(Consts.BLECharacteristic.WEDO2_PORT_TYPE_WRITE, data);
|
this.send(Consts.BLECharacteristic.WEDO2_PORT_TYPE_WRITE, data);
|
||||||
if (typeof color === "boolean") {
|
if (typeof color === "boolean") {
|
||||||
color = 0;
|
color = 0;
|
||||||
}
|
}
|
||||||
data = Buffer.from([0x06, 0x04, 0x01, color]);
|
data = Buffer.from([0x06, 0x04, 0x01, color]);
|
||||||
this._writeMessage(Consts.BLECharacteristic.WEDO2_MOTOR_VALUE_WRITE, data);
|
this.send(Consts.BLECharacteristic.WEDO2_MOTOR_VALUE_WRITE, data);
|
||||||
return resolve();
|
return resolve();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -146,7 +150,7 @@ export class WeDo2SmartHub extends Hub {
|
|||||||
*/
|
*/
|
||||||
public shutdown () {
|
public shutdown () {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
this._writeMessage(Consts.BLECharacteristic.WEDO2_DISCONNECT, Buffer.from([0x00]), () => {
|
this.send(Consts.BLECharacteristic.WEDO2_DISCONNECT, Buffer.from([0x00]), () => {
|
||||||
return resolve();
|
return resolve();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -164,9 +168,9 @@ export class WeDo2SmartHub extends Hub {
|
|||||||
public setLEDRGB (red: number, green: number, blue: number) {
|
public setLEDRGB (red: number, green: number, blue: number) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
let data = Buffer.from([0x06, 0x17, 0x01, 0x02]);
|
let data = Buffer.from([0x06, 0x17, 0x01, 0x02]);
|
||||||
this._writeMessage(Consts.BLECharacteristic.WEDO2_PORT_TYPE_WRITE, data);
|
this.send(Consts.BLECharacteristic.WEDO2_PORT_TYPE_WRITE, data);
|
||||||
data = Buffer.from([0x06, 0x04, 0x03, red, green, blue]);
|
data = Buffer.from([0x06, 0x04, 0x03, red, green, blue]);
|
||||||
this._writeMessage(Consts.BLECharacteristic.WEDO2_MOTOR_VALUE_WRITE, data);
|
this.send(Consts.BLECharacteristic.WEDO2_MOTOR_VALUE_WRITE, data);
|
||||||
return resolve();
|
return resolve();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -193,10 +197,10 @@ export class WeDo2SmartHub extends Hub {
|
|||||||
portObj.cancelEventTimer();
|
portObj.cancelEventTimer();
|
||||||
}
|
}
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
this._writeMessage(Consts.BLECharacteristic.WEDO2_MOTOR_VALUE_WRITE, Buffer.from([portObj.value, 0x01, 0x02, this._mapSpeed(speed)]));
|
this.send(Consts.BLECharacteristic.WEDO2_MOTOR_VALUE_WRITE, Buffer.from([portObj.value, 0x01, 0x02, this._mapSpeed(speed)]));
|
||||||
if (time && typeof time === "number") {
|
if (time && typeof time === "number") {
|
||||||
const timeout = global.setTimeout(() => {
|
const timeout = global.setTimeout(() => {
|
||||||
this._writeMessage(Consts.BLECharacteristic.WEDO2_MOTOR_VALUE_WRITE, Buffer.from([portObj.value, 0x01, 0x02, 0x00]));
|
this.send(Consts.BLECharacteristic.WEDO2_MOTOR_VALUE_WRITE, Buffer.from([portObj.value, 0x01, 0x02, 0x00]));
|
||||||
return resolve();
|
return resolve();
|
||||||
}, time);
|
}, time);
|
||||||
portObj.setEventTimer(timeout);
|
portObj.setEventTimer(timeout);
|
||||||
@ -252,7 +256,7 @@ export class WeDo2SmartHub extends Hub {
|
|||||||
const data = Buffer.from([0x05, 0x02, 0x04, 0x00, 0x00, 0x00, 0x00]);
|
const data = Buffer.from([0x05, 0x02, 0x04, 0x00, 0x00, 0x00, 0x00]);
|
||||||
data.writeUInt16LE(frequency, 3);
|
data.writeUInt16LE(frequency, 3);
|
||||||
data.writeUInt16LE(time, 5);
|
data.writeUInt16LE(time, 5);
|
||||||
this._writeMessage(Consts.BLECharacteristic.WEDO2_MOTOR_VALUE_WRITE, data);
|
this.send(Consts.BLECharacteristic.WEDO2_MOTOR_VALUE_WRITE, data);
|
||||||
global.setTimeout(resolve, time);
|
global.setTimeout(resolve, time);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -271,11 +275,11 @@ export class WeDo2SmartHub extends Hub {
|
|||||||
portObj.cancelEventTimer();
|
portObj.cancelEventTimer();
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
const data = Buffer.from([portObj.value, 0x01, 0x02, brightness]);
|
const data = Buffer.from([portObj.value, 0x01, 0x02, brightness]);
|
||||||
this._writeMessage(Consts.BLECharacteristic.WEDO2_MOTOR_VALUE_WRITE, data);
|
this.send(Consts.BLECharacteristic.WEDO2_MOTOR_VALUE_WRITE, data);
|
||||||
if (time) {
|
if (time) {
|
||||||
const timeout = global.setTimeout(() => {
|
const timeout = global.setTimeout(() => {
|
||||||
const data = Buffer.from([portObj.value, 0x01, 0x02, 0x00]);
|
const data = Buffer.from([portObj.value, 0x01, 0x02, 0x00]);
|
||||||
this._writeMessage(Consts.BLECharacteristic.WEDO2_MOTOR_VALUE_WRITE, data);
|
this.send(Consts.BLECharacteristic.WEDO2_MOTOR_VALUE_WRITE, data);
|
||||||
return resolve();
|
return resolve();
|
||||||
}, time);
|
}, time);
|
||||||
portObj.setEventTimer(timeout);
|
portObj.setEventTimer(timeout);
|
||||||
@ -286,26 +290,7 @@ export class WeDo2SmartHub extends Hub {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public sendRaw (message: Buffer, characteristic: string = Consts.BLECharacteristic.WEDO2_MOTOR_VALUE_WRITE) {
|
public send (uuid: string, message: Buffer, callback?: () => void) {
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
this._writeMessage(characteristic, message, () => {
|
|
||||||
return resolve();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
protected _activatePortDevice (port: number, type: number, mode: number, format: number, callback?: () => void) {
|
|
||||||
this._writeMessage(Consts.BLECharacteristic.WEDO2_PORT_TYPE_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) {
|
|
||||||
this._writeMessage(Consts.BLECharacteristic.WEDO2_PORT_TYPE_WRITE, Buffer.from([0x01, 0x02, port, type, mode, 0x01, 0x00, 0x00, 0x00, format, 0x00]), callback);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private _writeMessage (uuid: string, message: Buffer, callback?: () => void) {
|
|
||||||
if (debug.enabled) {
|
if (debug.enabled) {
|
||||||
debug(`Sent Message (${this._getCharacteristicNameFromUUID(uuid)})`, message);
|
debug(`Sent Message (${this._getCharacteristicNameFromUUID(uuid)})`, message);
|
||||||
}
|
}
|
||||||
@ -313,6 +298,16 @@ export class WeDo2SmartHub extends Hub {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
protected _activatePortDevice (port: number, type: number, mode: number, format: number, callback?: () => void) {
|
||||||
|
this.send(Consts.BLECharacteristic.WEDO2_PORT_TYPE_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) {
|
||||||
|
this.send(Consts.BLECharacteristic.WEDO2_PORT_TYPE_WRITE, Buffer.from([0x01, 0x02, port, type, mode, 0x01, 0x00, 0x00, 0x00, format, 0x00]), callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private _getCharacteristicNameFromUUID (uuid: string) {
|
private _getCharacteristicNameFromUUID (uuid: string) {
|
||||||
const keys = Object.keys(Consts.BLECharacteristic);
|
const keys = Object.keys(Consts.BLECharacteristic);
|
||||||
for (let i = 0; i < keys.length; i++) {
|
for (let i = 0; i < keys.length; i++) {
|
||||||
@ -346,14 +341,38 @@ export class WeDo2SmartHub extends Hub {
|
|||||||
|
|
||||||
debug("Received Message (WEDO2_PORT_TYPE)", data);
|
debug("Received Message (WEDO2_PORT_TYPE)", data);
|
||||||
|
|
||||||
const port = this._getPortForPortNumber(data[0]);
|
const portId = data[0];
|
||||||
|
const event = data[1];
|
||||||
|
const deviceType = event ? data[3] : 0;
|
||||||
|
|
||||||
if (!port) {
|
if (event === 0x01) {
|
||||||
return;
|
|
||||||
|
let device;
|
||||||
|
|
||||||
|
switch (deviceType) {
|
||||||
|
case Consts.DeviceType.CONTROL_PLUS_LARGE_MOTOR:
|
||||||
|
device = new ControlPlusLargeMotor(this, portId);
|
||||||
|
break;
|
||||||
|
case Consts.DeviceType.COLOR_DISTANCE_SENSOR:
|
||||||
|
device = new ColorDistanceSensor(this, portId);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
device = new Device(this, portId);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
port.connected = data[1] === 1 ? true : false;
|
this._registerDeviceAttachment(device);
|
||||||
this._registerDeviceAttachment(port, data[3]);
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// const port = this._getPortForPortNumber(data[0]);
|
||||||
|
|
||||||
|
// if (!port) {
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// port.connected = data[1] === 1 ? true : false;
|
||||||
|
// this._registerDeviceAttachment(port, data[3]);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -408,7 +427,7 @@ export class WeDo2SmartHub extends Hub {
|
|||||||
this.emit("distance", port.id, distance * 10);
|
this.emit("distance", port.id, distance * 10);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Consts.DeviceType.BOOST_DISTANCE: {
|
case Consts.DeviceType.COLOR_DISTANCE_SENSOR: {
|
||||||
const distance = data[2];
|
const distance = data[2];
|
||||||
/**
|
/**
|
||||||
* Emits when a color sensor is activated.
|
* Emits when a color sensor is activated.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user