Now fetches firmware revisions for WeDo 2.0 Smart Hubs

This commit is contained in:
Nathan Kellenicki 2019-01-18 14:46:31 -08:00
parent d62f8535a2
commit 47a0f56d0d
5 changed files with 64 additions and 25 deletions

View File

@ -137,6 +137,7 @@ export enum BLEService {
export enum BLECharacteristic { export enum BLECharacteristic {
WEDO2_BATTERY = "2a19", WEDO2_BATTERY = "2a19",
WEDO2_FIRMWARE_REVISION = "2a26",
WEDO2_BUTTON = "00001526-1212-efde-1523-785feabcd123", // "1526" WEDO2_BUTTON = "00001526-1212-efde-1523-785feabcd123", // "1526"
WEDO2_PORT_TYPE = "00001527-1212-efde-1523-785feabcd123", // "1527" // Handles plugging and unplugging of devices on WeDo 2.0 Smart Hub WEDO2_PORT_TYPE = "00001527-1212-efde-1523-785feabcd123", // "1527" // Handles plugging and unplugging of devices on WeDo 2.0 Smart Hub
WEDO2_LOW_VOLTAGE_ALERT = "00001528-1212-efde-1523-785feabcd123", // "1528" WEDO2_LOW_VOLTAGE_ALERT = "00001528-1212-efde-1523-785feabcd123", // "1528"

View File

@ -9,6 +9,14 @@ import Debug = require("debug");
const debug = Debug("hub"); const debug = Debug("hub");
export interface IFirmwareInfo {
major: number;
minor: number;
bugFix: number;
build: number;
}
/** /**
* @class Hub * @class Hub
* @ignore * @ignore
@ -25,7 +33,7 @@ export class Hub extends EventEmitter {
protected _characteristics: {[uuid: string]: Characteristic} = {}; protected _characteristics: {[uuid: string]: Characteristic} = {};
protected _name: string; protected _name: string;
protected _firmwareVersion: string = "0.0.0.0"; protected _firmwareInfo: IFirmwareInfo = { major: 0, minor: 0, bugFix: 0, build: 0 };
protected _batteryLevel: number = 100; protected _batteryLevel: number = 100;
private _peripheral: Peripheral; private _peripheral: Peripheral;
@ -55,7 +63,7 @@ export class Hub extends EventEmitter {
* @property {string} firmwareVersion Firmware version of the hub * @property {string} firmwareVersion Firmware version of the hub
*/ */
public get firmwareVersion () { public get firmwareVersion () {
return this._firmwareVersion; return `${this._firmwareInfo.major}.${this._firmwareInfo.minor}.${this._lpad(this._firmwareInfo.bugFix.toString(), 2)}.${this._lpad(this._firmwareInfo.build.toString(), 4)}`;
} }
@ -366,7 +374,7 @@ export class Hub extends EventEmitter {
}, delay); }, delay);
port.setEventTimer(interval); port.setEventTimer(interval);
return emitter; return emitter;
} }
protected _portLookup (port: string) { protected _portLookup (port: string) {
@ -377,6 +385,14 @@ export class Hub extends EventEmitter {
} }
protected _lpad (str: string, length: number) {
while (str.length < length) {
str = "0" + str;
}
return str;
}
private _getModeForDeviceType (type: Consts.DeviceType) { private _getModeForDeviceType (type: Consts.DeviceType) {
switch (type) { switch (type) {
case Consts.DeviceType.BASIC_MOTOR: case Consts.DeviceType.BASIC_MOTOR:

View File

@ -6,6 +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 { promises } from "fs";
const debug = Debug("lpf2hub"); const debug = Debug("lpf2hub");
@ -39,14 +40,16 @@ export class LPF2Hub extends Hub {
await super.connect(); await super.connect();
const characteristic = this._getCharacteristic(Consts.BLECharacteristic.LPF2_ALL); const characteristic = this._getCharacteristic(Consts.BLECharacteristic.LPF2_ALL);
this._subscribeToCharacteristic(characteristic, this._parseMessage.bind(this)); this._subscribeToCharacteristic(characteristic, this._parseMessage.bind(this));
setTimeout(() => {
this._writeMessage(Consts.BLECharacteristic.LPF2_ALL, Buffer.from([0x01, 0x03, 0x05])); // Request firmware version
this._writeMessage(Consts.BLECharacteristic.LPF2_ALL, Buffer.from([0x01, 0x02, 0x02])); // Activate button reports this._writeMessage(Consts.BLECharacteristic.LPF2_ALL, Buffer.from([0x01, 0x02, 0x02])); // Activate button reports
this._writeMessage(Consts.BLECharacteristic.LPF2_ALL, Buffer.from([0x01, 0x03, 0x05])); // Get firmware version this._writeMessage(Consts.BLECharacteristic.LPF2_ALL, Buffer.from([0x01, 0x06, 0x02])); // Activate battery level reports
this._writeMessage(Consts.BLECharacteristic.LPF2_ALL, Buffer.from([0x01, 0x06, 0x02])); // Get battery level?
this._writeMessage(Consts.BLECharacteristic.LPF2_ALL, Buffer.from([0x41, 0x3b, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01])); // Activate current reports this._writeMessage(Consts.BLECharacteristic.LPF2_ALL, Buffer.from([0x41, 0x3b, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01])); // Activate current reports
this._writeMessage(Consts.BLECharacteristic.LPF2_ALL, Buffer.from([0x41, 0x3c, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01])); // Activate voltage reports this._writeMessage(Consts.BLECharacteristic.LPF2_ALL, Buffer.from([0x41, 0x3c, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01])); // Activate voltage 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._writeMessage(Consts.BLECharacteristic.LPF2_ALL, Buffer.from([0x41, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01]));
} }
}, 1000);
return resolve(); return resolve();
}); });
} }
@ -113,6 +116,15 @@ export class LPF2Hub extends Hub {
} }
public sendRaw (message: Buffer) {
return new Promise((resolve, reject) => {
this._writeMessage(Consts.BLECharacteristic.LPF2_ALL, message, () => {
return resolve();
});
});
}
protected _activatePortDevice (port: number, type: number, mode: number, format: number, callback?: () => void) { protected _activatePortDevice (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, 0x01]), callback); this._writeMessage(Consts.BLECharacteristic.LPF2_ALL, Buffer.from([0x41, port, mode, 0x01, 0x00, 0x00, 0x00, 0x01]), callback);
} }
@ -178,8 +190,6 @@ export class LPF2Hub extends Hub {
private _parseDeviceInfo (data: Buffer) { private _parseDeviceInfo (data: Buffer) {
console.log(data);
if (data[3] === 2) { if (data[3] === 2) {
if (data[5] === 1) { if (data[5] === 1) {
/** /**
@ -195,17 +205,11 @@ export class LPF2Hub extends Hub {
return; return;
} }
} else if (data[3] === 3) { } else if (data[3] === 3) {
const fwData = data.slice(5, data.length); const build = data.readUInt16LE(5);
let bcd = fwData.readUInt8(3); const bugFix = data.readUInt8(7);
const major = bcd >>> 4; const major = data.readUInt8(8) >>> 4;
const minor = bcd & 0xf; const minor = data.readUInt8(8) & 0xf;
bcd = fwData.readUInt8(2); this._firmwareInfo = { major, minor, bugFix, build };
const bugFix = bcd >>> 4 * 10 + bcd & 0xf;
bcd = fwData.readUInt8(1);
let build = bcd >>> 4 * 1000 + bcd & 0xf * 100;
bcd = fwData.readUInt8(0);
build = build + bcd >>> 4 * 10 + bcd & 0xf;
this._firmwareVersion = `${major}.${minor}.${bugFix}.${build}`;
} }
} }

View File

@ -57,6 +57,9 @@ export class WeDo2SmartHub extends Hub {
this._getCharacteristic(Consts.BLECharacteristic.WEDO2_BATTERY).read((err, data) => { this._getCharacteristic(Consts.BLECharacteristic.WEDO2_BATTERY).read((err, data) => {
this._parseBatteryMessage(data); this._parseBatteryMessage(data);
}); });
this._getCharacteristic(Consts.BLECharacteristic.WEDO2_FIRMWARE_REVISION).read((err, data) => {
this._parseFirmwareRevisionString(data);
});
debug("Connect completed"); debug("Connect completed");
return resolve(); return resolve();
}); });
@ -237,6 +240,15 @@ export class WeDo2SmartHub extends Hub {
} }
public sendRaw (message: Buffer, characteristic: string = Consts.BLECharacteristic.WEDO2_MOTOR_VALUE_WRITE) {
return new Promise((resolve, reject) => {
this._writeMessage(characteristic, message, () => {
return resolve();
});
});
}
protected _activatePortDevice (port: number, type: number, mode: number, format: number, callback?: () => void) { 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); this._writeMessage(Consts.BLECharacteristic.WEDO2_PORT_TYPE_WRITE, Buffer.from([0x01, 0x02, port, type, mode, 0x01, 0x00, 0x00, 0x00, format, 0x01]), callback);
} }
@ -265,6 +277,12 @@ export class WeDo2SmartHub extends Hub {
} }
private _parseFirmwareRevisionString (data: Buffer) {
const parts = data.toString().split(".");
this._firmwareInfo = { major: parseInt(parts[0], 10), minor: parseInt(parts[1], 10), bugFix: parseInt(parts[2], 10), build: parseInt(parts[3], 10) };
}
private _parsePortMessage (data: Buffer) { private _parsePortMessage (data: Buffer) {
const port = this._getPortForPortNumber(data[0]); const port = this._getPortForPortNumber(data[0]);

View File

@ -14,7 +14,7 @@
"typedef": true, "typedef": true,
"no-console": false, "no-console": false,
"variable-name": [true, "ban-keywords", "check-format", "allow-leading-underscore"], "variable-name": [true, "ban-keywords", "check-format", "allow-leading-underscore"],
"object-literal-key-quotes": "consistent", "object-literal-key-quotes": false,
"object-literal-sort-keys": false, "object-literal-sort-keys": false,
"no-string-literal": false, "no-string-literal": false,
"no-shadowed-variable": [false] "no-shadowed-variable": [false]