Merge pull request #9 from bocoup/scratch-link-adapter

Add scratch link adapter class
This commit is contained in:
Valerie Young 2019-01-08 10:06:51 -05:00 committed by GitHub
commit d2351e99b7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 185 additions and 101 deletions

99
package-lock.json generated
View file

@ -1088,6 +1088,11 @@
}
}
},
"@vernier/godirect": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/@vernier/godirect/-/godirect-1.2.0.tgz",
"integrity": "sha512-VkkTap4MMFHAqHERotlU9EQ6AZYGuFqD5kR3t834xybPH+xbX3iNaKOVwsyG7eLapycNSTDYqJHwh9LqSN7T2A=="
},
"@webassemblyjs/ast": {
"version": "1.5.13",
"resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.5.13.tgz",
@ -1537,7 +1542,7 @@
"arr-flatten": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz",
"integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==",
"integrity": "sha1-NgSLv/TntH4TZkQxbJlmnqWukfE=",
"dev": true
},
"arr-union": {
@ -1713,7 +1718,7 @@
},
"aws4": {
"version": "1.6.0",
"resolved": "https://registry.npmjs.org/aws4/-/aws4-1.6.0.tgz",
"resolved": "http://registry.npmjs.org/aws4/-/aws4-1.6.0.tgz",
"integrity": "sha1-g+9cqGCysy5KDe7e6MdxudtXRx4="
},
"babel-code-frame": {
@ -2177,7 +2182,7 @@
},
"bl": {
"version": "1.2.2",
"resolved": "http://registry.npmjs.org/bl/-/bl-1.2.2.tgz",
"resolved": "https://registry.npmjs.org/bl/-/bl-1.2.2.tgz",
"integrity": "sha512-e8tQYnZodmebYDWGH7KMRvtzKXaJHx3BbilrgZCfvyLUYdKpK1t5PSPmpkny/SgiTSCnjfLW7v5rlONXVFkQEA==",
"dev": true,
"requires": {
@ -2231,7 +2236,7 @@
"bn.js": {
"version": "4.11.8",
"resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz",
"integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==",
"integrity": "sha1-LN4J617jQfSEdGuwMJsyU7GxRC8=",
"dev": true
},
"body-parser": {
@ -2338,7 +2343,7 @@
},
"brfs": {
"version": "1.6.1",
"resolved": "http://registry.npmjs.org/brfs/-/brfs-1.6.1.tgz",
"resolved": "https://registry.npmjs.org/brfs/-/brfs-1.6.1.tgz",
"integrity": "sha512-OfZpABRQQf+Xsmju8XE9bDjs+uU4vLREGolP7bDgcpsI17QREyZ4Bl+2KLxxx1kCgA0fAIhKQBaBYh+PEcCqYQ==",
"dev": true,
"requires": {
@ -2470,7 +2475,7 @@
"buffer-indexof": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/buffer-indexof/-/buffer-indexof-1.1.1.tgz",
"integrity": "sha512-4/rOEg86jivtPTeOUUT61jJO1Ya1TrR/OkqCSZDyq84WJh3LuuiphBYJN+fm5xufIk4XAFcEwte/8WzC8If/1g==",
"integrity": "sha1-Uvq8xqYG0aADAoAmSO9o9jnaJow=",
"dev": true
},
"buffer-shims": {
@ -2672,7 +2677,7 @@
"cipher-base": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz",
"integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==",
"integrity": "sha1-h2Dk7MJy9MNjUy+SbYdKriwTl94=",
"dev": true,
"requires": {
"inherits": "^2.0.1",
@ -2797,12 +2802,12 @@
"color-support": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz",
"integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==",
"integrity": "sha1-k4NDeaHMmgxh+C9S8NBDIiUb1aI=",
"dev": true
},
"colors": {
"version": "0.6.2",
"resolved": "http://registry.npmjs.org/colors/-/colors-0.6.2.tgz",
"resolved": "https://registry.npmjs.org/colors/-/colors-0.6.2.tgz",
"integrity": "sha1-JCP+ZnisDF2uiFLl0OW+CMmXq8w=",
"dev": true
},
@ -2945,7 +2950,7 @@
"content-type": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz",
"integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==",
"integrity": "sha1-4TjMdeBAxyexlm/l5fjJruJW/js=",
"dev": true
},
"convert-source-map": {
@ -3286,7 +3291,7 @@
"crypto-browserify": {
"version": "3.12.0",
"resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz",
"integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==",
"integrity": "sha1-OWz58xN/A+S45TLFj2mCVOAPgOw=",
"dev": true,
"requires": {
"browserify-cipher": "^1.0.0",
@ -4380,7 +4385,7 @@
"evp_bytestokey": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz",
"integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==",
"integrity": "sha1-f8vbGY3HGVlDLv4ThCaE4FJaywI=",
"dev": true,
"requires": {
"md5.js": "^1.3.4",
@ -4950,7 +4955,7 @@
"dependencies": {
"commander": {
"version": "2.1.0",
"resolved": "http://registry.npmjs.org/commander/-/commander-2.1.0.tgz",
"resolved": "https://registry.npmjs.org/commander/-/commander-2.1.0.tgz",
"integrity": "sha1-0SG7roYNmZKj1Re6lvVliOR8Z4E=",
"dev": true
}
@ -5315,7 +5320,7 @@
"string-width": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
"integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==",
"integrity": "sha1-q5Pyeo3BPSjKyBXEYhQ6bZASrp4=",
"dev": true,
"requires": {
"is-fullwidth-code-point": "^2.0.0",
@ -5509,14 +5514,12 @@
"balanced-match": {
"version": "1.0.0",
"bundled": true,
"dev": true,
"optional": true
"dev": true
},
"brace-expansion": {
"version": "1.1.11",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"balanced-match": "^1.0.0",
"concat-map": "0.0.1"
@ -5531,20 +5534,17 @@
"code-point-at": {
"version": "1.1.0",
"bundled": true,
"dev": true,
"optional": true
"dev": true
},
"concat-map": {
"version": "0.0.1",
"bundled": true,
"dev": true,
"optional": true
"dev": true
},
"console-control-strings": {
"version": "1.1.0",
"bundled": true,
"dev": true,
"optional": true
"dev": true
},
"core-util-is": {
"version": "1.0.2",
@ -5661,8 +5661,7 @@
"inherits": {
"version": "2.0.3",
"bundled": true,
"dev": true,
"optional": true
"dev": true
},
"ini": {
"version": "1.3.5",
@ -5674,7 +5673,6 @@
"version": "1.0.0",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"number-is-nan": "^1.0.0"
}
@ -5689,7 +5687,6 @@
"version": "3.0.4",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"brace-expansion": "^1.1.7"
}
@ -5697,14 +5694,12 @@
"minimist": {
"version": "0.0.8",
"bundled": true,
"dev": true,
"optional": true
"dev": true
},
"minipass": {
"version": "2.2.4",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"safe-buffer": "^5.1.1",
"yallist": "^3.0.0"
@ -5723,7 +5718,6 @@
"version": "0.5.1",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"minimist": "0.0.8"
}
@ -5804,8 +5798,7 @@
"number-is-nan": {
"version": "1.0.1",
"bundled": true,
"dev": true,
"optional": true
"dev": true
},
"object-assign": {
"version": "4.1.1",
@ -5817,7 +5810,6 @@
"version": "1.4.0",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"wrappy": "1"
}
@ -5939,7 +5931,6 @@
"version": "1.0.2",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"code-point-at": "^1.0.0",
"is-fullwidth-code-point": "^1.0.0",
@ -6857,12 +6848,12 @@
"is-buffer": {
"version": "1.1.6",
"resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz",
"integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==",
"integrity": "sha1-76ouqdqg16suoTqXsritUf776L4=",
"dev": true
},
"is-builtin-module": {
"version": "1.0.0",
"resolved": "http://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz",
"resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz",
"integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=",
"dev": true,
"requires": {
@ -7631,7 +7622,7 @@
},
"magic-string": {
"version": "0.22.5",
"resolved": "http://registry.npmjs.org/magic-string/-/magic-string-0.22.5.tgz",
"resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.22.5.tgz",
"integrity": "sha512-oreip9rJZkzvA8Qzk9HFs8fZGF/u7H/gtrE8EN6RjKJ9kh2HlC+yQ2QezifqTZfGyiuAV0dRv5a+y/8gBb1m9w==",
"dev": true,
"requires": {
@ -7901,7 +7892,7 @@
"miller-rabin": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz",
"integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==",
"integrity": "sha1-8IA1HIZbDcViqEYpZtqlNUPHik0=",
"dev": true,
"requires": {
"bn.js": "^4.0.0",
@ -7911,7 +7902,7 @@
"mime": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/mime/-/mime-1.4.1.tgz",
"integrity": "sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ==",
"integrity": "sha1-Eh+evEnjdm8xGnbh+hyAA8SwOqY=",
"dev": true
},
"mime-db": {
@ -8169,7 +8160,7 @@
},
"multipipe": {
"version": "0.3.1",
"resolved": "http://registry.npmjs.org/multipipe/-/multipipe-0.3.1.tgz",
"resolved": "https://registry.npmjs.org/multipipe/-/multipipe-0.3.1.tgz",
"integrity": "sha1-kmJVJXYboE/qoJYFtjgrziyR8R8=",
"dev": true,
"requires": {
@ -8335,7 +8326,7 @@
"normalize-package-data": {
"version": "2.4.0",
"resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.4.0.tgz",
"integrity": "sha512-9jjUFbTPfEy3R/ad/2oNbKtW9Hgovl5O1FvFWKkKblNXoN/Oou6+9+KKohPK13Yc3/TyunyWhJp6gvRNR/PPAw==",
"integrity": "sha1-EvlaMH1YNSB1oEkHuErIvpisAS8=",
"dev": true,
"requires": {
"hosted-git-info": "^2.1.4",
@ -8419,7 +8410,6 @@
"version": "0.1.4",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"kind-of": "^3.0.2",
"longest": "^1.0.1",
@ -9602,8 +9592,7 @@
"longest": {
"version": "1.0.1",
"bundled": true,
"dev": true,
"optional": true
"dev": true
},
"loose-envify": {
"version": "1.3.1",
@ -11270,7 +11259,7 @@
"p-map": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/p-map/-/p-map-1.2.0.tgz",
"integrity": "sha512-r6zKACMNhjPJMTl8KcFH4li//gkrXWfbD6feV8l6doRHlzljFWGJ2AP6iKaCJXyZmAUMOPtvbW7EXkbWO/pLEA==",
"integrity": "sha1-5OlPMR6rvIYzoeeZCBZfyiYkG2s=",
"dev": true
},
"p-try": {
@ -11460,7 +11449,7 @@
"pluralize": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/pluralize/-/pluralize-7.0.0.tgz",
"integrity": "sha512-ARhBOdzS3e41FbkW/XWrTEtukqqLoK5+Z/4UeDaLuSW+39JPeFgs4gCGqsrJHVZX0fUrx//4OF0K1CUGwlIFow==",
"integrity": "sha1-KYuJ34uTsCIdv0Ia0rGx6iP8Z3c=",
"dev": true
},
"pngjs": {
@ -12184,9 +12173,9 @@
}
},
"scratch-render": {
"version": "0.1.0-prerelease.20181220195236",
"resolved": "https://registry.npmjs.org/scratch-render/-/scratch-render-0.1.0-prerelease.20181220195236.tgz",
"integrity": "sha512-FcYezDaztkoQifUG9k4uOsIFbelMt8JaCMpHrQis0QVJmjSuQrCDB3DRUjwpMuyUrmV7B7GdBUvwt65VYPZJ6g==",
"version": "0.1.0-prerelease.20190107163047",
"resolved": "https://registry.npmjs.org/scratch-render/-/scratch-render-0.1.0-prerelease.20190107163047.tgz",
"integrity": "sha512-pvyiU4FiUVEuxPc484A1UE3Dry06SIvy3OUqDs2rYu1NMw5+iwIkQLsHcpb7WLjmIFf41mh3h8GHKHHoZAOM4Q==",
"dev": true,
"requires": {
"grapheme-breaker": "0.3.2",
@ -12450,7 +12439,7 @@
"setprototypeof": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz",
"integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==",
"integrity": "sha1-0L2FU2iHtv58DYGMuWLZ2RxU5lY=",
"dev": true
},
"sha.js": {
@ -12767,7 +12756,7 @@
"source-list-map": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.0.tgz",
"integrity": "sha512-I2UmuJSRr/T8jisiROLU3A3ltr+swpniSmNPI4Ml3ZCX6tVnDsuZzK7F2hl5jTqbZBWCEKlj5HRQiPExXLgE8A==",
"integrity": "sha1-qqR0A/eyRakvvJfqCPJQ1gh+0IU=",
"dev": true
},
"source-map": {
@ -13124,7 +13113,7 @@
"string-width": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
"integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==",
"integrity": "sha1-q5Pyeo3BPSjKyBXEYhQ6bZASrp4=",
"dev": true,
"requires": {
"is-fullwidth-code-point": "^2.0.0",
@ -13542,7 +13531,7 @@
"tmp": {
"version": "0.0.33",
"resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz",
"integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==",
"integrity": "sha1-bTQzWIl2jSGyvNoKonfO07G/rfk=",
"dev": true,
"requires": {
"os-tmpdir": "~1.0.2"
@ -13863,7 +13852,7 @@
"dependencies": {
"pako": {
"version": "0.2.9",
"resolved": "http://registry.npmjs.org/pako/-/pako-0.2.9.tgz",
"resolved": "https://registry.npmjs.org/pako/-/pako-0.2.9.tgz",
"integrity": "sha1-8/dSL073gjSNqBYbrZ7P1Rv4OnU=",
"dev": true
}

View file

@ -29,7 +29,7 @@
"version": "json -f package.json -I -e \"this.repository.sha = '$(git log -n1 --pretty=format:%H)'\""
},
"dependencies": {
"@vernier/godirect": "^1.0.3",
"@vernier/godirect": "^1.2.0",
"arraybuffer-loader": "^1.0.6",
"atob": "2.1.2",
"btoa": "1.2.1",

View file

@ -3,8 +3,9 @@ const BlockType = require('../../extension-support/block-type');
const log = require('../../util/log');
// const cast = require('../../util/cast');
const formatMessage = require('format-message');
// const ScratchLinkProxy = require('./scratch-link-proxy');
const BLE = require('../../io/ble');
const createDevice = require('@vernier/godirect').default.createDevice;
const ScratchLinkDeviceAdapter = require('./scratch-link-device-adapter');
/**
* Icon png to be displayed at the left edge of each extension block, encoded as a data URI.
@ -13,6 +14,18 @@ const createDevice = require('@vernier/godirect').default.createDevice;
// eslint-disable-next-line max-len
const blockIconURI = 'data:image/png;base64,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';
/**
* Enum for Vernier godirect protocol.
* @readonly
* @enum {string}
*/
const BLEUUID = {
service: 'd91714ef-28b9-4f91-ba16-f0d9a604f112',
commandChar: 'f4bf14a6-c7d5-4b6d-8aa8-df1a7c83adcb',
responseChar: 'b41e6675-a329-40e0-aa01-44d2f444babe'
};
/**
* Manage communication with a GDX-FOR peripheral over a Scratch Link client socket.
*/
@ -37,7 +50,15 @@ class GdxFor {
* @type {BLE}
* @private
*/
this._ble = null;
this._scratchLinkSocket = null;
/**
* A godirect device
* @type {@vernier/goDirect device}
* @private
*/
this._device = null;
this._runtime.registerPeripheralExtension(extensionId, this);
/**
@ -62,8 +83,6 @@ class GdxFor {
this.disconnect = this.disconnect.bind(this);
this._onConnect = this._onConnect.bind(this);
this._connected = false;
}
@ -71,20 +90,18 @@ class GdxFor {
* Called by the runtime when user wants to scan for a peripheral.
*/
scan () {
if (this._ble) {
this._ble.close();
if (this._device) {
this._device.close();
}
navigator.bluetooth.requestDevice({
filters: [{namePrefix: 'GDX'}],
optionalServices: ['d91714ef-28b9-4f91-ba16-f0d9a604f112']
}).then(bleWbtDevice => createDevice(bleWbtDevice, {open: false}))
.then(device => {
this._ble = device;
this._ble.open(false); // false prevents starting of measurements
this._ble.on('device-opened', this._onConnect);
this._ble.on('device-closed', this._onClose);
});
this._scratchLinkSocket = new BLE(this._runtime, this._extensionId, {
filters: [
{namePrefix: 'GDX-FOR'}
],
optionalServices: [
BLEUUID.service
]
}, this._onConnect);
}
/**
@ -92,29 +109,29 @@ class GdxFor {
* @param {number} id - the id of the peripheral to connect to.
*/
connect (id) {
if (this._ble) {
this._ble.connectPeripheral(id);
if (this._scratchLinkSocket) {
this._scratchLinkSocket.connectPeripheral(id);
}
}
/**
* Called by the runtime when a use exits the connection popup.
* Disconnect from the micro:bit.
* Disconnect from the GDX FOR.
*/
disconnect () {
if (this._ble) {
this._ble.close();
if (this._device) {
this._device.close();
}
}
/**
* Return true if connected to the micro:bit.
* @return {boolean} - whether the micro:bit is connected.
* Return true if connected to the goforce device.
* @return {boolean} - whether the goforce is connected.
*/
isConnected () {
let connected = false;
if (this._ble) {
connected = this._connected;
if (this._scratchLinkSocket) {
connected = this._scratchLinkSocket.isConnected();
}
return connected;
}
@ -124,55 +141,77 @@ class GdxFor {
* @private
*/
_onConnect () {
this._connected = true;
const adapter = new ScratchLinkDeviceAdapter(this._scratchLinkSocket);
createDevice(adapter, {open: true, startMeasurements: false}).then(device => {
this._device = device;
this._startMeasurements();
});
}
this._ble.sensors.forEach(sensor => {
/**
* Enable and begin reading measurements
* @private
*/
_startMeasurements () {
this._device.sensors.forEach(sensor => {
sensor.setEnabled(true);
// do some calculations here?
sensor.on('value-changed', changedSensor => {
// We don't need this list, essentially.
if (changedSensor.values.length > 1000) {
changedSensor.clear();
}
});
});
this._ble.start(); // Can set period here if needed.
this._device.start(); // Can set period here if needed.
}
getForce () {
return this._ble.getSensor(1).value;
if (this.isConnected()) {
return this._device.getSensor(1).value;
}
return 0;
}
getAccelerationX () {
return this._ble.getSensor(2).value;
if (this.isConnected()) {
return this._device.getSensor(2).value;
}
return 0;
}
getAccelerationY () {
return this._ble.getSensor(3).value;
if (this.isConnected()) {
return this._device.getSensor(3).value;
}
return 0;
}
getAccelerationZ () {
return this._ble.getSensor(4).value;
if (this.isConnected()) {
return this._device.getSensor(4).value;
}
return 0;
}
getAngularSpeedX () {
return this._ble.getSensor(5).value;
if (this.isConnected()) {
return this._device.getSensor(5).value;
}
return 0;
}
getAngularSpeedY () {
return this._ble.getSensor(6).value;
if (this.isConnected()) {
return this._device.getSensor(6).value;
}
return 0;
}
getAngularSpeedZ () {
return this._ble.getSensor(7).value;
}
_onClose () {
this._connected = false;
if (this.isConnected()) {
return this._device.getSensor(7).value;
}
return 0;
}
}

View file

@ -0,0 +1,56 @@
const Base64Util = require('../../util/base64-util');
/**
* Enum for Vernier godirect protocol.
* @readonly
* @enum {string}
*/
const BLEUUID = {
service: 'd91714ef-28b9-4f91-ba16-f0d9a604f112',
commandChar: 'f4bf14a6-c7d5-4b6d-8aa8-df1a7c83adcb',
responseChar: 'b41e6675-a329-40e0-aa01-44d2f444babe'
};
/**
* Adapter class
*/
class ScratchLinkDeviceAdapter {
constructor (scratchLinkSocket) {
this.scratchLinkSocket = scratchLinkSocket;
this._onResponse = this._onResponse.bind(this);
this._deviceOnResponse = null;
}
get godirectAdapter () {
return true;
}
writeCommand (commandBuffer) {
const data = Base64Util.uint8ArrayToBase64(commandBuffer);
return this.scratchLinkSocket
.write(BLEUUID.service, BLEUUID.commandChar, data, 'base64', true);
}
setup ({onResponse}) {
this._deviceOnResponse = onResponse;
return this.scratchLinkSocket
.startNotifications(BLEUUID.service, BLEUUID.responseChar, this._onResponse);
// TODO:
// How do we find out from scratch link if communication closes?
}
_onResponse (base64) {
const array = Base64Util.base64ToUint8Array(base64);
const response = new DataView(array.buffer);
return this._deviceOnResponse(response);
}
close () {
return this.scratchLinkSocket.disconnect();
}
}
module.exports = ScratchLinkDeviceAdapter;