diff --git a/src/extensions/scratch3_boost/index.js b/src/extensions/scratch3_boost/index.js index 29a8640b2..ed5a3a440 100644 --- a/src/extensions/scratch3_boost/index.js +++ b/src/extensions/scratch3_boost/index.js @@ -93,13 +93,24 @@ const BoostPortFeedback = { * @readonly * @enum {number} */ -const BoostPort = { + +const BoostPort10000223OrOlder = { A: 55, B: 56, C: 1, D: 2 }; +const BoostPort10000224OrNewer = { + A: 0, + B: 1, + C: 2, + D: 3 +}; + +// Set default port mapping to support the newer firmware +let BoostPort = BoostPort10000224OrNewer; + /** * Ids for each color sensor value used by the extension. * @readonly @@ -154,6 +165,45 @@ const BoostMessage = { PORT_FEEDBACK: 0x82 }; +/** + * Enum for Hub Property Types + * @readonly + * @enum {number} + */ + +const BoostHubProperty = { + ADVERTISEMENT_NAME: 0x01, + BUTTON: 0x02, + FW_VERSION: 0x03, + HW_VERSION: 0x04, + RSSI: 0x05, + BATTERY_VOLTAGE: 0x06, + BATTERY_TYPE: 0x07, + MANUFACTURER_NAME: 0x08, + RADIO_FW_VERSION: 0x09, + LEGO_WP_VERSION: 0x0A, + SYSTEM_TYPE_ID: 0x0B, + HW_NETWORK_ID: 0x0C, + PRIMARY_MAC: 0x0D, + SECONDARY_MAC: 0x0E, + HW_NETWORK_FAMILY: 0x0F +}; + +/** + * Enum for Hub Property Operations + * @readonly + * @enum {number} + */ + +const BoostHubPropertyOperation = { + SET: 0x01, + ENABLE_UPDATES: 0x02, + DISABLE_UPDATES: 0x03, + RESET: 0x04, + REQUEST_UPDATE: 0x05, + UPDATE: 0x06 +}; + /** * Enum for Motor Subcommands (for 0x81) * @readonly @@ -944,6 +994,19 @@ class Boost { this._onMessage ); this._pingDeviceId = window.setInterval(this._pingDevice, BoostPingInterval); + + // Send a request for firmware version. + setTimeout(() => { + const command = [ + 0x00, // Hub ID + BoostMessage.HUB_PROPERTIES, + BoostHubProperty.FW_VERSION, + BoostHubPropertyOperation.REQUEST_UPDATE + ]; + command.unshift(command.length + 1); + this.send(BoostBLE.characteristic, command, false); + }, 500); + } /** @@ -967,6 +1030,25 @@ class Boost { const portID = data[3]; switch (messageType) { + + case BoostMessage.HUB_PROPERTIES: { + const property = data[3]; + switch (property) { + case BoostHubProperty.FW_VERSION: { + // Establish firmware version 1.0.00.0224 as a 32-bit signed integer (little endian) + const fwVersion10000224 = int32ArrayToNumber([0x24, 0x02, 0x00, 0x10]); + const fwHub = int32ArrayToNumber(data.slice(5, data.length)); + if (fwHub < fwVersion10000224) { + BoostPort = BoostPort10000223OrOlder; + log.info('Move Hub firmware older than version 1.0.00.0224 detected. Using old port mapping.'); + } else { + BoostPort = BoostPort10000224OrNewer; + } + break; + } + } + break; + } case BoostMessage.HUB_ATTACHED_IO: { // IO Attach/Detach events const event = data[4]; const typeId = data[5]; @@ -1011,6 +1093,7 @@ class Boost { break; case BoostIO.CURRENT: case BoostIO.VOLTAGE: + case BoostIO.LED: break; default: log.warn(`Unknown sensor value! Type: ${type}`); @@ -1851,7 +1934,7 @@ class Scratch3BoostBlocks { log.warn('Asked for a motor position that doesnt exist!'); return false; } - if (portID && this._peripheral.motor(portID)) { + if (portID !== null && this._peripheral.motor(portID)) { let val = this._peripheral.motor(portID).position; // Boost motor A position direction is reversed by design // so we have to reverse the position here