mirror of
https://github.com/scratchfoundation/scratch-vm.git
synced 2024-12-24 06:52:40 -05:00
WeDo2 rate limiting (#1509)
* Starting work on #1456: rate limiting. * Fixing #1456: rate limit send messages. * Chaining a couple of send operation Promises. * Fixing linting.
This commit is contained in:
parent
d1761466fc
commit
ab7f24bf9a
1 changed files with 78 additions and 8 deletions
|
@ -24,6 +24,12 @@ const UUID = {
|
||||||
OUTPUT_COMMAND: '00001565-1212-efde-1523-785feabcd123'
|
OUTPUT_COMMAND: '00001565-1212-efde-1523-785feabcd123'
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A time interval to wait (in milliseconds) while a block that sends a BLE message is running.
|
||||||
|
* @type {number}
|
||||||
|
*/
|
||||||
|
const BLESendInterval = 100;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enum for WeDo2 sensor and output types.
|
* Enum for WeDo2 sensor and output types.
|
||||||
* @readonly
|
* @readonly
|
||||||
|
@ -340,6 +346,19 @@ class WeDo2 {
|
||||||
distance: 0
|
distance: 0
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A flag that is true while we are busy sendng data to the BLE session.
|
||||||
|
* @type {boolean}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
this._sending = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ID for a timeout which is used to clear the sending flag if it has been
|
||||||
|
* true for a long time.
|
||||||
|
*/
|
||||||
|
this._sendingTimeoutID = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The Bluetooth connection session for reading/writing device data.
|
* The Bluetooth connection session for reading/writing device data.
|
||||||
* @type {BLESession}
|
* @type {BLESession}
|
||||||
|
@ -396,7 +415,7 @@ class WeDo2 {
|
||||||
/**
|
/**
|
||||||
* Set the WeDo 2.0 hub's LED to a specific color.
|
* Set the WeDo 2.0 hub's LED to a specific color.
|
||||||
* @param {int} rgb - a 24-bit RGB color in 0xRRGGBB format.
|
* @param {int} rgb - a 24-bit RGB color in 0xRRGGBB format.
|
||||||
* @return {Promise} - a promise of the set led send operation.
|
* @return {Promise} - a promise of the completion of the set led send operation.
|
||||||
*/
|
*/
|
||||||
setLED (rgb) {
|
setLED (rgb) {
|
||||||
const cmd = new Uint8Array(6);
|
const cmd = new Uint8Array(6);
|
||||||
|
@ -412,6 +431,7 @@ class WeDo2 {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Switch off the LED on the WeDo2.
|
* Switch off the LED on the WeDo2.
|
||||||
|
* @return {Promise} - a promise of the completion of the stop led send operation.
|
||||||
*/
|
*/
|
||||||
stopLED () {
|
stopLED () {
|
||||||
const cmd = new Uint8Array(6);
|
const cmd = new Uint8Array(6);
|
||||||
|
@ -422,13 +442,14 @@ class WeDo2 {
|
||||||
cmd[4] = 0x000000;
|
cmd[4] = 0x000000;
|
||||||
cmd[5] = 0x000000;
|
cmd[5] = 0x000000;
|
||||||
|
|
||||||
this._send(UUID.OUTPUT_COMMAND, Base64Util.uint8ArrayToBase64(cmd));
|
return this._send(UUID.OUTPUT_COMMAND, Base64Util.uint8ArrayToBase64(cmd));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Play a tone from the WeDo 2.0 hub for a specific amount of time.
|
* Play a tone from the WeDo 2.0 hub for a specific amount of time.
|
||||||
* @param {int} tone - the pitch of the tone, in Hz.
|
* @param {int} tone - the pitch of the tone, in Hz.
|
||||||
* @param {int} milliseconds - the duration of the note, in milliseconds.
|
* @param {int} milliseconds - the duration of the note, in milliseconds.
|
||||||
|
* @return {Promise} - a promise of the completion of the play tone send operation.
|
||||||
*/
|
*/
|
||||||
playTone (tone, milliseconds) {
|
playTone (tone, milliseconds) {
|
||||||
const cmd = new Uint8Array(7);
|
const cmd = new Uint8Array(7);
|
||||||
|
@ -440,18 +461,19 @@ class WeDo2 {
|
||||||
cmd[5] = milliseconds;
|
cmd[5] = milliseconds;
|
||||||
cmd[6] = milliseconds >> 8;
|
cmd[6] = milliseconds >> 8;
|
||||||
|
|
||||||
this._send(UUID.OUTPUT_COMMAND, Base64Util.uint8ArrayToBase64(cmd));
|
return this._send(UUID.OUTPUT_COMMAND, Base64Util.uint8ArrayToBase64(cmd));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Stop the tone playing from the WeDo 2.0 hub, if any.
|
* Stop the tone playing from the WeDo 2.0 hub, if any.
|
||||||
|
* @return {Promise} - a promise that the command sent.
|
||||||
*/
|
*/
|
||||||
stopTone () {
|
stopTone () {
|
||||||
const cmd = new Uint8Array(2);
|
const cmd = new Uint8Array(2);
|
||||||
cmd[0] = WeDo2ConnectIDs.PIEZO; // connect id
|
cmd[0] = WeDo2ConnectIDs.PIEZO; // connect id
|
||||||
cmd[1] = WeDo2Commands.STOP_TONE; // command
|
cmd[1] = WeDo2Commands.STOP_TONE; // command
|
||||||
|
|
||||||
this._send(UUID.OUTPUT_COMMAND, Base64Util.uint8ArrayToBase64(cmd));
|
return this._send(UUID.OUTPUT_COMMAND, Base64Util.uint8ArrayToBase64(cmd));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -526,7 +548,19 @@ class WeDo2 {
|
||||||
*/
|
*/
|
||||||
_send (uuid, message) {
|
_send (uuid, message) {
|
||||||
if (!this.getPeripheralIsConnected()) return;
|
if (!this.getPeripheralIsConnected()) return;
|
||||||
return this._ble.write(UUID.IO_SERVICE, uuid, message, 'base64');
|
if (this._sending) return;
|
||||||
|
|
||||||
|
this._sending = true;
|
||||||
|
|
||||||
|
this._sendingTimeoutID = window.setTimeout(() => {
|
||||||
|
this._sending = false;
|
||||||
|
}, 5000);
|
||||||
|
|
||||||
|
return this._ble.write(UUID.IO_SERVICE, uuid, message, 'base64')
|
||||||
|
.then(() => {
|
||||||
|
this._sending = false;
|
||||||
|
window.clearTimeout(this._sendingTimeoutID);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -657,9 +691,10 @@ class WeDo2 {
|
||||||
* Stop the tone playing and motors on the WeDo 2.0 hub.
|
* Stop the tone playing and motors on the WeDo 2.0 hub.
|
||||||
*/
|
*/
|
||||||
_stopAll () {
|
_stopAll () {
|
||||||
this.stopTone();
|
this.stopTone()
|
||||||
|
.then(() => {
|
||||||
this.stopAllMotors();
|
this.stopAllMotors();
|
||||||
// this.stopLED();
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -988,6 +1023,7 @@ class Scratch3WeDo2Blocks {
|
||||||
* Turn specified motor(s) on indefinitely.
|
* Turn specified motor(s) on indefinitely.
|
||||||
* @param {object} args - the block's arguments.
|
* @param {object} args - the block's arguments.
|
||||||
* @property {MotorID} MOTOR_ID - the motor(s) to activate.
|
* @property {MotorID} MOTOR_ID - the motor(s) to activate.
|
||||||
|
* @return {Promise} - a Promise that resolves after some delay.
|
||||||
*/
|
*/
|
||||||
motorOn (args) {
|
motorOn (args) {
|
||||||
this._forEachMotor(args.MOTOR_ID, motorIndex => {
|
this._forEachMotor(args.MOTOR_ID, motorIndex => {
|
||||||
|
@ -996,12 +1032,19 @@ class Scratch3WeDo2Blocks {
|
||||||
motor.setMotorOn();
|
motor.setMotorOn();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
return new Promise(resolve => {
|
||||||
|
window.setTimeout(() => {
|
||||||
|
resolve();
|
||||||
|
}, BLESendInterval);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Turn specified motor(s) off.
|
* Turn specified motor(s) off.
|
||||||
* @param {object} args - the block's arguments.
|
* @param {object} args - the block's arguments.
|
||||||
* @property {MotorID} MOTOR_ID - the motor(s) to deactivate.
|
* @property {MotorID} MOTOR_ID - the motor(s) to deactivate.
|
||||||
|
* @return {Promise} - a Promise that resolves after some delay.
|
||||||
*/
|
*/
|
||||||
motorOff (args) {
|
motorOff (args) {
|
||||||
this._forEachMotor(args.MOTOR_ID, motorIndex => {
|
this._forEachMotor(args.MOTOR_ID, motorIndex => {
|
||||||
|
@ -1010,6 +1053,12 @@ class Scratch3WeDo2Blocks {
|
||||||
motor.setMotorOff();
|
motor.setMotorOff();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
return new Promise(resolve => {
|
||||||
|
window.setTimeout(() => {
|
||||||
|
resolve();
|
||||||
|
}, BLESendInterval);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1017,6 +1066,7 @@ class Scratch3WeDo2Blocks {
|
||||||
* @param {object} args - the block's arguments.
|
* @param {object} args - the block's arguments.
|
||||||
* @property {MotorID} MOTOR_ID - the motor(s) to be affected.
|
* @property {MotorID} MOTOR_ID - the motor(s) to be affected.
|
||||||
* @property {int} POWER - the new power level for the motor(s).
|
* @property {int} POWER - the new power level for the motor(s).
|
||||||
|
* @return {Promise} - a Promise that resolves after some delay.
|
||||||
*/
|
*/
|
||||||
startMotorPower (args) {
|
startMotorPower (args) {
|
||||||
this._forEachMotor(args.MOTOR_ID, motorIndex => {
|
this._forEachMotor(args.MOTOR_ID, motorIndex => {
|
||||||
|
@ -1026,6 +1076,12 @@ class Scratch3WeDo2Blocks {
|
||||||
motor.setMotorOn();
|
motor.setMotorOn();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
return new Promise(resolve => {
|
||||||
|
window.setTimeout(() => {
|
||||||
|
resolve();
|
||||||
|
}, BLESendInterval);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1034,6 +1090,7 @@ class Scratch3WeDo2Blocks {
|
||||||
* @param {object} args - the block's arguments.
|
* @param {object} args - the block's arguments.
|
||||||
* @property {MotorID} MOTOR_ID - the motor(s) to be affected.
|
* @property {MotorID} MOTOR_ID - the motor(s) to be affected.
|
||||||
* @property {MotorDirection} MOTOR_DIRECTION - the new direction for the motor(s).
|
* @property {MotorDirection} MOTOR_DIRECTION - the new direction for the motor(s).
|
||||||
|
* @return {Promise} - a Promise that resolves after some delay.
|
||||||
*/
|
*/
|
||||||
setMotorDirection (args) {
|
setMotorDirection (args) {
|
||||||
this._forEachMotor(args.MOTOR_ID, motorIndex => {
|
this._forEachMotor(args.MOTOR_ID, motorIndex => {
|
||||||
|
@ -1063,12 +1120,19 @@ class Scratch3WeDo2Blocks {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
return new Promise(resolve => {
|
||||||
|
window.setTimeout(() => {
|
||||||
|
resolve();
|
||||||
|
}, BLESendInterval);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the LED's hue.
|
* Set the LED's hue.
|
||||||
* @param {object} args - the block's arguments.
|
* @param {object} args - the block's arguments.
|
||||||
* @property {number} HUE - the hue to set, in the range [0,100].
|
* @property {number} HUE - the hue to set, in the range [0,100].
|
||||||
|
* @return {Promise} - a Promise that resolves after some delay.
|
||||||
*/
|
*/
|
||||||
setLightHue (args) {
|
setLightHue (args) {
|
||||||
// Convert from [0,100] to [0,360]
|
// Convert from [0,100] to [0,360]
|
||||||
|
@ -1081,6 +1145,12 @@ class Scratch3WeDo2Blocks {
|
||||||
const rgbDecimal = color.rgbToDecimal(rgbObject);
|
const rgbDecimal = color.rgbToDecimal(rgbObject);
|
||||||
|
|
||||||
this._device.setLED(rgbDecimal);
|
this._device.setLED(rgbDecimal);
|
||||||
|
|
||||||
|
return new Promise(resolve => {
|
||||||
|
window.setTimeout(() => {
|
||||||
|
resolve();
|
||||||
|
}, BLESendInterval);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Reference in a new issue