diff --git a/src/extensions/scratch3_ev3/index.js b/src/extensions/scratch3_ev3/index.js index d2dd6bbf6..b24dac572 100644 --- a/src/extensions/scratch3_ev3/index.js +++ b/src/extensions/scratch3_ev3/index.js @@ -266,6 +266,8 @@ class EV3Motor { * @param {number} milliseconds - run the motor for this long. */ turnOnFor (milliseconds) { + if (this._power === 0) return; + const port = this._portMask(this._index); let n = milliseconds; let speed = this._power * this._direction; @@ -323,6 +325,8 @@ class EV3Motor { * @param {number} time - the time in milliseconds. */ coastAfter (time) { + if (this._power === 0) return; + // Set the motor command id to check before starting coast const commandId = uid(); this._commandID = commandId; @@ -341,6 +345,8 @@ class EV3Motor { * Set the motor to coast. */ coast () { + if (this._power === 0) return; + const cmd = this._parent.generateCommand( Ev3Command.DIRECT_COMMAND_NO_REPLY, [ diff --git a/src/extensions/scratch3_microbit/index.js b/src/extensions/scratch3_microbit/index.js index f3f6b22e0..03b78b57f 100644 --- a/src/extensions/scratch3_microbit/index.js +++ b/src/extensions/scratch3_microbit/index.js @@ -328,7 +328,7 @@ class MicroBit { * @readonly * @enum {string} */ -const TiltDirection = { +const MicroBitTiltDirection = { FRONT: 'front', BACK: 'back', LEFT: 'left', @@ -341,7 +341,7 @@ const TiltDirection = { * @readonly * @enum {string} */ -const Gestures = { +const MicroBitGestures = { MOVED: 'moved', SHAKEN: 'shaken', JUMPED: 'jumped' @@ -352,7 +352,7 @@ const Gestures = { * @readonly * @enum {string} */ -const Buttons = { +const MicroBitButtons = { A: 'A', B: 'B', ANY: 'any' @@ -363,7 +363,7 @@ const Buttons = { * @readonly * @enum {string} */ -const PinState = { +const MicroBitPinState = { ON: 'on', OFF: 'off' }; @@ -401,11 +401,11 @@ class Scratch3MicroBitBlocks { return [ { text: 'A', - value: Buttons.A + value: MicroBitButtons.A }, { text: 'B', - value: Buttons.B + value: MicroBitButtons.B }, { text: formatMessage({ @@ -413,7 +413,7 @@ class Scratch3MicroBitBlocks { default: 'any', description: 'label for "any" element in button picker for micro:bit extension' }), - value: Buttons.ANY + value: MicroBitButtons.ANY } ]; } @@ -429,7 +429,7 @@ class Scratch3MicroBitBlocks { default: 'moved', description: 'label for moved gesture in gesture picker for micro:bit extension' }), - value: Gestures.MOVED + value: MicroBitGestures.MOVED }, { text: formatMessage({ @@ -437,7 +437,7 @@ class Scratch3MicroBitBlocks { default: 'shaken', description: 'label for shaken gesture in gesture picker for micro:bit extension' }), - value: Gestures.SHAKEN + value: MicroBitGestures.SHAKEN }, { text: formatMessage({ @@ -445,7 +445,7 @@ class Scratch3MicroBitBlocks { default: 'jumped', description: 'label for jumped gesture in gesture picker for micro:bit extension' }), - value: Gestures.JUMPED + value: MicroBitGestures.JUMPED } ]; } @@ -461,7 +461,7 @@ class Scratch3MicroBitBlocks { default: 'on', description: 'label for on element in pin state picker for micro:bit extension' }), - value: PinState.ON + value: MicroBitPinState.ON }, { text: formatMessage({ @@ -469,7 +469,7 @@ class Scratch3MicroBitBlocks { default: 'off', description: 'label for off element in pin state picker for micro:bit extension' }), - value: PinState.OFF + value: MicroBitPinState.OFF } ]; } @@ -485,7 +485,7 @@ class Scratch3MicroBitBlocks { default: 'front', description: 'label for front element in tilt direction picker for micro:bit extension' }), - value: TiltDirection.FRONT + value: MicroBitTiltDirection.FRONT }, { text: formatMessage({ @@ -493,7 +493,7 @@ class Scratch3MicroBitBlocks { default: 'back', description: 'label for back element in tilt direction picker for micro:bit extension' }), - value: TiltDirection.BACK + value: MicroBitTiltDirection.BACK }, { text: formatMessage({ @@ -501,7 +501,7 @@ class Scratch3MicroBitBlocks { default: 'left', description: 'label for left element in tilt direction picker for micro:bit extension' }), - value: TiltDirection.LEFT + value: MicroBitTiltDirection.LEFT }, { text: formatMessage({ @@ -509,7 +509,7 @@ class Scratch3MicroBitBlocks { default: 'right', description: 'label for right element in tilt direction picker for micro:bit extension' }), - value: TiltDirection.RIGHT + value: MicroBitTiltDirection.RIGHT } ]; } @@ -526,7 +526,7 @@ class Scratch3MicroBitBlocks { default: 'any', description: 'label for any direction element in tilt direction picker for micro:bit extension' }), - value: TiltDirection.ANY + value: MicroBitTiltDirection.ANY } ]; } @@ -568,7 +568,7 @@ class Scratch3MicroBitBlocks { BTN: { type: ArgumentType.STRING, menu: 'buttons', - defaultValue: Buttons.A + defaultValue: MicroBitButtons.A } } }, @@ -584,7 +584,7 @@ class Scratch3MicroBitBlocks { BTN: { type: ArgumentType.STRING, menu: 'buttons', - defaultValue: Buttons.A + defaultValue: MicroBitButtons.A } } }, @@ -601,7 +601,7 @@ class Scratch3MicroBitBlocks { GESTURE: { type: ArgumentType.STRING, menu: 'gestures', - defaultValue: Gestures.MOVED + defaultValue: MicroBitGestures.MOVED } } }, @@ -667,7 +667,7 @@ class Scratch3MicroBitBlocks { DIRECTION: { type: ArgumentType.STRING, menu: 'tiltDirectionAny', - defaultValue: TiltDirection.ANY + defaultValue: MicroBitTiltDirection.ANY } } }, @@ -683,7 +683,7 @@ class Scratch3MicroBitBlocks { DIRECTION: { type: ArgumentType.STRING, menu: 'tiltDirectionAny', - defaultValue: TiltDirection.ANY + defaultValue: MicroBitTiltDirection.ANY } } }, @@ -699,7 +699,7 @@ class Scratch3MicroBitBlocks { DIRECTION: { type: ArgumentType.STRING, menu: 'tiltDirection', - defaultValue: TiltDirection.FRONT + defaultValue: MicroBitTiltDirection.FRONT } } }, @@ -887,7 +887,7 @@ class Scratch3MicroBitBlocks { */ _isTilted (direction) { switch (direction) { - case TiltDirection.ANY: + case MicroBitTiltDirection.ANY: return (Math.abs(this._peripheral.tiltX / 10) >= Scratch3MicroBitBlocks.TILT_THRESHOLD) || (Math.abs(this._peripheral.tiltY / 10) >= Scratch3MicroBitBlocks.TILT_THRESHOLD); default: @@ -903,13 +903,13 @@ class Scratch3MicroBitBlocks { */ _getTiltAngle (direction) { switch (direction) { - case TiltDirection.FRONT: + case MicroBitTiltDirection.FRONT: return Math.round(this._peripheral.tiltY / -10); - case TiltDirection.BACK: + case MicroBitTiltDirection.BACK: return Math.round(this._peripheral.tiltY / 10); - case TiltDirection.LEFT: + case MicroBitTiltDirection.LEFT: return Math.round(this._peripheral.tiltX / -10); - case TiltDirection.RIGHT: + case MicroBitTiltDirection.RIGHT: return Math.round(this._peripheral.tiltX / 10); default: log.warn(`Unknown tilt direction in _getTiltAngle: ${direction}`); diff --git a/src/extensions/scratch3_wedo2/index.js b/src/extensions/scratch3_wedo2/index.js index 95ff5102b..5781781f9 100644 --- a/src/extensions/scratch3_wedo2/index.js +++ b/src/extensions/scratch3_wedo2/index.js @@ -226,7 +226,15 @@ class WeDo2Motor { * @param {int} value - this motor's new power level, in the range [0,100]. */ set power (value) { - this._power = Math.max(0, Math.min(value, 100)); + const p = Math.max(0, Math.min(value, 100)); + // Lego Wedo 2.0 hub only turns motors at power range [30 - 100], so + // map value from [0 - 100] to [30 - 100]. + if (p === 0) { + this._power = 0; + } else { + const delta = 100 / p; + this._power = 30 + (70 / delta); + } } /** @@ -254,6 +262,8 @@ class WeDo2Motor { * Turn this motor on indefinitely. */ turnOn () { + if (this._power === 0) return; + const cmd = this._parent.generateOutputCommand( this._index + 1, WeDo2Command.MOTOR_POWER, @@ -271,6 +281,8 @@ class WeDo2Motor { * @param {number} milliseconds - run the motor for this long. */ turnOnFor (milliseconds) { + if (this._power === 0) return; + milliseconds = Math.max(0, milliseconds); this.turnOn(); this._setNewTimeout(this.startBraking, milliseconds); @@ -281,6 +293,8 @@ class WeDo2Motor { * // TODO: rename this to coastAfter? */ startBraking () { + if (this._power === 0) return; + const cmd = this._parent.generateOutputCommand( this._index + 1, WeDo2Command.MOTOR_POWER, @@ -298,6 +312,8 @@ class WeDo2Motor { * @param {boolean} [useLimiter=true] - if true, use the rate limiter */ turnOff (useLimiter = true) { + if (this._power === 0) return; + const cmd = this._parent.generateOutputCommand( this._index + 1, WeDo2Command.MOTOR_POWER, @@ -1077,28 +1093,136 @@ class Scratch3WeDo2Blocks { ], menus: { MOTOR_ID: [ - WeDo2MotorLabel.DEFAULT, - WeDo2MotorLabel.A, - WeDo2MotorLabel.B, - WeDo2MotorLabel.ALL + { + text: formatMessage({ + id: 'wedo2.motorId.default', + default: 'motor', + description: 'label for motor element in motor menu for LEGO WeDo 2 extension' + }), + value: WeDo2MotorLabel.DEFAULT + }, + { + text: formatMessage({ + id: 'wedo2.motorId.a', + default: 'motor A', + description: 'label for motor A element in motor menu for LEGO WeDo 2 extension' + }), + value: WeDo2MotorLabel.A + }, + { + text: formatMessage({ + id: 'wedo2.motorId.b', + default: 'motor B', + description: 'label for motor B element in motor menu for LEGO WeDo 2 extension' + }), + value: WeDo2MotorLabel.B + }, + { + text: formatMessage({ + id: 'wedo2.motorId.all', + default: 'all motors', + description: 'label for all motors element in motor menu for LEGO WeDo 2 extension' + }), + value: WeDo2MotorLabel.ALL + } ], MOTOR_DIRECTION: [ - WeDo2MotorDirection.FORWARD, - WeDo2MotorDirection.BACKWARD, - WeDo2MotorDirection.REVERSE + { + text: formatMessage({ + id: 'wedo2.motorDirection.forward', + default: 'this way', + description: 'label for forward element in motor direction menu for LEGO WeDo 2 extension' + }), + value: WeDo2MotorDirection.FORWARD + }, + { + text: formatMessage({ + id: 'wedo2.motorDirection.backward', + default: 'that way', + description: 'label for backward element in motor direction menu for LEGO WeDo 2 extension' + }), + value: WeDo2MotorDirection.BACKWARD + }, + { + text: formatMessage({ + id: 'wedo2.motorDirection.reverse', + default: 'reverse', + description: 'label for reverse element in motor direction menu for LEGO WeDo 2 extension' + }), + value: WeDo2MotorDirection.REVERSE + } ], TILT_DIRECTION: [ - WeDo2TiltDirection.UP, - WeDo2TiltDirection.DOWN, - WeDo2TiltDirection.LEFT, - WeDo2TiltDirection.RIGHT + { + text: formatMessage({ + id: 'wedo2.tiltDirection.up', + default: 'up', + description: 'label for up element in tilt direction menu for LEGO WeDo 2 extension' + }), + value: WeDo2TiltDirection.UP + }, + { + text: formatMessage({ + id: 'wedo2.tiltDirection.down', + default: 'down', + description: 'label for down element in tilt direction menu for LEGO WeDo 2 extension' + }), + value: WeDo2TiltDirection.DOWN + }, + { + text: formatMessage({ + id: 'wedo2.tiltDirection.left', + default: 'left', + description: 'label for left element in tilt direction menu for LEGO WeDo 2 extension' + }), + value: WeDo2TiltDirection.LEFT + }, + { + text: formatMessage({ + id: 'wedo2.tiltDirection.right', + default: 'right', + description: 'label for right element in tilt direction menu for LEGO WeDo 2 extension' + }), + value: WeDo2TiltDirection.RIGHT + } ], TILT_DIRECTION_ANY: [ - WeDo2TiltDirection.UP, - WeDo2TiltDirection.DOWN, - WeDo2TiltDirection.LEFT, - WeDo2TiltDirection.RIGHT, - WeDo2TiltDirection.ANY + { + text: formatMessage({ + id: 'wedo2.tiltDirection.up', + default: 'up' + }), + value: WeDo2TiltDirection.UP + }, + { + text: formatMessage({ + id: 'wedo2.tiltDirection.down', + default: 'down' + }), + value: WeDo2TiltDirection.DOWN + }, + { + text: formatMessage({ + id: 'wedo2.tiltDirection.left', + default: 'left' + }), + value: WeDo2TiltDirection.LEFT + }, + { + text: formatMessage({ + id: 'wedo2.tiltDirection.right', + default: 'right' + }), + value: WeDo2TiltDirection.RIGHT + }, + { + text: formatMessage({ + id: 'wedo2.tiltDirection.any', + default: 'any', + description: 'label for any element in tilt direction menu for LEGO WeDo 2 extension' + }), + value: WeDo2TiltDirection.ANY + } ], OP: ['<', '>'] } diff --git a/src/io/ble.js b/src/io/ble.js index af0dc3086..cf6530f8d 100644 --- a/src/io/ble.js +++ b/src/io/ble.js @@ -172,7 +172,7 @@ class BLE extends JSONRPCWebSocket { } _sendError (/* e */) { - this.disconnect(); + if (this._connected) this.disconnect(); // log.error(`BLE error: ${JSON.stringify(e)}`); this._runtime.emit(this._runtime.constructor.PERIPHERAL_ERROR, { message: `Scratch lost connection to`, diff --git a/src/io/bt.js b/src/io/bt.js index 60e74ff00..bf492f84a 100644 --- a/src/io/bt.js +++ b/src/io/bt.js @@ -115,7 +115,7 @@ class BT extends JSONRPCWebSocket { } _sendError (/* e */) { - this.disconnect(); + if (this._connected) this.disconnect(); // log.error(`BT error: ${JSON.stringify(e)}`); this._runtime.emit(this._runtime.constructor.PERIPHERAL_ERROR, { message: `Scratch lost connection to`,