diff --git a/src/consts.ts b/src/consts.ts index 0c70471..4a853e0 100644 --- a/src/consts.ts +++ b/src/consts.ts @@ -20,11 +20,7 @@ export enum HubType { // tslint:disable-next-line -export let HubTypeNames = Object.keys(HubType).reduce((result: {[hubType: string]: string}, item) => { - // @ts-ignore - result[HubType[item]] = item; - return result; -}, {}); +export const HubTypeNames = HubType; /** @@ -33,7 +29,10 @@ export let HubTypeNames = Object.keys(HubType).reduce((result: {[hubType: string * @property {number} BASIC_MOTOR 1 * @property {number} TRAIN_MOTOR 2 * @property {number} LED_LIGHTS 8 - * @property {number} BOOST_LED 22 + * @property {number} VOLTAGE 20 + * @property {number} CURRENT 21 + * @property {number} PIEZO_TONE 22 + * @property {number} RGB_LIGHT 23 * @property {number} WEDO2_TILT 34 * @property {number} WEDO2_DISTANCE 35 * @property {number} BOOST_DISTANCE 37 @@ -47,6 +46,7 @@ export let HubTypeNames = Object.keys(HubType).reduce((result: {[hubType: string * @property {number} CONTROL_PLUS_LARGE_MOTOR 46 * @property {number} CONTROL_PLUS_XLARGE_MOTOR 47 * @property {number} POWERED_UP_REMOTE_BUTTON 55 + * @property {number} RSSI 56 * @property {number} CONTROL_PLUS_ACCELEROMETER 58 * @property {number} CONTROL_PLUS_TILT 59 */ @@ -55,7 +55,10 @@ export enum DeviceType { BASIC_MOTOR = 1, TRAIN_MOTOR = 2, LED_LIGHTS = 8, - BOOST_LED = 22, + VOLTAGE = 20, + CURRENT = 21, + PIEZO_TONE = 22, + RGB_LIGHT = 23, WEDO2_TILT = 34, WEDO2_DISTANCE = 35, BOOST_DISTANCE = 37, @@ -69,17 +72,14 @@ export enum DeviceType { CONTROL_PLUS_LARGE_MOTOR = 46, CONTROL_PLUS_XLARGE_MOTOR = 47, POWERED_UP_REMOTE_BUTTON = 55, + RSSI = 56, CONTROL_PLUS_ACCELEROMETER = 58, CONTROL_PLUS_TILT = 59 } // tslint:disable-next-line -export let DeviceTypeNames = Object.keys(DeviceType).reduce((result: {[deviceType: string]: string}, item) => { - // @ts-ignore - result[DeviceType[item]] = item; - return result; -}, {}); +export const DeviceTypeNames = DeviceType; /** @@ -114,11 +114,7 @@ export enum Color { // tslint:disable-next-line -export let ColorNames = Object.keys(Color).reduce((result: {[color: string]: string}, item) => { - // @ts-ignore - result[Color[item]] = item; - return result; -}, {}); +export const ColorNames = Color; /** diff --git a/src/hub.ts b/src/hub.ts index 5dcd873..dff1883 100644 --- a/src/hub.ts +++ b/src/hub.ts @@ -362,15 +362,6 @@ export class Hub extends EventEmitter { return port; } - - protected _lpad (str: string, length: number) { - while (str.length < length) { - str = "0" + str; - } - return str; - } - - private _getModeForDeviceType (type: Consts.DeviceType) { switch (type) { case Consts.DeviceType.BASIC_MOTOR: diff --git a/src/lpf2hub.ts b/src/lpf2hub.ts index d65aa22..0e49b33 100644 --- a/src/lpf2hub.ts +++ b/src/lpf2hub.ts @@ -4,6 +4,7 @@ import { Hub } from "./hub"; import { Port } from "./port"; import * as Consts from "./consts"; +import { toBin, toHex } from "./utils"; import Debug = require("debug"); const debug = Debug("lpf2hub"); @@ -273,12 +274,17 @@ export class LPF2Hub extends Hub { } - private _parsePortMessage (data: Buffer) { let port = this._getPortForPortNumber(data[3]); + const type = data[4] ? data.readUInt16LE(5) : 0; - if (data[4] === 0x01 && process.env["PORT_DEBUG_INFO"]) { + if (data[4] === 0x01 && modeInfoDebug.enabled) { + const typeName = Consts.DeviceTypeNames[data[5]] || "unknown"; + modeInfoDebug(`Port ${toHex(data[3])}, type ${toHex(type, 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]); } @@ -291,7 +297,7 @@ export class LPF2Hub extends Hub { port = this._getPortForPortNumber(data[3]); if (port) { port.connected = true; - this._registerDeviceAttachment(port, data[5]); + this._registerDeviceAttachment(port, type); } else { return; } @@ -303,7 +309,7 @@ export class LPF2Hub extends Hub { } } else { port.connected = (data[4] === 0x01 || data[4] === 0x02) ? true : false; - this._registerDeviceAttachment(port, data[5]); + this._registerDeviceAttachment(port, type); } } @@ -311,15 +317,24 @@ export class LPF2Hub extends Hub { private _sendPortInformationRequest (port: number) { this._writeMessage(Consts.BLECharacteristic.LPF2_ALL, Buffer.from([0x21, port, 0x01])); + this._writeMessage(Consts.BLECharacteristic.LPF2_ALL, Buffer.from([0x21, port, 0x02])); // Mode combinations } private _parsePortInformationResponse (data: Buffer) { const port = data[3]; + if (data[4] === 2) { + const modeCombinationMasks: number[] = []; + for (let i = 5; i < data.length; i += 2) { + modeCombinationMasks.push(data.readUInt16LE(i)); + } + modeInfoDebug(`Port ${toHex(port)}, mode combinations [${modeCombinationMasks.map((c) => toBin(c, 0)).join(", ")}]`); + return; + } const count = data[6]; - const input = data.readUInt16LE(7); - const output = data.readUInt16LE(9); - modeInfoDebug(`Port ${port}, total modes ${count}, input modes ${input.toString(2)}, output modes ${output.toString(2)}`); + const input = toBin(data.readUInt16LE(7), count); + const output = toBin(data.readUInt16LE(9), count); + modeInfoDebug(`Port ${toHex(port)}, total modes ${count}, input modes ${input}, output modes ${output}`); for (let i = 0; i < count; i++) { this._sendModeInformationRequest(port, i, 0x00); // Mode Name @@ -327,6 +342,7 @@ export class LPF2Hub extends Hub { this._sendModeInformationRequest(port, i, 0x02); // PCT Range this._sendModeInformationRequest(port, i, 0x03); // SI Range this._sendModeInformationRequest(port, i, 0x04); // SI Symbol + this._sendModeInformationRequest(port, i, 0x80); // Value Format } } @@ -337,7 +353,7 @@ export class LPF2Hub extends Hub { private _parseModeInformationResponse (data: Buffer) { - const port = data[3]; + const port = toHex(data[3]); const mode = data[4]; const type = data[5]; switch (type) { @@ -356,6 +372,12 @@ export class LPF2Hub extends Hub { case 0x04: // SI Symbol modeInfoDebug(`Port ${port}, mode ${mode}, SI symbol ${data.slice(6, data.length).toString()}`); break; + case 0x80: // Value Format + const numValues = data[6]; + const dataType = ["8bit", "16bit", "32bit", "float"][data[7]]; + const totalFigures = data[8]; + const decimals = data[9]; + modeInfoDebug(`Port ${port}, mode ${mode}, Value ${numValues} x ${dataType}, Decimal format ${totalFigures}.${decimals}`); } } diff --git a/src/utils.ts b/src/utils.ts index 629b5ef..83650aa 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -1,2 +1,9 @@ // @ts-ignore export const isWebBluetooth = (typeof navigator !== "undefined" && navigator && navigator.bluetooth); + +export function toHex (value: number, length: number = 2) { + return value.toString(16).padStart(length, "0"); +} +export function toBin (value: number, length: number = 8) { + return value.toString(2).padStart(length, "0"); +}