Comparar commits

..

18 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
20 arquivos alterados com 2342 adições e 991 exclusões
+56 -2
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:
---
@@ -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');
@@ -126,7 +141,7 @@ var ourBoard = new OpenBCIBoard({
simulate: true
});
```
ps: go [checkout out the example](examples/debug/debug.js) to do it right now!
Go [checkout out the debug example](examples/debug/debug.js)!
'ready' event
------------
@@ -391,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`)
@@ -510,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.
@@ -522,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)!
@@ -711,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.
@@ -1076,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.
+33
Ver Arquivo
@@ -1,3 +1,36 @@
# 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
@@ -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
}));
+223 -84
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 = {};
@@ -206,6 +216,7 @@ function OpenBCIFactory () {
this.timeOfPacketArrival = 0;
this.writeOutDelay = k.OBCIWriteIntervalDelayMSShort;
// Strings
this.portName = null;
// NTP
if (this.options.sntpTimeSync) {
@@ -254,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,
@@ -378,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.
@@ -1012,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}
@@ -1695,7 +1816,7 @@ function OpenBCIFactory () {
case k.OBCIParsingEOT:
if (openBCISample.doesBufferHaveEOT(data)) {
this.curParsingMode = k.OBCIParsingNormal;
this.emit('eot', data);
this.emit(k.OBCIEmitterEot, data);
this.buffer = openBCISample.stripToEOTBuffer(data);
} else {
this.buffer = data;
@@ -1705,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.emit('ready');
this.buffer = openBCISample.stripToEOTBuffer(data);
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;
}
@@ -1807,13 +1950,9 @@ function OpenBCIFactory () {
*/
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)) {
+14
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,
+1 -1
Ver Arquivo
@@ -1119,7 +1119,7 @@ function isSuccessInBuffer (dataBuffer) {
*/
function stripToEOTBuffer (dataBuffer) {
let indexOfEOT = dataBuffer.indexOf(k.OBCIParseEOT);
if (indexOfEOT > 0) {
if (indexOfEOT >= 0) {
indexOfEOT += k.OBCIParseEOT.length;
} else {
return dataBuffer;
+25
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],
@@ -252,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.1",
"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"
},
+13
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 () {
@@ -1440,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);
});
+15
Ver Arquivo
@@ -1221,6 +1221,21 @@ $$$`);
}
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;
+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
+59 -1
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();
});