Comparar commits

..

38 Commits

Autor SHA1 Mensagem Data
AJ Keller 3f42be4df6 Merge pull request #136 from aj-ptw/fix-16-chan
Fix 16 chan
2017-01-04 00:01:04 -05:00
AJ Keller 2523f72059 Update readme for new functions and emitters 2017-01-03 23:30:59 -05:00
AJ Keller af9f08642e Fix #131 and add example for daisy with hardset 2017-01-03 23:17:40 -05:00
AJ Keller a2b4d73847 Bump minor version because of breaking changes 2017-01-03 22:45:33 -05:00
AJ Keller c2958f408e Add tests for new daisy code and Enh separated radio tests from main board test 2017-01-03 22:44:17 -05:00
AJ Keller 0dd0eceb46 Add: max channel support for simulator 2017-01-03 22:44:16 -05:00
AJ Keller 70a6165366 Merge pull request #135 from OpenBCI/development
Development
2017-01-02 12:22:49 -05:00
AJ Keller 2d7547ce79 Merge pull request #134 from aj-ptw/16-chan-bug
Addresses #131 - 16 channels not always working
2017-01-02 11:59:03 -05:00
AJ Keller de381a80de Addresses #131 - 16 channels not always working 2016-12-28 16:43:43 -05:00
AJ Keller 888be5d60f Merge pull request #132 from aj-ptw/add-exp-python
Remove simulator line from python example
2016-12-05 10:29:56 -05:00
AJ Keller 57e6d9f7c2 Remove simulator line from python example 2016-12-05 10:26:39 -05:00
AJ Keller fb3d722fc8 Update package.json 2016-12-02 02:34:29 -05:00
AJ Keller 2728617126 Update readme.md 2016-12-02 02:34:09 -05:00
AJ Keller dd7639829a Update readme.md 2016-12-02 02:33:27 -05:00
AJ Keller b11775ecde Update README.md 2016-12-02 02:16:56 -05:00
AJ Keller f96cdd94ec Merge pull request #130 from aj-ptw/add-exp-python
Add exp python
2016-12-02 02:14:51 -05:00
AJ Keller 4ce630dc4c Add: Python example 2016-12-02 02:14:08 -05:00
AJ Keller 8557444c55 1.4.2 2016-12-02 00:25:07 -05:00
AJ Keller c2c75fe9d8 Merge pull request #129 from aj-ptw/add-exp-debug
Add debug and get streaming examples
2016-12-02 00:23:26 -05:00
AJ Keller 13d4f57003 Add debug and get streaming examples 2016-12-02 00:23:02 -05:00
AJ Keller b9d0a466f8 Update changelog.md 2016-11-16 01:41:53 -05:00
AJ Keller 4428040a06 Merge pull request #123 from OpenBCI/development
1.4.1
2016-11-16 01:40:52 -05:00
AJ Keller f7e5c4988e Merge pull request #124 from baffo32/1.4.0-writes-resolve-promises
Write Promises Resolve When Write Completes
2016-11-09 23:56:24 -05:00
Karl Semich d4799dd45a Improve coverage 2016-11-09 19:54:09 +00:00
AJ Keller 212db205f2 Merge pull request #125 from baffo32/no-parallel-sntp
Refrain from testing sntp in parallel
2016-11-09 14:29:03 -05:00
Karl Semich 47b2df5802 openBCIBoard.js: make use of write promises 2016-11-09 18:59:34 +00:00
Karl Semich d06b6101e3 Resolve write promises when writes complete. Fixes #91 2016-11-09 18:58:17 +00:00
Karl Semich eb0510be6f Refrain from testing sntp in parallel 2016-11-09 18:48:37 +00:00
AJ Keller c696d4f5ca Update changelog.md 2016-11-08 02:37:17 -05:00
AJ Keller 677517715a Merge pull request #122 from khwilson/fix-typos-in-readme
Some fixes to typos in the README
2016-11-08 02:35:33 -05:00
AJ Keller 600b1b2b28 Merge pull request #121 from khwilson/fix-channelSet-so-promise-only-resolves-one-value
Bugfix: channelSet always fails due to bad resolve()
2016-11-07 16:38:00 -05:00
Kevin Wilson 32d011d1f9 Bugfix: channelSet always fails due to bad resolve()
The `resolve` function of a Promise takes *exactly one* argument.
All further arguments are ignored. Thus, the newChannelSettingsObject
that was being returned by the channelSet Promise was ignored and
the corresponding value in openBCIBoard was always undefined.

Thus, any calls to channel set would actually break the openBCISample
code as the channelSettingsArray contained an `undefined`.

This fixes the bug.
2016-11-07 15:44:30 -05:00
Kevin Wilson ee6c50294c Some fixes to typos in the README
Contributing should be off of the `development` branch, `SNTP` misspelled,
and a broken link to the `Testing` section.
2016-11-07 15:44:08 -05:00
AJ Keller 34be4c9fe3 Update changelog.md 2016-11-02 21:53:37 -04:00
AJ Keller 57dc399742 Merge pull request #118 from baffo32/1.4.0-bugtests
Fragmented and Buffered Samples (#115)
2016-11-02 21:41:44 -04:00
Karl Semich 5d989f6ea4 lint fixes 2016-11-03 00:29:32 +00:00
AJ Keller 2eebde6053 Add strip to EOT function and tests. 2016-11-03 00:29:32 +00:00
AJ Keller f7f8517c28 Update verison number to 1.4.1 2016-11-01 15:43:23 -04:00
24 arquivos alterados com 3077 adições e 1211 exclusões
+69 -5
Ver Arquivo
@@ -14,6 +14,8 @@ We are proud to support all functionality of the OpenBCI 8 and 16 Channel boards
The purpose of this module is to **get connected** and **start streaming** as fast as possible.
Python researcher or developer? Check out how easy it is to [get access to the entire API in the Python example](examples/python)!
### Table of Contents:
---
@@ -28,7 +30,7 @@ The purpose of this module is to **get connected** and **start streaming** as fa
4. [Constants](#constants)
6. [Interfacing With Other Tools](#interfacing-with-other-tools)
7. [Developing](#developing)
8. [Testing](#testing)
8. [Testing](#developing-testing)
9. [Contribute](#contribute)
10. [License](#license)
11. [Roadmap](#roadmap)
@@ -38,7 +40,7 @@ The purpose of this module is to **get connected** and **start streaming** as fa
npm install openbci
```
### <a name="tldr"></a> TL;DR:
Get connected and start streaming right now
Get connected and [start streaming right now with the example code](examples/getStreaming/getStreaming.js).
```js
var OpenBCIBoard = require('openbci').OpenBCIBoard;
@@ -71,7 +73,9 @@ Want to know if the module really works? Check out some projects and organizatio
Still not satisfied it works?? Check out this [detailed report](http://s132342840.onlinehome.us/pushtheworld/files/voltageVerificationTestPlanAndResults.pdf) that scientifically validates the output voltages of this module.
How are you still doubting and not using this already? Fine, go look at some of the [700 **_automatic_** tests](https://codecov.io/gh/OpenBCI/OpenBCI_NodeJS) written for it!
How are you still doubting and not using this already? Fine, go look at some of the [800 **_automatic_** tests](https://codecov.io/gh/OpenBCI/OpenBCI_NodeJS) written for it!
Python researcher or developer? Check out how easy it is to [get access to the entire API in the Python example](examples/python)!
### <a name="general-overview"></a> General Overview:
@@ -84,6 +88,7 @@ Initializing the board:
var OpenBCIBoard = require('openbci');
var ourBoard = new OpenBCIBoard.OpenBCIBoard();
```
Go [checkout out the get streaming example](examples/getStreaming/getStreaming.js)!
For initializing with options, such as verbose print outs:
@@ -103,6 +108,16 @@ var ourBoard = new OpenBCIBoard({
});
```
Have a daisy?:
```js
var OpenBCIBoard = require('openbci').OpenBCIBoard;
var ourBoard = new OpenBCIBoard({
boardType: `daisy`,
hardSet: true
});
```
Go [checkout out the get streaming with daisy example](examples/getStreamingDaisy/getStreamingDaisy.js)!
Another useful way to start the simulator:
```js
var openBCIBoard = require('openbci');
@@ -118,6 +133,15 @@ ourBoard.connect(k.OBCISimulatorPortName) // This will set `simulate` to true
});
```
To debug, it's amazing, do:
```js
var OpenBCIBoard = require('openbci').OpenBCIBoard;
var ourBoard = new OpenBCIBoard({
simulate: true
});
```
Go [checkout out the debug example](examples/debug/debug.js)!
'ready' event
------------
@@ -382,6 +406,7 @@ Board optional configurations.
* `daisy` - 8 Channel board with Daisy Module - 16 Channels
* `ganglion` - 4 Channel board
(NOTE: THIS IS IN-OP TIL RELEASE OF GANGLION BOARD 08/2016)
* `hardSet` {Boolean} - Recommended if using `daisy` board! For some reason, the `daisy` is sometimes not picked up by the module so you can set `hardSet` to true which will ensure the daisy is picked up. (Default `false`)
* `simulate` {Boolean} - Full functionality, just mock data. Must attach Daisy module by setting `simulatorDaisyModuleAttached` to `true` in order to get 16 channels. (Default `false`)
* `simulatorBoardFailure` {Boolean} - Simulates board communications failure. This occurs when the RFduino on the board is not polling the RFduino on the dongle. (Default `false`)
* `simulatorDaisyModuleAttached` {Boolean} - Simulates a daisy module being attached to the OpenBCI board. This is useful if you want to test how your application reacts to a user requesting 16 channels but there is no daisy module actually attached, or vice versa, where there is a daisy module attached and the user only wants to use 8 channels. (Default `false`)
@@ -501,6 +526,12 @@ Closes the serial port opened by [`.connect()`](#method-connect). Waits for sto
**_Returns_** a promise, fulfilled by a successful close of the serial port object, rejected otherwise.
### <a name="method-get-info"></a> .getInfo()
Get the core info object. It's the object that actually drives the parsing of data.
**_Returns_** Object - {{boardType: string, sampleRate: number, firmware: string, numberOfChannels: number, missedPackets: number}}
### <a name="method-get-settings-for-channel"></a> .getSettingsForChannel(channelNumber)
Gets the specified channelSettings register data from printRegisterSettings call.
@@ -513,6 +544,21 @@ A number specifying which channel you want to get data on. Only 1-8 at this time
**_Returns_** a promise, fulfilled if the command was sent to the board and the `.processBytes()` function is ready to reach for the specified channel.
### <a name="method-hard-set-board-type"></a> .hardSetBoardType(boardType)
Used to sync the module and board to `boardType`.
**Note: This has the potential to change the way data is parsed**
**_boardType_**
A String indicating the number of channels.
* `default` - Default board: Sample rate is `250Hz` and number of channels is `8`.
* `daisy` - Daisy board: Sample rate is `125Hz` and number of channels is `16`.
**_Returns_** a promise, fulfilled if both the board and module are the requested `boardType`, rejects otherwise.
### <a name="method-impedance-test-all-channels"></a> .impedanceTestAllChannels()
To apply test signals to the channels on the OpenBCI board used to test for impedance. This can take a little while to actually run (<8 seconds)!
@@ -702,6 +748,19 @@ Get the current number of channels available to use. (i.e. 8 or 16).
**_Returns_** a number, the total number of available channels.
### <a name="method-override-info-for-board-type"></a> .overrideInfoForBoardType(boardType)
Set the info property for board type.
**Note: This has the potential to change the way data is parsed**
**_boardType_**
A String indicating the number of channels.
* `default` - Default board: Sample rate is `250Hz` and number of channels is `8`.
* `daisy` - Daisy board: Sample rate is `125Hz` and number of channels is `16`.
### <a name="method-print-bytes-in"></a> .printBytesIn()
Prints the total number of bytes that were read in this session to the console.
@@ -846,7 +905,7 @@ To leave simulate mode.
### <a name="method-sntp"></a> .sntp
Extends the popular STNP package on [npmjs](https://www.npmjs.com/package/sntp)
Extends the popular SNTP package on [npmjs](https://www.npmjs.com/package/sntp)
### <a name="method-sntp-get-offset"></a> .sntpGetOffset()
@@ -1067,6 +1126,10 @@ Emitted when a packet (or packets) are dropped. Returns an array.
Emitted when there is an on the serial port.
### <a name="event-hard-set"></a> .on('hardSet', callback)
Emitted when the module detects the board is not configured as the options for the module intended and tries to save itself. i.e. when the `daisy` option is `true` and a soft reset message is parsed and the module determines that a daisy was not detected, the module will emit `hardSet` then send an attach daisy command to recover. Either `error` will be emitted if unable to attach or `ready` will be emitted if success.
### <a name="event-impedance-array"></a> .on('impedanceArray', callback)
Emitted when there is a new impedanceArray available. Returns an array.
@@ -1166,13 +1229,14 @@ npm test
## <a name="contribute"></a> Contribute:
1. Fork it!
2. Branch off of `development`: `git checkout development`
2. Create your feature branch: `git checkout -b my-new-feature`
3. Make changes
4. If adding a feature, please add test coverage.
5. Ensure tests all pass. (`npm test`)
6. Commit your changes: `git commit -m 'Add some feature'`
7. Push to the branch: `git push origin my-new-feature`
8. Submit a pull request :D
8. Submit a pull request. Make sure it is based off of the `development` branch when submitting! :D
## <a name="license"></a> License:
+47
Ver Arquivo
@@ -1,3 +1,49 @@
# 1.5.0
### New Features
* New simulator option `simulatorDaisyModuleCanBeAttached` - Boolean, deafults to true, allows the simulation of the a hot swapped daisy board or simulates a misinformed module.
* New `EventEmitter` - `hardSet` - for when the module detects the board is not configured as the options for the module intended and tries to save itself. i.e. when the `daisy` option is `true` and a soft reset message is parsed and the module determines that a daisy was not detected, the module will emit `hardSet` then send an attach daisy command to recover. Either `error` will be emitted if unable to attach or `ready` will be emitted if success.
* Add example for streaming with `daisy` and `hardSet`.
### Breaking changes
* `.setInfoForBoardType()` changed to `.overrideInfoForBoardType()` to elevate it's dangerous nature.
* `.setMaxChannels()` changed to `.hardSetBoardType()` and input changed from numerical to string: 8 and 16 to `default` and `daisy` respectively.
### Bug Fixes
* Fixes #131 - 16 chan not working by sending a channel command and parsing the return.
* Fixed bug where end of transmission characters would not be ejected from buffer.
### Enhancements
* Separated radio tests from main board test file.
# 1.4.4
### New Features
* Set max number of channels for the board to use with `.setMaxChannels()` see readme.md
* Set the core info object that drives the module with `.overrideInfoForBoardType()` see readme.md
* Get info for the core object that drives the module with `.getInfo()` see readme.md
### Work In Progress
* Bug where daisy would sometimes not be recognized which destroyed all data.
# 1.4.3
### New examples
* Add example of node to python
# 1.4.2
### New examples
* Add example of debug
* Add example of get streaming
# 1.4.1
### Bug Fixes
* Fixes bug where extra data after EOT (`$$$`) was dumped by preserving the poriton after the EOT for further decomposition.
* Fixes bug where any calls to channel set would actually break the openBCISample code as the channelSettingsArray contained an undefined.
* Writes promises resolve when they are actually sent over the serial port.
# 1.4.0
### New Features
@@ -22,6 +68,7 @@
* The `.streaming` property has been removed, replaced by `.isStreaming()`. Removed from docs.
* An error event will be emitted if sntp fails to initialize on construction
* The simulator will no longer communicate when disconnected
* Promises returned by writes will now only resolve after the write has been sent
### Bug Fixes
+108
Ver Arquivo
@@ -0,0 +1,108 @@
/**
* This is an example of debugging the board. Thanks to Karl @baffo32
* On windows you should run with PowerShell not git bash.
* Install
* [nodejs](https://nodejs.org/en/)
*
* To run:
* change directory to this file `cd examples/debug`
* do `npm install`
* then `npm start`
*/
var stream = true;
var debug = true; // Pretty print any bytes in and out... it's amazing...
var verbose = true; // Adds verbosity to functions
var OpenBCIBoard = require('openbci').OpenBCIBoard;
var ourBoard = new OpenBCIBoard({
debug: debug,
verbose: verbose
});
ourBoard.autoFindOpenBCIBoard().then(portName => {
if (portName) {
/**
* Connect to the board with portName
* Only works if one board is plugged in
* i.e. ourBoard.connect(portName).....
*/
// Call to connect
ourBoard.connect(portName).then(() => {
console.log(`connected`);
})
.catch(err => {
console.log(`connect: ${err}`);
});
} else {
/** Unable to auto find OpenBCI board */
console.log('Unable to auto find OpenBCI board');
}
});
/**
* The board is ready to start streaming after the ready function is fired.
*/
var readyFunc = () => {
// Get the sample rate after 'ready'
sampleRate = ourBoard.sampleRate();
if (stream) {
ourBoard.streamStart()
.catch(err => {
console.log(`stream start: ${err}`);
});
}
};
var sampleFunc = sample => {
/**
* Checkout the README.md for all other API functions.
* We support every feature.
* */
};
// Subscribe to your functions
ourBoard.on('ready', readyFunc);
ourBoard.on('sample', sampleFunc);
function exitHandler (options, err) {
if (options.cleanup) {
if (verbose) console.log('clean');
/** Do additional clean up here */
}
if (err) console.log(err.stack);
if (options.exit) {
if (verbose) console.log('exit');
if (stream) {
ourBoard.streamStop().catch(console.log);
}
ourBoard.disconnect().catch(console.log);
}
}
if (process.platform === "win32") {
const rl = require("readline").createInterface({
input: process.stdin,
output: process.stdout
});
rl.on("SIGINT", function () {
process.emit("SIGINT");
});
}
// do something when app is closing
process.on('exit', exitHandler.bind(null, {
cleanup: true
}));
// catches ctrl+c event
process.on('SIGINT', exitHandler.bind(null, {
exit: true
}));
// catches uncaught exceptions
process.on('uncaughtException', exitHandler.bind(null, {
exit: true
}));
+18
Ver Arquivo
@@ -0,0 +1,18 @@
{
"name": "debug",
"version": "1.0.0",
"description": "Debug example",
"main": "debug.js",
"scripts": {
"start": "node debug.js",
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [
"debug"
],
"author": "AJ Keller",
"license": "MIT",
"dependencies": {
"openbci": "^1.4.1"
}
}
+87
Ver Arquivo
@@ -0,0 +1,87 @@
/**
* This is an example from the readme.md
* On windows you should run with PowerShell not git bash.
* Install
* [nodejs](https://nodejs.org/en/)
*
* To run:
* change directory to this file `cd examples/debug`
* do `npm install`
* then `npm start`
*/
var debug = false; // Pretty print any bytes in and out... it's amazing...
var verbose = true; // Adds verbosity to functions
var OpenBCIBoard = require('openbci').OpenBCIBoard;
var ourBoard = new OpenBCIBoard({
debug: debug,
verbose: verbose
});
ourBoard.autoFindOpenBCIBoard().then(portName => {
if (portName) {
/**
* Connect to the board with portName
* Only works if one board is plugged in
* i.e. ourBoard.connect(portName).....
*/
ourBoard.connect(portName) // Port name is a serial port name, see `.listPorts()`
.then(() => {
ourBoard.on('ready',() => {
ourBoard.streamStart();
ourBoard.on('sample',(sample) => {
/** Work with sample */
for (var i = 0; i < ourBoard.numberOfChannels(); i++) {
console.log("Channel " + (i + 1) + ": " + sample.channelData[i].toFixed(8) + " Volts.");
// prints to the console
// "Channel 1: 0.00001987 Volts."
// "Channel 2: 0.00002255 Volts."
// ...
// "Channel 8: -0.00001875 Volts."
}
});
});
});
} else {
/** Unable to auto find OpenBCI board */
console.log('Unable to auto find OpenBCI board');
}
});
function exitHandler (options, err) {
if (options.cleanup) {
if (verbose) console.log('clean');
/** Do additional clean up here */
}
if (err) console.log(err.stack);
if (options.exit) {
if (verbose) console.log('exit');
ourBoard.disconnect().catch(console.log);
}
}
if (process.platform === "win32") {
const rl = require("readline").createInterface({
input: process.stdin,
output: process.stdout
});
rl.on("SIGINT", function () {
process.emit("SIGINT");
});
}
// do something when app is closing
process.on('exit', exitHandler.bind(null, {
cleanup: true
}));
// catches ctrl+c event
process.on('SIGINT', exitHandler.bind(null, {
exit: true
}));
// catches uncaught exceptions
process.on('uncaughtException', exitHandler.bind(null, {
exit: true
}));
+18
Ver Arquivo
@@ -0,0 +1,18 @@
{
"name": "get-streaming",
"version": "1.0.0",
"description": "Get streaming example",
"main": "getStreaming.js",
"scripts": {
"start": "node getStreaming.js",
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [
"get"
],
"author": "AJ Keller",
"license": "MIT",
"dependencies": {
"openbci": "^1.4.1"
}
}
@@ -0,0 +1,93 @@
/**
* This is an example from the readme.md
* On windows you should run with PowerShell not git bash.
* Install
* [nodejs](https://nodejs.org/en/)
*
* To run:
* change directory to this file `cd examples/debug`
* do `npm install`
* then `npm start`
*/
var debug = false; // Pretty print any bytes in and out... it's amazing...
var verbose = true; // Adds verbosity to functions
var OpenBCIBoard = require('openbci').OpenBCIBoard;
var ourBoard = new OpenBCIBoard({
boardType: 'daisy',
debug: debug,
hardSet: true,
verbose: verbose
});
ourBoard.on('error', (err) => {
console.log(err);
});
ourBoard.autoFindOpenBCIBoard().then(portName => {
if (portName) {
/**
* Connect to the board with portName
* Only works if one board is plugged in
* i.e. ourBoard.connect(portName).....
*/
ourBoard.connect(portName) // Port name is a serial port name, see `.listPorts()`
.then(() => {
ourBoard.once('ready',() => {
ourBoard.streamStart();
ourBoard.on('sample',(sample) => {
/** Work with sample */
for (var i = 0; i < ourBoard.numberOfChannels(); i++) {
console.log("Channel " + (i + 1) + ": " + sample.channelData[i].toFixed(8) + " Volts.");
// prints to the console
// "Channel 1: 0.00001987 Volts."
// "Channel 2: 0.00002255 Volts."
// ...
// "Channel 16: -0.00001875 Volts."
}
});
});
});
} else {
/** Unable to auto find OpenBCI board */
console.log('Unable to auto find OpenBCI board');
}
});
function exitHandler (options, err) {
if (options.cleanup) {
if (verbose) console.log('clean');
/** Do additional clean up here */
}
if (err) console.log(err.stack);
if (options.exit) {
if (verbose) console.log('exit');
ourBoard.disconnect().catch(console.log);
}
}
if (process.platform === "win32") {
const rl = require("readline").createInterface({
input: process.stdin,
output: process.stdout
});
rl.on("SIGINT", function () {
process.emit("SIGINT");
});
}
// do something when app is closing
process.on('exit', exitHandler.bind(null, {
cleanup: true
}));
// catches ctrl+c event
process.on('SIGINT', exitHandler.bind(null, {
exit: true
}));
// catches uncaught exceptions
process.on('uncaughtException', exitHandler.bind(null, {
exit: true
}));
+18
Ver Arquivo
@@ -0,0 +1,18 @@
{
"name": "get-streaming-daisy",
"version": "1.0.0",
"description": "Get streaming with hard set daisy example",
"main": "getStreaming.js",
"scripts": {
"start": "node getStreamingDaisy.js",
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [
"get"
],
"author": "AJ Keller",
"license": "MIT",
"dependencies": {
"openbci": "^1.5.0"
}
}
+117
Ver Arquivo
@@ -0,0 +1,117 @@
import json
import sys
import numpy as np
import time
import zmq
class Interface:
def __init__(self, verbose=False):
context = zmq.Context()
self._socket = context.socket(zmq.PAIR)
self._socket.connect("tcp://localhost:3004")
self.verbose = verbose
if self.verbose:
print "Client Ready!"
# Send a quick message to tell node process we are up and running
self.send(json.dumps({
'action': 'started',
'command': 'status',
'message': time.time()*1000.0
}))
def send(self, msg):
"""
Sends a message to TCP server
:param msg: str
A string to send to node TCP server, could be a JSON dumps...
:return: None
"""
if self.verbose:
print '<- out ' + msg
self._socket.send(msg)
return
def recv(self):
"""
Checks the ZeroMQ for data
:return: str
String of data
"""
return self._socket.recv()
class RingBuffer(np.ndarray):
"""A multidimensional ring buffer."""
def __new__(cls, input_array):
obj = np.asarray(input_array).view(cls)
return obj
def __array_finalize__(self, obj):
if obj is None:
return
def __array_wrap__(self, out_arr, context=None):
return np.ndarray.__array_wrap__(self, out_arr, context)
def append(self, x):
"""Adds element x to the ring buffer."""
x = np.asarray(x)
self[:, :-1] = self[:, 1:]
self[:, -1] = x
def main(argv):
nb_chan = 8
verbose = True
# Create a new python interface.
interface = Interface(verbose=verbose)
# Signal buffer
signal = RingBuffer(np.zeros((nb_chan + 1, 2500)))
while True:
msg = interface.recv()
try:
dicty = json.loads(msg)
action = dicty.get('action')
command = dicty.get('command')
message = dicty.get('message')
if command == 'sample':
if action == 'process':
# Do sample processing here
try:
if type(message) is not dict:
print "sample is not a dict", message
raise ValueError
# Get keys of sample
data = np.zeros(9)
data[:-1] = message.get('channelData')
data[-1] = message.get('timeStamp')
# Add data to end of ring buffer
signal.append(data)
print message.get('sampleNumber')
except ValueError as e:
print e
elif command == 'status':
if action == 'active':
interface.send(json.dumps({
'action': 'alive',
'command': 'status',
'message': time.time() * 1000.0
}))
except BaseException as e:
print e
if __name__ == '__main__':
main(sys.argv[1:])
+212
Ver Arquivo
@@ -0,0 +1,212 @@
/**
* This is an example from the readme.md
* On windows you should run with PowerShell not git bash.
* Install
* [nodejs](https://nodejs.org/en/)
*
* To run:
* change directory to this file `cd examples/debug`
* do `npm install`
* then `npm start`
*/
var OpenBCIBoard = require('openbci').OpenBCIBoard;
var port_pub = 'tcp://127.0.0.1:3004';
var zmq = require('zmq-prebuilt');
var socket = zmq.socket('pair');
var simulate = true; // Sends synthetic data
var debug = false; // Pretty print any bytes in and out... it's amazing...
var verbose = true; // Adds verbosity to functions
var ourBoard = new OpenBCIBoard({
// simulate: simulate, // Uncomment to see how it works with simulator!
simulatorFirmwareVersion: 'v2',
debug: debug,
verbose: verbose
});
var sampleRate = 250; // Default to 250, ALWAYS verify with a call to `.sampleRate()` after 'ready' event!
var timeSyncPossible = false;
var resyncPeriodMin = 1;
var secondsInMinute = 60;
var resyncPeriod = ourBoard.sampleRate() * resyncPeriodMin * secondsInMinute;
ourBoard.autoFindOpenBCIBoard().then(portName => {
if (portName) {
/**
* Connect to the board with portName
* i.e. ourBoard.connect(portName).....
*/
// Call to connect
ourBoard.connect(portName)
.then(() => {
ourBoard.on('ready', () => {
// Get the sample rate after 'ready'
sampleRate = ourBoard.sampleRate();
// Find out if you can even time sync, you must be using v2 and this is only accurate after a `.softReset()` call which is called internally on `.connect()`. We parse the `.softReset()` response for the presence of firmware version 2 properties.
timeSyncPossible = ourBoard.usingVersionTwoFirmware();
if (timeSyncPossible) {
ourBoard.streamStart()
.catch(err => {
console.log(`stream start: ${err}`);
});
} else {
console.log('not able to time sync');
}
})
})
.catch(err => {
console.log(`connect: ${err}`);
});
} else {
/** Unable to auto find OpenBCI board */
console.log('Unable to auto find OpenBCI board');
}
});
var sampleFunc = sample => {
if (sample._count % resyncPeriod === 0) {
ourBoard.syncClocksFull()
.then(syncObj => {
// Sync was successful
if (syncObj.valid) {
// Log the object to check it out!
console.log(`timeOffset`, syncObj.timeOffsetMaster);
} else {
// Retry it
console.log(`Was not able to sync... retry!`);
}
});
}
if (sample.timeStamp) { // true after the first successful sync
if (sample.timeStamp < 10 * 60 * 60 * 1000) { // Less than 10 hours
console.log(`Bad time sync ${sample.timeStamp}`);
} else {
sendToPython({
action: 'process',
command: 'sample',
message: sample
});
}
}
};
// Subscribe to your functions
ourBoard.on('sample', sampleFunc);
// ZMQ fun
socket.bind(port_pub, function (err) {
if (err) throw err;
console.log(`bound to ${port_pub}`);
});
/**
* Used to send a message to the Python process.
* @param {Object} interProcessObject The standard inter-process object.
* @return {None}
*/
var sendToPython = (interProcessObject, verbose) => {
if (verbose) {
console.log(`<- out ${JSON.stringify(interProcessObject)}`);
}
if (socket) {
socket.send(JSON.stringify(interProcessObject));
}
};
var receiveFromPython = (raw_data) => {
try {
let body = JSON.parse(raw_data); // five because `resp `
processInterfaceObject(body);
} catch (err) {
console.log('in -> ' + 'bad json');
}
};
socket.on('message', receiveFromPython);
var sendStatus = () => {
sendToPython({'action': 'active', 'message': 'ready', 'command': 'status'}, true);
};
sendStatus();
/**
* Process an incoming message
* @param {String} body A stringify JSON object that shall be parsed.
* @return {None}
*/
var processInterfaceObject = (body) => {
switch (body.command) {
case 'status':
processStatus(body);
break;
default:
unrecognizedCommand(body);
break;
}
};
/**
* Used to process a status related command from TCP IPC.
* @param {Object} body
* @return {None}
*/
var processStatus = (body) => {
switch (body.action) {
case 'started':
console.log(`python started @ ${body.message}ms`);
break;
case 'alive':
console.log(`python duplex communication test completed @ ${body.message}ms`);
break;
default:
unrecognizedCommand(body);
break;
}
};
function unrecognizedCommand (body) {
console.log(`unrecognizedCommand ${body}`);
}
function exitHandler (options, err) {
if (options.cleanup) {
if (verbose) console.log('clean');
/** Do additional clean up here */
}
if (err) console.log(err.stack);
if (options.exit) {
if (verbose) console.log('exit');
ourBoard.disconnect().catch(console.log);
}
}
if (process.platform === "win32") {
const rl = require("readline").createInterface({
input: process.stdin,
output: process.stdout
});
rl.on("SIGINT", function () {
process.emit("SIGINT");
});
}
// do something when app is closing
process.on('exit', exitHandler.bind(null, {
cleanup: true
}));
// catches ctrl+c event
process.on('SIGINT', exitHandler.bind(null, {
exit: true
}));
// catches uncaught exceptions
process.on('uncaughtException', exitHandler.bind(null, {
exit: true
}));
+29
Ver Arquivo
@@ -0,0 +1,29 @@
{
"name": "python",
"version": "1.0.0",
"description": "node to python example",
"main": "index.js",
"scripts": {
"start": "concurrently --kill-others \"python handoff.py\" \"node index.js\"",
"start-node": "node index.js",
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [
"python",
"openbci",
"node"
],
"author": "AJ Keller",
"license": "MIT",
"dependencies": {
"openbci": "^1.4.2",
"zmq-prebuilt": "^2.1.0"
},
"devEngines": {
"node": "<=6.x",
"npm": ">=3.x"
},
"devDependencies": {
"concurrently": "^3.1.0"
}
}
+40
Ver Arquivo
@@ -0,0 +1,40 @@
# OpenBCI Node SDK to Python
## About
Written to end the struggles of python researchers and developers. ~ written with love by [Push The World!](http://www.pushtheworldllc.com)
This module has every feature available on the OpenBCI Board.
## Prerequisites
* [Python 2.7](https://www.python.org/downloads/)
* [ZeroMQ](http://zeromq.org/bindings:python)
```py
pip install pyzmq
```
* [Node.js LTS](https://nodejs.org/en/)
## Installation
For Python 2.7 do:
```bash
python setup.py install
```
For Node:
```bash
npm install
```
## Running
```
npm start
```
For running just the node, for example if you were running the python in a separate ide and debugging, it's useful.
```python
npm run start-node
```
## Contributing
Please PR if you have code to contribute!
+12
Ver Arquivo
@@ -0,0 +1,12 @@
from setuptools import setup, find_packages
setup(name='openbci-node-python',
version='0.0.1',
description='Node to Python the right way',
url='',
author='AJ Keller',
author_email='pushtheworldllc@gmail.com',
license='MIT',
packages=find_packages(),
install_requires=['numpy', 'pyzmq'],
zip_safe=False)
+39
Ver Arquivo
@@ -29,6 +29,7 @@ ourBoard.autoFindOpenBCIBoard().then(portName => {
});
} else {
/** Unable to auto find OpenBCI board */
console.log('Unable to auto find OpenBCI board');
}
});
@@ -86,3 +87,41 @@ var sampleFunc = sample => {
// Subscribe to your functions
ourBoard.on('ready', readyFunc);
ourBoard.on('sample', sampleFunc);
function exitHandler (options, err) {
if (options.cleanup) {
if (verbose) console.log('clean');
/** Do additional clean up here */
}
if (err) console.log(err.stack);
if (options.exit) {
if (verbose) console.log('exit');
ourBoard.disconnect().catch(console.log);
}
}
if (process.platform === "win32") {
const rl = require("readline").createInterface({
input: process.stdin,
output: process.stdout
});
rl.on("SIGINT", function () {
process.emit("SIGINT");
});
}
// do something when app is closing
process.on('exit', exitHandler.bind(null, {
cleanup: true
}));
// catches ctrl+c event
process.on('SIGINT', exitHandler.bind(null, {
exit: true
}));
// catches uncaught exceptions
process.on('uncaughtException', exitHandler.bind(null, {
exit: true
}));
+346 -202
Ver Arquivo
@@ -20,9 +20,11 @@ function OpenBCIFactory () {
var _options = {
boardType: [k.OBCIBoardDefault, k.OBCIBoardDaisy, k.OBCIBoardGanglion],
baudRate: 115200,
hardSet: false,
simulate: false,
simulatorBoardFailure: false,
simulatorDaisyModuleAttached: false,
simulatorDaisyModuleCanBeAttached: true,
simulatorFirmwareVersion: [k.OBCIFirmwareV1, k.OBCIFirmwareV2],
simulatorFragmentation: [k.OBCISimulatorFragmentationNone, k.OBCISimulatorFragmentationRandom, k.OBCISimulatorFragmentationFullBuffers, k.OBCISimulatorFragmentationOneByOne],
simulatorLatencyTime: 16,
@@ -41,80 +43,88 @@ function OpenBCIFactory () {
};
/**
* @description The initialization method to call first, before any other method.
* @param options (optional) - Board optional configurations.
* - `baudRate` {Number} - Baud Rate, defaults to 115200. Manipulating this is allowed if
* firmware on board has been previously configured.
*
* - `boardType` {String} - Specifies type of OpenBCI board.
* 3 Possible Boards:
* `default` - 8 Channel OpenBCI board (Default)
* `daisy` - 8 Channel OpenBCI board with Daisy Module. Total of 16 channels.
* `ganglion` - 4 Channel board
* (NOTE: THIS IS IN-OP TIL RELEASE OF GANGLION BOARD 07/2016)
*
* - `simulate` {Boolean} - Full functionality, just mock data. Must attach Daisy module by setting
* `simulatorDaisyModuleAttached` to `true` in order to get 16 channels. (Default `false`)
*
* - `simulatorBoardFailure` {Boolean} - Simulates board communications failure. This occurs when the RFduino on
* the board is not polling the RFduino on the dongle. (Default `false`)
*
* - `simulatorDaisyModuleAttached` {Boolean} - Simulates a daisy module being attached to the OpenBCI board.
* This is useful if you want to test how your application reacts to a user requesting 16 channels
* but there is no daisy module actually attached, or vice versa, where there is a daisy module
* attached and the user only wants to use 8 channels. (Default `false`)
*
* - `simulatorFirmwareVersion` {String} - Allows simulator to be started with firmware version 2 features
* 2 Possible Options:
* `v1` - Firmware Version 1 (Default)
* `v2` - Firmware Version 2
*
* - `simulatorFragmentation` {String} - Specifies how to break packets to simulate fragmentation, which
* occurs commonly in real devices. It is recommended to test code with this enabled.
* 4 Possible Options:
* `none` - do not fragment packets; output complete chunks immediately when produced (Default)
* `random` - output random small chunks of data interspersed with full buffers
* `fullBuffers` - allow buffers to fill up until the latency timer has expired
* `oneByOne` - output each byte separately
*
* - `simulatorLatencyTime` {Number} - The time in milliseconds to wait before sending partially full buffers,
if `simulatorFragmentation` is specified. (Default `16`)
*
* - `simulatorBufferSize` {Number} - The size of a full buffer of data, if `simulatorFragmentation` is
* specified. (Default `4096`)
*
* - `simulatorHasAccelerometer` - {Boolean} - Sets simulator to send packets with accelerometer data. (Default `true`)
*
* - `simulatorInjectAlpha` - {Boolean} - Inject a 10Hz alpha wave in Channels 1 and 2 (Default `true`)
*
* - `simulatorInjectLineNoise` {String} - Injects line noise on channels.
* 3 Possible Options:
* `60Hz` - 60Hz line noise (Default) [America]
* `50Hz` - 50Hz line noise [Europe]
* `none` - Do not inject line noise.
*
* - `simulatorSampleRate` {Number} - The sample rate to use for the simulator. Simulator will set to 125 if
* `simulatorDaisyModuleAttached` is set `true`. However, setting this option overrides that
* setting and this sample rate will be used. (Default is `250`)
*
* - `simulatorSerialPortFailure` {Boolean} - Simulates not being able to open a serial connection. Most likely
* due to a OpenBCI dongle not being plugged in.
*
* - `sntpTimeSync` - {Boolean} Syncs the module up with an SNTP time server and uses that as single source
* of truth instead of local computer time. If you are running experiements on your local
* computer, keep this `false`. (Default `false`)
*
* - `sntpTimeSyncHost` - {String} The ntp server to use, can be either sntp or ntp. (Defaults `pool.ntp.org`).
*
* - `sntpTimeSyncPort` - {Number} The port to access the ntp server. (Defaults `123`)
*
* - `verbose` {Boolean} - Print out useful debugging events. (Default `false`)
*
* - `debug` {Boolean} - Print out a raw dump of bytes sent and received. (Default `false`)
*
* @constructor
* @author AJ Keller (@pushtheworldllc)
*/
* @description The initialization method to call first, before any other method.
* @param options (optional) - Board optional configurations.
* - `baudRate` {Number} - Baud Rate, defaults to 115200. Manipulating this is allowed if
* firmware on board has been previously configured.
*
* - `boardType` {String} - Specifies type of OpenBCI board.
* 3 Possible Boards:
* `default` - 8 Channel OpenBCI board (Default)
* `daisy` - 8 Channel OpenBCI board with Daisy Module. Total of 16 channels.
* `ganglion` - 4 Channel board
* (NOTE: THIS IS IN-OP TIL RELEASE OF GANGLION BOARD 07/2016)
*
* - `hardSet` {Boolean} - Recommended if using `daisy` board! For some reason, the `daisy` is sometimes
* not picked up by the module so you can set `hardSet` to true which will ensure the daisy
* is picked up. (Default `false`)
*
* - `simulate` {Boolean} - Full functionality, just mock data. Must attach Daisy module by setting
* `simulatorDaisyModuleAttached` to `true` in order to get 16 channels. (Default `false`)
*
* - `simulatorBoardFailure` {Boolean} - Simulates board communications failure. This occurs when the RFduino on
* the board is not polling the RFduino on the dongle. (Default `false`)
*
* - `simulatorDaisyModuleAttached` {Boolean} - Simulates a daisy module being attached to the OpenBCI board.
* This is useful if you want to test how your application reacts to a user requesting 16 channels
* but there is no daisy module actually attached, or vice versa, where there is a daisy module
* attached and the user only wants to use 8 channels. (Default `false`)
*
* - `simulatorDaisyModuleCanBeAttached` {Boolean} - Allows the simulation of the a hot swapped daisy board.
* For example: You coule simulate if the board has only detected 8 channels and the user requested
* 16 channels. (Default `true`)
*
* - `simulatorFirmwareVersion` {String} - Allows simulator to be started with firmware version 2 features
* 2 Possible Options:
* `v1` - Firmware Version 1 (Default)
* `v2` - Firmware Version 2
*
* - `simulatorFragmentation` {String} - Specifies how to break packets to simulate fragmentation, which
* occurs commonly in real devices. It is recommended to test code with this enabled.
* 4 Possible Options:
* `none` - do not fragment packets; output complete chunks immediately when produced (Default)
* `random` - output random small chunks of data interspersed with full buffers
* `fullBuffers` - allow buffers to fill up until the latency timer has expired
* `oneByOne` - output each byte separately
*
* - `simulatorLatencyTime` {Number} - The time in milliseconds to wait before sending partially full buffers,
* if `simulatorFragmentation` is specified. (Default `16`)
*
* - `simulatorBufferSize` {Number} - The size of a full buffer of data, if `simulatorFragmentation` is
* specified. (Default `4096`)
*
* - `simulatorHasAccelerometer` - {Boolean} - Sets simulator to send packets with accelerometer data. (Default `true`)
*
* - `simulatorInjectAlpha` - {Boolean} - Inject a 10Hz alpha wave in Channels 1 and 2 (Default `true`)
*
* - `simulatorInjectLineNoise` {String} - Injects line noise on channels.
* 3 Possible Options:
* `60Hz` - 60Hz line noise (Default) [America]
* `50Hz` - 50Hz line noise [Europe]
* `none` - Do not inject line noise.
*
* - `simulatorSampleRate` {Number} - The sample rate to use for the simulator. Simulator will set to 125 if
* `simulatorDaisyModuleAttached` is set `true`. However, setting this option overrides that
* setting and this sample rate will be used. (Default is `250`)
*
* - `simulatorSerialPortFailure` {Boolean} - Simulates not being able to open a serial connection. Most likely
* due to a OpenBCI dongle not being plugged in.
*
* - `sntpTimeSync` - {Boolean} Syncs the module up with an SNTP time server and uses that as single source
* of truth instead of local computer time. If you are running experiements on your local
* computer, keep this `false`. (Default `false`)
*
* - `sntpTimeSyncHost` - {String} The ntp server to use, can be either sntp or ntp. (Defaults `pool.ntp.org`).
*
* - `sntpTimeSyncPort` - {Number} The port to access the ntp server. (Defaults `123`)
*
* - `verbose` {Boolean} - Print out useful debugging events. (Default `false`)
*
* - `debug` {Boolean} - Print out a raw dump of bytes sent and received. (Default `false`)
*
* @constructor
* @author AJ Keller (@pushtheworldllc)
*/
function OpenBCIBoard (options) {
options = (typeof options !== 'function') && options || {};
var opts = {};
@@ -157,7 +167,7 @@ function OpenBCIFactory () {
// Arrays
this.accelArray = [0, 0, 0]; // X, Y, Z
this.channelSettingsArray = k.channelSettingsArrayInit(k.numberOfChannelsForBoardType(this.options.boardType));
this.writeOutArray = new Array(100);
this.writeOutArray = [];
// Booleans
this._streaming = false;
// Buffers
@@ -200,13 +210,13 @@ function OpenBCIFactory () {
// Numbers
this.badPackets = 0;
this.curParsingMode = k.OBCIParsingReset;
this.commandsToWrite = 0;
this.impedanceArray = openBCISample.impedanceArray(k.numberOfChannelsForBoardType(this.options.boardType));
this.previousSampleNumber = -1;
this.sampleCount = 0;
this.timeOfPacketArrival = 0;
this.writeOutDelay = k.OBCIWriteIntervalDelayMSShort;
// Strings
this.portName = null;
// NTP
if (this.options.sntpTimeSync) {
@@ -255,6 +265,7 @@ function OpenBCIFactory () {
alpha: this.options.simulatorInjectAlpha,
boardFailure: this.options.simulatorBoardFailure,
daisy: this.options.simulatorDaisyModuleAttached,
daisyCanBeAttached: this.options.simulatorDaisyModuleCanBeAttached,
drift: this.options.simulatorInternalClockDrift,
firmwareVersion: this.options.simulatorFirmwareVersion,
fragmentation: this.options.simulatorFragmentation,
@@ -281,29 +292,42 @@ function OpenBCIFactory () {
this._processBytes(data);
});
this.serial.once('open', () => {
var timeoutLength = this.options.simulate ? 50 : 300;
if (this.options.verbose) console.log('Serial port open');
setTimeout(() => {
new Promise(resolve => {
// TODO: document why this 300 ms delay is needed
setTimeout(resolve, this.options.simulate ? 50 : 300);
}).then(() => {
if (this.options.verbose) console.log('Sending stop command, in case the device was left streaming...');
this.write(k.OBCIStreamStop);
if (this.serial) this.serial.flush();
}, timeoutLength);
setTimeout(() => {
return this.write(k.OBCIStreamStop);
}).then(() => {
return new Promise(resolve => this.serial.flush(resolve));
}).then(() => {
// TODO: document why this 250 ms delay is needed
return new Promise(resolve => setTimeout(resolve, 250));
}).then(() => {
if (this.options.verbose) console.log('Sending soft reset');
this.softReset();
// TODO: this promise chain resolves early because
// A. some legacy code (in tests) sets the ready handler after this resolves
// and
// B. other legacy code (in tests) needs the simulator to reply with segmented packets, never fragmented
// which is C. not implemented yet except in a manner such that replies occur in the write handler,
// resulting in the EOT arriving before this resolves
// Fix one or more of the above 3 situations, then move resolve() to the next block.
resolve();
return this.softReset();
}).then(() => {
if (this.options.verbose) console.log("Waiting for '$$$'");
}, timeoutLength + 250);
});
});
this.serial.once('close', () => {
if (this.options.verbose) console.log('Serial Port Closed');
// 'close' is emitted in _disconnected()
this._disconnected();
this._disconnected('port closed');
});
this.serial.once('error', (err) => {
if (this.options.verbose) console.log('Serial Port Error');
this.emit('error', err);
this._disconnected();
this._disconnected(err);
});
});
};
@@ -312,10 +336,9 @@ function OpenBCIFactory () {
* @description Called once when for any reason the serial port is no longer open.
* @private
*/
OpenBCIBoard.prototype._disconnected = function () {
OpenBCIBoard.prototype._disconnected = function (err) {
this._streaming = false;
this.commandsToWrite = 0;
clearTimeout(this.writer);
this.writer = null;
@@ -323,6 +346,11 @@ function OpenBCIFactory () {
this.serial = null;
this.emit('close');
while (this.writeOutArray.length > 0) {
var command = this.writeOutArray.pop();
if (command.reject) command.reject(err);
}
};
/**
@@ -332,9 +360,6 @@ function OpenBCIFactory () {
* @author AJ Keller (@pushtheworldllc)
*/
OpenBCIBoard.prototype.disconnect = function () {
if (!this.isConnected()) return Promise.reject('no board connected');
// no need for timeout here; streamStop already performs a delay
return Promise.resolve()
.then(() => {
if (this.isStreaming()) {
@@ -343,12 +368,16 @@ function OpenBCIFactory () {
}
})
.then(() => {
return new Promise((resolve, reject) => {
// serial emitting 'close' will call _disconnected
this.serial.close(() => {
resolve();
if (!this.isConnected()) {
return Promise.reject('no board connected');
} else {
return new Promise((resolve, reject) => {
// serial emitting 'close' will call _disconnected
this.serial.close(() => {
resolve();
});
});
});
}
});
};
@@ -361,14 +390,24 @@ function OpenBCIFactory () {
return this.serial.isOpen();
};
/**
* @description Checks if the board is currently sending samples.
* @returns {boolean} - True if streaming.
*/
OpenBCIBoard.prototype.isSimulating = function () {
return this.options.simulate;
};
/**
* @description Checks if the board is currently sending samples.
* @returns {boolean} - True if streaming.
*/
OpenBCIBoard.prototype.isStreaming = function () {
return this._streaming;
};
/**
* @description Sends a start streaming command to the board.
* @returns {Promise} indicating if the signal was able to be sent.
@@ -382,13 +421,7 @@ function OpenBCIFactory () {
if (this.isStreaming()) return reject('Error [.streamStart()]: Already streaming');
this._streaming = true;
this._reset_ABANDONED(); // framework is incomplete but looks useful
this.write(k.OBCIStreamStart)
.then(() => {
setTimeout(() => {
resolve();
}, 10); // allow time for command to get sent
})
.catch(err => reject(err));
this.write(k.OBCIStreamStart).then(resolve, reject);
});
};
@@ -404,13 +437,7 @@ function OpenBCIFactory () {
return new Promise((resolve, reject) => {
if (!this.isStreaming()) return reject('Error [.streamStop()]: No stream to stop');
this._streaming = false;
this.write(k.OBCIStreamStop)
.then(() => {
setTimeout(() => {
resolve();
}, 10); // allow time for command to get sent
})
.catch(err => reject(err));
this.write(k.OBCIStreamStop).then(resolve, reject);
});
};
@@ -462,50 +489,55 @@ function OpenBCIFactory () {
/**
* @description To be able to easily write to the board but ensure that we never send commands
* with less than a 10ms spacing between sends. This uses an array and pops off
* the entries until there are none left.
* with less than a 10ms spacing between sends in early version boards. This uses
* an array and shifts off the entries until there are none left.
* @param dataToWrite - Either a single character or an Array of characters
* @returns {Promise}
* @author AJ Keller (@pushtheworldllc)
*/
OpenBCIBoard.prototype.write = function (dataToWrite) {
var writerFunction = () => {
/* istanbul ignore else */
if (this.commandsToWrite > 0) {
var command = this.writeOutArray.shift();
this.commandsToWrite--;
if (this.commandsToWrite === 0) {
this.writer = null;
return new Promise((resolve, reject) => {
if (!this.isConnected()) {
reject('not connected');
} else {
if (Array.isArray(dataToWrite)) { // Got an input array
var len = dataToWrite.length;
for (var i = 0; i < len; i++) {
this.writeOutArray.push({ cmd: dataToWrite[i], reject: reject });
}
this.writeOutArray[this.writeOutArray.length - 1].resolve = resolve;
} else {
this.writeOutArray.push({ cmd: dataToWrite, reject: reject, resolve: resolve });
}
if (!this.writer) { // there is no writer started
var writerFunction = () => {
if (this.writeOutArray.length === 0) {
this.writer = null;
return;
}
var command = this.writeOutArray.shift();
var promise = this._writeAndDrain(command.cmd);
promise.then(() => {
this.writer = setTimeout(writerFunction, this.writeOutDelay);
}, () => {
// write failed but more commands may be pending that need a result
writerFunction();
});
if (command.reject) {
promise.catch(err => {
if (this.options.verbose) console.log('write failure: ' + err);
command.reject(err);
});
}
if (command.resolve) promise.then(command.resolve);
};
this.writer = setTimeout(writerFunction, this.writeOutDelay);
}
this._writeAndDrain(command)
.catch(err => {
/* istanbul ignore if */
if (this.options.verbose) console.log('write failure: ' + err);
});
} else {
if (this.options.verbose) console.log('Big problem! Writer started with no commands to write');
}
};
return new Promise((resolve, reject) => {
// console.log('write method called')
if (!this.isConnected()) return reject('not connected');
if (Array.isArray(dataToWrite)) { // Got an input array
var len = dataToWrite.length;
for (var i = 0; i < len; i++) {
this.writeOutArray[this.commandsToWrite] = dataToWrite[i];
this.commandsToWrite++;
}
} else {
this.writeOutArray[this.commandsToWrite] = dataToWrite;
this.commandsToWrite++;
}
if (this.writer === null || this.writer === undefined) { // there is no writer started
this.writer = setTimeout(writerFunction, this.writeOutDelay);
}
resolve();
});
};
@@ -651,7 +683,7 @@ function OpenBCIFactory () {
this.curParsingMode = k.OBCIParsingEOT;
// Send the radio channel query command
this._writeAndDrain(new Buffer([k.OBCIRadioKey, k.OBCIRadioCmdChannelSet, channelNumber]));
this._writeAndDrain(new Buffer([k.OBCIRadioKey, k.OBCIRadioCmdChannelSet, channelNumber])).catch(reject);
});
};
@@ -701,7 +733,7 @@ function OpenBCIFactory () {
this.curParsingMode = k.OBCIParsingEOT;
// Send the radio channel query command
this._writeAndDrain(new Buffer([k.OBCIRadioKey, k.OBCIRadioCmdChannelSetOverride, channelNumber]));
this._writeAndDrain(new Buffer([k.OBCIRadioKey, k.OBCIRadioCmdChannelSetOverride, channelNumber])).catch(reject);
});
};
@@ -751,7 +783,7 @@ function OpenBCIFactory () {
this.curParsingMode = k.OBCIParsingEOT;
// Send the radio channel query command
this._writeAndDrain(new Buffer([k.OBCIRadioKey, k.OBCIRadioCmdChannelGet]));
this._writeAndDrain(new Buffer([k.OBCIRadioKey, k.OBCIRadioCmdChannelGet])).catch(reject);
});
};
@@ -797,7 +829,7 @@ function OpenBCIFactory () {
this.curParsingMode = k.OBCIParsingEOT;
// Send the radio channel query command
this._writeAndDrain(new Buffer([k.OBCIRadioKey, k.OBCIRadioCmdPollTimeGet]));
this._writeAndDrain(new Buffer([k.OBCIRadioKey, k.OBCIRadioCmdPollTimeGet])).catch(reject);
});
};
@@ -848,7 +880,7 @@ function OpenBCIFactory () {
this.curParsingMode = k.OBCIParsingEOT;
// Send the radio channel query command
this._writeAndDrain(new Buffer([k.OBCIRadioKey, k.OBCIRadioCmdPollTimeSet, pollTime]));
this._writeAndDrain(new Buffer([k.OBCIRadioKey, k.OBCIRadioCmdPollTimeSet, pollTime])).catch(reject);
});
};
@@ -920,9 +952,9 @@ function OpenBCIFactory () {
// Send the radio channel query command
if (speed === k.OBCIRadioBaudRateFastStr) {
this._writeAndDrain(new Buffer([k.OBCIRadioKey, k.OBCIRadioCmdBaudRateSetFast]));
this._writeAndDrain(new Buffer([k.OBCIRadioKey, k.OBCIRadioCmdBaudRateSetFast])).catch(reject);
} else {
this._writeAndDrain(new Buffer([k.OBCIRadioKey, k.OBCIRadioCmdBaudRateSetDefault]));
this._writeAndDrain(new Buffer([k.OBCIRadioKey, k.OBCIRadioCmdBaudRateSetDefault])).catch(reject);
}
});
};
@@ -970,7 +1002,7 @@ function OpenBCIFactory () {
this.curParsingMode = k.OBCIParsingEOT;
// Send the radio channel query command
this._writeAndDrain(new Buffer([k.OBCIRadioKey, k.OBCIRadioCmdSystemStatus]));
this._writeAndDrain(new Buffer([k.OBCIRadioKey, k.OBCIRadioCmdSystemStatus])).catch(reject);
});
};
@@ -1002,6 +1034,105 @@ function OpenBCIFactory () {
});
};
/**
* Get the board type.
* @return boardType: string
*/
OpenBCIBoard.prototype.getBoardType = function() {
return this.info.boardType;
};
/**
* Get the core info object.
* @return {{boardType: string, sampleRate: number, firmware: string, numberOfChannels: number, missedPackets: number}}
*/
OpenBCIBoard.prototype.getInfo = function() {
return this.info;
};
/**
* Set the info property for board type.
* @param boardType {String}
* `default` or `daisy`. Defaults to `default`.
*/
OpenBCIBoard.prototype.overrideInfoForBoardType = function(boardType) {
switch (boardType) {
case k.OBCIBoardDaisy:
this.info.boardType = k.OBCIBoardDaisy;
this.info.numberOfChannels = k.OBCINumberOfChannelsDaisy;
this.info.sampleRate = k.OBCISampleRate125;
this.channelSettingsArray = k.channelSettingsArrayInit(k.OBCINumberOfChannelsDaisy);
this.goertzelObject = openBCISample.goertzelNewObject(k.OBCINumberOfChannelsDaisy);
this.impedanceArray = openBCISample.impedanceArray(k.OBCINumberOfChannelsDaisy);
break;
case k.OBCIBoardDefault:
default:
this.info.boardType = k.OBCIBoardDefault;
this.info.numberOfChannels = k.OBCINumberOfChannelsDefault;
this.info.sampleRate = k.OBCISampleRate250;
this.channelSettingsArray = k.channelSettingsArrayInit(k.OBCINumberOfChannelsDefault);
this.goertzelObject = openBCISample.goertzelNewObject(k.OBCINumberOfChannelsDefault);
this.impedanceArray = openBCISample.impedanceArray(k.OBCINumberOfChannelsDefault);
break;
}
};
/**
* Used to sync the module and board to `boardType`
* @param boardType {String}
* Either `default` or `daisy`
* @return {Promise}
*/
OpenBCIBoard.prototype.hardSetBoardType = function (boardType) {
if (this.isStreaming()) return Promise.reject('Must not be streaming!');
return new Promise((resolve, reject) => {
const eotFunc = (data) => {
switch (data.slice(0, data.length - k.OBCIParseEOT.length).toString()) {
case k.OBCIChannelMaxNumber8SuccessDaisyRemoved:
this.overrideInfoForBoardType(k.OBCIBoardDefault);
resolve('daisy removed');
break;
case k.OBCIChannelMaxNumber16DaisyAlreadyAttached:
this.overrideInfoForBoardType(k.OBCIBoardDaisy);
resolve('daisy already attached');
break;
case k.OBCIChannelMaxNumber16DaisyAttached:
this.overrideInfoForBoardType(k.OBCIBoardDaisy);
resolve('daisy attached');
break;
case k.OBCIChannelMaxNumber16NoDaisyAttached:
this.overrideInfoForBoardType(k.OBCIBoardDefault);
reject('unable to attach daisy');
break;
case k.OBCIChannelMaxNumber8NoDaisyToRemove:
default:
this.overrideInfoForBoardType(k.OBCIBoardDefault);
resolve('no daisy to remove');
break;
}
};
if (boardType === k.OBCIBoardDefault) {
this.curParsingMode = k.OBCIParsingEOT;
this.once(k.OBCIEmitterEot, eotFunc);
this.write(k.OBCIChannelMaxNumber8)
.catch((err) => {
this.removeListener(k.OBCIEmitterEot, eotFunc);
reject(err);
});
} else if (boardType === k.OBCIBoardDaisy) {
this.curParsingMode = k.OBCIParsingEOT;
this.once(k.OBCIEmitterEot, eotFunc);
this.write(k.OBCIChannelMaxNumber16)
.catch((err) => {
this.removeListener(k.OBCIEmitterEot, eotFunc);
reject(err);
});
} else {
reject('invalid board type');
}
});
};
/**
* @description Sends a soft reset command to the board
* @returns {Promise}
@@ -1092,13 +1223,11 @@ function OpenBCIFactory () {
var arrayOfCommands = [];
return new Promise((resolve, reject) => {
k.getChannelSetter(channelNumber, powerDown, gain, inputType, bias, srb2, srb1)
.then((arr, newChannelSettingObject) => {
arrayOfCommands = arr;
this.channelSettingsArray[channelNumber - 1] = newChannelSettingObject;
resolve(this.write(arrayOfCommands));
}, function (err) {
reject(err);
});
.then((val) => {
arrayOfCommands = val.commandArray;
this.channelSettingsArray[channelNumber - 1] = val.newChannelSettingsObject;
return this.write(arrayOfCommands);
}).then(resolve, reject);
});
};
@@ -1146,12 +1275,13 @@ function OpenBCIFactory () {
this.impedanceTest.active = true;
this.impedanceTest.continuousMode = true;
var chain = Promise.resolve();
for (var i = 0; i < this.numberOfChannels(); i++) {
k.getImpedanceSetter(i + 1, false, true).then((commandsArray) => {
this.write(commandsArray);
});
chain = chain
.then(() => k.getImpedanceSetter(i + 1, false, true))
.then((commandsArray) => this.write(commandsArray));
}
resolve();
chain.then(resolve, reject);
});
};
@@ -1168,12 +1298,13 @@ function OpenBCIFactory () {
this.impedanceTest.active = false;
this.impedanceTest.continuousMode = false;
var chain = Promise.resolve();
for (var i = 0; i < this.numberOfChannels(); i++) {
k.getImpedanceSetter(i + 1, false, false).then((commandsArray) => {
this.write(commandsArray);
});
chain = chain
.then(() => k.getImpedanceSetter(i + 1, false, false))
.then((commandsArray) => this.write(commandsArray));
}
resolve();
chain.then(resolve, reject);
});
};
@@ -1358,8 +1489,6 @@ function OpenBCIFactory () {
return new Promise((resolve, reject) => {
if (!this.isConnected()) return reject('Must be connected');
var delayInMS = 0;
/* istanbul ignore if */
if (this.options.verbose) {
if (pInput && !nInput) {
@@ -1382,18 +1511,15 @@ function OpenBCIFactory () {
if (this.options.verbose) console.log('pInput: ' + pInput + ' nInput: ' + nInput);
// Get impedance settings to send the board
k.getImpedanceSetter(channelNumber, pInput, nInput).then((commandsArray) => {
this.write(commandsArray);
// delayInMS += commandsArray.length * k.OBCIWriteIntervalDelayMSLong
delayInMS += this.commandsToWrite * k.OBCIWriteIntervalDelayMSShort; // Account for commands waiting to be sent in the write buffer
setTimeout(() => {
/**
* If either pInput or nInput are true then we should start calculating impedance. Setting
* this.impedanceTest.active to true here allows us to route every sample for an impedance
* calculation instead of the normal sample output.
*/
if (pInput || nInput) this.impedanceTest.active = true;
resolve(channelNumber);
}, delayInMS); // Prevents emitting .impedanceArray before all setting commands have been applied
return this.write(commandsArray);
}).then(() => {
/**
* If either pInput or nInput are true then we should start calculating impedance. Setting
* this.impedanceTest.active to true here allows us to route every sample for an impedance
* calculation instead of the normal sample output.
*/
if (pInput || nInput) this.impedanceTest.active = true;
resolve(channelNumber);
}, (err) => {
reject(err);
});
@@ -1494,7 +1620,7 @@ function OpenBCIFactory () {
* response from the board.
* @param recordingDuration {String} - The duration you want to log SD information for. Limited to:
* '14sec', '5min', '15min', '30min', '1hour', '2hour', '4hour', '12hour', '24hour'
* @returns {Promise} - Resolves if the command was added to write queue.
* @returns {Promise} - Resolves when the command has been written.
* @private
* @author AJ Keller (@pushtheworldllc)
*/
@@ -1517,7 +1643,7 @@ function OpenBCIFactory () {
/**
* @description Sends the stop SD logging command to the board. If not streaming then `eot` event will be emitted
* with request response from the board.
* @returns {Promise} - Resovles if added to the write queue
* @returns {Promise} - Resolves when written
* @author AJ Keller (@pushtheworldllc)
*/
OpenBCIBoard.prototype.sdStop = function () {
@@ -1593,8 +1719,7 @@ function OpenBCIFactory () {
this.sync.curSyncObj = openBCISample.newSyncObject();
this.sync.curSyncObj.timeSyncSent = this.time();
this.curParsingMode = k.OBCIParsingTimeSyncSent;
this._writeAndDrain(k.OBCISyncTimeSet);
resolve();
this._writeAndDrain(k.OBCISyncTimeSet).then(resolve, reject);
});
};
@@ -1691,8 +1816,8 @@ function OpenBCIFactory () {
case k.OBCIParsingEOT:
if (openBCISample.doesBufferHaveEOT(data)) {
this.curParsingMode = k.OBCIParsingNormal;
this.emit('eot', data);
this.buffer = null;
this.emit(k.OBCIEmitterEot, data);
this.buffer = openBCISample.stripToEOTBuffer(data);
} else {
this.buffer = data;
}
@@ -1701,9 +1826,31 @@ function OpenBCIFactory () {
// Does the buffer have an EOT in it?
if (openBCISample.doesBufferHaveEOT(data)) {
this._processParseBufferForReset(data);
this.curParsingMode = k.OBCIParsingNormal;
this.buffer = null;
this.emit('ready');
if (this.options.hardSet) {
if (this.getBoardType() !== this.options.boardType) {
this.emit(k.OBCIEmitterHardSet);
this.hardSetBoardType(this.options.boardType)
.then(() => {
this.emit(k.OBCIEmitterReady)
})
.catch((err) => {
this.emit(k.OBCIEmitterError, err);
});
} else {
this.curParsingMode = k.OBCIParsingNormal;
this.emit(k.OBCIEmitterReady);
this.buffer = openBCISample.stripToEOTBuffer(data);
}
} else {
if (this.getBoardType() !== this.options.boardType && this.options.verbose) {
console.log(`Module detected ${this.getBoardType()} board type but you specified ${this.options.boardType}, use 'hardSet' to force the module to correct itself`);
}
this.curParsingMode = k.OBCIParsingNormal;
this.emit(k.OBCIEmitterReady);
this.buffer = openBCISample.stripToEOTBuffer(data);
}
} else {
this.buffer = data;
}
@@ -1795,20 +1942,17 @@ function OpenBCIFactory () {
};
/**
* @description Alters the global info object by parseing an incoming soft reset key
* @param dataBuffer {Buffer} - The soft reset data buffer
* @private
* @author AJ Keller (@pushtheworldllc)
*/
* @description Alters the global info object by parseing an incoming soft reset key
* @param dataBuffer {Buffer} - The soft reset data buffer
* @returns {Buffer} - If there is data left in the buffer, just it will be returned.
* @private
* @author AJ Keller (@pushtheworldllc)
*/
OpenBCIBoard.prototype._processParseBufferForReset = function (dataBuffer) {
if (openBCISample.countADSPresent(dataBuffer) === 2) {
this.info.boardType = k.OBCIBoardDaisy;
this.info.numberOfChannels = k.OBCINumberOfChannelsDaisy;
this.info.sampleRate = k.OBCISampleRate125;
this.overrideInfoForBoardType(k.OBCIBoardDaisy);
} else {
this.info.boardType = k.OBCIBoardDefault;
this.info.numberOfChannels = k.OBCINumberOfChannelsDefault;
this.info.sampleRate = k.OBCISampleRate250;
this.overrideInfoForBoardType(k.OBCIBoardDefault);
}
if (openBCISample.findV2Firmware(dataBuffer)) {
+19 -3
Ver Arquivo
@@ -156,6 +156,11 @@ const obciMiscSoftReset = 'v';
/** 16 Channel Commands */
const obciChannelMaxNumber8 = 'c';
const obciChannelMaxNumber16 = 'C';
const obciChannelMaxNumber8NoDaisyToRemove = '';
const obciChannelMaxNumber8SuccessDaisyRemoved = 'daisy removed';
const obciChannelMaxNumber16DaisyAlreadyAttached = '16';
const obciChannelMaxNumber16DaisyAttached = 'daisy attached16';
const obciChannelMaxNumber16NoDaisyAttached = 'no daisy to attach!8';
/** 60Hz line filter */
const obciFilterDisable = 'g';
@@ -335,7 +340,9 @@ const obciRadioBaudRateFastStr = 'fast';
/** Emitters */
const obciEmitterClose = 'close';
const obciEmitterDroppedPacket = 'droppedPacket';
const obciEmitterEot = 'eot';
const obciEmitterError = 'error';
const obciEmitterHardSet = 'hardSet';
const obciEmitterImpedanceArray = 'impedanceArray';
const obciEmitterQuery = 'query';
const obciEmitterRawDataPacket = 'rawDataPacket';
@@ -724,6 +731,11 @@ module.exports = {
/** 16 Channel Commands */
OBCIChannelMaxNumber8: obciChannelMaxNumber8,
OBCIChannelMaxNumber16: obciChannelMaxNumber16,
OBCIChannelMaxNumber8NoDaisyToRemove: obciChannelMaxNumber8NoDaisyToRemove,
OBCIChannelMaxNumber8SuccessDaisyRemoved: obciChannelMaxNumber8SuccessDaisyRemoved,
OBCIChannelMaxNumber16DaisyAlreadyAttached: obciChannelMaxNumber16DaisyAlreadyAttached,
OBCIChannelMaxNumber16DaisyAttached: obciChannelMaxNumber16DaisyAttached,
OBCIChannelMaxNumber16NoDaisyAttached: obciChannelMaxNumber16NoDaisyAttached,
/** Filters */
OBCIFilterDisable: obciFilterDisable,
OBCIFilterEnable: obciFilterEnable,
@@ -894,7 +906,9 @@ module.exports = {
/** Emitters */
OBCIEmitterClose: obciEmitterClose,
OBCIEmitterDroppedPacket: obciEmitterDroppedPacket,
OBCIEmitterEot: obciEmitterEot,
OBCIEmitterError: obciEmitterError,
OBCIEmitterHardSet: obciEmitterHardSet,
OBCIEmitterImpedanceArray: obciEmitterImpedanceArray,
OBCIEmitterQuery: obciEmitterQuery,
OBCIEmitterRawDataPacket: obciEmitterRawDataPacket,
@@ -926,7 +940,10 @@ module.exports = {
* false -> Disconnect all N inputs from SRB1 (default))
* Select to connect (true) all channels' N inputs to SRB1. This effects all pins,
* and disconnects all N inputs from the ADC.
* @returns {Promise} resolves array of commands to be sent, rejects on bad input or no board
* @returns {Promise} resolves {commandArray: array of commands to be sent,
newChannelSettingsObject: an updated channel settings object
to be stored in openBCIBoard.channelSettingsArray},
rejects on bad input or no board
*/
function channelSetter (channelNumber, powerDown, gain, inputType, bias, srb2, srb1) {
// Used to store and assemble the commands
@@ -991,8 +1008,7 @@ function channelSetter (channelNumber, powerDown, gain, inputType, bias, srb2, s
cmdSrb1,
obciChannelCmdLatch
];
// console.log(outputArray)
resolve(outputArray, newChannelSettingsObject);
resolve({commandArray: outputArray, newChannelSettingsObject: newChannelSettingsObject});
});
});
}
+26
Ver Arquivo
@@ -522,6 +522,7 @@ var sampleModule = {
makeTailByteFromPacketType,
isStopByte,
newSyncObject,
stripToEOTBuffer,
/**
* @description Checks to make sure the previous sample number is one less
* then the new sample number. Takes into account sample numbers wrapping
@@ -1111,6 +1112,31 @@ function isSuccessInBuffer (dataBuffer) {
return s.matches >= 1;
}
/**
* @description Used to slice a buffer for the EOT '$$$'.
* @param dataBuffer {Buffer} - The buffer of some length to parse
* @returns {Buffer} - The remaining buffer.
*/
function stripToEOTBuffer (dataBuffer) {
let indexOfEOT = dataBuffer.indexOf(k.OBCIParseEOT);
if (indexOfEOT >= 0) {
indexOfEOT += k.OBCIParseEOT.length;
} else {
return dataBuffer;
}
if (indexOfEOT < dataBuffer.byteLength) {
if (k.getVersionNumber(process.version) >= 6) {
// From introduced in node version 6.x.x
return Buffer.from(dataBuffer.slice(indexOfEOT));
} else {
return new Buffer(dataBuffer.slice(indexOfEOT));
}
} else {
return null;
}
}
/**
* @description Used to parse a buffer for the `,` character that is acked back after a time sync request is sent
* @param dataBuffer {Buffer} - The buffer of some length to parse
+28 -1
Ver Arquivo
@@ -15,6 +15,7 @@ function OpenBCISimulatorFactory () {
alpha: true,
boardFailure: false,
daisy: false,
daisyCanBeAttached: true,
drift: 0,
firmwareVersion: [k.OBCIFirmwareV1, k.OBCIFirmwareV2],
fragmentation: [k.OBCISimulatorFragmentationNone, k.OBCISimulatorFragmentationRandom, k.OBCISimulatorFragmentationFullBuffers, k.OBCISimulatorFragmentationOneByOne],
@@ -101,11 +102,13 @@ function OpenBCISimulatorFactory () {
// TODO: upgrade from old-style streams to stream.Duplex or stream.Transform
util.inherits(OpenBCISimulator, stream.Stream);
OpenBCISimulator.prototype.flush = function () {
OpenBCISimulator.prototype.flush = function (callback) {
this.outputBuffered = 0;
clearTimeout(this.outputLoopHandle);
this.outputLoopHandle = null;
if (callback) callback();
};
OpenBCISimulator.prototype.isOpen = function () {
@@ -250,6 +253,30 @@ function OpenBCISimulatorFactory () {
}, 10);
}
break;
case k.OBCIChannelMaxNumber8:
if (this.options.daisy) {
this.options.daisy = false;
this._output(new Buffer(k.OBCIChannelMaxNumber8SuccessDaisyRemoved));
this._printEOT();
} else {
this._printEOT();
}
break;
case k.OBCIChannelMaxNumber16:
if (this.options.daisy) {
this._output(new Buffer(k.OBCIChannelMaxNumber16DaisyAlreadyAttached));
this._printEOT();
} else {
if (this.options.daisyCanBeAttached) {
this.options.daisy = true;
this._output(new Buffer(k.OBCIChannelMaxNumber16DaisyAttached));
this._printEOT();
} else {
this._output(new Buffer(k.OBCIChannelMaxNumber16NoDaisyAttached));
this._printEOT();
}
}
break;
default:
break;
}
+2 -1
Ver Arquivo
@@ -1,6 +1,6 @@
{
"name": "openbci",
"version": "1.4.0",
"version": "1.5.0",
"description": "The official Node.js SDK for the OpenBCI Biosensor Board.",
"main": "openBCIBoard",
"scripts": {
@@ -36,6 +36,7 @@
"sandboxed-module": "^2.0.3",
"semistandard": "^9.0.0",
"sinon": "^1.17.2",
"sinon-as-promised": "^4.0.2",
"sinon-chai": "^2.8.0",
"snazzy": "^5.0.0"
},
+256 -54
Ver Arquivo
@@ -443,6 +443,13 @@ describe('OpenBCIConstants', function () {
it('sets max of 16', function () {
assert.equal('C', k.OBCIChannelMaxNumber16);
});
it('has correct return messages', function () {
assert.equal('', k.OBCIChannelMaxNumber8NoDaisyToRemove);
assert.equal('daisy removed', k.OBCIChannelMaxNumber8SuccessDaisyRemoved);
assert.equal('16', k.OBCIChannelMaxNumber16DaisyAlreadyAttached);
assert.equal('daisy attached16', k.OBCIChannelMaxNumber16DaisyAttached);
assert.equal('no daisy to attach!8', k.OBCIChannelMaxNumber16NoDaisyAttached);
});
});
describe('On board filters', function () {
it('disable', function () {
@@ -792,32 +799,60 @@ describe('OpenBCIConstants', function () {
describe('channel input selection works', function () {
// this.timeout(5000)
it('channel 2', function (done) {
k.getChannelSetter(2, false, 24, 'normal', true, true, false).then(function (arrayOfCommands) {
arrayOfCommands[1].should.equal('2');
k.getChannelSetter(2, false, 24, 'normal', true, true, false).then(function (val) {
val.commandArray[1].should.equal('2');
val.newChannelSettingsObject.channelNumber.should.equal(2);
val.newChannelSettingsObject.powerDown.should.equal(false);
val.newChannelSettingsObject.gain.should.equal(24);
val.newChannelSettingsObject.inputType.should.equal('normal');
val.newChannelSettingsObject.bias.should.equal(true);
val.newChannelSettingsObject.srb2.should.equal(true);
val.newChannelSettingsObject.srb1.should.equal(false);
done();
}).catch(function (err) {
done(err);
});
});
it('channel 5', function (done) {
k.getChannelSetter(5, false, 24, 'normal', true, true, false).then(function (arrayOfCommands) {
arrayOfCommands[1].should.equal('5');
k.getChannelSetter(5, false, 24, 'normal', true, true, false).then(function (val) {
val.commandArray[1].should.equal('5');
val.newChannelSettingsObject.channelNumber.should.equal(5);
val.newChannelSettingsObject.powerDown.should.equal(false);
val.newChannelSettingsObject.gain.should.equal(24);
val.newChannelSettingsObject.inputType.should.equal('normal');
val.newChannelSettingsObject.bias.should.equal(true);
val.newChannelSettingsObject.srb2.should.equal(true);
val.newChannelSettingsObject.srb1.should.equal(false);
done();
}).catch(function (err) {
done(err);
});
});
it('channel 9', function (done) {
k.getChannelSetter(9, false, 24, 'normal', true, true, false).then(function (arrayOfCommands) {
arrayOfCommands[1].should.equal('Q');
k.getChannelSetter(9, false, 24, 'normal', true, true, false).then(function (val) {
val.commandArray[1].should.equal('Q');
val.newChannelSettingsObject.channelNumber.should.equal(9);
val.newChannelSettingsObject.powerDown.should.equal(false);
val.newChannelSettingsObject.gain.should.equal(24);
val.newChannelSettingsObject.inputType.should.equal('normal');
val.newChannelSettingsObject.bias.should.equal(true);
val.newChannelSettingsObject.srb2.should.equal(true);
val.newChannelSettingsObject.srb1.should.equal(false);
done();
}).catch(function (err) {
done(err);
});
});
it('channel 15', function (done) {
k.getChannelSetter(15, false, 24, 'normal', true, true, false).then(function (arrayOfCommands) {
arrayOfCommands[1].should.equal('U');
k.getChannelSetter(15, false, 24, 'normal', true, true, false).then(function (val) {
val.commandArray[1].should.equal('U');
val.newChannelSettingsObject.channelNumber.should.equal(15);
val.newChannelSettingsObject.powerDown.should.equal(false);
val.newChannelSettingsObject.gain.should.equal(24);
val.newChannelSettingsObject.inputType.should.equal('normal');
val.newChannelSettingsObject.bias.should.equal(true);
val.newChannelSettingsObject.srb2.should.equal(true);
val.newChannelSettingsObject.srb1.should.equal(false);
done();
}).catch(function (err) {
done(err);
@@ -832,16 +867,30 @@ describe('OpenBCIConstants', function () {
});
describe('power selection works', function () {
it('on', function (done) {
k.getChannelSetter(1, false, 24, 'normal', true, true, false).then(function (arrayOfCommands) {
arrayOfCommands[2].should.equal('0');
k.getChannelSetter(1, false, 24, 'normal', true, true, false).then(function (val) {
val.commandArray[2].should.equal('0');
val.newChannelSettingsObject.channelNumber.should.equal(1);
val.newChannelSettingsObject.powerDown.should.equal(false);
val.newChannelSettingsObject.gain.should.equal(24);
val.newChannelSettingsObject.inputType.should.equal('normal');
val.newChannelSettingsObject.bias.should.equal(true);
val.newChannelSettingsObject.srb2.should.equal(true);
val.newChannelSettingsObject.srb1.should.equal(false);
done();
}).catch(function (err) {
done(err);
});
});
it('off', function (done) {
k.getChannelSetter(1, true, 24, 'normal', true, true, false).then(function (arrayOfCommands) {
arrayOfCommands[2].should.equal('1');
k.getChannelSetter(1, true, 24, 'normal', true, true, false).then(function (val) {
val.commandArray[2].should.equal('1');
val.newChannelSettingsObject.channelNumber.should.equal(1);
val.newChannelSettingsObject.powerDown.should.equal(true);
val.newChannelSettingsObject.gain.should.equal(24);
val.newChannelSettingsObject.inputType.should.equal('normal');
val.newChannelSettingsObject.bias.should.equal(true);
val.newChannelSettingsObject.srb2.should.equal(true);
val.newChannelSettingsObject.srb1.should.equal(false);
done();
}).catch(function (err) {
done(err);
@@ -853,56 +902,105 @@ describe('OpenBCIConstants', function () {
});
describe('gain selection works', function () {
it('1x', function (done) {
k.getChannelSetter(1, false, 1, 'normal', true, true, false).then(function (arrayOfCommands) {
arrayOfCommands[3].should.equal('0');
k.getChannelSetter(1, false, 1, 'normal', true, true, false).then(function (val) {
val.commandArray[3].should.equal('0');
val.newChannelSettingsObject.channelNumber.should.equal(1);
val.newChannelSettingsObject.powerDown.should.equal(false);
val.newChannelSettingsObject.gain.should.equal(1);
val.newChannelSettingsObject.inputType.should.equal('normal');
val.newChannelSettingsObject.bias.should.equal(true);
val.newChannelSettingsObject.srb2.should.equal(true);
val.newChannelSettingsObject.srb1.should.equal(false);
done();
}).catch(function (err) {
done(err);
});
});
it('2x', function (done) {
k.getChannelSetter(1, false, 2, 'normal', true, true, false).then(function (arrayOfCommands) {
arrayOfCommands[3].should.equal('1');
k.getChannelSetter(1, false, 2, 'normal', true, true, false).then(function (val) {
val.commandArray[3].should.equal('1');
val.newChannelSettingsObject.channelNumber.should.equal(1);
val.newChannelSettingsObject.powerDown.should.equal(false);
val.newChannelSettingsObject.gain.should.equal(2);
val.newChannelSettingsObject.inputType.should.equal('normal');
val.newChannelSettingsObject.bias.should.equal(true);
val.newChannelSettingsObject.srb2.should.equal(true);
val.newChannelSettingsObject.srb1.should.equal(false);
done();
}).catch(function (err) {
done(err);
});
});
it('4x', function (done) {
k.getChannelSetter(1, false, 4, 'normal', true, true, false).then(function (arrayOfCommands) {
arrayOfCommands[3].should.equal('2');
k.getChannelSetter(1, false, 4, 'normal', true, true, false).then(function (val) {
val.commandArray[3].should.equal('2');
val.newChannelSettingsObject.channelNumber.should.equal(1);
val.newChannelSettingsObject.powerDown.should.equal(false);
val.newChannelSettingsObject.gain.should.equal(4);
val.newChannelSettingsObject.inputType.should.equal('normal');
val.newChannelSettingsObject.bias.should.equal(true);
val.newChannelSettingsObject.srb2.should.equal(true);
val.newChannelSettingsObject.srb1.should.equal(false);
done();
}).catch(function (err) {
done(err);
});
});
it('6x', function (done) {
k.getChannelSetter(1, false, 6, 'normal', true, true, false).then(function (arrayOfCommands) {
arrayOfCommands[3].should.equal('3');
k.getChannelSetter(1, false, 6, 'normal', true, true, false).then(function (val) {
val.commandArray[3].should.equal('3');
val.newChannelSettingsObject.channelNumber.should.equal(1);
val.newChannelSettingsObject.powerDown.should.equal(false);
val.newChannelSettingsObject.gain.should.equal(6);
val.newChannelSettingsObject.inputType.should.equal('normal');
val.newChannelSettingsObject.bias.should.equal(true);
val.newChannelSettingsObject.srb2.should.equal(true);
val.newChannelSettingsObject.srb1.should.equal(false);
done();
}).catch(function (err) {
done(err);
});
});
it('8x', function (done) {
k.getChannelSetter(1, false, 8, 'normal', true, true, false).then(function (arrayOfCommands) {
arrayOfCommands[3].should.equal('4');
k.getChannelSetter(1, false, 8, 'normal', true, true, false).then(function (val) {
val.commandArray[3].should.equal('4');
val.newChannelSettingsObject.channelNumber.should.equal(1);
val.newChannelSettingsObject.powerDown.should.equal(false);
val.newChannelSettingsObject.gain.should.equal(8);
val.newChannelSettingsObject.inputType.should.equal('normal');
val.newChannelSettingsObject.bias.should.equal(true);
val.newChannelSettingsObject.srb2.should.equal(true);
val.newChannelSettingsObject.srb1.should.equal(false);
done();
}).catch(function (err) {
done(err);
});
});
it('12x', function (done) {
k.getChannelSetter(1, false, 12, 'normal', true, true, false).then(function (arrayOfCommands) {
arrayOfCommands[3].should.equal('5');
k.getChannelSetter(1, false, 12, 'normal', true, true, false).then(function (val) {
val.commandArray[3].should.equal('5');
val.newChannelSettingsObject.channelNumber.should.equal(1);
val.newChannelSettingsObject.powerDown.should.equal(false);
val.newChannelSettingsObject.gain.should.equal(12);
val.newChannelSettingsObject.inputType.should.equal('normal');
val.newChannelSettingsObject.bias.should.equal(true);
val.newChannelSettingsObject.srb2.should.equal(true);
val.newChannelSettingsObject.srb1.should.equal(false);
done();
}).catch(function (err) {
done(err);
});
});
it('24x', function (done) {
k.getChannelSetter(1, false, 24, 'normal', true, true, false).then(function (arrayOfCommands) {
arrayOfCommands[3].should.equal('6');
k.getChannelSetter(1, false, 24, 'normal', true, true, false).then(function (val) {
val.commandArray[3].should.equal('6');
val.newChannelSettingsObject.channelNumber.should.equal(1);
val.newChannelSettingsObject.powerDown.should.equal(false);
val.newChannelSettingsObject.gain.should.equal(24);
val.newChannelSettingsObject.inputType.should.equal('normal');
val.newChannelSettingsObject.bias.should.equal(true);
val.newChannelSettingsObject.srb2.should.equal(true);
val.newChannelSettingsObject.srb1.should.equal(false);
done();
}).catch(function (err) {
done(err);
@@ -917,64 +1015,120 @@ describe('OpenBCIConstants', function () {
});
describe('input type', function () {
it('normal', function (done) {
k.getChannelSetter(1, false, 24, 'normal', true, true, false).then(function (arrayOfCommands) {
arrayOfCommands[4].should.equal('0');
k.getChannelSetter(1, false, 24, 'normal', true, true, false).then(function (val) {
val.commandArray[4].should.equal('0');
val.newChannelSettingsObject.channelNumber.should.equal(1);
val.newChannelSettingsObject.powerDown.should.equal(false);
val.newChannelSettingsObject.gain.should.equal(24);
val.newChannelSettingsObject.inputType.should.equal('normal');
val.newChannelSettingsObject.bias.should.equal(true);
val.newChannelSettingsObject.srb2.should.equal(true);
val.newChannelSettingsObject.srb1.should.equal(false);
done();
}).catch(function (err) {
done(err);
});
});
it('shorted', function (done) {
k.getChannelSetter(1, false, 24, 'shorted', true, true, false).then(function (arrayOfCommands) {
arrayOfCommands[4].should.equal('1');
k.getChannelSetter(1, false, 24, 'shorted', true, true, false).then(function (val) {
val.commandArray[4].should.equal('1');
val.newChannelSettingsObject.channelNumber.should.equal(1);
val.newChannelSettingsObject.powerDown.should.equal(false);
val.newChannelSettingsObject.gain.should.equal(24);
val.newChannelSettingsObject.inputType.should.equal('shorted');
val.newChannelSettingsObject.bias.should.equal(true);
val.newChannelSettingsObject.srb2.should.equal(true);
val.newChannelSettingsObject.srb1.should.equal(false);
done();
}).catch(function (err) {
done(err);
});
});
it('biasMethod', function (done) {
k.getChannelSetter(1, false, 24, 'biasMethod', true, true, false).then(function (arrayOfCommands) {
arrayOfCommands[4].should.equal('2');
k.getChannelSetter(1, false, 24, 'biasMethod', true, true, false).then(function (val) {
val.commandArray[4].should.equal('2');
val.newChannelSettingsObject.channelNumber.should.equal(1);
val.newChannelSettingsObject.powerDown.should.equal(false);
val.newChannelSettingsObject.gain.should.equal(24);
val.newChannelSettingsObject.inputType.should.equal('biasMethod');
val.newChannelSettingsObject.bias.should.equal(true);
val.newChannelSettingsObject.srb2.should.equal(true);
val.newChannelSettingsObject.srb1.should.equal(false);
done();
}).catch(function (err) {
done(err);
});
});
it('mvdd', function (done) {
k.getChannelSetter(1, false, 24, 'mvdd', true, true, false).then(function (arrayOfCommands) {
arrayOfCommands[4].should.equal('3');
k.getChannelSetter(1, false, 24, 'mvdd', true, true, false).then(function (val) {
val.commandArray[4].should.equal('3');
val.newChannelSettingsObject.channelNumber.should.equal(1);
val.newChannelSettingsObject.powerDown.should.equal(false);
val.newChannelSettingsObject.gain.should.equal(24);
val.newChannelSettingsObject.inputType.should.equal('mvdd');
val.newChannelSettingsObject.bias.should.equal(true);
val.newChannelSettingsObject.srb2.should.equal(true);
val.newChannelSettingsObject.srb1.should.equal(false);
done();
}).catch(function (err) {
done(err);
});
});
it('temp', function (done) {
k.getChannelSetter(1, false, 24, 'temp', true, true, false).then(function (arrayOfCommands) {
arrayOfCommands[4].should.equal('4');
k.getChannelSetter(1, false, 24, 'temp', true, true, false).then(function (val) {
val.commandArray[4].should.equal('4');
val.newChannelSettingsObject.channelNumber.should.equal(1);
val.newChannelSettingsObject.powerDown.should.equal(false);
val.newChannelSettingsObject.gain.should.equal(24);
val.newChannelSettingsObject.inputType.should.equal('temp');
val.newChannelSettingsObject.bias.should.equal(true);
val.newChannelSettingsObject.srb2.should.equal(true);
val.newChannelSettingsObject.srb1.should.equal(false);
done();
}).catch(function (err) {
done(err);
});
});
it('testsig', function (done) {
k.getChannelSetter(1, false, 24, 'testSig', true, true, false).then(function (arrayOfCommands) {
arrayOfCommands[4].should.equal('5');
k.getChannelSetter(1, false, 24, 'testSig', true, true, false).then(function (val) {
val.commandArray[4].should.equal('5');
val.newChannelSettingsObject.channelNumber.should.equal(1);
val.newChannelSettingsObject.powerDown.should.equal(false);
val.newChannelSettingsObject.gain.should.equal(24);
val.newChannelSettingsObject.inputType.should.equal('testSig');
val.newChannelSettingsObject.bias.should.equal(true);
val.newChannelSettingsObject.srb2.should.equal(true);
val.newChannelSettingsObject.srb1.should.equal(false);
done();
}).catch(function (err) {
done(err);
});
});
it('biasDrp', function (done) {
k.getChannelSetter(1, false, 24, 'biasDrp', true, true, false).then(function (arrayOfCommands) {
arrayOfCommands[4].should.equal('6');
k.getChannelSetter(1, false, 24, 'biasDrp', true, true, false).then(function (val) {
val.commandArray[4].should.equal('6');
val.newChannelSettingsObject.channelNumber.should.equal(1);
val.newChannelSettingsObject.powerDown.should.equal(false);
val.newChannelSettingsObject.gain.should.equal(24);
val.newChannelSettingsObject.inputType.should.equal('biasDrp');
val.newChannelSettingsObject.bias.should.equal(true);
val.newChannelSettingsObject.srb2.should.equal(true);
val.newChannelSettingsObject.srb1.should.equal(false);
done();
}).catch(function (err) {
done(err);
});
});
it('biasDrn', function (done) {
k.getChannelSetter(1, false, 24, 'biasDrn', true, true, false).then(function (arrayOfCommands) {
arrayOfCommands[4].should.equal('7');
k.getChannelSetter(1, false, 24, 'biasDrn', true, true, false).then(function (val) {
val.commandArray[4].should.equal('7');
val.newChannelSettingsObject.channelNumber.should.equal(1);
val.newChannelSettingsObject.powerDown.should.equal(false);
val.newChannelSettingsObject.gain.should.equal(24);
val.newChannelSettingsObject.inputType.should.equal('biasDrn');
val.newChannelSettingsObject.bias.should.equal(true);
val.newChannelSettingsObject.srb2.should.equal(true);
val.newChannelSettingsObject.srb1.should.equal(false);
done();
}).catch(function (err) {
done(err);
@@ -989,16 +1143,30 @@ describe('OpenBCIConstants', function () {
});
describe('bias selection works', function () {
it('Include', function (done) {
k.getChannelSetter(1, false, 24, 'normal', true, true, false).then(function (arrayOfCommands) {
arrayOfCommands[5].should.equal('1');
k.getChannelSetter(1, false, 24, 'normal', true, true, false).then(function (val) {
val.commandArray[5].should.equal('1');
val.newChannelSettingsObject.channelNumber.should.equal(1);
val.newChannelSettingsObject.powerDown.should.equal(false);
val.newChannelSettingsObject.gain.should.equal(24);
val.newChannelSettingsObject.inputType.should.equal('normal');
val.newChannelSettingsObject.bias.should.equal(true);
val.newChannelSettingsObject.srb2.should.equal(true);
val.newChannelSettingsObject.srb1.should.equal(false);
done();
}).catch(function (err) {
done(err);
});
});
it('Remove', function (done) {
k.getChannelSetter(1, false, 24, 'normal', false, true, false).then(function (arrayOfCommands) {
arrayOfCommands[5].should.equal('0');
k.getChannelSetter(1, false, 24, 'normal', false, true, false).then(function (val) {
val.commandArray[5].should.equal('0');
val.newChannelSettingsObject.channelNumber.should.equal(1);
val.newChannelSettingsObject.powerDown.should.equal(false);
val.newChannelSettingsObject.gain.should.equal(24);
val.newChannelSettingsObject.inputType.should.equal('normal');
val.newChannelSettingsObject.bias.should.equal(false);
val.newChannelSettingsObject.srb2.should.equal(true);
val.newChannelSettingsObject.srb1.should.equal(false);
done();
}).catch(function (err) {
done(err);
@@ -1010,16 +1178,30 @@ describe('OpenBCIConstants', function () {
});
describe('SRB2 selection works', function () {
it('Connect', function (done) {
k.getChannelSetter(1, false, 24, 'normal', true, true, false).then(function (arrayOfCommands) {
arrayOfCommands[6].should.equal('1');
k.getChannelSetter(1, false, 24, 'normal', true, true, false).then(function (val) {
val.commandArray[6].should.equal('1');
val.newChannelSettingsObject.channelNumber.should.equal(1);
val.newChannelSettingsObject.powerDown.should.equal(false);
val.newChannelSettingsObject.gain.should.equal(24);
val.newChannelSettingsObject.inputType.should.equal('normal');
val.newChannelSettingsObject.bias.should.equal(true);
val.newChannelSettingsObject.srb2.should.equal(true);
val.newChannelSettingsObject.srb1.should.equal(false);
done();
}).catch(function (err) {
done(err);
});
});
it('Disconnect', function (done) {
k.getChannelSetter(1, false, 24, 'normal', true, false, false).then(function (arrayOfCommands) {
arrayOfCommands[6].should.equal('0');
k.getChannelSetter(1, false, 24, 'normal', true, false, false).then(function (val) {
val.commandArray[6].should.equal('0');
val.newChannelSettingsObject.channelNumber.should.equal(1);
val.newChannelSettingsObject.powerDown.should.equal(false);
val.newChannelSettingsObject.gain.should.equal(24);
val.newChannelSettingsObject.inputType.should.equal('normal');
val.newChannelSettingsObject.bias.should.equal(true);
val.newChannelSettingsObject.srb2.should.equal(false);
val.newChannelSettingsObject.srb1.should.equal(false);
done();
}).catch(function (err) {
done(err);
@@ -1031,16 +1213,30 @@ describe('OpenBCIConstants', function () {
});
describe('SRB1 selection works', function () {
it('Connect', function (done) {
k.getChannelSetter(1, false, 24, 'normal', true, true, true).then(function (arrayOfCommands) {
arrayOfCommands[7].should.equal('1');
k.getChannelSetter(1, false, 24, 'normal', true, true, true).then(function (val) {
val.commandArray[7].should.equal('1');
val.newChannelSettingsObject.channelNumber.should.equal(1);
val.newChannelSettingsObject.powerDown.should.equal(false);
val.newChannelSettingsObject.gain.should.equal(24);
val.newChannelSettingsObject.inputType.should.equal('normal');
val.newChannelSettingsObject.bias.should.equal(true);
val.newChannelSettingsObject.srb2.should.equal(true);
val.newChannelSettingsObject.srb1.should.equal(true);
done();
}).catch(function (err) {
done(err);
});
});
it('Disconnect', function (done) {
k.getChannelSetter(1, false, 24, 'normal', true, true, false).then(function (arrayOfCommands) {
arrayOfCommands[7].should.equal('0');
k.getChannelSetter(1, false, 24, 'normal', true, true, false).then(function (val) {
val.commandArray[7].should.equal('0');
val.newChannelSettingsObject.channelNumber.should.equal(1);
val.newChannelSettingsObject.powerDown.should.equal(false);
val.newChannelSettingsObject.gain.should.equal(24);
val.newChannelSettingsObject.inputType.should.equal('normal');
val.newChannelSettingsObject.bias.should.equal(true);
val.newChannelSettingsObject.srb2.should.equal(true);
val.newChannelSettingsObject.srb1.should.equal(false);
done();
}).catch(function (err) {
done(err);
@@ -1251,9 +1447,15 @@ describe('OpenBCIConstants', function () {
it('Event Emitter Dropped Packet', function () {
assert.equal('droppedPacket', k.OBCIEmitterDroppedPacket);
});
it('Event Emitter EOT', function () {
assert.equal('eot', k.OBCIEmitterEot);
});
it('Event Emitter Error', function () {
assert.equal('error', k.OBCIEmitterError);
});
it('Event Emitter Hard Set', function () {
assert.equal('hardSet', k.OBCIEmitterHardSet);
});
it('Event Emitter Impedance Array', function () {
assert.equal('impedanceArray', k.OBCIEmitterImpedanceArray);
});
+60
Ver Arquivo
@@ -1210,6 +1210,66 @@ $$$`);
expect(openBCISample.droppedPacketCheck(previous, current)).to.be.null;
});
});
describe('#stripToEOTBuffer', function () {
it('should return the buffer if no EOT', function () {
let buf = null;
if (k.getVersionNumber(process.version) >= 6) {
// From introduced in node version 6.x.x
buf = Buffer.from('tacos are delicious');
} else {
buf = new Buffer('tacos are delicious');
}
expect(openBCISample.stripToEOTBuffer(buf).toString()).to.equal(buf.toString());
});
it('should slice the buffer after just eot $$$', function () {
let eotBuf = null;
let bufPost = null;
if (k.getVersionNumber(process.version) >= 6) {
// From introduced in node version 6.x.x
eotBuf = Buffer.from(k.OBCIParseEOT);
bufPost = Buffer.from('tacos');
} else {
eotBuf = new Buffer(k.OBCIParseEOT);
bufPost = new Buffer('tacos');
}
let totalBuf = Buffer.concat([eotBuf, bufPost]);
expect(openBCISample.stripToEOTBuffer(totalBuf).toString()).to.equal(bufPost.toString());
});
it('should slice the buffer after eot $$$', function () {
let bufPre = null;
let eotBuf = null;
let bufPost = null;
if (k.getVersionNumber(process.version) >= 6) {
// From introduced in node version 6.x.x
bufPre = Buffer.from('tacos are delicious');
eotBuf = Buffer.from(k.OBCIParseEOT);
bufPost = Buffer.from('tacos');
} else {
bufPre = new Buffer('tacos are delicious');
eotBuf = new Buffer(k.OBCIParseEOT);
bufPost = new Buffer('tacos');
}
let totalBuf = Buffer.concat([bufPre, eotBuf, bufPost]);
expect(openBCISample.stripToEOTBuffer(totalBuf).toString()).to.equal(bufPost.toString());
});
it('should return null if nothing left', function () {
let bufPre = null;
let eotBuf = null;
if (k.getVersionNumber(process.version) >= 6) {
// From introduced in node version 6.x.x
bufPre = Buffer.from('tacos are delicious');
eotBuf = Buffer.from(k.OBCIParseEOT);
} else {
bufPre = new Buffer('tacos are delicious');
eotBuf = new Buffer(k.OBCIParseEOT);
}
let totalBuf = Buffer.concat([bufPre, eotBuf]);
expect(openBCISample.stripToEOTBuffer(totalBuf)).to.equal(null);
});
});
});
describe('#goertzelProcessSample', function () {
+954
Ver Arquivo
@@ -0,0 +1,954 @@
'use strict';
var bluebirdChecks = require('./bluebirdChecks');
var sinon = require('sinon');
var chai = require('chai');
var expect = chai.expect;
var should = chai.should(); // eslint-disable-line no-unused-vars
var openBCIBoard = require('../openBCIBoard');
var openBCISample = openBCIBoard.OpenBCISample;
var k = openBCISample.k;
var chaiAsPromised = require('chai-as-promised');
var sinonChai = require('sinon-chai');
var sinonAsPromised = require('sinon-as-promised')(bluebirdChecks.BluebirdPromise);
var fs = require('fs');
chai.use(chaiAsPromised);
chai.use(sinonChai);
describe('openbci-radios', function () {
this.timeout(2000);
var ourBoard, masterPortName, realBoard;
before(function (done) {
ourBoard = new openBCIBoard.OpenBCIBoard();
ourBoard.autoFindOpenBCIBoard()
.then(portName => {
ourBoard = null;
realBoard = true;
masterPortName = portName;
done();
})
.catch(() => {
ourBoard = null;
realBoard = false;
masterPortName = k.OBCISimulatorPortName;
done();
});
});
after(done => {
if (ourBoard) {
if (ourBoard['connected']) {
ourBoard.disconnect()
.then(() => {
done();
})
.catch(err => {
done(err);
});
} else {
done();
}
} else {
done();
}
});
describe('#radioChannelSet', function () {
afterEach(function (done) {
if (ourBoard.isConnected()) {
ourBoard.disconnect().then(() => {
done();
}).catch(() => done);
} else {
done();
}
});
afterEach(() => bluebirdChecks.noPendingPromises());
it('should not change the channel number if not connected', function (done) {
ourBoard = new openBCIBoard.OpenBCIBoard({
verbose: true,
simulate: true,
simulatorFirmwareVersion: 'v2'
});
ourBoard.radioChannelGet().should.be.rejected.and.notify(done);
});
it('should reject if streaming', function (done) {
ourBoard = new openBCIBoard.OpenBCIBoard({
verbose: true,
simulate: true,
simulatorFirmwareVersion: 'v2'
});
ourBoard.connect(k.OBCISimulatorPortName)
.then(() => {
ourBoard.once('ready', () => {
ourBoard.streamStart()
.then(() => {
ourBoard.radioChannelSet(1).then(() => {
done('should have rejected');
}).catch(() => {
done(); // Test pass
});
}).catch(err => done(err));
});
}).catch(err => done(err));
});
it('should reject if not firmware version 2', function (done) {
ourBoard = new openBCIBoard.OpenBCIBoard({
verbose: true,
simulate: true
});
ourBoard.connect(k.OBCISimulatorPortName)
.then(() => {
ourBoard.once('ready', () => {
ourBoard.radioChannelSet(1).should.be.rejected.and.notify(done);
});
}).catch(err => done(err));
});
it('should reject if a number is not sent as input', function (done) {
ourBoard = new openBCIBoard.OpenBCIBoard({
verbose: true,
simulate: true,
simulatorFirmwareVersion: 'v2'
});
ourBoard.connect(k.OBCISimulatorPortName)
.then(() => {
ourBoard.once('ready', () => {
ourBoard.radioChannelSet('1').should.be.rejected.and.notify(done);
});
}).catch(err => done(err));
});
it('should reject if no channel number is presented as arg', function (done) {
ourBoard = new openBCIBoard.OpenBCIBoard({
verbose: true,
simulate: true,
simulatorFirmwareVersion: 'v2'
});
ourBoard.connect(k.OBCISimulatorPortName)
.then(() => {
ourBoard.once('ready', () => {
ourBoard.radioChannelSet().should.be.rejected.and.notify(done);
});
}).catch(err => done(err));
});
it('should reject if the requested new channel number is lower than 0', function (done) {
ourBoard = new openBCIBoard.OpenBCIBoard({
verbose: true,
simulate: true,
simulatorFirmwareVersion: 'v2'
});
ourBoard.connect(k.OBCISimulatorPortName)
.then(() => {
ourBoard.once('ready', () => {
ourBoard.radioChannelSet(-1).should.be.rejected.and.notify(done);
});
}).catch(err => done(err));
});
it('should reject if the requested new channel number is higher than 25', function (done) {
ourBoard = new openBCIBoard.OpenBCIBoard({
verbose: true,
simulate: true,
simulatorFirmwareVersion: 'v2'
});
ourBoard.connect(k.OBCISimulatorPortName)
.then(() => {
ourBoard.once('ready', () => {
ourBoard.radioChannelSet(26).should.be.rejected.and.notify(done);
});
}).catch(err => done(err));
});
it('should not change the channel if the board is not communicating with the host', function (done) {
ourBoard = new openBCIBoard.OpenBCIBoard({
verbose: true,
simulate: true,
simulatorBoardFailure: true,
simulatorFirmwareVersion: 'v2'
});
ourBoard.connect(k.OBCISimulatorPortName)
.then(() => {
ourBoard.once('ready', () => {
ourBoard.radioChannelSet(1).should.be.rejected.and.notify(done);
});
}).catch(err => done(err));
});
it('should change the channel if connected, not steaming, and using firmware version 2+', function (done) {
var newChannelNumber = 2;
ourBoard = new openBCIBoard.OpenBCIBoard({
verbose: true,
simulate: true,
simulatorFirmwareVersion: 'v2'
});
ourBoard.connect(k.OBCISimulatorPortName)
.then(() => {
ourBoard.once('ready', () => {
ourBoard.radioChannelSet(newChannelNumber).then(channelNumber => {
expect(channelNumber).to.be.equal(newChannelNumber);
done();
}).catch(err => done(err));
});
}).catch(err => done(err));
});
});
describe('#radioChannelSetHostOverride', function () {
afterEach(function (done) {
if (ourBoard.isConnected()) {
ourBoard.disconnect().then(() => {
done();
}).catch(() => done);
} else {
done();
}
});
afterEach(() => bluebirdChecks.noPendingPromises());
it('should not change the channel number if not connected', function (done) {
ourBoard = new openBCIBoard.OpenBCIBoard({
verbose: true,
simulate: true,
simulatorFirmwareVersion: 'v2'
});
ourBoard.radioChannelSetHostOverride().should.be.rejected.and.notify(done);
});
it('should reject if streaming', function (done) {
ourBoard = new openBCIBoard.OpenBCIBoard({
verbose: true,
simulate: true,
simulatorFirmwareVersion: 'v2'
});
ourBoard.connect(k.OBCISimulatorPortName)
.then(() => {
ourBoard.once('ready', () => {
ourBoard.streamStart()
.then(() => {
ourBoard.radioChannelSetHostOverride(1).then(() => {
done('should have rejected');
}).catch(() => {
done(); // Test pass
});
}).catch(err => done(err));
});
}).catch(err => done(err));
});
it('should reject if a number is not sent as input', function (done) {
ourBoard = new openBCIBoard.OpenBCIBoard({
verbose: true,
simulate: true,
simulatorFirmwareVersion: 'v2'
});
ourBoard.connect(k.OBCISimulatorPortName)
.then(() => {
ourBoard.once('ready', () => {
ourBoard.radioChannelSetHostOverride('1').should.be.rejected.and.notify(done);
});
}).catch(err => done(err));
});
it('should reject if no channel number is presented as arg', function (done) {
ourBoard = new openBCIBoard.OpenBCIBoard({
verbose: true,
simulate: true,
simulatorFirmwareVersion: 'v2'
});
ourBoard.connect(k.OBCISimulatorPortName)
.then(() => {
ourBoard.once('ready', () => {
ourBoard.radioChannelSetHostOverride().should.be.rejected.and.notify(done);
});
}).catch(err => done(err));
});
it('should reject if the requested new channel number is lower than 0', function (done) {
ourBoard = new openBCIBoard.OpenBCIBoard({
verbose: true,
simulate: true,
simulatorFirmwareVersion: 'v2'
});
ourBoard.connect(k.OBCISimulatorPortName)
.then(() => {
ourBoard.once('ready', () => {
ourBoard.radioChannelSetHostOverride(-1).should.be.rejected.and.notify(done);
});
}).catch(err => done(err));
});
it('should reject if the requested new channel number is higher than 25', function (done) {
ourBoard = new openBCIBoard.OpenBCIBoard({
verbose: true,
simulate: true,
simulatorFirmwareVersion: 'v2'
});
ourBoard.connect(k.OBCISimulatorPortName)
.then(() => {
ourBoard.once('ready', () => {
ourBoard.radioChannelSetHostOverride(26).should.be.rejected.and.notify(done);
});
}).catch(err => done(err));
});
it('should change the channel if connected, not steaming, and using firmware version 2+', function (done) {
var newChannelNumber = 2;
ourBoard = new openBCIBoard.OpenBCIBoard({
verbose: true,
simulate: true,
simulatorFirmwareVersion: 'v2'
});
ourBoard.connect(k.OBCISimulatorPortName)
.then(() => {
ourBoard.once('ready', () => {
ourBoard.radioChannelSetHostOverride(newChannelNumber).then(channelNumber => {
expect(channelNumber).to.be.equal(newChannelNumber);
done();
}).catch(err => done(err));
});
}).catch(err => done(err));
});
});
describe('#radioChannelGet', function () {
afterEach(function (done) {
if (ourBoard.isConnected()) {
ourBoard.disconnect().then(() => {
done();
}).catch(() => done);
} else {
done();
}
});
afterEach(() => bluebirdChecks.noPendingPromises());
it('should not query if not connected', function (done) {
ourBoard = new openBCIBoard.OpenBCIBoard({
verbose: true,
simulate: true
});
ourBoard.radioChannelGet().should.be.rejected.and.notify(done);
});
it('should not query if streaming', function (done) {
ourBoard = new openBCIBoard.OpenBCIBoard({
verbose: true,
simulate: true
});
ourBoard.connect(k.OBCISimulatorPortName)
.then(() => {
ourBoard.once('ready', () => {
ourBoard.streamStart()
.then(() => {
ourBoard.radioChannelGet().then(() => {
done('should have rejected');
}).catch(() => {
done(); // Test pass
});
}).catch(err => done(err));
});
}).catch(err => done(err));
});
it('should not query if not firmware version 2', function (done) {
ourBoard = new openBCIBoard.OpenBCIBoard({
verbose: true,
simulate: true
});
ourBoard.connect(k.OBCISimulatorPortName)
.then(() => {
ourBoard.once('ready', () => {
ourBoard.radioChannelGet().should.be.rejected.and.notify(done);
});
}).catch(err => done(err));
});
it('should query if firmware version 2', function (done) {
ourBoard = new openBCIBoard.OpenBCIBoard({
verbose: true,
simulate: true,
simulatorFirmwareVersion: 'v2'
});
ourBoard.connect(k.OBCISimulatorPortName)
.then(() => {
ourBoard.once('ready', () => {
ourBoard.radioChannelGet().then(res => {
expect(res.channelNumber).to.be.within(k.OBCIRadioChannelMin, k.OBCIRadioChannelMax);
done();
}).catch(err => done(err));
});
}).catch(err => done(err));
});
it('should get message even if the board is not communicating with dongle', function (done) {
ourBoard = new openBCIBoard.OpenBCIBoard({
verbose: true,
simulate: true,
simulatorBoardFailure: true,
simulatorFirmwareVersion: 'v2'
});
ourBoard.connect(k.OBCISimulatorPortName)
.then(() => {
ourBoard.once('ready', () => {
ourBoard.radioChannelGet().should.be.rejected.and.notify(done);
});
}).catch(err => done(err));
});
});
describe('#radioPollTimeSet', function () {
afterEach(function (done) {
if (ourBoard.isConnected()) {
ourBoard.disconnect().then(() => {
done();
}).catch(() => done);
} else {
done();
}
});
afterEach(() => bluebirdChecks.noPendingPromises());
it('should not change the channel number if not connected', function (done) {
ourBoard = new openBCIBoard.OpenBCIBoard({
verbose: true,
simulate: true,
simulatorFirmwareVersion: 'v2'
});
ourBoard.radioPollTimeSet().should.be.rejected.and.notify(done);
});
it('should reject if streaming', function (done) {
ourBoard = new openBCIBoard.OpenBCIBoard({
verbose: true,
simulate: true,
simulatorFirmwareVersion: 'v2'
});
ourBoard.connect(k.OBCISimulatorPortName)
.then(() => {
ourBoard.once('ready', () => {
ourBoard.streamStart()
.then(() => {
ourBoard.radioPollTimeSet(1).then(() => {
done('should have rejected');
}).catch(() => {
done(); // Test pass
});
}).catch(err => done(err));
});
}).catch(err => done(err));
});
it('should reject if not firmware version 2', function (done) {
ourBoard = new openBCIBoard.OpenBCIBoard({
verbose: true,
simulate: true
});
ourBoard.connect(k.OBCISimulatorPortName)
.then(() => {
ourBoard.once('ready', () => {
ourBoard.radioPollTimeSet(1).should.be.rejected.and.notify(done);
});
}).catch(err => done(err));
});
it('should reject if a number is not sent as input', function (done) {
ourBoard = new openBCIBoard.OpenBCIBoard({
verbose: true,
simulate: true,
simulatorFirmwareVersion: 'v2'
});
ourBoard.connect(k.OBCISimulatorPortName)
.then(() => {
ourBoard.once('ready', () => {
ourBoard.radioPollTimeSet('1').should.be.rejected.and.notify(done);
});
}).catch(err => done(err));
});
it('should reject if no poll time is presented as arg', function (done) {
ourBoard = new openBCIBoard.OpenBCIBoard({
verbose: true,
simulate: true,
simulatorFirmwareVersion: 'v2'
});
ourBoard.connect(k.OBCISimulatorPortName)
.then(() => {
ourBoard.once('ready', () => {
ourBoard.radioPollTimeSet().should.be.rejected.and.notify(done);
});
}).catch(err => done(err));
});
it('should reject if the requested new poll time is lower than 0', function (done) {
ourBoard = new openBCIBoard.OpenBCIBoard({
verbose: true,
simulate: true,
simulatorFirmwareVersion: 'v2'
});
ourBoard.connect(k.OBCISimulatorPortName)
.then(() => {
ourBoard.once('ready', () => {
ourBoard.radioPollTimeSet(-1).should.be.rejected.and.notify(done);
});
}).catch(err => done(err));
});
it('should reject if the requested new poll time is higher than 255', function (done) {
ourBoard = new openBCIBoard.OpenBCIBoard({
verbose: true,
simulate: true,
simulatorFirmwareVersion: 'v2'
});
ourBoard.connect(k.OBCISimulatorPortName)
.then(() => {
ourBoard.once('ready', () => {
ourBoard.radioPollTimeSet(256).should.be.rejected.and.notify(done);
});
}).catch(err => done(err));
});
it('should not change the poll time if the board is not communicating with the host', function (done) {
ourBoard = new openBCIBoard.OpenBCIBoard({
verbose: true,
simulate: true,
simulatorBoardFailure: true,
simulatorFirmwareVersion: 'v2'
});
ourBoard.connect(k.OBCISimulatorPortName)
.then(() => {
ourBoard.once('ready', () => {
ourBoard.radioPollTimeSet(1).should.be.rejected.and.notify(done);
});
}).catch(err => done(err));
});
it('should change the poll time if connected, not steaming, and using firmware version 2+', function (done) {
var newPollTime = 69;
ourBoard = new openBCIBoard.OpenBCIBoard({
verbose: true,
simulate: true,
simulatorFirmwareVersion: 'v2'
});
ourBoard.connect(k.OBCISimulatorPortName)
.then(() => {
ourBoard.once('ready', () => {
ourBoard.radioPollTimeSet(newPollTime).then(() => {
done();
}).catch(err => {
done(err);
});
});
}).catch(err => done(err));
});
});
describe('#radioPollTimeGet', function () {
afterEach(function (done) {
if (ourBoard.isConnected()) {
ourBoard.disconnect().then(() => {
done();
}).catch(() => done);
} else {
done();
}
});
afterEach(() => bluebirdChecks.noPendingPromises());
it('should not query if not connected', function (done) {
ourBoard = new openBCIBoard.OpenBCIBoard({
verbose: true,
simulate: true
});
ourBoard.radioPollTimeGet().should.be.rejected.and.notify(done);
});
it('should not query if streaming', function (done) {
ourBoard = new openBCIBoard.OpenBCIBoard({
verbose: true,
simulate: true
});
ourBoard.connect(k.OBCISimulatorPortName)
.then(() => {
ourBoard.once('ready', () => {
ourBoard.streamStart()
.then(() => {
ourBoard.radioPollTimeGet().then(() => {
done('should have rejected');
}).catch(() => {
done(); // Test pass
});
}).catch(err => done(err));
});
}).catch(err => done(err));
});
it('should not query if not firmware version 2', function (done) {
ourBoard = new openBCIBoard.OpenBCIBoard({
verbose: true,
simulate: true
});
ourBoard.connect(k.OBCISimulatorPortName)
.then(() => {
ourBoard.once('ready', () => {
ourBoard.radioPollTimeGet().should.be.rejected.and.notify(done);
});
}).catch(err => done(err));
});
it('should query if firmware version 2', function (done) {
ourBoard = new openBCIBoard.OpenBCIBoard({
verbose: true,
simulate: true,
simulatorFirmwareVersion: 'v2'
});
ourBoard.connect(k.OBCISimulatorPortName)
.then(() => {
ourBoard.once('ready', () => {
ourBoard.radioPollTimeGet().then(pollTime => {
expect(pollTime).to.be.greaterThan(0);
done();
}).catch(err => done(err));
});
}).catch(err => done(err));
});
it('should get failure message if the board is not communicating with dongle', function (done) {
ourBoard = new openBCIBoard.OpenBCIBoard({
verbose: true,
simulate: true,
simulatorBoardFailure: true,
simulatorFirmwareVersion: 'v2'
});
ourBoard.connect(k.OBCISimulatorPortName)
.then(() => {
ourBoard.once('ready', () => {
ourBoard.radioPollTimeGet().should.be.rejected.and.notify(done);
});
}).catch(err => done(err));
});
});
describe('#radioBaudRateSet', function () {
afterEach(function (done) {
if (ourBoard.isConnected()) {
ourBoard.disconnect().then(() => {
done();
}).catch(() => done);
} else {
done();
}
});
afterEach(() => bluebirdChecks.noPendingPromises());
it('should not try to set baud rate if not connected', function (done) {
ourBoard = new openBCIBoard.OpenBCIBoard({
verbose: true,
simulate: true
});
ourBoard.radioBaudRateSet('default').should.be.rejected.and.notify(done);
});
it('should reject if no input', function (done) {
ourBoard = new openBCIBoard.OpenBCIBoard({
verbose: true,
simulate: true
});
ourBoard.radioBaudRateSet().should.be.rejected.and.notify(done);
});
it('should be rejected if input type incorrect', function (done) {
ourBoard = new openBCIBoard.OpenBCIBoard({
verbose: true,
simulate: true
});
ourBoard.radioBaudRateSet(1).should.be.rejected.and.notify(done);
});
it('should not try to change the baud rate if streaming', function (done) {
ourBoard = new openBCIBoard.OpenBCIBoard({
verbose: true,
simulate: true
});
ourBoard.connect(k.OBCISimulatorPortName)
.then(() => {
ourBoard.once('ready', () => {
ourBoard.streamStart()
.then(() => {
ourBoard.radioBaudRateSet('default').then(() => {
done('should have rejected');
}).catch(() => {
done(); // Test pass
});
}).catch(err => done(err));
});
}).catch(err => done(err));
});
it('should not try to change the baud rate if not firmware version 2', function (done) {
ourBoard = new openBCIBoard.OpenBCIBoard({
verbose: true,
simulate: true
});
ourBoard.connect(k.OBCISimulatorPortName)
.then(() => {
ourBoard.once('ready', () => {
ourBoard.radioBaudRateSet('default').should.be.rejected.and.notify(done);
});
}).catch(err => done(err));
});
it('should set the baud rate to default if firmware version 2', function (done) {
ourBoard = new openBCIBoard.OpenBCIBoard({
verbose: true,
simulate: true,
simulatorFirmwareVersion: 'v2'
});
ourBoard.connect(k.OBCISimulatorPortName)
.then(() => {
ourBoard.once('ready', () => {
ourBoard.radioBaudRateSet('default').then(baudrate => {
expect(baudrate).to.be.equal(115200);
done();
}).catch(err => done(err));
});
}).catch(err => done(err));
});
it('should set the baud rate to fast if firmware version 2', function (done) {
ourBoard = new openBCIBoard.OpenBCIBoard({
verbose: true,
simulate: true,
simulatorFirmwareVersion: 'v2'
});
ourBoard.connect(k.OBCISimulatorPortName)
.then(() => {
ourBoard.once('ready', () => {
ourBoard.radioBaudRateSet('fast').then(baudrate => {
expect(baudrate).to.be.equal(230400);
done();
}).catch(err => done(err));
});
}).catch(err => done(err));
});
});
describe('#radioSystemStatusGet', function () {
afterEach(function (done) {
if (ourBoard.isConnected()) {
ourBoard.disconnect().then(() => {
done();
}).catch(() => done);
} else {
done();
}
});
afterEach(() => bluebirdChecks.noPendingPromises());
it('should not get system status if not connected', function (done) {
ourBoard = new openBCIBoard.OpenBCIBoard({
verbose: true,
simulate: true
});
ourBoard.radioSystemStatusGet().should.be.rejected.and.notify(done);
});
it('should not get system status if streaming', function (done) {
ourBoard = new openBCIBoard.OpenBCIBoard({
verbose: true,
simulate: true
});
ourBoard.connect(k.OBCISimulatorPortName)
.then(() => {
ourBoard.once('ready', () => {
ourBoard.streamStart()
.then(() => {
ourBoard.radioSystemStatusGet().then(() => {
done('should have rejected');
}).catch(() => {
done(); // Test pass
});
}).catch(err => done(err));
});
}).catch(err => done(err));
});
it('should not get system status if not firmware version 2', function (done) {
ourBoard = new openBCIBoard.OpenBCIBoard({
verbose: true,
simulate: true
});
ourBoard.connect(k.OBCISimulatorPortName)
.then(() => {
ourBoard.once('ready', () => {
ourBoard.radioSystemStatusGet().should.be.rejected.and.notify(done);
});
}).catch(err => done(err));
});
it('should get up system status if firmware version 2', function (done) {
ourBoard = new openBCIBoard.OpenBCIBoard({
verbose: true,
simulate: true,
simulatorFirmwareVersion: 'v2'
});
ourBoard.connect(k.OBCISimulatorPortName)
.then(() => {
ourBoard.once('ready', () => {
ourBoard.radioSystemStatusGet().then(isUp => {
expect(isUp).to.be.true;
done();
}).catch(err => done(err));
});
}).catch(err => done(err));
});
it('should get down system status if firmware version 2', function (done) {
ourBoard = new openBCIBoard.OpenBCIBoard({
verbose: true,
simulate: true,
simulatorFirmwareVersion: 'v2',
simulatorBoardFailure: true
});
ourBoard.connect(k.OBCISimulatorPortName)
.then(() => {
ourBoard.once('ready', () => {
ourBoard.radioSystemStatusGet().then(isUp => {
expect(isUp).to.be.false;
done();
}).catch(err => done(err));
});
}).catch(err => done(err));
});
});
describe('#radioTests', function () {
this.timeout(0);
before(function (done) {
ourBoard = new openBCIBoard.OpenBCIBoard({
verbose: true,
simulatorFirmwareVersion: 'v2',
simulatorFragmentation: k.OBCISimulatorFragmentationRandom
});
ourBoard.connect(masterPortName).catch(err => done(err));
ourBoard.once('ready', () => {
done();
});
});
after(function (done) {
if (ourBoard.isConnected()) {
ourBoard.disconnect().then(() => {
done();
});
} else {
done();
}
});
after(() => bluebirdChecks.noPendingPromises());
it('should be able to get the channel number', function (done) {
// Don't test if not using v2
if (!ourBoard.usingVersionTwoFirmware()) return done();
// The channel number should be between 0 and 25. Those are hard limits.
ourBoard.radioChannelGet().then(res => {
expect(res.channelNumber).to.be.within(0, 25);
done();
}).catch(err => done(err));
});
it('should be able to set the channel to 1', function (done) {
// Don't test if not using v2
if (!ourBoard.usingVersionTwoFirmware()) return done();
ourBoard.radioChannelSet(1).then(channelNumber => {
expect(channelNumber).to.equal(1);
done();
}).catch(err => done(err));
});
it('should be able to set the channel to 2', function (done) {
// Don't test if not using v2
if (!ourBoard.usingVersionTwoFirmware()) return done();
ourBoard.radioChannelSet(2).then(channelNumber => {
expect(channelNumber).to.equal(2);
done();
}).catch(err => done(err));
});
it('should be able to set the channel to 25', function (done) {
// Don't test if not using v2
if (!ourBoard.usingVersionTwoFirmware()) return done();
ourBoard.radioChannelSet(25).then(channelNumber => {
expect(channelNumber).to.equal(25);
done();
}).catch(err => done(err));
});
it('should be able to set the channel to 5', function (done) {
// Don't test if not using v2
if (!ourBoard.usingVersionTwoFirmware()) return done();
ourBoard.radioChannelSet(5).then(channelNumber => {
expect(channelNumber).to.equal(5);
done();
}).catch(err => done(err));
});
it('should be able to override host channel number, verify system is down, set the host back and verify system is up', function (done) {
// Don't test if not using v2
if (!ourBoard.usingVersionTwoFirmware()) return done();
var systemChanNumber = 0;
var newChanNum = 0;
// var timey = Date.now()
// Get the current system channel
ourBoard.radioChannelGet()
.then(res => {
// Store it
systemChanNumber = res.channelNumber;
// console.log(`system channel number: ${res.channelNumber}`)
if (systemChanNumber === 25) {
newChanNum = 24;
} else {
newChanNum = systemChanNumber + 1;
}
// Call to change just the host
return ourBoard.radioChannelSetHostOverride(newChanNum);
})
.then(newChanNumActual => {
expect(newChanNumActual).to.equal(newChanNum);
// timey = Date.now()
// console.log(`new chan ${newChanNumActual} got`, timey, '0ms')
return new Promise((resolve, reject) => {
setTimeout(function () {
// console.log(`get status`, Date.now(), `${Date.now() - timey}ms`)
ourBoard.radioSystemStatusGet().then(isUp => {
// console.log('resolving', Date.now(), `${Date.now() - timey}ms`)
resolve(isUp);
})
.catch(err => {
reject(err);
});
}, 270); // Should be accurate after 270 seconds
});
})
.then(isUp => {
// console.log(`isUp test`, Date.now(), `${Date.now() - timey}ms`)
expect(isUp).to.be.false;
return ourBoard.radioChannelSetHostOverride(systemChanNumber); // Set back to good
})
.then(newChanNumActual => {
// Verify we set it back to normal
expect(newChanNumActual).to.equal(systemChanNumber);
return ourBoard.radioSystemStatusGet();
})
.then(isUp => {
expect(isUp).to.be.true;
done();
})
.catch(err => done(err));
});
it('should be able to get the poll time', function (done) {
// Don't test if not using v2
if (!ourBoard.usingVersionTwoFirmware()) return done();
ourBoard.radioPollTimeGet().should.eventually.be.greaterThan(0).and.notify(done);
});
it('should be able to set the poll time', function (done) {
// Don't test if not using v2
if (!ourBoard.usingVersionTwoFirmware()) return done();
ourBoard.radioPollTimeSet(80).should.become(80).and.notify(done);
});
it('should be able to change to default baud rate', function (done) {
// Don't test if not using v2
if (!ourBoard.usingVersionTwoFirmware()) return done();
ourBoard.radioBaudRateSet('default').should.become(115200).and.notify(done);
});
it('should be able to change to fast baud rate', function (done) {
// Don't test if not using v2
if (!ourBoard.usingVersionTwoFirmware()) return done();
ourBoard.radioBaudRateSet('fast').then(newBaudRate => {
expect(newBaudRate).to.equal(230400);
return ourBoard.radioBaudRateSet('default');
}).then(() => {
done();
}).catch(err => done(err));
});
it('should be able to set the system status', function (done) {
// Don't test if not using v2
if (!ourBoard.usingVersionTwoFirmware()) return done();
ourBoard.radioSystemStatusGet().then(isUp => {
expect(isUp).to.be.true;
done();
}).catch(err => done(err));
});
});
});
Diferenças do arquivo suprimidas por serem muito extensas Carregar Diff
+60 -2
Ver Arquivo
@@ -32,6 +32,7 @@ describe('openBCISimulator', function () {
expect(simulator.options.alpha).to.be.true;
expect(simulator.options.boardFailure).to.be.false;
expect(simulator.options.daisy).to.be.false;
expect(simulator.options.daisyCanBeAttached).to.be.true;
expect(simulator.options.drift).to.equal(0);
expect(simulator.options.firmwareVersion).to.equal(k.OBCIFirmwareV1);
expect(simulator.options.lineNoise).to.equal(k.OBCISimulatorLineNoiseHz60);
@@ -272,12 +273,69 @@ describe('openBCISimulator', function () {
simulator.once('open', done);
});
afterEach(() => {
simulator.removeAllListeners('data');
simulator = null;
});
describe('set max channels', function () {
this.timeout(100);
it('should send nothing if no daisy attached', function (done) {
simulator.options.daisy = false;
simulator.on('data', function (data) {
expect(data.toString().match(k.OBCIParseEOT)).to.not.equal(null);
if (data.toString().match(k.OBCIParseEOT)) {
done();
}
});
simulator.write(k.OBCIChannelMaxNumber8);
});
it('should send daisy removed if daisy attached', function (done) {
simulator.options.daisy = true;
simulator.on('data', function (data) {
expect(data.toString().match(`daisy removed${k.OBCIParseEOT}`)).to.not.equal(null);
if (data.toString().match(k.OBCIParseEOT)) {
expect(simulator.options.daisy).to.equal(false);
done();
}
});
simulator.write(k.OBCIChannelMaxNumber8);
});
it('should send just 16 if daisy already attached', function (done) {
simulator.options.daisy = true;
simulator.on('data', function (data) {
expect(data.toString().match(`16${k.OBCIParseEOT}`)).to.not.equal(null);
if (data.toString().match(k.OBCIParseEOT)) {
done();
}
});
simulator.write(k.OBCIChannelMaxNumber16);
});
it('should send daisy attached if able to attach', function (done) {
simulator.options.daisy = false;
simulator.options.daisyCanBeAttached = true;
simulator.on('data', function (data) {
expect(data.toString().match(`daisy attached16`)).to.not.equal(null);
if (data.toString().match(k.OBCIParseEOT)) {
expect(simulator.options.daisy).to.equal(true);
done();
}
});
simulator.write(k.OBCIChannelMaxNumber16);
});
it('should send daisy attached if not able to attach', function (done) {
simulator.options.daisy = false;
simulator.options.daisyCanBeAttached = false;
simulator.on('data', function (data) {
expect(data.toString().match(`no daisy to attach!`)).to.not.equal(null);
if (data.toString().match(k.OBCIParseEOT)) {
done();
}
});
simulator.write(k.OBCIChannelMaxNumber16);
});
});
describe('reset', function () {
it('should be v2', function (done) {
simulator.on('data', function (data) {
console.log(data.toString());
expect(data.toString().match('v2')).to.not.equal(null);
done();
});
@@ -667,7 +725,7 @@ describe('openBCISimulator', function () {
bufferSize: bufferSize,
latencyTime: 1000
});
simulator.on('data', function (buffer) {
simulator.once('data', function (buffer) {
expect(buffer.length).to.equal(bufferSize);
done();
});