Comparar commits
251 Commits
| Autor | SHA1 | Data | |
|---|---|---|---|
| 483811b092 | |||
| 54d223533a | |||
| a552248f21 | |||
| 5013112b36 | |||
| b65694575b | |||
| e47128cc4a | |||
| 1a6029770f | |||
| a404703d2e | |||
| f618dcd038 | |||
| 0f4cb8baf0 | |||
| 1ad709659b | |||
| b871bd159d | |||
| 9d778b64f8 | |||
| 95d6529e3a | |||
| 3f42be4df6 | |||
| 2523f72059 | |||
| af9f08642e | |||
| a2b4d73847 | |||
| c2958f408e | |||
| 0dd0eceb46 | |||
| 70a6165366 | |||
| 2d7547ce79 | |||
| de381a80de | |||
| 888be5d60f | |||
| 57e6d9f7c2 | |||
| fb3d722fc8 | |||
| 2728617126 | |||
| dd7639829a | |||
| b11775ecde | |||
| f96cdd94ec | |||
| 4ce630dc4c | |||
| 8557444c55 | |||
| c2c75fe9d8 | |||
| 13d4f57003 | |||
| b9d0a466f8 | |||
| 4428040a06 | |||
| f7e5c4988e | |||
| d4799dd45a | |||
| 212db205f2 | |||
| 47b2df5802 | |||
| d06b6101e3 | |||
| eb0510be6f | |||
| c696d4f5ca | |||
| 677517715a | |||
| 600b1b2b28 | |||
| 32d011d1f9 | |||
| ee6c50294c | |||
| 34be4c9fe3 | |||
| 57dc399742 | |||
| 5d989f6ea4 | |||
| 2eebde6053 | |||
| f7f8517c28 | |||
| d4f62ef382 | |||
| c4e29bbaa7 | |||
| f553cdea35 | |||
| 25c7871fec | |||
| c2097670e7 | |||
| cfb8071a9d | |||
| 22aca53dac | |||
| 9467d8a052 | |||
| b6ef09c220 | |||
| 238d4cc119 | |||
| c59cd18cf4 | |||
| 69cd84f446 | |||
| 9a17e41c0b | |||
| edff39504c | |||
| 2d1285a887 | |||
| 2100aaee5c | |||
| eba46f8e6c | |||
| de57563f51 | |||
| f59b41109d | |||
| 0193031d20 | |||
| 2904830309 | |||
| 08ce44d4e9 | |||
| 62a69e01cc | |||
| e9e6dbd624 | |||
| 1ade656876 | |||
| 83d32bc9b9 | |||
| 4b5e4ab0a6 | |||
| 2cc0d42fdf | |||
| 94e0a13d71 | |||
| 6b11910fa7 | |||
| 83ac939d4e | |||
| 38687d42bb | |||
| 1a43a06786 | |||
| 47c6918194 | |||
| c351f3afd1 | |||
| e65707cb31 | |||
| 97e44171b8 | |||
| 0f7bb33434 | |||
| 884f2f14ee | |||
| 5fde5b09bf | |||
| 23776e4b9c | |||
| 5b70268390 | |||
| 37db876f11 | |||
| 864469d3d8 | |||
| 7d78748532 | |||
| d6fbce3e4c | |||
| 7ecff0a08d | |||
| ab891d7565 | |||
| 3e99a77e88 | |||
| e3061c03ce | |||
| d6335257e1 | |||
| aea599a7dd | |||
| 031861d2ed | |||
| 6fd9ddf01b | |||
| fe2abac07b | |||
| 2528d56ac9 | |||
| 18b137b498 | |||
| 470ee81928 | |||
| 3c46100e1d | |||
| 2c0b2e37d2 | |||
| 094e328296 | |||
| 4c9bbb1f6d | |||
| b51cb54f92 | |||
| 19f05e362f | |||
| c33d08b486 | |||
| 97cff2dac9 | |||
| 6cf5e993ed | |||
| 6cbf99e635 | |||
| 9bd1121ab8 | |||
| 7d878f1a16 | |||
| ba4370793c | |||
| e88922c106 | |||
| a43c52fdec | |||
| 5cf97383b9 | |||
| d51c8f80d4 | |||
| 0a1f3de1a7 | |||
| e68f85d5b3 | |||
| 9c51fd673e | |||
| 2cf1a46994 | |||
| 77f7946790 | |||
| 9bd83aaf15 | |||
| 22f5ddbcef | |||
| 918451ebcb | |||
| a03250502c | |||
| 265e89284c | |||
| 0cd2e57f96 | |||
| 4a58dcb36a | |||
| 82a3fc3ced | |||
| 23e8364185 | |||
| e21160fa4d | |||
| 6d3813c4e1 | |||
| d8342879cf | |||
| 3322e9ca5c | |||
| 5f0085ddb3 | |||
| a005c8b711 | |||
| 49d0a5376f | |||
| de22e725d5 | |||
| 74cd163bd5 | |||
| 9fd53d2bec | |||
| da8e407e84 | |||
| d624b1d387 | |||
| f861563326 | |||
| 083df5a109 | |||
| aa5e42575a | |||
| cd482558bb | |||
| fa5890d5ad | |||
| 3df7d3170c | |||
| 46edd477a5 | |||
| c36e9d6126 | |||
| ccd2983cc9 | |||
| 08a575cc9c | |||
| 83223cb50a | |||
| dbd9987d5e | |||
| 2832fcb6b2 | |||
| 61a2971275 | |||
| cc177e200d | |||
| 12429398ca | |||
| de3604f3b8 | |||
| 6f6ffe7ad8 | |||
| f4cd6b3a65 | |||
| 443ee211ad | |||
| bfc0fe62a1 | |||
| 4d7d4eb5d8 | |||
| f948ec25f2 | |||
| 78b830e5c0 | |||
| 63a15cb950 | |||
| f5bf4db9a0 | |||
| 117c4411da | |||
| 927f6c1596 | |||
| 81af1098ed | |||
| a8fa5bab02 | |||
| 982688008a | |||
| cbbecc8b37 | |||
| 4080fe0d1b | |||
| 9e745331eb | |||
| b1c8b81aa1 | |||
| de6e1ab353 | |||
| cd108bd29a | |||
| 79b46ecb53 | |||
| f8a47560b8 | |||
| 03ed89b516 | |||
| bc436a7e1f | |||
| 2108ae2a75 | |||
| 70689548a1 | |||
| 701bc75a1f | |||
| cce4f930ef | |||
| 737f40e51e | |||
| f00988716a | |||
| 7e7eb8f549 | |||
| 8383070639 | |||
| b24d682e49 | |||
| b36a7b3409 | |||
| cfa8f4bdc8 | |||
| ee66c49ff0 | |||
| abfb37a38e | |||
| 48be1a01db | |||
| 8bbc011ead | |||
| cc839b3b32 | |||
| e2cd5d1dd7 | |||
| 682074dff7 | |||
| 0af11eabe5 | |||
| 31eea736dd | |||
| 8cafa3f7ff | |||
| 971787720e | |||
| c267cca924 | |||
| 3a90e5ab96 | |||
| a18e17c7ca | |||
| 5da869f059 | |||
| e32ec71c47 | |||
| 5ee44ae531 | |||
| b7f8c135b9 | |||
| 8aa69a18dd | |||
| 617e111812 | |||
| d8c74d5b30 | |||
| aaf9f08c24 | |||
| 37c622fdf4 | |||
| 1d9927a7d7 | |||
| 1eda6df549 | |||
| 88f973d349 | |||
| afcf1de6e2 | |||
| caeeaf7dbd | |||
| 6474391d1e | |||
| 169422e77e | |||
| 21438f5a37 | |||
| 2f5a31e481 | |||
| 04f6fbae14 | |||
| 8a22f3f11b | |||
| 3ab00cfaf5 | |||
| 29b713b7f1 | |||
| 74339c126b | |||
| 465b3cc3a5 | |||
| 920eab9ed1 | |||
| 3a6d87ca90 | |||
| 6a0e1c609f | |||
| cd7d388e69 | |||
| 0ef2add033 | |||
| 8f24aa55b7 | |||
| 92242c87b2 | |||
| 655513e757 |
@@ -0,0 +1 @@
|
||||
{"extends": ["standard"], "parser": "babel-eslint"}
|
||||
@@ -33,6 +33,13 @@ public
|
||||
|
||||
# Test output files
|
||||
myOutput.txt
|
||||
hardwareVoltageOutputAll.txt
|
||||
|
||||
# Local npm builds for testing end in .tgz
|
||||
*.tgz
|
||||
|
||||
# For git
|
||||
*.orig
|
||||
|
||||
# Text editor temporary files
|
||||
.*.sw* # vi/vim
|
||||
|
||||
+2
-1
@@ -17,4 +17,5 @@ node_modules
|
||||
.DS_Store
|
||||
public
|
||||
myOutput.txt
|
||||
*.tgz
|
||||
*.tgz
|
||||
openBCISerialFormat
|
||||
|
||||
@@ -1,3 +1,24 @@
|
||||
language: node_js
|
||||
node_js:
|
||||
- "4.0"
|
||||
- "4.1"
|
||||
- "4.2"
|
||||
- "4.3"
|
||||
- "4.4"
|
||||
- "4.5"
|
||||
- "4.6"
|
||||
- "5.11.0"
|
||||
- "6.0"
|
||||
- "6.1"
|
||||
- "6.2"
|
||||
- "6.3"
|
||||
- "6.4"
|
||||
- "6.5"
|
||||
- "6.6"
|
||||
- "6.7"
|
||||
- "6.8"
|
||||
install:
|
||||
- npm install --all
|
||||
script:
|
||||
- npm run lint
|
||||
- npm run test-cov
|
||||
|
||||
+958
-199
Diferenças do arquivo suprimidas por serem muito extensas
Carregar Diff
+334
@@ -0,0 +1,334 @@
|
||||
# 1.5.2
|
||||
|
||||
### Dependency Package Updates
|
||||
* `performance-now`: from `^0.2.0` to `2.1.0`
|
||||
* `serialport` - from `4.0.1` to `4.0.7`
|
||||
|
||||
### Development Dependency Package Updates
|
||||
* `bluebird`: from `3.4.6` to `3.5.0`
|
||||
* `chai-as-promised`: from `^5.2.0` to `^6.0.0`
|
||||
* `codecov`: from `^1.0.1` to `^2.1.0`
|
||||
* `semistandard`: from `^9.0.0` to `^10.0.0`
|
||||
* `sinon`: from `^1.17.2` to `^2.1.0`
|
||||
* `snazzy`: from `^5.0.0` to `^6.0.0`
|
||||
|
||||
# 1.5.1
|
||||
|
||||
### New Features
|
||||
* Add new example for Lab stream layer (#139) thanks @gabrielibagon
|
||||
|
||||
### Breaking changes
|
||||
* Removed `impedanceCalculationForChannel()` and `impedanceCalculationForAllChannels` from `OpenBCISample.js`
|
||||
|
||||
### Bug Fixes
|
||||
* Fixes #28- Impedance not working properly.
|
||||
|
||||
# 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
|
||||
|
||||
* Three new initialization options: `simulatorFragmentation`, `simulatorBufferSize`, and `simulatorLatencyTimer`. Together, these enable a more _realistic_ serial port simulation, mimicking different potential user computer systems.
|
||||
* New option `debug` gives a live dump of serial traffic on the console if enabled
|
||||
* New API function `.isConnected()` to check if communications are active.
|
||||
* New API function `.isStreaming()` to check if samples are coming from the board.
|
||||
|
||||
### Enhancements
|
||||
|
||||
* Implement and adapt semi-standard code style. Closes #83
|
||||
* autoFindOpenBCIBoard now notices and uses the stock dongle on Linux
|
||||
* 'synced' object now has `error` property, null on good syncs, error description on bad syncs.
|
||||
|
||||
### Breaking Changes
|
||||
|
||||
* The setting for simulatorInjectLineNoise has changed from `None` to `none`
|
||||
* connect() will now fail if already connected
|
||||
* The constructor will throw an error now if an invalid option is passed
|
||||
* The `.connected` property has been removed, replaced by `.isConnected()`. Removed from docs.
|
||||
* 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
|
||||
|
||||
* Fixed bug where early packet fragments were dropped after board reset
|
||||
* Fixed bug where time sync replies that began a buffered chunk were ignored
|
||||
* Fixed bug where simulator would output wrong version in its reset message
|
||||
* Fixed bug where resources were not cleaned up if connect was called twice
|
||||
* Fixed bug where serial data was written after disconnection
|
||||
* Fixed bug where unexpected disconnection was not detected
|
||||
* Fixed bug where promises could lead to out of order packet processing.
|
||||
|
||||
# 1.3.3
|
||||
|
||||
### New Features
|
||||
|
||||
* Add `timeOffsetMaster` to object emitted when bad time sync.
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Fixed log statement on impedance setting function
|
||||
* Remove event emitter with time sync on reject of sync clock full
|
||||
|
||||
# 1.3.2
|
||||
|
||||
### Enhancements
|
||||
|
||||
* Added master time offset `timeOffsetMaster` to `syncObj` which is a running average across sync attempts.
|
||||
|
||||
# 1.3.1
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Fixed bug where `connected` and `streaming` were not set in constructor
|
||||
|
||||
# 1.3.0
|
||||
|
||||
### New Features
|
||||
|
||||
* Add dropped packet detection, new event `droppedPacket` can be added to get an array of dropped packet numbers in the case of the dropped packet event.
|
||||
|
||||
# 1.2.3
|
||||
|
||||
### Enhancements
|
||||
|
||||
* Add table of contents to read me
|
||||
* Reduce size of repo by removing impedance test report
|
||||
|
||||
# 1.2.2
|
||||
|
||||
### Enhancements
|
||||
|
||||
* Upgrade serialport to 4.x
|
||||
|
||||
# 1.2.1
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Fixed bug where set channel function allowed for channel 0 to be set. Cannot set system to channel 0; lower limit is 1.
|
||||
|
||||
# 1.2.0
|
||||
|
||||
### New Features
|
||||
|
||||
* Add tutorial/sample code for interfacing the module with lab streaming layer.
|
||||
|
||||
### Breaking Changes
|
||||
|
||||
* Fixed time synced accel to work OpenBCI_32bit_Library release candidate 5 and newer.
|
||||
|
||||
# 1.1.0
|
||||
|
||||
### New Features
|
||||
|
||||
* Add function `.time()` which should be used in time syncing
|
||||
* Add function `.syncClocksFull()` which should be used for immediate consecutive time syncs
|
||||
* Synced object can be emitted on `synced` event. Check `valid` property for if the sync was done
|
||||
* Add detailed description of object returned on `synced` event to README.md
|
||||
|
||||
### Breaking Changes
|
||||
|
||||
* Changed option named `timeSync` to `sntpTimeSync`
|
||||
* Removed function called `.sntpNow()` because it was replaced by `.time()`
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Time sync working
|
||||
* Module could not work with local time
|
||||
|
||||
# 1.0.1
|
||||
|
||||
### New Features
|
||||
|
||||
* Add time sync tutorial in `README.md`
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Fixed bug in simulator that lead to samples being all zeros.
|
||||
* Fixed time sync sent confirmation bug that led to bad time values.
|
||||
|
||||
# 1.0.0
|
||||
|
||||
The second major release for the OpenBCI Node.js SDK brings major changes, improvements and stability, on top of a push to increase automated test coverage.
|
||||
|
||||
### New Features
|
||||
|
||||
* NPM Module now called `openbci` instead of `openbci-sdk`
|
||||
* Firmware version 2.0 support.
|
||||
* Clock synchronization between OpenBCI board and this driver
|
||||
* `.info` property which contains verified board information parsed from the OpenBCI's `softReset()` response.
|
||||
* `eot` event that is emitted when a user sends a command that results in an EOT ("$$$") being sent from the board
|
||||
* Daisy (16 channel) support
|
||||
* Simulator overhaul, it completely mocks the board. Can now simulate board failure, where the board stops talking to the dongle. Can also mock a serial port failure.
|
||||
* `error` and `close` events from serialport now emtted events users can subscribe to.
|
||||
|
||||
### Breaking Changes
|
||||
|
||||
* NPM package is not called `openbci-sdk` anymore, now called `openbci`
|
||||
* Accelerometer data now goes into `.accelData` array instead of `.auxData` array.
|
||||
* In openBCISample.js
|
||||
* `parseRawPacket()` is now called `parseRawPacketStandard()`
|
||||
* `ready` event only triggered after soft reset. `eot` event emitted in all other conditions resulting in the board sending EOT ("$$$")
|
||||
* Must use camel case on the OpenBCISimulator object.
|
||||
* Renamed constructor options for readability:
|
||||
* `simulatorAlpha` to `simulatorInjectAlpha`
|
||||
* `simulatorLineNoise` to `simulatorInjectLineNoise`
|
||||
* `connect()` no longer rejects on `close` or `error` event from the serialport.
|
||||
|
||||
# 0.3.9
|
||||
|
||||
### Enhancements
|
||||
|
||||
* Add tests for parsing raw packets
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Removed `got here` log from `.streamStart()`
|
||||
* Validate stop byte before emitting `rawDataPacket`
|
||||
|
||||
# 0.3.8
|
||||
|
||||
### Bug Fixes
|
||||
* Fixed readme.md
|
||||
|
||||
# 0.3.7
|
||||
|
||||
### New Features
|
||||
|
||||
* Upgrade dependencies
|
||||
* Update Travis
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* `.numberOfChannels()` now uses the info object, which is set in the constructor and on the return message from `.softReset()`
|
||||
* `.sampleRate()` now uses the info object, which is set in the constructor and on the return message from `.softReset()`
|
||||
|
||||
# 0.3.6
|
||||
|
||||
### New Features
|
||||
|
||||
* Simulator now has accelerometer data
|
||||
|
||||
# 0.3.5
|
||||
|
||||
### New Features
|
||||
|
||||
* SD card support! Now logging to an SD card is easier than ever.
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Sample rate does not return correct sample rate for custom rate on simulator. #58
|
||||
|
||||
# 0.3.4
|
||||
|
||||
### New Features
|
||||
|
||||
* Simulator made to look more like brainwave data to the user. Implemented a 1/f filter. Defaults to injecting 60Hz line noise with two channels of alpha (10Hz) boost.
|
||||
|
||||
### Github Issues Addressed
|
||||
|
||||
* [https://github.com/OpenBCI/openbci-js-sdk/issues/44](#44)
|
||||
|
||||
# 0.3.3
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* `rawDataPacket` not being emitted
|
||||
|
||||
# 0.3.2
|
||||
|
||||
### Work In Progress
|
||||
|
||||
* SNTP Time Synchronization
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* updates to README.me and comments to change ntp to sntp, because the two are similar, but not the same and we do not want to be misleading
|
||||
* Extended [Stnp](https://www.npmjs.com/package/sntp) to main openBCIBoard.js
|
||||
* Add `.sntpNow()` function to get ntp time.
|
||||
|
||||
# 0.3.1
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Bumped serialport version
|
||||
|
||||
# 0.3.0
|
||||
|
||||
### New Features
|
||||
|
||||
* Test Signals with ADS1299 using `.testSignal()`
|
||||
* Continuous impedance testing, where each sample gets an `impedances` object that is an array of impedances for each
|
||||
channel.
|
||||
* OpenBCI Radio Test File
|
||||
* Added Sntp npm module with helper functions
|
||||
* Removed stopByte and startByte from sampleObjects
|
||||
|
||||
### Breaking Changes
|
||||
|
||||
* Changed simulator name to `OpenBCISimulator`
|
||||
* Changed name of function `simulatorOn` to `simulatorEnable`
|
||||
* Changed name of function `simulatorOff` to `simulatorDisable`
|
||||
|
||||
### Work In Progress
|
||||
|
||||
* NTP Time Synchronization
|
||||
* Goertzel algorithm to get voltage for impedance calculation
|
||||
|
||||
### Bug fixes
|
||||
|
||||
* Impedance calculations
|
||||
* Readme updates
|
||||
* Serial buffer had the chance to become permanently unaligned, optimized and completely transformed and refactored the way bytes are processed.
|
||||
* Changes to gain of channels not working correctly.
|
||||
* Node 5 compatibility
|
||||
|
||||
### Github Issues Addressed
|
||||
|
||||
* #25, #26, #27, #29, #30, #31, #33, #34
|
||||
@@ -0,0 +1,107 @@
|
||||
/**
|
||||
* 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'
|
||||
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');
|
||||
ourBoard.removeAllListeners();
|
||||
/** 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
|
||||
}));
|
||||
@@ -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.5.0"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
/**
|
||||
* 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 (let 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');
|
||||
ourBoard.removeAllListeners();
|
||||
/** 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
|
||||
}));
|
||||
@@ -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.5.0"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
/**
|
||||
* 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 (let 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');
|
||||
ourBoard.removeAllListeners();
|
||||
/** 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
|
||||
}));
|
||||
@@ -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"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,142 @@
|
||||
/**
|
||||
* 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
|
||||
});
|
||||
var k = require('openbci').OpenBCIConstants;
|
||||
|
||||
let startedImpedance = false;
|
||||
let iBuffer = [];
|
||||
let count = 0;
|
||||
const window = 50;
|
||||
|
||||
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) => {
|
||||
if (startedImpedance === false) {
|
||||
startedImpedance = true;
|
||||
k.getImpedanceSetter(1, false, true)
|
||||
.then((commands) => {
|
||||
return ourBoard.write(commands);
|
||||
})
|
||||
.then(() => {
|
||||
console.log('wrote commands to board');
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log('errr', err);
|
||||
});
|
||||
}
|
||||
/** Work with sample */
|
||||
const chan1ValInVolts = sample.channelData[0];
|
||||
|
||||
// const impedance = chan1ValInVolts / k.OBCILeadOffDriveInAmps;
|
||||
|
||||
// console.log(`impedance:\t${impedance} kOhms`);
|
||||
iBuffer.push(chan1ValInVolts);
|
||||
count++;
|
||||
if (count >= window) {
|
||||
let max = 0.0; // sumSquared
|
||||
for (let i = 0; i < window; i++) {
|
||||
if (iBuffer[i] > max) {
|
||||
max = iBuffer[i];
|
||||
}
|
||||
// sumSquared += iBuffer[i] * iBuffer[i];
|
||||
}
|
||||
let min = 0.0;
|
||||
for (let i = 0; i < window; i++) {
|
||||
if (iBuffer[i] < min) {
|
||||
min = iBuffer[i];
|
||||
}
|
||||
// sumSquared += iBuffer[i] * iBuffer[i];
|
||||
}
|
||||
const vP2P = max - min; // peak to peak
|
||||
|
||||
console.log(`impedance: \t${vP2P / 2 / k.OBCILeadOffDriveInAmps}`);
|
||||
// console.log(`impedance: ${vRms/k.OBCILeadOffDriveInAmps}`);
|
||||
|
||||
// const mean_squared = sumSquared / window;
|
||||
// const root_mean_squared = Math.sqrt(mean_squared);
|
||||
// console.log(`impedance: ${root_mean_squared/k.OBCILeadOffDriveInAmps}`);
|
||||
|
||||
count = 0;
|
||||
iBuffer = [];
|
||||
}
|
||||
// console.log(`uV:\t${chan1ValInVolts/(10*6)}\nimpedance:\t${impedance}`);
|
||||
});
|
||||
});
|
||||
});
|
||||
} 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 */
|
||||
ourBoard.disconnect().catch(console.log);
|
||||
ourBoard.removeAllListeners();
|
||||
}
|
||||
if (err) console.log(err.stack);
|
||||
if (options.exit) {
|
||||
if (verbose) console.log('exit');
|
||||
ourBoard.streamStop()
|
||||
.then(() => {
|
||||
process.exit(0);
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log(err);
|
||||
process.exit(0);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
}));
|
||||
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"name": "get-streaming",
|
||||
"version": "1.0.0",
|
||||
"description": "Get impedance example",
|
||||
"main": "getStreaming.js",
|
||||
"scripts": {
|
||||
"start": "node impedance.js",
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"keywords": [
|
||||
"get"
|
||||
],
|
||||
"author": "AJ Keller",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"openbci": "^1.5.0"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
import json
|
||||
import sys
|
||||
import numpy as np
|
||||
import time
|
||||
import zmq
|
||||
from pylsl import StreamInfo, StreamOutlet
|
||||
|
||||
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_string(msg)
|
||||
return
|
||||
|
||||
def recv(self):
|
||||
"""
|
||||
Checks the ZeroMQ for data
|
||||
:return: str
|
||||
String of data
|
||||
"""
|
||||
return self._socket.recv()
|
||||
|
||||
|
||||
def initializeOutlet(interface):
|
||||
"""
|
||||
Initializes and returns an LSL outlet
|
||||
:param interface: Interface
|
||||
the Python interface to communicate with node
|
||||
:return: StreamOutlet
|
||||
returns a labstreaminglayer StreamOutlet
|
||||
"""
|
||||
numChans = None
|
||||
while not numChans:
|
||||
msg = interface.recv()
|
||||
try:
|
||||
dicty = json.loads(msg)
|
||||
numChans = dicty.get('numChans')
|
||||
sampleRate = dicty.get('sampleRate')
|
||||
except ValueError as e:
|
||||
print(e)
|
||||
info = StreamInfo('OpenBCI_EEG', 'EEG', numChans, sampleRate, 'float32', 'myuid34234')
|
||||
outlet = StreamOutlet(info)
|
||||
print('init')
|
||||
return outlet
|
||||
|
||||
def main(argv):
|
||||
verbose = False
|
||||
# Create a new python interface.
|
||||
interface = Interface(verbose)
|
||||
# Create a new labstreaminglayer outlet
|
||||
outlet = initializeOutlet(interface);
|
||||
|
||||
# Stream incoming data to LSL
|
||||
while True:
|
||||
msg = interface.recv()
|
||||
try:
|
||||
dicty = json.loads(msg)
|
||||
message = dicty.get('message')
|
||||
data=message.get('channelData')
|
||||
timeStamp = message.get('timeStamp')
|
||||
outlet.push_sample(data,timeStamp)
|
||||
except BaseException as e:
|
||||
print(e)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main(sys.argv[1:])
|
||||
@@ -0,0 +1,157 @@
|
||||
/**
|
||||
* 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 portPub = 'tcp://127.0.0.1:3004';
|
||||
var zmq = require('zmq-prebuilt');
|
||||
var socket = zmq.socket('pair');
|
||||
var debug = false; // Pretty print any bytes in and out... it's amazing...
|
||||
var verbose = true; // Adds verbosity to functions
|
||||
|
||||
var ourBoard = new OpenBCIBoard({
|
||||
simulatorFirmwareVersion: 'v2',
|
||||
debug: debug,
|
||||
verbose: verbose
|
||||
});
|
||||
|
||||
var timeSyncPossible = false;
|
||||
var resyncPeriodMin = 1;
|
||||
var secondsInMinute = 60;
|
||||
var numChans = 8;
|
||||
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'
|
||||
numChans = ourBoard.numberOfChannels();
|
||||
if (numChans === 16) {
|
||||
ourBoard.overrideInfoForBoardType('daisy');
|
||||
}
|
||||
|
||||
// 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();
|
||||
|
||||
sendToPython({'numChans': numChans, 'sampleRate': ourBoard.sampleRate()});
|
||||
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
|
||||
socket.bind(portPub, function (err) {
|
||||
if (err) throw err;
|
||||
console.log(`bound to ${portPub}`);
|
||||
});
|
||||
|
||||
/**
|
||||
* 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));
|
||||
}
|
||||
};
|
||||
|
||||
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
|
||||
}));
|
||||
@@ -0,0 +1,31 @@
|
||||
{
|
||||
"name": "labstreaminglayer",
|
||||
"version": "1.0.0",
|
||||
"description": "labstreaminglayer 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",
|
||||
"labstreaminglayer",
|
||||
"LSL"
|
||||
],
|
||||
"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"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,111 @@
|
||||
# OpenBCI Node SDK to Lab Streaming Layer
|
||||
|
||||
## About
|
||||
|
||||
This code provides an example of how to stream OpenBCI data through the [lab streaming layer](https://github.com/sccn/labstreaminglayer) using the NodeJS SDK.
|
||||
|
||||
Follow the steps in this README to start streaming. The code is ready to run as-is, but can be modified and extended to customize how you are sending your data. This is designed to be used with the **OpenBCI Cyton** (for **Ganglion support**, see the [Ganglion Node SDK](https://github.com/OpenBCI/OpenBCI_NodeJS_Ganglion/tree/master/examples/labstreaminglayer)).
|
||||
|
||||
## Prerequisites
|
||||
|
||||
* [Python](https://www.python.org/downloads/)
|
||||
* [ZeroMQ](http://zeromq.org/bindings:python)
|
||||
|
||||
```py
|
||||
pip install pyzmq
|
||||
```
|
||||
* [Node.js LTS](https://nodejs.org/en/)
|
||||
* [Lab Streaming Layer](https://github.com/sccn/labstreaminglayer)
|
||||
|
||||
```py
|
||||
pip install pylsl
|
||||
```
|
||||
|
||||
|
||||
## Installation
|
||||
First, install Python dependencies:
|
||||
```bash
|
||||
python setup.py install
|
||||
```
|
||||
Next, install NodeJS dependencies:
|
||||
```bash
|
||||
npm install
|
||||
```
|
||||
Note: depending on your computer settings, you may need to run as administrator or with `sudo`.
|
||||
|
||||
## 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
|
||||
```
|
||||
Note: depending on your computer settings, you may need to run as administrator or with `sudo`.
|
||||
|
||||
## Writing Lab Streaming Layer Code
|
||||
If you would like to use lab streaming layer in a custom OpenBCI NodeJS application, you must include an instance of the OpenBCI NodeJS library and an instance of a Python interface. A basic example is shown below:
|
||||
|
||||
index.js
|
||||
```js
|
||||
var OpenBCIBoard = require('openbci').OpenBCIBoard;
|
||||
var portPub = 'tcp://127.0.0.1:3004';
|
||||
var zmq = require('zmq-prebuilt');
|
||||
var socket = zmq.socket('pair');
|
||||
var ourBoard = new OpenBCIBoard();
|
||||
|
||||
socket.bind(portPub);
|
||||
|
||||
ourBoard.autoFindOpenBCIBoard().then(portName => {
|
||||
if (portName) {
|
||||
ourBoard.connect(portName) // Port name is a serial port name, see `.listPorts()`
|
||||
.then(() => {
|
||||
ourBoard.on('ready',() => {
|
||||
ourBoard.streamStart();
|
||||
ourBoard.on('sample',(sample) => {
|
||||
if (socket) {
|
||||
socket.send(JSON.stringify({message: sample}));
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
} else {
|
||||
console.log('Unable to auto find OpenBCI board');
|
||||
}
|
||||
});
|
||||
|
||||
/* Insert additional exit handlers and cleanup below*/
|
||||
```
|
||||
|
||||
handoff.py
|
||||
```python
|
||||
import json
|
||||
import zmq
|
||||
from pylsl import StreamInfo, StreamOutlet
|
||||
|
||||
# Create ZMQ socket
|
||||
context = zmq.Context()
|
||||
_socket = context.socket(zmq.PAIR)
|
||||
_socket.connect("tcp://localhost:3004")
|
||||
|
||||
# Create a new labstreaminglayer outlet
|
||||
numChans = 8;
|
||||
sampleRate = 250;
|
||||
info = StreamInfo('OpenBCI_EEG', 'EEG', numChans, sampleRate, 'float32', 'openbci_12345')
|
||||
outlet = StreamOutlet(info)
|
||||
# Stream incoming data to LSL
|
||||
while True:
|
||||
msg = _socket.recv()
|
||||
try:
|
||||
dicty = json.loads(msg)
|
||||
message = dicty.get('message')
|
||||
data=message.get('channelData')
|
||||
timeStamp = message.get('timeStamp')
|
||||
outlet.push_sample(data,timeStamp)
|
||||
except BaseException as e:
|
||||
print(e)
|
||||
```
|
||||
|
||||
## Contributing
|
||||
Please PR if you have code to contribute!
|
||||
@@ -0,0 +1,12 @@
|
||||
from setuptools import setup, find_packages
|
||||
|
||||
setup(name='openbci-node-labstreaminglayer',
|
||||
version='0.0.1',
|
||||
description='Labstreaminglayer with NodeJS',
|
||||
url='',
|
||||
author='AJ Keller',
|
||||
author_email='pushtheworldllc@gmail.com',
|
||||
license='MIT',
|
||||
packages=find_packages(),
|
||||
install_requires=['numpy', 'pyzmq','pylsl'],
|
||||
zip_safe=False)
|
||||
@@ -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:])
|
||||
@@ -0,0 +1,208 @@
|
||||
/**
|
||||
* 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 portPub = 'tcp://127.0.0.1:3004';
|
||||
var zmq = require('zmq-prebuilt');
|
||||
var socket = zmq.socket('pair');
|
||||
var simulate = false; // 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 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', () => {
|
||||
// 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(portPub, function (err) {
|
||||
if (err) throw err;
|
||||
console.log(`bound to ${portPub}`);
|
||||
});
|
||||
|
||||
/**
|
||||
* 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 = (rawData) => {
|
||||
try {
|
||||
let body = JSON.parse(rawData); // 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
|
||||
}));
|
||||
@@ -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"
|
||||
}
|
||||
}
|
||||
@@ -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!
|
||||
@@ -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)
|
||||
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"name": "timesync",
|
||||
"version": "1.0.0",
|
||||
"description": "Time sync example",
|
||||
"main": "timeSync.js",
|
||||
"scripts": {
|
||||
"start": "node timeSync.js",
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"keywords": [
|
||||
"time",
|
||||
"sync"
|
||||
],
|
||||
"author": "AJ Keller",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"openbci": "^1.3.1"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,128 @@
|
||||
/**
|
||||
* This is an example of time syncing every second for one minute. Used with a
|
||||
* real board.
|
||||
* To run:
|
||||
* change directory to this file `cd examples/timeSync`
|
||||
* do `npm install`
|
||||
* then `npm start`
|
||||
*/
|
||||
|
||||
var OpenBCIBoard = require('openbci').OpenBCIBoard;
|
||||
|
||||
var ourBoard = new OpenBCIBoard({});
|
||||
var verbose = true; // Adds verbosity to functions
|
||||
|
||||
var sampleRate = 250; // Default to 250, ALWAYS verify with a call to `.sampleRate()` after 'ready' event!
|
||||
var timeSyncPossible = false;
|
||||
|
||||
ourBoard.autoFindOpenBCIBoard().then(portName => {
|
||||
if (portName) {
|
||||
/**
|
||||
* Connect to the board with portName
|
||||
* 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');
|
||||
}
|
||||
});
|
||||
|
||||
var readyFunc = () => {
|
||||
// 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 {
|
||||
killFunc();
|
||||
}
|
||||
};
|
||||
|
||||
var killFunc = () => {
|
||||
ourBoard.disconnect()
|
||||
.then(() => {
|
||||
process.kill();
|
||||
});
|
||||
};
|
||||
|
||||
var sampleFunc = sample => {
|
||||
// Resynchronize every every second
|
||||
if (sample._count % (sampleRate * 1) === 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}`);
|
||||
}
|
||||
}
|
||||
|
||||
// Stop after one minute
|
||||
if (sample._count > sampleRate * 60) {
|
||||
killFunc();
|
||||
}
|
||||
};
|
||||
|
||||
// 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
|
||||
}));
|
||||
+2470
-902
Diferenças do arquivo suprimidas por serem muito extensas
Carregar Diff
+1146
-694
Diferenças do arquivo suprimidas por serem muito extensas
Carregar Diff
+1172
-165
Diferenças do arquivo suprimidas por serem muito extensas
Carregar Diff
@@ -0,0 +1,488 @@
|
||||
'use strict';
|
||||
var EventEmitter = require('events').EventEmitter;
|
||||
var util = require('util');
|
||||
var stream = require('stream');
|
||||
|
||||
var openBCISample = require('./openBCISample');
|
||||
var k = openBCISample.k;
|
||||
var now = require('performance-now');
|
||||
|
||||
function OpenBCISimulatorFactory () {
|
||||
var factory = this;
|
||||
|
||||
var _options = {
|
||||
accel: true,
|
||||
alpha: true,
|
||||
boardFailure: false,
|
||||
daisy: false,
|
||||
daisyCanBeAttached: true,
|
||||
drift: 0,
|
||||
firmwareVersion: [k.OBCIFirmwareV1, k.OBCIFirmwareV2],
|
||||
fragmentation: [k.OBCISimulatorFragmentationNone, k.OBCISimulatorFragmentationRandom, k.OBCISimulatorFragmentationFullBuffers, k.OBCISimulatorFragmentationOneByOne],
|
||||
latencyTime: 16,
|
||||
bufferSize: 4096,
|
||||
lineNoise: [k.OBCISimulatorLineNoiseHz60, k.OBCISimulatorLineNoiseHz50, k.OBCISimulatorLineNoiseNone],
|
||||
sampleRate: 250,
|
||||
serialPortFailure: false,
|
||||
verbose: false
|
||||
};
|
||||
|
||||
function OpenBCISimulator (portName, options) {
|
||||
options = (typeof options !== 'function') && options || {};
|
||||
var opts = {};
|
||||
|
||||
stream.Stream.call(this);
|
||||
|
||||
/** Configuring Options */
|
||||
var o;
|
||||
for (o in _options) {
|
||||
var userValue = options[o];
|
||||
delete options[o];
|
||||
|
||||
if (typeof _options[o] === 'object') {
|
||||
// an array specifying a list of choices
|
||||
// if the choice is not in the list, the first one is defaulted to
|
||||
|
||||
if (_options[o].indexOf(userValue) !== -1) {
|
||||
opts[o] = userValue;
|
||||
} else {
|
||||
opts[o] = _options[o][0];
|
||||
}
|
||||
} else {
|
||||
// anything else takes the user value if provided, otherwise is a default
|
||||
|
||||
if (userValue !== undefined) {
|
||||
opts[o] = userValue;
|
||||
} else {
|
||||
opts[o] = _options[o];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (o in options) throw new Error('"' + o + '" is not a valid option');
|
||||
|
||||
this.options = opts;
|
||||
|
||||
// Bools
|
||||
this.connected = false;
|
||||
this.sd = {
|
||||
active: false,
|
||||
startTime: 0
|
||||
};
|
||||
this.streaming = false;
|
||||
this.synced = false;
|
||||
this.sendSyncSetPacket = false;
|
||||
// Buffers
|
||||
this.outputBuffer = new Buffer(this.options.bufferSize);
|
||||
this.outputBuffered = 0;
|
||||
// Numbers
|
||||
this.channelNumber = 1;
|
||||
this.hostChannelNumber = this.channelNumber;
|
||||
this.pollTime = 80;
|
||||
this.sampleNumber = -1; // So the first sample is 0
|
||||
// Objects
|
||||
this.sampleGenerator = openBCISample.randomSample(k.OBCINumberOfChannelsDefault, this.options.sampleRate, this.options.alpha, this.options.lineNoise);
|
||||
this.time = {
|
||||
current: 0,
|
||||
start: now(),
|
||||
loop: null
|
||||
};
|
||||
// Strings
|
||||
this.portName = portName || k.OBCISimulatorPortName;
|
||||
|
||||
// Call 'open'
|
||||
if (this.options.verbose) console.log(`Port name: ${portName}`);
|
||||
setTimeout(() => {
|
||||
this.connected = true;
|
||||
this.emit('open');
|
||||
}, 200);
|
||||
}
|
||||
|
||||
// This allows us to use the emitter class freely outside of the module
|
||||
// TODO: upgrade from old-style streams to stream.Duplex or stream.Transform
|
||||
util.inherits(OpenBCISimulator, stream.Stream);
|
||||
|
||||
OpenBCISimulator.prototype.flush = function (callback) {
|
||||
this.outputBuffered = 0;
|
||||
|
||||
clearTimeout(this.outputLoopHandle);
|
||||
this.outputLoopHandle = null;
|
||||
|
||||
if (callback) callback();
|
||||
};
|
||||
|
||||
OpenBCISimulator.prototype.isOpen = function () {
|
||||
return this.connected;
|
||||
};
|
||||
|
||||
// output only size bytes of the output buffer
|
||||
OpenBCISimulator.prototype._partialDrain = function (size) {
|
||||
if (!this.connected) throw new Error('not connected');
|
||||
|
||||
if (size > this.outputBuffered) size = this.outputBuffered;
|
||||
|
||||
// buffer is copied because presently openBCIBoard.js reuses it
|
||||
var outBuffer = new Buffer(this.outputBuffer.slice(0, size));
|
||||
|
||||
this.outputBuffer.copy(this.outputBuffer, 0, size, this.outputBuffered);
|
||||
this.outputBuffered -= size;
|
||||
|
||||
this.emit('data', outBuffer);
|
||||
};
|
||||
|
||||
// queue some data for output and send it out depending on options.fragmentation
|
||||
OpenBCISimulator.prototype._output = function (dataBuffer) {
|
||||
// drain full buffers until there is no overflow
|
||||
while (this.outputBuffered + dataBuffer.length > this.outputBuffer.length) {
|
||||
var len = dataBuffer.copy(this.outputBuffer, this.outputBuffered);
|
||||
dataBuffer = dataBuffer.slice(len);
|
||||
this.outputBuffered += len;
|
||||
|
||||
this._partialDrain(this.outputBuffered);
|
||||
this.flush();
|
||||
}
|
||||
|
||||
dataBuffer.copy(this.outputBuffer, this.outputBuffered);
|
||||
this.outputBuffered += dataBuffer.length;
|
||||
|
||||
if (!this.outputLoopHandle) {
|
||||
var latencyTime = this.options.latencyTime;
|
||||
if (this.options.fragmentation === k.OBCISimulatorFragmentationOneByOne ||
|
||||
this.options.fragmentation === k.OBCISimulatorFragmentationNone) {
|
||||
// no need to wait for latencyTime
|
||||
// note that this is the only difference between 'none' and 'fullBuffers'
|
||||
latencyTime = 0;
|
||||
}
|
||||
var outputLoop = () => {
|
||||
var size;
|
||||
switch (this.options.fragmentation) {
|
||||
case k.OBCISimulatorFragmentationRandom:
|
||||
if (Math.random() < 0.5) {
|
||||
// randomly picked to send out a fragment
|
||||
size = Math.ceil(Math.random() * Math.max(this.outputBuffered, 62));
|
||||
break;
|
||||
} // else, randomly picked to send a complete buffer in next block
|
||||
/* falls through */
|
||||
case k.OBCISimulatorFragmentationFullBuffers:
|
||||
case k.OBCISimulatorFragmentationNone:
|
||||
case false:
|
||||
size = this.outputBuffered;
|
||||
break;
|
||||
case k.OBCISimulatorFragmentationOneByOne:
|
||||
size = 1;
|
||||
break;
|
||||
}
|
||||
this._partialDrain(size);
|
||||
if (this.outputBuffered) {
|
||||
this.outputLoopHandle = setTimeout(outputLoop, latencyTime);
|
||||
} else {
|
||||
this.outputLoopHandle = null;
|
||||
}
|
||||
};
|
||||
if (latencyTime === 0) {
|
||||
outputLoop();
|
||||
} else {
|
||||
this.outputLoopHandle = setTimeout(outputLoop, latencyTime);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
OpenBCISimulator.prototype.write = function (data, callback) {
|
||||
if (!this.connected) {
|
||||
if (callback) callback('Not connected');
|
||||
else throw new Error('Not connected!');
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: this function assumes a type of Buffer for radio, and a type of String otherwise
|
||||
// FIX THIS it makes it unusable outside the api code
|
||||
switch (data[0]) {
|
||||
case k.OBCIRadioKey:
|
||||
this._processPrivateRadioMessage(data);
|
||||
break;
|
||||
case k.OBCIStreamStart:
|
||||
if (!this.stream) this._startStream();
|
||||
this.streaming = true;
|
||||
break;
|
||||
case k.OBCIStreamStop:
|
||||
if (this.stream) clearInterval(this.stream); // Stops the stream
|
||||
this.streaming = false;
|
||||
break;
|
||||
case k.OBCIMiscSoftReset:
|
||||
if (this.stream) clearInterval(this.stream);
|
||||
this.streaming = false;
|
||||
this._output(new Buffer(`OpenBCI V3 Simulator On Board ADS1299 Device ID: 0x12345 ${this.options.daisy ? `On Daisy ADS1299 Device ID: 0xFFFFF\n` : ``} LIS3DH Device ID: 0x38422 ${this.options.firmwareVersion === k.OBCIFirmwareV2 ? `Firmware: v2.0.0\n` : ``}$$$`));
|
||||
break;
|
||||
case k.OBCISDLogForHour1:
|
||||
case k.OBCISDLogForHour2:
|
||||
case k.OBCISDLogForHour4:
|
||||
case k.OBCISDLogForHour12:
|
||||
case k.OBCISDLogForHour24:
|
||||
case k.OBCISDLogForMin5:
|
||||
case k.OBCISDLogForMin15:
|
||||
case k.OBCISDLogForMin30:
|
||||
case k.OBCISDLogForSec14:
|
||||
// If we are not streaming, then do verbose output
|
||||
if (!this.streaming) {
|
||||
this._output(new Buffer('Wiring is correct and a card is present.\nCorresponding SD file OBCI_69.TXT\n$$$'));
|
||||
}
|
||||
this.sd.active = true;
|
||||
this.sd.startTime = now();
|
||||
break;
|
||||
case k.OBCISDLogStop:
|
||||
if (!this.streaming) {
|
||||
if (this.SDLogActive) {
|
||||
this._output(new Buffer(`Total Elapsed Time: ${now() - this.sd.startTime} ms`));
|
||||
this._output(new Buffer(`Max write time: ${Math.random() * 500} us`));
|
||||
this._output(new Buffer(`Min write time: ${Math.random() * 200} us`));
|
||||
this._output(new Buffer(`Overruns: 0`));
|
||||
this._printEOT();
|
||||
} else {
|
||||
this._output(new Buffer('No open file to close\n'));
|
||||
this._printEOT();
|
||||
}
|
||||
}
|
||||
this.SDLogActive = false;
|
||||
break;
|
||||
case k.OBCISyncTimeSet:
|
||||
if (this.options.firmwareVersion === k.OBCIFirmwareV2) {
|
||||
this.synced = true;
|
||||
setTimeout(() => {
|
||||
this._output(new Buffer(k.OBCISyncTimeSent));
|
||||
this._syncUp();
|
||||
}, 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;
|
||||
}
|
||||
|
||||
/** Handle Callback */
|
||||
if (callback) {
|
||||
callback(null, 'Success!');
|
||||
}
|
||||
};
|
||||
|
||||
OpenBCISimulator.prototype.drain = function (callback) {
|
||||
if (callback) callback();
|
||||
};
|
||||
|
||||
OpenBCISimulator.prototype.close = function (callback) {
|
||||
if (this.connected) {
|
||||
this.flush();
|
||||
|
||||
if (this.stream) clearInterval(this.stream);
|
||||
|
||||
this.connected = false;
|
||||
this.emit('close');
|
||||
if (callback) callback();
|
||||
} else {
|
||||
if (callback) callback('not connected');
|
||||
}
|
||||
};
|
||||
|
||||
OpenBCISimulator.prototype._startStream = function () {
|
||||
var intervalInMS = 1000 / this.options.sampleRate;
|
||||
|
||||
if (intervalInMS < 2) intervalInMS = 2;
|
||||
|
||||
var getNewPacket = sampNumber => {
|
||||
if (this.options.accel) {
|
||||
if (this.synced) {
|
||||
if (this.sendSyncSetPacket) {
|
||||
this.sendSyncSetPacket = false;
|
||||
return openBCISample.convertSampleToPacketAccelTimeSyncSet(this.sampleGenerator(sampNumber), now().toFixed(0));
|
||||
} else {
|
||||
return openBCISample.convertSampleToPacketAccelTimeSynced(this.sampleGenerator(sampNumber), now().toFixed(0));
|
||||
}
|
||||
} else {
|
||||
return openBCISample.convertSampleToPacketStandard(this.sampleGenerator(sampNumber));
|
||||
}
|
||||
} else {
|
||||
if (this.synced) {
|
||||
if (this.sendSyncSetPacket) {
|
||||
this.sendSyncSetPacket = false;
|
||||
return openBCISample.convertSampleToPacketRawAuxTimeSyncSet(this.sampleGenerator(sampNumber), now().toFixed(0), new Buffer([0, 0, 0, 0, 0, 0]));
|
||||
} else {
|
||||
return openBCISample.convertSampleToPacketRawAuxTimeSynced(this.sampleGenerator(sampNumber), now().toFixed(0), new Buffer([0, 0, 0, 0, 0, 0]));
|
||||
}
|
||||
} else {
|
||||
return openBCISample.convertSampleToPacketRawAux(this.sampleGenerator(sampNumber), new Buffer([0, 0, 0, 0, 0, 0]));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
this.stream = setInterval(() => {
|
||||
this._output(getNewPacket(this.sampleNumber));
|
||||
this.sampleNumber++;
|
||||
}, intervalInMS);
|
||||
};
|
||||
|
||||
OpenBCISimulator.prototype._syncUp = function () {
|
||||
setTimeout(() => {
|
||||
this.sendSyncSetPacket = true;
|
||||
}, 12); // 3 packets later
|
||||
};
|
||||
|
||||
OpenBCISimulator.prototype._printEOT = function () {
|
||||
this._output(new Buffer('$$$'));
|
||||
};
|
||||
|
||||
OpenBCISimulator.prototype._printFailure = function () {
|
||||
this._output(new Buffer('Failure: '));
|
||||
};
|
||||
|
||||
OpenBCISimulator.prototype._printSuccess = function () {
|
||||
this._output(new Buffer('Success: '));
|
||||
};
|
||||
|
||||
OpenBCISimulator.prototype._printValidatedCommsTimeout = function () {
|
||||
this._printFailure();
|
||||
this._output(new Buffer('Communications timeout - Device failed to poll Host'));
|
||||
this._printEOT();
|
||||
};
|
||||
|
||||
OpenBCISimulator.prototype._processPrivateRadioMessage = function (dataBuffer) {
|
||||
switch (dataBuffer[1]) {
|
||||
case k.OBCIRadioCmdChannelGet:
|
||||
if (this.options.firmwareVersion === k.OBCIFirmwareV2) {
|
||||
if (!this.options.boardFailure) {
|
||||
this._printSuccess();
|
||||
this._output(new Buffer(`Host and Device on Channel Number ${this.channelNumber}`));
|
||||
this._output(new Buffer([this.channelNumber]));
|
||||
this._printEOT();
|
||||
} else if (!this.serialPortFailure) {
|
||||
this._printFailure();
|
||||
this._output(new Buffer(`Host on Channel Number ${this.channelNumber}`));
|
||||
this._output(new Buffer([this.channelNumber]));
|
||||
this._printEOT();
|
||||
}
|
||||
}
|
||||
break;
|
||||
case k.OBCIRadioCmdChannelSet:
|
||||
if (this.options.firmwareVersion === k.OBCIFirmwareV2) {
|
||||
if (!this.options.boardFailure) {
|
||||
if (dataBuffer[2] <= k.OBCIRadioChannelMax) {
|
||||
this.channelNumber = dataBuffer[2];
|
||||
this.hostChannelNumber = this.channelNumber;
|
||||
this._printSuccess();
|
||||
this._output(new Buffer(`Channel Number ${this.channelNumber}`));
|
||||
this._output(new Buffer([this.channelNumber]));
|
||||
this._printEOT();
|
||||
} else {
|
||||
this._printFailure();
|
||||
this._output(new Buffer('Verify channel number is less than 25'));
|
||||
this._printEOT();
|
||||
}
|
||||
} else if (!this.serialPortFailure) {
|
||||
this._printValidatedCommsTimeout();
|
||||
}
|
||||
}
|
||||
break;
|
||||
case k.OBCIRadioCmdChannelSetOverride:
|
||||
if (this.options.firmwareVersion === k.OBCIFirmwareV2) {
|
||||
if (dataBuffer[2] <= k.OBCIRadioChannelMax) {
|
||||
if (dataBuffer[2] === this.channelNumber) {
|
||||
this.options.boardFailure = false;
|
||||
} else {
|
||||
this.options.boardFailure = true;
|
||||
}
|
||||
this.hostChannelNumber = dataBuffer[2];
|
||||
this._printSuccess();
|
||||
this._output(new Buffer(`Host override - Channel Number ${this.hostChannelNumber}`));
|
||||
this._output(new Buffer([this.hostChannelNumber]));
|
||||
this._printEOT();
|
||||
} else {
|
||||
this._printFailure();
|
||||
this._output(new Buffer('Verify channel number is less than 25'));
|
||||
this._printEOT();
|
||||
}
|
||||
}
|
||||
break;
|
||||
case k.OBCIRadioCmdPollTimeGet:
|
||||
if (this.options.firmwareVersion === k.OBCIFirmwareV2) {
|
||||
if (!this.options.boardFailure) {
|
||||
this._printSuccess();
|
||||
this._output(new Buffer(`Poll Time ${this.pollTime}`));
|
||||
this._output(new Buffer([this.pollTime]));
|
||||
this._printEOT();
|
||||
} else {
|
||||
this._printValidatedCommsTimeout();
|
||||
}
|
||||
}
|
||||
break;
|
||||
case k.OBCIRadioCmdPollTimeSet:
|
||||
if (this.options.firmwareVersion === k.OBCIFirmwareV2) {
|
||||
if (!this.options.boardFailure) {
|
||||
this.pollTime = dataBuffer[2];
|
||||
this._printSuccess();
|
||||
this._output(new Buffer(`Poll Time ${this.pollTime}`));
|
||||
this._output(new Buffer([this.pollTime]));
|
||||
this._printEOT();
|
||||
} else {
|
||||
this._printValidatedCommsTimeout();
|
||||
}
|
||||
}
|
||||
break;
|
||||
case k.OBCIRadioCmdBaudRateSetDefault:
|
||||
if (this.options.firmwareVersion === k.OBCIFirmwareV2) {
|
||||
this._printSuccess();
|
||||
this._output(new Buffer('Switch your baud rate to 115200'));
|
||||
this._output(new Buffer([0x24, 0x24, 0x24, 0xFF])); // The board really does this
|
||||
}
|
||||
break;
|
||||
case k.OBCIRadioCmdBaudRateSetFast:
|
||||
if (this.options.firmwareVersion === k.OBCIFirmwareV2) {
|
||||
this._printSuccess();
|
||||
this._output(new Buffer('Switch your baud rate to 230400'));
|
||||
this._output(new Buffer([0x24, 0x24, 0x24, 0xFF])); // The board really does this
|
||||
}
|
||||
break;
|
||||
case k.OBCIRadioCmdSystemStatus:
|
||||
if (this.options.firmwareVersion === k.OBCIFirmwareV2) {
|
||||
if (!this.options.boardFailure) {
|
||||
this._printSuccess();
|
||||
this._output(new Buffer('System is Up'));
|
||||
this._printEOT();
|
||||
} else {
|
||||
this._printFailure();
|
||||
this._output(new Buffer('System is Down'));
|
||||
this._printEOT();
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
factory.OpenBCISimulator = OpenBCISimulator;
|
||||
}
|
||||
|
||||
util.inherits(OpenBCISimulatorFactory, EventEmitter);
|
||||
|
||||
module.exports = new OpenBCISimulatorFactory();
|
||||
+38
-11
@@ -1,11 +1,13 @@
|
||||
{
|
||||
"name": "openbci-sdk",
|
||||
"version": "0.1.9",
|
||||
"description": "A fully NodeJS based API for the OpenBCI board connecting to the hardware directly over serial",
|
||||
"name": "openbci",
|
||||
"version": "1.5.2",
|
||||
"description": "The official Node.js SDK for the OpenBCI Biosensor Board.",
|
||||
"main": "openBCIBoard",
|
||||
"scripts": {
|
||||
"lint": "semistandard | snazzy",
|
||||
"start": "node index",
|
||||
"test": "mocha test"
|
||||
"test": "semistandard | snazzy && mocha test",
|
||||
"test-cov": "istanbul cover ./node_modules/mocha/bin/_mocha -- -R spec && codecov"
|
||||
},
|
||||
"keywords": [
|
||||
"openbci",
|
||||
@@ -14,28 +16,53 @@
|
||||
"author": "AJ Keller <aj@pushtheworld.us> (www.openbci.com)",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"buffer-equal": "^1.0.0",
|
||||
"gaussian": "^1.0.0",
|
||||
"serialport": "^2.0.2"
|
||||
"mathjs": "^3.3.0",
|
||||
"performance-now": "^2.1.0",
|
||||
"serialport": "4.0.7",
|
||||
"sntp": "^2.0.0",
|
||||
"streamsearch": "^0.1.2"
|
||||
},
|
||||
"directories": {
|
||||
"test": "test"
|
||||
},
|
||||
"devDependencies": {
|
||||
"bluebird": "3.5.0",
|
||||
"chai": "^3.4.1",
|
||||
"chai-as-promised": "^5.2.0",
|
||||
"mocha": "^2.3.4",
|
||||
"chai-as-promised": "^6.0.0",
|
||||
"codecov": "^2.1.0",
|
||||
"istanbul": "^0.4.4",
|
||||
"mocha": "^3.0.2",
|
||||
"sandboxed-module": "^2.0.3",
|
||||
"sinon": "^1.17.2"
|
||||
"semistandard": "^10.0.0",
|
||||
"sinon": "^2.1.0",
|
||||
"sinon-as-promised": "^4.0.2",
|
||||
"sinon-chai": "^2.8.0",
|
||||
"snazzy": "^6.0.0"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/openbci/openbci-js-sdk.git"
|
||||
"url": "git+https://github.com/openbci/openbci_nodejs.git"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/openbci/openbci-js-sdk/issues"
|
||||
"url": "https://github.com/openbci/openbci_nodejs/issues"
|
||||
},
|
||||
"homepage": "https://github.com/openbci/openbci-js-sdk#readme",
|
||||
"homepage": "https://github.com/openbci/openbci_nodejs#readme",
|
||||
"engines": {
|
||||
"node": ">=4.0.0"
|
||||
},
|
||||
"semistandard": {
|
||||
"globals": [
|
||||
"describe",
|
||||
"context",
|
||||
"before",
|
||||
"beforeEach",
|
||||
"after",
|
||||
"afterEach",
|
||||
"it",
|
||||
"expect",
|
||||
"should"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,273 +0,0 @@
|
||||
/**
|
||||
* Created by AJ Keller
|
||||
* Date: 12/23/15
|
||||
* Purpose: To unit test the OpenBCIBoard file
|
||||
*/
|
||||
|
||||
var assert = require('assert');
|
||||
var OpenBCIBoard = require('../openBCIBoard');
|
||||
var OpenBCISample = OpenBCIBoard.OpenBCISample;
|
||||
var k = OpenBCIBoard.OpenBCIConstants;
|
||||
var chai = require('chai')
|
||||
, expect = chai.expect
|
||||
, should = chai.should();
|
||||
var chaiAsPromised = require("chai-as-promised");
|
||||
|
||||
chai.use(chaiAsPromised);
|
||||
|
||||
var sampleSelf = function() {
|
||||
return {
|
||||
masterBuffer: {
|
||||
buffer: new Buffer(3300),
|
||||
positionRead:0,
|
||||
positionWrite:0,
|
||||
packetsIn:0,
|
||||
packetsRead:0,
|
||||
looseBytes:0
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
var sampleData;
|
||||
var bciBoard;
|
||||
|
||||
var samplePacket = function () {
|
||||
var byteSample = 0x45;
|
||||
var buffy = new Buffer([0xA0,byteSample,0,0,1,0,0,2,0,0,3,0,0,4,0,0,5,0,0,6,0,0,7,0,0,8,0,0,0,1,0,2,0xC0]);
|
||||
return buffy;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
describe('OpenBCIBoard',function() {
|
||||
describe('#_bufMerger',function() {
|
||||
beforeEach(function() {
|
||||
bciBoard = new OpenBCIBoard.OpenBCIBoard();
|
||||
sampleData = [];
|
||||
(function(){
|
||||
for(var i = 0;i < 100;i++) {
|
||||
var sample = samplePacket();
|
||||
sample.sampleNumber = i;
|
||||
sampleData[i] = sample;
|
||||
}
|
||||
}());
|
||||
});
|
||||
it('should write the buffer to the empty master buffer', function() {
|
||||
bciBoard._bufMerger(sampleData[0]);
|
||||
|
||||
// test to see if buffers match
|
||||
assert.equal(0,sampleData[0].compare(bciBoard.masterBuffer.buffer.slice(0, k.OBCIPacketSize)));
|
||||
// test to make sure the write position was moved
|
||||
assert.equal(k.OBCIPacketSize, bciBoard.masterBuffer.positionWrite);
|
||||
// test to make sure we read in the right number of packets
|
||||
assert.equal(bciBoard.masterBuffer.packetsIn,1);
|
||||
// test to make sure there are no loose bytes
|
||||
assert.equal(bciBoard.masterBuffer.looseBytes,0);
|
||||
});
|
||||
it('should write the tiny buffer to the empty master buffer, but not record a packet in', function() {
|
||||
var tinyBufferSize = 10; //tiny because its smaller than a packet
|
||||
var tinyBuffer = sampleData[0].slice(0,tinyBufferSize);
|
||||
|
||||
bciBoard._bufMerger(tinyBuffer);
|
||||
|
||||
// test to see if buffers match
|
||||
assert.equal(0,tinyBuffer.compare(bciBoard.masterBuffer.buffer.slice(0, tinyBufferSize)));
|
||||
// test to make sure the write position was moved
|
||||
assert.equal(tinyBufferSize, bciBoard.masterBuffer.positionWrite);
|
||||
// test to make sure we read in the right number of packets
|
||||
assert.equal(bciBoard.masterBuffer.packetsIn,0);
|
||||
// test to make sure there are 10 loose bytes
|
||||
assert.equal(bciBoard.masterBuffer.looseBytes,tinyBufferSize);
|
||||
});
|
||||
it('should write the multi packet plus loose byte buffer to the empty master buffer', function() {
|
||||
var tinyBufferSize = 10; //tiny because its smaller than a packet
|
||||
var tinyBuffer = sampleData[0].slice(0,tinyBufferSize);
|
||||
|
||||
var buffers = [sampleData[0],sampleData[1],sampleData[2],tinyBuffer];
|
||||
var totalLength = k.OBCIPacketSize * 3 + tinyBufferSize;
|
||||
|
||||
var multiPacketBuffer = Buffer.concat(buffers,totalLength);
|
||||
|
||||
bciBoard._bufMerger(multiPacketBuffer);
|
||||
|
||||
// test to see if buffers match
|
||||
assert.equal(0,multiPacketBuffer.compare(bciBoard.masterBuffer.buffer.slice(0, totalLength)));
|
||||
// test to make sure the write position was moved
|
||||
assert.equal(totalLength, bciBoard.masterBuffer.positionWrite);
|
||||
// test to make sure we read in the right number of packets (shall be three)
|
||||
assert.equal(bciBoard.masterBuffer.packetsIn,3);
|
||||
// test to make sure there are 10 loose bytes
|
||||
assert.equal(bciBoard.masterBuffer.looseBytes,tinyBufferSize);
|
||||
});
|
||||
it('should use looseBytes in to write the multi packet to the master buffer and record an extra packet in', function() {
|
||||
var tinyBufferSize = 10; //tiny because its smaller than a packet
|
||||
var tinyBuffer = sampleData[0].slice(0,tinyBufferSize);
|
||||
|
||||
var hackedBufferSize = k.OBCIPacketSize - tinyBufferSize;
|
||||
var hackedBuffer = sampleData[0].slice(tinyBufferSize);
|
||||
|
||||
bciBoard.masterBuffer.looseBytes = tinyBufferSize;
|
||||
|
||||
var buffers = [hackedBuffer,sampleData[0],sampleData[1],sampleData[2]];
|
||||
var totalLength = k.OBCIPacketSize * 3 + hackedBufferSize;
|
||||
|
||||
var multiPacketBuffer = Buffer.concat(buffers,totalLength);
|
||||
|
||||
bciBoard._bufMerger(multiPacketBuffer);
|
||||
|
||||
// test to see if buffers match
|
||||
assert.equal(0,multiPacketBuffer.compare(bciBoard.masterBuffer.buffer.slice(0, totalLength)));
|
||||
// test to make sure the write position was moved
|
||||
assert.equal(totalLength, bciBoard.masterBuffer.positionWrite);
|
||||
// test to make sure we read in the right number of packets (shall be three)
|
||||
assert.equal(bciBoard.masterBuffer.packetsIn,4);
|
||||
// test to make sure there are 10 loose bytes
|
||||
assert.equal(bciBoard.masterBuffer.looseBytes,0);
|
||||
});
|
||||
it('should write in the position of the masterBufferPositionWrite', function() {
|
||||
var originalWritePosition = 69;
|
||||
bciBoard.masterBuffer.positionWrite = originalWritePosition;
|
||||
|
||||
bciBoard._bufMerger(sampleData[0]);
|
||||
|
||||
// test to see if the master buffer contains the correct data
|
||||
assert.equal(0,sampleData[0].compare(bciBoard.masterBuffer.buffer.slice(originalWritePosition, originalWritePosition + k.OBCIPacketSize)));
|
||||
// test to see if the write position was moved properly
|
||||
assert.equal(bciBoard.masterBuffer.positionWrite,originalWritePosition + k.OBCIPacketSize);
|
||||
// test to make sure we read in the right number of packets
|
||||
assert.equal(bciBoard.masterBuffer.packetsIn,1);
|
||||
// test to make sure there are no loose bytes
|
||||
assert.equal(bciBoard.masterBuffer.looseBytes,0);
|
||||
});
|
||||
it('should wrap the input buffer around the master buffer',function() {
|
||||
var spaceRemaingInMasterBuffer = 15;
|
||||
var originalWritePosition = k.OBCIMasterBufferSize - spaceRemaingInMasterBuffer;
|
||||
|
||||
bciBoard.masterBuffer.positionWrite = originalWritePosition;
|
||||
|
||||
bciBoard._bufMerger(sampleData[0]);
|
||||
|
||||
// test to see that the end of master buffer contains half of sample
|
||||
assert.equal(0,sampleData[0].slice(0,spaceRemaingInMasterBuffer).compare(bciBoard.masterBuffer.buffer.slice(originalWritePosition)));
|
||||
// test to see that the beginning of master buffer contains the second half of sampleData[0]
|
||||
assert.equal(0,sampleData[0].slice(spaceRemaingInMasterBuffer).compare(bciBoard.masterBuffer.buffer.slice(0,sampleData[0].byteLength - spaceRemaingInMasterBuffer)));
|
||||
// test to make sure the write position was moved correctly
|
||||
assert.equal(bciBoard.masterBuffer.positionWrite,sampleData[0].byteLength - spaceRemaingInMasterBuffer);
|
||||
// test to make sure we read in the right number of packets
|
||||
assert.equal(bciBoard.masterBuffer.packetsIn,1);
|
||||
// test to make sure there are no loose bytes
|
||||
assert.equal(bciBoard.masterBuffer.looseBytes,0);
|
||||
});
|
||||
});
|
||||
describe('#_bufPacketStripper', function() {
|
||||
beforeEach(function() {
|
||||
bciBoard = new OpenBCIBoard.OpenBCIBoard();
|
||||
sampleData = [];
|
||||
(function(){
|
||||
for(var i = 0;i < 100;i++) {
|
||||
var sample = samplePacket();
|
||||
sample.sampleNumber = i;
|
||||
sampleData[i] = sample;
|
||||
}
|
||||
}());
|
||||
});
|
||||
it('should remove a packet from the master buffer', function() {
|
||||
var buffers = [sampleData[0],sampleData[1],sampleData[2]];
|
||||
var totalLength = k.OBCIPacketSize * 3;
|
||||
|
||||
var multiPacketBuffer = Buffer.concat(buffers,totalLength);
|
||||
|
||||
//console.log(multiPacketBuffer);
|
||||
|
||||
|
||||
bciBoard._bufMerger(multiPacketBuffer);
|
||||
|
||||
// run through three iterations of stripping packets
|
||||
for (var i = 0; i < 3; i++) {
|
||||
var rawPacket = bciBoard._bufPacketStripper();
|
||||
var sample = OpenBCISample.convertPacketToSample(rawPacket);
|
||||
//console.log(OpenBCISample.debugPrettyPrint(sample));
|
||||
//console.log('Sample ' + i + ' has sample number ' + sample.sampleNumber);
|
||||
assert.equal(sample.sampleNumber,69);
|
||||
}
|
||||
});
|
||||
it('should remove a packet from the master buffer, even at wrap..', function() {
|
||||
|
||||
var buffers = [sampleData[0],sampleData[1],sampleData[2]];
|
||||
var totalLength = k.OBCIPacketSize * 3;
|
||||
|
||||
bciBoard.masterBuffer.positionWrite = k.OBCIMasterBufferSize - 10;
|
||||
bciBoard.masterBuffer.positionRead = bciBoard.masterBuffer.positionWrite;
|
||||
|
||||
var multiPacketBuffer = Buffer.concat(buffers,totalLength);
|
||||
|
||||
bciBoard._bufMerger(multiPacketBuffer);
|
||||
|
||||
// run through three iterations of stripping packets
|
||||
for (var i = 0; i < 3; i++) {
|
||||
var rawPacket = bciBoard._bufPacketStripper();
|
||||
var sample = OpenBCISample.convertPacketToSample(rawPacket);
|
||||
assert(sample.sampleNumber,i);
|
||||
}
|
||||
});
|
||||
});
|
||||
describe('#_bufAlign',function() {
|
||||
beforeEach(function() {
|
||||
bciBoard = new OpenBCIBoard.OpenBCIBoard();
|
||||
sampleData = [];
|
||||
(function(){
|
||||
for(var i = 0;i < 100;i++) {
|
||||
var sample = samplePacket();
|
||||
sample.sampleNumber = i;
|
||||
sampleData[i] = sample;
|
||||
}
|
||||
}());
|
||||
});
|
||||
it('should fix a buffer', function() {
|
||||
var buffers = [sampleData[0],sampleData[1],sampleData[2]];
|
||||
var totalLength = k.OBCIPacketSize * 3;
|
||||
|
||||
|
||||
var multiPacketBuffer = Buffer.concat(buffers,totalLength);
|
||||
|
||||
//console.log(multiPacketBuffer);
|
||||
|
||||
var bytesToHackOffSample = 10;
|
||||
var expectedNewPositionRead = k.OBCIPacketSize - bytesToHackOffSample;
|
||||
|
||||
bciBoard._bufMerger(multiPacketBuffer.slice(10,totalLength));
|
||||
|
||||
bciBoard._bufAlign();
|
||||
|
||||
assert(expectedNewPositionRead,bciBoard.masterBuffer.positionRead);
|
||||
|
||||
});
|
||||
it('should wrap & then fix a buffer', function() {
|
||||
var buffers = [sampleData[0],sampleData[1],sampleData[2]];
|
||||
var totalLength = k.OBCIPacketSize * 3;
|
||||
|
||||
|
||||
var multiPacketBuffer = Buffer.concat(buffers,totalLength);
|
||||
|
||||
var bytesFromEndOfBuffer = 5;
|
||||
|
||||
bciBoard.masterBuffer.positionRead = k.OBCIMasterBufferSize - bytesFromEndOfBuffer;
|
||||
|
||||
var bytesToHackOffSample = 10;
|
||||
var expectedNewPositionRead = bytesToHackOffSample - bytesFromEndOfBuffer;
|
||||
|
||||
bciBoard._bufMerger(multiPacketBuffer.slice(10,totalLength));
|
||||
|
||||
bciBoard._bufAlign();
|
||||
|
||||
assert(expectedNewPositionRead,bciBoard.masterBuffer.positionRead);
|
||||
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
function debugPrintBufferCompare(buf1,buf2) {
|
||||
console.log('Comparing:\n\tBuffer 1\n\t\t' + buf1.toString('hex') + '\n\tBuffer 2\n\t\t' + buf2.toString('hex'));
|
||||
|
||||
}
|
||||
+1455
-1034
Diferenças do arquivo suprimidas por serem muito extensas
Carregar Diff
+1286
-116
Diferenças do arquivo suprimidas por serem muito extensas
Carregar Diff
@@ -0,0 +1,142 @@
|
||||
var timingEventsAsPromises = require('./timingEventsAsPromises');
|
||||
exports.BluebirdPromise = require('bluebird');
|
||||
exports.PromiseIgnored = global.Promise;
|
||||
|
||||
// Enable bluebird for all promise usage during tests only
|
||||
// Fails tests for issues bluebird finds
|
||||
// Exports a function to list all promises (getPendingPromises)
|
||||
// Exports a function to verify no promises pending within a timeout (noPendingPromises)
|
||||
|
||||
exports.BluebirdPromise.config({
|
||||
// TODO: wForgottenReturn is disabled because timingEventsAsPromises triggers it; find a workaround
|
||||
warnings: { wForgottenReturn: false },
|
||||
longStackTraces: true,
|
||||
monitoring: true,
|
||||
cancellation: true
|
||||
});
|
||||
|
||||
// nextTick conveniently not instrumented by timingEventsAsPromises
|
||||
exports.BluebirdPromise.setScheduler(process.nextTick);
|
||||
|
||||
// unhandled rejections become test failures
|
||||
process.on('unhandledRejection', (reason, promise) => {
|
||||
if (!(reason instanceof Error)) {
|
||||
reason = new Error('unhandled promise rejection: ' + reason);
|
||||
} else {
|
||||
reason.message = 'unhandled promise rejection: ' + reason.message;
|
||||
}
|
||||
process.nextTick(() => { throw reason; });
|
||||
});
|
||||
|
||||
// // warnings become test failures
|
||||
// process.on('warning', (warning) => {
|
||||
// var error = new Error(warning);
|
||||
// process.nextTick(() => { throw error; });
|
||||
// });
|
||||
|
||||
// provide access to all currently pending promises
|
||||
var pendingPromises = {};
|
||||
var promiseId = 0;
|
||||
var nested = 0;
|
||||
|
||||
function promiseCreationHandler (promise) {
|
||||
// promise created already resolved; ignore
|
||||
if (!promise.isPending()) return;
|
||||
|
||||
// need to create another promise to get access to the extended stack trace
|
||||
// nested detects if we are inside our own dummy promise
|
||||
++nested;
|
||||
if (nested === 1) {
|
||||
// not the dummy promise
|
||||
promise.___id = ++promiseId;
|
||||
// store promise details
|
||||
var error = new Error('Promise ' + promise.___id + ' is still pending');
|
||||
var entry = {
|
||||
promise: promise,
|
||||
id: promise.___id,
|
||||
error: error
|
||||
};
|
||||
pendingPromises[promise.___id] = entry;
|
||||
// extract stack trace by rejecting an error; bluebird fills in expanded stack
|
||||
exports.BluebirdPromise.reject(error).catch(error => {
|
||||
entry.error = error;
|
||||
entry.stack = error.stack;
|
||||
});
|
||||
} else {
|
||||
promise.___nested = nested;
|
||||
}
|
||||
--nested;
|
||||
}
|
||||
process.on('promiseCreated', promiseCreationHandler);
|
||||
|
||||
function promiseDoneHandler (promise) {
|
||||
if (promise.___nested) return;
|
||||
delete pendingPromises[promise.___id];
|
||||
}
|
||||
process.on('promiseFulfilled', promiseDoneHandler);
|
||||
process.on('promiseRejected', promiseDoneHandler);
|
||||
process.on('promiseResolved', promiseDoneHandler);
|
||||
process.on('promiseCancelled', promiseDoneHandler);
|
||||
|
||||
exports.getPendingPromises = function () {
|
||||
var ret = [];
|
||||
for (var promise in pendingPromises) {
|
||||
ret.push(pendingPromises[promise]);
|
||||
}
|
||||
return ret;
|
||||
};
|
||||
|
||||
exports.noPendingPromises = function (milliseconds) {
|
||||
if (!milliseconds) milliseconds = 0;
|
||||
|
||||
return new exports.PromiseIgnored((resolve, reject) => {
|
||||
function waited100 () {
|
||||
var promises = exports.getPendingPromises();
|
||||
|
||||
if (promises.length === 0) {
|
||||
return resolve();
|
||||
}
|
||||
|
||||
if (milliseconds > 0) {
|
||||
milliseconds -= 100;
|
||||
return timingEventsAsPromises.setTimeoutIgnored(waited100, 100);
|
||||
}
|
||||
|
||||
// timed out, but promises remaining: cancel all
|
||||
|
||||
console.log(promises.length + ' promises still pending');
|
||||
|
||||
promises.forEach(promise => {
|
||||
promise.promise.cancel();
|
||||
});
|
||||
|
||||
// report one
|
||||
reject(promises[0].error);
|
||||
}
|
||||
|
||||
timingEventsAsPromises.setTimeoutIgnored(waited100, 0);
|
||||
});
|
||||
};
|
||||
|
||||
// now instrument the Promise object itself to always use a simplified version of bluebird
|
||||
// bluebird is composed inside a bare-bones Promise object providing only the official calls
|
||||
|
||||
global.Promise = function (handler) {
|
||||
this._promise = new exports.BluebirdPromise(handler);
|
||||
};
|
||||
|
||||
// compose class methods
|
||||
['all', 'race', 'reject', 'resolve'].forEach(classMethod => {
|
||||
global.Promise[classMethod] = function () {
|
||||
return exports.BluebirdPromise[classMethod].apply(exports.BluebirdPromise, [].slice.call(arguments));
|
||||
};
|
||||
Object.defineProperty(global.Promise[classMethod], 'name', { value: 'Promise.' + classMethod });
|
||||
});
|
||||
|
||||
// compose object methods
|
||||
['then', 'catch'].forEach(objectMethod => {
|
||||
global.Promise.prototype[objectMethod] = function () {
|
||||
return this._promise[objectMethod].apply(this._promise, [].slice.call(arguments));
|
||||
};
|
||||
Object.defineProperty(global.Promise.prototype[objectMethod], 'name', { value: 'Promise.' + objectMethod });
|
||||
});
|
||||
@@ -0,0 +1,608 @@
|
||||
'use strict';
|
||||
var bluebirdChecks = require('./bluebirdChecks');
|
||||
var chai = require('chai');
|
||||
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');
|
||||
chai.use(chaiAsPromised);
|
||||
chai.use(sinonChai);
|
||||
|
||||
describe('#impedanceTesting', function () {
|
||||
var ourBoard;
|
||||
this.timeout(20000);
|
||||
|
||||
before(function (done) {
|
||||
ourBoard = new openBCIBoard.OpenBCIBoard({
|
||||
verbose: true,
|
||||
simulatorFragmentation: k.OBCISimulatorFragmentationRandom
|
||||
});
|
||||
var useSim = () => {
|
||||
return ourBoard.simulatorEnable().then(() => {
|
||||
return ourBoard.connect(k.OBCISimulatorPortName);
|
||||
});
|
||||
};
|
||||
ourBoard.autoFindOpenBCIBoard()
|
||||
.then(portName => {
|
||||
return ourBoard.connect(portName);
|
||||
})
|
||||
.catch(() => {
|
||||
return useSim();
|
||||
})
|
||||
.then(() => {
|
||||
console.log('connected');
|
||||
})
|
||||
.catch(err => {
|
||||
console.log('Error: ' + err);
|
||||
});
|
||||
|
||||
ourBoard.once('ready', () => {
|
||||
ourBoard.streamStart()
|
||||
.then(() => {
|
||||
setTimeout(() => {
|
||||
done();
|
||||
}, 100); // give some time for the stream command to be sent
|
||||
})
|
||||
.catch(err => {
|
||||
console.log(err);
|
||||
done(err);
|
||||
});
|
||||
});
|
||||
});
|
||||
after(done => {
|
||||
if (ourBoard.isConnected()) {
|
||||
ourBoard.disconnect()
|
||||
.then(() => {
|
||||
done();
|
||||
})
|
||||
.catch(err => {
|
||||
done(err);
|
||||
});
|
||||
} else {
|
||||
done();
|
||||
}
|
||||
});
|
||||
after(() => bluebirdChecks.noPendingPromises());
|
||||
|
||||
describe('#impedanceTestAllChannels', function () {
|
||||
var impedanceArray = [];
|
||||
|
||||
before(function (done) {
|
||||
ourBoard.once('impedanceArray', arr => {
|
||||
impedanceArray = arr;
|
||||
console.log(impedanceArray);
|
||||
done();
|
||||
});
|
||||
ourBoard.impedanceTestAllChannels();
|
||||
});
|
||||
describe('#channel1', function () {
|
||||
it('has valid channel number', function () {
|
||||
impedanceArray[0].channel.should.be.equal(1);
|
||||
});
|
||||
describe('#inputP', function () {
|
||||
it('got raw impedance value', function () {
|
||||
impedanceArray[0].P.should.have.property('raw').above(-1);
|
||||
});
|
||||
it("text is not 'init'", function () {
|
||||
impedanceArray[0].P.should.have.property('text').not.be.equal(k.OBCIImpedanceTextInit);
|
||||
});
|
||||
});
|
||||
describe('#inputN', function () {
|
||||
it('got raw impedance value', function () {
|
||||
impedanceArray[0].N.should.have.property('raw').above(-1);
|
||||
});
|
||||
it("text is not 'init'", function () {
|
||||
impedanceArray[0].N.should.have.property('text').not.be.equal(k.OBCIImpedanceTextInit);
|
||||
});
|
||||
});
|
||||
});
|
||||
describe('#channel2', function () {
|
||||
it('has valid channel number', function () {
|
||||
impedanceArray[1].channel.should.be.equal(2);
|
||||
});
|
||||
describe('#inputP', function () {
|
||||
it('got raw impedance value', function () {
|
||||
impedanceArray[1].P.should.have.property('raw').above(-1);
|
||||
});
|
||||
it("text is not 'init'", function () {
|
||||
impedanceArray[1].P.should.have.property('text').not.be.equal(k.OBCIImpedanceTextInit);
|
||||
});
|
||||
});
|
||||
describe('#inputN', function () {
|
||||
it('got raw impedance value', function () {
|
||||
impedanceArray[1].N.should.have.property('raw').above(-1);
|
||||
});
|
||||
it("text is not 'init'", function () {
|
||||
impedanceArray[1].N.should.have.property('text').not.be.equal(k.OBCIImpedanceTextInit);
|
||||
});
|
||||
});
|
||||
});
|
||||
describe('#channel3', function () {
|
||||
it('has valid channel number', function () {
|
||||
impedanceArray[2].channel.should.be.equal(3);
|
||||
});
|
||||
describe('#inputP', function () {
|
||||
it('got raw impedance value', function () {
|
||||
impedanceArray[2].P.should.have.property('raw').above(-1);
|
||||
});
|
||||
it("text is not 'init'", function () {
|
||||
impedanceArray[2].P.should.have.property('text').not.be.equal(k.OBCIImpedanceTextInit);
|
||||
});
|
||||
});
|
||||
describe('#inputN', function () {
|
||||
it('got raw impedance value', function () {
|
||||
impedanceArray[2].N.should.have.property('raw').above(-1);
|
||||
});
|
||||
it("text is not 'init'", function () {
|
||||
impedanceArray[2].N.should.have.property('text').not.be.equal(k.OBCIImpedanceTextInit);
|
||||
});
|
||||
});
|
||||
});
|
||||
describe('#channel4', function () {
|
||||
it('has valid channel number', function () {
|
||||
impedanceArray[3].channel.should.be.equal(4);
|
||||
});
|
||||
describe('#inputP', function () {
|
||||
it('got raw impedance value', function () {
|
||||
impedanceArray[3].P.should.have.property('raw').above(-1);
|
||||
});
|
||||
it("text is not 'init'", function () {
|
||||
impedanceArray[3].P.should.have.property('text').not.be.equal(k.OBCIImpedanceTextInit);
|
||||
});
|
||||
});
|
||||
describe('#inputN', function () {
|
||||
it('got raw impedance value', function () {
|
||||
impedanceArray[3].N.should.have.property('raw').above(-1);
|
||||
});
|
||||
it("text is not 'init'", function () {
|
||||
impedanceArray[3].N.should.have.property('text').not.be.equal(k.OBCIImpedanceTextInit);
|
||||
});
|
||||
});
|
||||
});
|
||||
describe('#channel5', function () {
|
||||
it('has valid channel number', function () {
|
||||
impedanceArray[4].channel.should.be.equal(5);
|
||||
});
|
||||
describe('#inputP', function () {
|
||||
it('got raw impedance value', function () {
|
||||
impedanceArray[4].P.should.have.property('raw').above(-1);
|
||||
});
|
||||
it("text is not 'init'", function () {
|
||||
impedanceArray[4].P.should.have.property('text').not.be.equal(k.OBCIImpedanceTextInit);
|
||||
});
|
||||
});
|
||||
describe('#inputN', function () {
|
||||
it('got raw impedance value', function () {
|
||||
impedanceArray[4].N.should.have.property('raw').above(-1);
|
||||
});
|
||||
it("text is not 'init'", function () {
|
||||
impedanceArray[4].N.should.have.property('text').not.be.equal(k.OBCIImpedanceTextInit);
|
||||
});
|
||||
});
|
||||
});
|
||||
describe('#channel6', function () {
|
||||
it('has valid channel number', function () {
|
||||
impedanceArray[5].channel.should.be.equal(6);
|
||||
});
|
||||
describe('#inputP', function () {
|
||||
it('got raw impedance value', function () {
|
||||
impedanceArray[5].P.should.have.property('raw').above(-1);
|
||||
});
|
||||
it("text is not 'init'", function () {
|
||||
impedanceArray[5].P.should.have.property('text').not.be.equal(k.OBCIImpedanceTextInit);
|
||||
});
|
||||
});
|
||||
describe('#inputN', function () {
|
||||
it('got raw impedance value', function () {
|
||||
impedanceArray[5].N.should.have.property('raw').above(-1);
|
||||
});
|
||||
it("text is not 'init'", function () {
|
||||
impedanceArray[5].N.should.have.property('text').not.be.equal(k.OBCIImpedanceTextInit);
|
||||
});
|
||||
});
|
||||
});
|
||||
describe('#channel7', function () {
|
||||
it('has valid channel number', function () {
|
||||
impedanceArray[6].channel.should.be.equal(7);
|
||||
});
|
||||
describe('#inputP', function () {
|
||||
it('got raw impedance value', function () {
|
||||
impedanceArray[6].P.should.have.property('raw').above(-1);
|
||||
});
|
||||
it("text is not 'init'", function () {
|
||||
impedanceArray[6].P.should.have.property('text').not.be.equal(k.OBCIImpedanceTextInit);
|
||||
});
|
||||
});
|
||||
describe('#inputN', function () {
|
||||
it('got raw impedance value', function () {
|
||||
impedanceArray[6].N.should.have.property('raw').above(-1);
|
||||
});
|
||||
it("text is not 'init'", function () {
|
||||
impedanceArray[6].N.should.have.property('text').not.be.equal(k.OBCIImpedanceTextInit);
|
||||
});
|
||||
});
|
||||
});
|
||||
describe('#channel8', function () {
|
||||
it('has valid channel number', function () {
|
||||
impedanceArray[7].channel.should.be.equal(8);
|
||||
});
|
||||
describe('#inputP', function () {
|
||||
it('got raw impedance value', function () {
|
||||
impedanceArray[7].P.should.have.property('raw').above(-1);
|
||||
});
|
||||
it("text is not 'init'", function () {
|
||||
impedanceArray[7].P.should.have.property('text').not.be.equal(k.OBCIImpedanceTextInit);
|
||||
});
|
||||
});
|
||||
describe('#inputN', function () {
|
||||
it('got raw impedance value', function () {
|
||||
impedanceArray[7].N.should.have.property('raw').above(-1);
|
||||
});
|
||||
it("text is not 'init'", function () {
|
||||
impedanceArray[7].N.should.have.property('text').not.be.equal(k.OBCIImpedanceTextInit);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
describe('#impedanceTestChannelsRejects', function () {
|
||||
it('rejects when it does not get an array', function (done) {
|
||||
ourBoard.impedanceTestChannels('taco').should.be.rejected.and.notify(done);
|
||||
});
|
||||
|
||||
it('rejects when it array length does not match number of channels', function (done) {
|
||||
ourBoard.impedanceTestChannels(['-', 'N', 'n', 'p', 'P', 'p', 'b']).should.be.rejected.and.notify(done);
|
||||
});
|
||||
});
|
||||
describe('#impedanceTestChannels', function () {
|
||||
var impedanceArray = [];
|
||||
|
||||
before(function (done) {
|
||||
ourBoard.once('impedanceArray', arr => {
|
||||
impedanceArray = arr;
|
||||
done();
|
||||
});
|
||||
ourBoard.impedanceArray[0] = openBCISample.impedanceObject(1);
|
||||
ourBoard.impedanceTestChannels(['-', 'N', 'n', 'p', 'P', 'p', 'b', 'B']).catch(err => done(err));
|
||||
});
|
||||
describe('#channel1', function () {
|
||||
it('has valid channel number', function () {
|
||||
impedanceArray[0].channel.should.be.equal(1);
|
||||
});
|
||||
describe('#inputP', function () {
|
||||
it('got raw impedance value', function () {
|
||||
impedanceArray[0].P.should.have.property('raw').equal(-1);
|
||||
});
|
||||
it("text is not 'init'", function () {
|
||||
impedanceArray[0].P.should.have.property('text').equal(k.OBCIImpedanceTextInit);
|
||||
});
|
||||
});
|
||||
describe('#inputN', function () {
|
||||
it('got raw impedance value', function () {
|
||||
impedanceArray[0].N.should.have.property('raw').equal(-1);
|
||||
});
|
||||
it("text is not 'init'", function () {
|
||||
impedanceArray[0].N.should.have.property('text').equal(k.OBCIImpedanceTextInit);
|
||||
});
|
||||
});
|
||||
});
|
||||
describe('#channel2', function () {
|
||||
it('has valid channel number', function () {
|
||||
impedanceArray[1].channel.should.be.equal(2);
|
||||
});
|
||||
describe('#inputP', function () {
|
||||
it('got raw impedance value', function () {
|
||||
impedanceArray[1].P.should.have.property('raw').equal(-1);
|
||||
});
|
||||
it("text is not 'init'", function () {
|
||||
impedanceArray[1].P.should.have.property('text').equal(k.OBCIImpedanceTextInit);
|
||||
});
|
||||
});
|
||||
describe('#inputN', function () {
|
||||
it('got raw impedance value', function () {
|
||||
impedanceArray[1].N.should.have.property('raw').above(-1);
|
||||
});
|
||||
it("text is not 'init'", function () {
|
||||
impedanceArray[1].N.should.have.property('text').not.be.equal(k.OBCIImpedanceTextInit);
|
||||
});
|
||||
});
|
||||
});
|
||||
describe('#channel3', function () {
|
||||
it('has valid channel number', function () {
|
||||
impedanceArray[2].channel.should.be.equal(3);
|
||||
});
|
||||
describe('#inputP', function () {
|
||||
it('got raw impedance value', function () {
|
||||
impedanceArray[2].P.should.have.property('raw').equal(-1);
|
||||
});
|
||||
it("text is not 'init'", function () {
|
||||
impedanceArray[2].P.should.have.property('text').equal(k.OBCIImpedanceTextInit);
|
||||
});
|
||||
});
|
||||
describe('#inputN', function () {
|
||||
it('got raw impedance value', function () {
|
||||
impedanceArray[2].N.should.have.property('raw').above(-1);
|
||||
});
|
||||
it("text is not 'init'", function () {
|
||||
impedanceArray[2].N.should.have.property('text').not.be.equal(k.OBCIImpedanceTextInit);
|
||||
});
|
||||
});
|
||||
});
|
||||
describe('#channel4', function () {
|
||||
it('has valid channel number', function () {
|
||||
impedanceArray[3].channel.should.be.equal(4);
|
||||
});
|
||||
describe('#inputP', function () {
|
||||
it('got raw impedance value', function () {
|
||||
impedanceArray[3].P.should.have.property('raw').above(-1);
|
||||
});
|
||||
it("text is not 'init'", function () {
|
||||
impedanceArray[3].P.should.have.property('text').not.be.equal(k.OBCIImpedanceTextInit);
|
||||
});
|
||||
});
|
||||
describe('#inputN', function () {
|
||||
it('got raw impedance value', function () {
|
||||
impedanceArray[3].N.should.have.property('raw').equal(-1);
|
||||
});
|
||||
it("text is not 'init'", function () {
|
||||
impedanceArray[3].N.should.have.property('text').equal(k.OBCIImpedanceTextInit);
|
||||
});
|
||||
});
|
||||
});
|
||||
describe('#channel5', function () {
|
||||
it('has valid channel number', function () {
|
||||
impedanceArray[4].channel.should.be.equal(5);
|
||||
});
|
||||
describe('#inputP', function () {
|
||||
it('got raw impedance value', function () {
|
||||
impedanceArray[4].P.should.have.property('raw').above(-1);
|
||||
});
|
||||
it("text is not 'init'", function () {
|
||||
impedanceArray[4].P.should.have.property('text').not.be.equal(k.OBCIImpedanceTextInit);
|
||||
});
|
||||
});
|
||||
describe('#inputN', function () {
|
||||
it('got raw impedance value', function () {
|
||||
impedanceArray[4].N.should.have.property('raw').equal(-1);
|
||||
});
|
||||
it("text is not 'init'", function () {
|
||||
impedanceArray[4].N.should.have.property('text').equal(k.OBCIImpedanceTextInit);
|
||||
});
|
||||
});
|
||||
});
|
||||
describe('#channel6', function () {
|
||||
it('has valid channel number', function () {
|
||||
impedanceArray[5].channel.should.be.equal(6);
|
||||
});
|
||||
describe('#inputP', function () {
|
||||
it('got raw impedance value', function () {
|
||||
impedanceArray[5].P.should.have.property('raw').above(-1);
|
||||
});
|
||||
it("text is not 'init'", function () {
|
||||
impedanceArray[5].P.should.have.property('text').not.be.equal(k.OBCIImpedanceTextInit);
|
||||
});
|
||||
});
|
||||
describe('#inputN', function () {
|
||||
it('got raw impedance value', function () {
|
||||
impedanceArray[5].N.should.have.property('raw').equal(-1);
|
||||
});
|
||||
it("text is not 'init'", function () {
|
||||
impedanceArray[5].N.should.have.property('text').equal(k.OBCIImpedanceTextInit);
|
||||
});
|
||||
});
|
||||
});
|
||||
describe('#channel7', function () {
|
||||
it('has valid channel number', function () {
|
||||
impedanceArray[6].channel.should.be.equal(7);
|
||||
});
|
||||
describe('#inputP', function () {
|
||||
it('got raw impedance value', function () {
|
||||
impedanceArray[6].P.should.have.property('raw').above(-1);
|
||||
});
|
||||
it("text is not 'init'", function () {
|
||||
impedanceArray[6].P.should.have.property('text').not.be.equal(k.OBCIImpedanceTextInit);
|
||||
});
|
||||
});
|
||||
describe('#inputN', function () {
|
||||
it('got raw impedance value', function () {
|
||||
impedanceArray[6].N.should.have.property('raw').above(-1);
|
||||
});
|
||||
it("text is not 'init'", function () {
|
||||
impedanceArray[6].N.should.have.property('text').not.be.equal(k.OBCIImpedanceTextInit);
|
||||
});
|
||||
});
|
||||
});
|
||||
describe('#channel8', function () {
|
||||
it('has valid channel number', function () {
|
||||
impedanceArray[7].channel.should.be.equal(8);
|
||||
});
|
||||
describe('#inputP', function () {
|
||||
it('got raw impedance value', function () {
|
||||
impedanceArray[7].P.should.have.property('raw').above(-1);
|
||||
});
|
||||
it("text is not 'init'", function () {
|
||||
impedanceArray[7].P.should.have.property('text').not.be.equal(k.OBCIImpedanceTextInit);
|
||||
});
|
||||
});
|
||||
describe('#inputN', function () {
|
||||
it('got raw impedance value', function () {
|
||||
impedanceArray[7].N.should.have.property('raw').above(-1);
|
||||
});
|
||||
it("text is not 'init'", function () {
|
||||
impedanceArray[7].N.should.have.property('text').not.be.equal(k.OBCIImpedanceTextInit);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
describe('#impedanceTestChannel', function () {
|
||||
var impedanceObject = {};
|
||||
|
||||
before(function (done) {
|
||||
ourBoard.impedanceTestChannel(1)
|
||||
.then(impdObj => {
|
||||
impedanceObject = impdObj;
|
||||
done();
|
||||
})
|
||||
.catch(err => done(err));
|
||||
});
|
||||
describe('#channel1', function () {
|
||||
it('has valid channel number', function () {
|
||||
impedanceObject.channel.should.be.equal(1);
|
||||
});
|
||||
describe('#inputP', function () {
|
||||
it('got raw impedance value', function () {
|
||||
impedanceObject.P.should.have.property('raw').above(-1);
|
||||
});
|
||||
it("text is not 'init'", function () {
|
||||
impedanceObject.P.should.have.property('text').not.be.equal(k.OBCIImpedanceTextInit);
|
||||
});
|
||||
});
|
||||
describe('#inputN', function () {
|
||||
it('got raw impedance value', function () {
|
||||
impedanceObject.N.should.have.property('raw').above(-1);
|
||||
});
|
||||
it("text is not 'init'", function () {
|
||||
impedanceObject.N.should.have.property('text').not.be.equal(k.OBCIImpedanceTextInit);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
describe('#impedanceTestChannelInputP', function () {
|
||||
var impedanceObject = {};
|
||||
|
||||
before(function (done) {
|
||||
ourBoard.impedanceTestChannelInputP(1)
|
||||
.then(impdObj => {
|
||||
impedanceObject = impdObj;
|
||||
done();
|
||||
})
|
||||
.catch(err => done(err));
|
||||
});
|
||||
describe('#channel1', function () {
|
||||
it('has valid channel number', function () {
|
||||
impedanceObject.channel.should.be.equal(1);
|
||||
});
|
||||
describe('#inputP', function () {
|
||||
it('got raw impedance value', function () {
|
||||
impedanceObject.P.should.have.property('raw').above(-1);
|
||||
});
|
||||
it("text is not 'init'", function () {
|
||||
impedanceObject.P.should.have.property('text').not.be.equal(k.OBCIImpedanceTextInit);
|
||||
});
|
||||
});
|
||||
describe('#inputN', function () {
|
||||
it('got raw impedance value', function () {
|
||||
impedanceObject.N.should.have.property('raw').equal(-1);
|
||||
});
|
||||
it("text is not 'init'", function () {
|
||||
impedanceObject.N.should.have.property('text').equal(k.OBCIImpedanceTextInit);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
describe('#impedanceTestChannelInputN', function () {
|
||||
var impedanceObject = {};
|
||||
// wstream = fs.createWriteStream('hardwareVoltageOutputAll.txt')
|
||||
|
||||
before(function (done) {
|
||||
console.log('7');
|
||||
|
||||
ourBoard.on('sample', sample => {
|
||||
// console.log('8')
|
||||
// OpenBCISample.debugPrettyPrint(sample)
|
||||
// good to start impedance testing..
|
||||
});
|
||||
|
||||
ourBoard.impedanceTestChannelInputN(1)
|
||||
.then(impdObj => {
|
||||
impedanceObject = impdObj;
|
||||
setTimeout(() => {
|
||||
done();
|
||||
}, 1000);
|
||||
})
|
||||
.catch(err => done(err));
|
||||
});
|
||||
describe('#channel1', function () {
|
||||
it('has valid channel number', function () {
|
||||
impedanceObject.channel.should.be.equal(1);
|
||||
});
|
||||
describe('#inputP', function () {
|
||||
it('got raw impedance value', function () {
|
||||
impedanceObject.P.should.have.property('raw').equal(-1);
|
||||
});
|
||||
it("text is not 'init'", function () {
|
||||
impedanceObject.P.should.have.property('text').equal(k.OBCIImpedanceTextInit);
|
||||
});
|
||||
});
|
||||
describe('#inputN', function () {
|
||||
it('got raw impedance value', function () {
|
||||
impedanceObject.N.should.have.property('raw').above(-1);
|
||||
});
|
||||
it("text is not 'init'", function () {
|
||||
impedanceObject.N.should.have.property('text').not.be.equal(k.OBCIImpedanceTextInit);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
describe('#impedanceTestContinuousStXX', function () {
|
||||
before(function (done) {
|
||||
ourBoard.impedanceTestContinuousStart()
|
||||
.then(done).catch(err => done(err));
|
||||
});
|
||||
|
||||
after(function (done) {
|
||||
ourBoard.impedanceTestContinuousStop()
|
||||
.then(done);
|
||||
});
|
||||
|
||||
it('prints 10 impedance arrays', function (done) {
|
||||
var count = 1;
|
||||
|
||||
var listener = impedanceArray => {
|
||||
// console.log('\nImpedance Array: ' + count)
|
||||
// console.log(impedanceArray)
|
||||
count++;
|
||||
if (count > 10) {
|
||||
ourBoard.removeListener('impedanceArray', listener);
|
||||
done();
|
||||
}
|
||||
};
|
||||
ourBoard.on('impedanceArray', listener);
|
||||
});
|
||||
});
|
||||
describe('#_impedanceTestSetChannel', function () {
|
||||
it('reject with invalid channel', function (done) {
|
||||
ourBoard._impedanceTestSetChannel(0, false, false).should.be.rejected.and.notify(done);
|
||||
});
|
||||
});
|
||||
describe('#_impedanceTestCalculateChannel', function () {
|
||||
it('reject with low invalid channel', function (done) {
|
||||
ourBoard._impedanceTestCalculateChannel(0, false, false).should.be.rejected.and.notify(done);
|
||||
});
|
||||
it('reject with high invalid channel', function (done) {
|
||||
ourBoard._impedanceTestCalculateChannel(69, false, false).should.be.rejected.and.notify(done);
|
||||
});
|
||||
it('reject with invalid data type pInput', function (done) {
|
||||
ourBoard._impedanceTestCalculateChannel(1, 'taco', false).should.be.rejected.and.notify(done);
|
||||
});
|
||||
it('reject with invalid data type nInput', function (done) {
|
||||
ourBoard._impedanceTestCalculateChannel(1, false, 'taco').should.be.rejected.and.notify(done);
|
||||
});
|
||||
});
|
||||
describe('#_impedanceTestFinalizeChannel', function () {
|
||||
it('reject with low invalid channel', function (done) {
|
||||
ourBoard._impedanceTestFinalizeChannel(0, false, false).should.be.rejected.and.notify(done);
|
||||
});
|
||||
it('reject with high invalid channel', function (done) {
|
||||
ourBoard._impedanceTestFinalizeChannel(69, false, false).should.be.rejected.and.notify(done);
|
||||
});
|
||||
it('reject with invalid data type pInput', function (done) {
|
||||
ourBoard._impedanceTestFinalizeChannel(1, 'taco', false).should.be.rejected.and.notify(done);
|
||||
});
|
||||
it('reject with invalid data type nInput', function (done) {
|
||||
ourBoard._impedanceTestFinalizeChannel(1, false, 'taco').should.be.rejected.and.notify(done);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,949 @@
|
||||
'use strict';
|
||||
var bluebirdChecks = require('./bluebirdChecks');
|
||||
var sinon = require('sinon'); // eslint-disable-line no-unused-vars
|
||||
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');
|
||||
|
||||
chai.use(chaiAsPromised);
|
||||
chai.use(sinonChai);
|
||||
|
||||
describe('openbci-radios', function () {
|
||||
this.timeout(2000);
|
||||
var ourBoard, masterPortName;
|
||||
|
||||
before(function (done) {
|
||||
ourBoard = new openBCIBoard.OpenBCIBoard();
|
||||
ourBoard.autoFindOpenBCIBoard()
|
||||
.then(portName => {
|
||||
ourBoard = null;
|
||||
masterPortName = portName;
|
||||
done();
|
||||
})
|
||||
.catch(() => {
|
||||
ourBoard = null;
|
||||
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));
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,26 +0,0 @@
|
||||
//'use strict';
|
||||
//
|
||||
//var sinon = require('sinon');
|
||||
//var chai = require('chai');
|
||||
//var expect = chai.expect;
|
||||
//
|
||||
//var MockedOpenBCIBoard = require('../test_mocks/openbci-hardware');
|
||||
//var openBCIBoard = MockedOpenBCIBoard.openBCIBoard;
|
||||
//var hardware = MockedOpenBCIBoard.hardware;
|
||||
//
|
||||
//describe('openBCIBoard', function () {
|
||||
// var sandbox;
|
||||
//
|
||||
// beforeEach(function (){
|
||||
// sandbox = sinon.sandbox.create();
|
||||
//
|
||||
// // Create a board for fun and profit
|
||||
// hardware.reset();
|
||||
// hardware.createBoard();
|
||||
// });
|
||||
//
|
||||
// afterEach(function () {
|
||||
// sandbox.restore();
|
||||
// });
|
||||
//
|
||||
//});
|
||||
Diferenças do arquivo suprimidas por serem muito extensas
Carregar Diff
@@ -0,0 +1,894 @@
|
||||
'use strict';
|
||||
var bluebirdChecks = require('./bluebirdChecks');
|
||||
var bufferEqual = require('buffer-equal');
|
||||
var chai = require('chai');
|
||||
var chaiAsPromised = require(`chai-as-promised`);
|
||||
var expect = chai.expect;
|
||||
var should = chai.should(); // eslint-disable-line no-unused-vars
|
||||
var openBCISimulator = require('../openBCISimulator');
|
||||
var openBCISample = require('../openBCISample');
|
||||
var k = openBCISample.k;
|
||||
|
||||
chai.use(chaiAsPromised);
|
||||
|
||||
describe('openBCISimulator', function () {
|
||||
this.timeout(4000);
|
||||
var portName = k.OBCISimulatorPortName;
|
||||
afterEach(() => bluebirdChecks.noPendingPromises(200));
|
||||
describe('#constructor', function () {
|
||||
var simulator;
|
||||
afterEach(() => {
|
||||
simulator = null;
|
||||
});
|
||||
after(done => {
|
||||
setTimeout(() => {
|
||||
// Since there is a conditional timeout, it's important to wait to start the next test till this ends for sure
|
||||
done();
|
||||
}, 200); // The same amount of time in the simulator
|
||||
});
|
||||
it('constructs with the correct default options', function () {
|
||||
simulator = new openBCISimulator.OpenBCISimulator();
|
||||
expect(simulator.options.accel).to.be.true;
|
||||
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);
|
||||
expect(simulator.options.sampleRate).to.equal(k.OBCISampleRate250);
|
||||
expect(simulator.options.serialPortFailure).to.be.false;
|
||||
expect(simulator.options.verbose).to.be.false;
|
||||
expect(simulator.options.fragmentation).to.equal(k.OBCISimulatorFragmentationNone);
|
||||
expect(simulator.options.latencyTime).to.equal(16);
|
||||
expect(simulator.options.bufferSize).to.equal(4096);
|
||||
});
|
||||
it('should be able to get into daisy mode', function () {
|
||||
simulator = new openBCISimulator.OpenBCISimulator(portName, {
|
||||
daisy: true
|
||||
});
|
||||
expect(simulator.options.daisy).to.be.true;
|
||||
});
|
||||
it('should set the correct sample rate in daisy mode, if no sampleRate is provided', function () {
|
||||
simulator = new openBCISimulator.OpenBCISimulator(portName, {
|
||||
daisy: true
|
||||
});
|
||||
expect(simulator.options.sampleRate).to.equal(250); // produce samples at same rate
|
||||
});
|
||||
it('should use provided sample rate even if daisy is true', function () {
|
||||
simulator = new openBCISimulator.OpenBCISimulator(portName, {
|
||||
daisy: true,
|
||||
sampleRate: 20
|
||||
});
|
||||
expect(simulator.options.daisy).to.be.true;
|
||||
expect(simulator.options.sampleRate).to.equal(20);
|
||||
});
|
||||
it('should be able to put into firmware version 2', function () {
|
||||
simulator = new openBCISimulator.OpenBCISimulator(portName, {
|
||||
firmwareVersion: 'v2'
|
||||
});
|
||||
expect(simulator.options.firmwareVersion).to.equal(k.OBCIFirmwareV2);
|
||||
});
|
||||
it('should be able to simulate board failure', function () {
|
||||
simulator = new openBCISimulator.OpenBCISimulator(portName, {
|
||||
boardFailure: true
|
||||
});
|
||||
expect(simulator.options.boardFailure).to.be.true;
|
||||
});
|
||||
it('should be able to simulate serial port failure', function () {
|
||||
simulator = new openBCISimulator.OpenBCISimulator(portName, {
|
||||
serialPortFailure: true
|
||||
});
|
||||
expect(simulator.options.serialPortFailure).to.be.true;
|
||||
});
|
||||
it('can turn 50Hz line noise on', function () {
|
||||
simulator = new openBCISimulator.OpenBCISimulator(portName, {
|
||||
lineNoise: '50Hz'
|
||||
});
|
||||
(simulator.options.lineNoise).should.equal(k.OBCISimulatorLineNoiseHz50);
|
||||
});
|
||||
it('can turn no line noise on', function () {
|
||||
simulator = new openBCISimulator.OpenBCISimulator(portName, {
|
||||
lineNoise: 'none'
|
||||
});
|
||||
(simulator.options.lineNoise).should.equal(k.OBCISimulatorLineNoiseNone);
|
||||
});
|
||||
it('should not inject alpha if desired', function () {
|
||||
simulator = new openBCISimulator.OpenBCISimulator(portName, {
|
||||
alpha: false
|
||||
});
|
||||
expect(simulator.options.alpha).to.be.false;
|
||||
});
|
||||
it('should be able to not use the accel', function () {
|
||||
simulator = new openBCISimulator.OpenBCISimulator(portName, {
|
||||
accel: false
|
||||
});
|
||||
expect(simulator.options.accel).to.be.false;
|
||||
});
|
||||
it('should be able to set positive drift', function () {
|
||||
simulator = new openBCISimulator.OpenBCISimulator(portName, {
|
||||
drift: 1
|
||||
});
|
||||
expect(simulator.options.drift).to.be.greaterThan(0);
|
||||
});
|
||||
it('should be able to set negative drift', function () {
|
||||
simulator = new openBCISimulator.OpenBCISimulator(portName, {
|
||||
drift: -1
|
||||
});
|
||||
expect(simulator.options.drift).to.be.lessThan(0);
|
||||
});
|
||||
it('should throw if passed an invalid option', function (done) {
|
||||
try {
|
||||
simulator = new openBCISimulator.OpenBCISimulator(portName, {
|
||||
foo: 'bar'
|
||||
});
|
||||
done('did not throw');
|
||||
} catch (e) { done(); }
|
||||
});
|
||||
});
|
||||
describe('#write', function () {
|
||||
it('should refuse to write when not connected', function (done) {
|
||||
var simulator = new openBCISimulator.OpenBCISimulator(k.OBCISimulatorPortName);
|
||||
try {
|
||||
simulator.write('q');
|
||||
done('did not throw on disconnected write');
|
||||
} catch (e) {
|
||||
simulator.write('q', err => {
|
||||
if (err) {
|
||||
done();
|
||||
} else {
|
||||
done('did not provide error on disconnected write');
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
describe('#close', function () {
|
||||
it('should provide an error closing when already closed', function (done) {
|
||||
var simulator = new openBCISimulator.OpenBCISimulator(k.OBCISimulatorPortName);
|
||||
simulator.close(err => {
|
||||
if (err) {
|
||||
done();
|
||||
} else {
|
||||
done('closed successfully but had no time to open');
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
describe(`_startStream`, function () {
|
||||
it('should return a packet with sample data in it', function (done) {
|
||||
var simulator = new openBCISimulator.OpenBCISimulator(k.OBCISimulatorPortName);
|
||||
var sampleCounter = 0;
|
||||
var sampleTestSize = 5;
|
||||
|
||||
var newDataFunc = data => {
|
||||
if (sampleCounter > sampleTestSize) {
|
||||
simulator.write(k.OBCIStreamStop);
|
||||
simulator.removeListener('data', newDataFunc);
|
||||
let sample = openBCISample.parseRawPacketStandard(data, k.channelSettingsArrayInit(k.OBCINumberOfChannelsDefault), true);
|
||||
expect(sample.channelData).to.not.all.equal(0);
|
||||
done();
|
||||
simulator = null;
|
||||
} else {
|
||||
sampleCounter++;
|
||||
}
|
||||
};
|
||||
simulator.on('data', newDataFunc);
|
||||
simulator.once('open', () => simulator._startStream());
|
||||
});
|
||||
it('should return a sync set packet with accel', function (done) {
|
||||
var simulator = new openBCISimulator.OpenBCISimulator(k.OBCISimulatorPortName);
|
||||
var sampleCounter = 0;
|
||||
var sampleTestSize = 5;
|
||||
|
||||
var newDataFunc = data => {
|
||||
if (sampleCounter === 0) {
|
||||
// Ensure everything is switched on for this test
|
||||
simulator.options.accel = true;
|
||||
simulator.synced = true;
|
||||
simulator.sendSyncSetPacket = true;
|
||||
expect(data[k.OBCIPacketPositionStopByte]).to.equal(openBCISample.makeTailByteFromPacketType(k.OBCIStreamPacketStandardAccel));
|
||||
} else if (sampleCounter === 1) {
|
||||
// Now this data should be the time sync up packet
|
||||
expect(data[k.OBCIPacketPositionStopByte]).to.equal(openBCISample.makeTailByteFromPacketType(k.OBCIStreamPacketAccelTimeSyncSet));
|
||||
// Expect flag to be down
|
||||
expect(simulator.sendSyncSetPacket).to.be.false;
|
||||
} else if (sampleCounter >= sampleTestSize) {
|
||||
simulator.write(k.OBCIStreamStop);
|
||||
simulator.removeListener('data', newDataFunc);
|
||||
simulator = null;
|
||||
done();
|
||||
} else {
|
||||
// Now this data should be the time sync up packet
|
||||
expect(data[k.OBCIPacketPositionStopByte]).to.equal(openBCISample.makeTailByteFromPacketType(k.OBCIStreamPacketAccelTimeSynced));
|
||||
}
|
||||
sampleCounter++;
|
||||
};
|
||||
|
||||
simulator.on('data', newDataFunc);
|
||||
simulator.once('open', () => simulator.write(k.OBCIStreamStart));
|
||||
});
|
||||
it('should return a sync set packet with raw aux', function (done) {
|
||||
var simulator = new openBCISimulator.OpenBCISimulator(k.OBCISimulatorPortName, {
|
||||
accel: false
|
||||
});
|
||||
var sampleCounter = 0;
|
||||
var sampleTestSize = 5;
|
||||
|
||||
var newDataFunc = data => {
|
||||
if (sampleCounter === 0) {
|
||||
// Ensure everything is switched on for this test
|
||||
simulator.synced = true;
|
||||
simulator.sendSyncSetPacket = true;
|
||||
expect(data[k.OBCIPacketPositionStopByte]).to.equal(openBCISample.makeTailByteFromPacketType(k.OBCIStreamPacketStandardRawAux));
|
||||
} else if (sampleCounter === 1) {
|
||||
// Now this data should be the time sync up packet
|
||||
expect(data[k.OBCIPacketPositionStopByte]).to.equal(openBCISample.makeTailByteFromPacketType(k.OBCIStreamPacketRawAuxTimeSyncSet));
|
||||
// Expect flag to be down
|
||||
expect(simulator.sendSyncSetPacket).to.be.false;
|
||||
} else if (sampleCounter >= sampleTestSize) {
|
||||
simulator.write(k.OBCIStreamStop);
|
||||
simulator.removeListener('data', newDataFunc);
|
||||
simulator = null;
|
||||
done();
|
||||
} else {
|
||||
// Now this data should be the time sync up packet
|
||||
expect(data[k.OBCIPacketPositionStopByte]).to.equal(openBCISample.makeTailByteFromPacketType(k.OBCIStreamPacketRawAuxTimeSynced));
|
||||
}
|
||||
sampleCounter++;
|
||||
};
|
||||
|
||||
simulator.on('data', newDataFunc);
|
||||
simulator.once('open', () => simulator.write(k.OBCIStreamStart));
|
||||
});
|
||||
});
|
||||
describe(`firmwareVersion1`, function () {
|
||||
var simulator;
|
||||
beforeEach((done) => {
|
||||
simulator = new openBCISimulator.OpenBCISimulator(k.OBCISimulatorPortName, {
|
||||
firmwareVersion: 'v1'
|
||||
});
|
||||
simulator.once('open', done);
|
||||
});
|
||||
afterEach(() => {
|
||||
simulator = null;
|
||||
});
|
||||
describe('reset', function () {
|
||||
it('should not be v2', function (done) {
|
||||
simulator.on('data', function (data) {
|
||||
console.log(data.toString());
|
||||
expect(data.toString().match('v2')).to.equal(null);
|
||||
done();
|
||||
});
|
||||
simulator.write(k.OBCIMiscSoftReset);
|
||||
});
|
||||
});
|
||||
});
|
||||
describe(`firmwareVersion2`, function () {
|
||||
var simulator;
|
||||
beforeEach((done) => {
|
||||
simulator = new openBCISimulator.OpenBCISimulator(k.OBCISimulatorPortName, {
|
||||
firmwareVersion: 'v2'
|
||||
});
|
||||
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) {
|
||||
expect(data.toString().match('v2')).to.not.equal(null);
|
||||
done();
|
||||
});
|
||||
simulator.write(k.OBCIMiscSoftReset);
|
||||
});
|
||||
});
|
||||
describe('_processPrivateRadioMessage', function () {
|
||||
describe('OBCIRadioCmdChannelGet', function () {
|
||||
it('should emit success if firmware version 2', done => {
|
||||
simulator.channelNumber = 0;
|
||||
var buf = new Buffer(0);
|
||||
var dataEmit = data => {
|
||||
buf = Buffer.concat([buf, data]);
|
||||
if (openBCISample.doesBufferHaveEOT(buf)) {
|
||||
expect(openBCISample.isSuccessInBuffer(buf)).to.be.true;
|
||||
expect(openBCISample.isFailureInBuffer(buf)).to.be.false;
|
||||
expect(buf[buf.length - 4]).to.equal(0);
|
||||
simulator.removeListener('data', dataEmit);
|
||||
done();
|
||||
}
|
||||
};
|
||||
|
||||
simulator.on('data', dataEmit);
|
||||
|
||||
simulator._processPrivateRadioMessage(new Buffer([k.OBCIRadioKey, k.OBCIRadioCmdChannelGet]));
|
||||
});
|
||||
it('should emit failure if board failure and host channel number', done => {
|
||||
// Turn board failure mode
|
||||
simulator.options.boardFailure = true;
|
||||
simulator.channelNumber = 9;
|
||||
var buf = new Buffer(0);
|
||||
var dataEmit = data => {
|
||||
buf = Buffer.concat([buf, data]);
|
||||
if (openBCISample.doesBufferHaveEOT(buf)) {
|
||||
expect(openBCISample.isSuccessInBuffer(buf)).to.be.false;
|
||||
expect(openBCISample.isFailureInBuffer(buf)).to.be.true;
|
||||
expect(buf[buf.length - 4]).to.equal(9);
|
||||
simulator.removeListener('data', dataEmit);
|
||||
done();
|
||||
}
|
||||
};
|
||||
|
||||
simulator.on('data', dataEmit);
|
||||
|
||||
simulator._processPrivateRadioMessage(new Buffer([k.OBCIRadioKey, k.OBCIRadioCmdChannelGet]));
|
||||
});
|
||||
});
|
||||
describe('OBCIRadioCmdChannelSet', function () {
|
||||
it('should set the channel number if in bounds', done => {
|
||||
var newChanNum = 20;
|
||||
var buf = new Buffer(0);
|
||||
var dataEmit = data => {
|
||||
buf = Buffer.concat([buf, data]);
|
||||
if (openBCISample.doesBufferHaveEOT(buf)) {
|
||||
expect(openBCISample.isSuccessInBuffer(buf)).to.be.true;
|
||||
expect(openBCISample.isFailureInBuffer(buf)).to.be.false;
|
||||
expect(buf[buf.length - 4]).to.equal(newChanNum);
|
||||
expect(simulator.channelNumber).to.equal(newChanNum);
|
||||
expect(simulator.hostChannelNumber).to.equal(newChanNum);
|
||||
simulator.removeListener('data', dataEmit);
|
||||
done();
|
||||
}
|
||||
};
|
||||
|
||||
simulator.on('data', dataEmit);
|
||||
|
||||
simulator._processPrivateRadioMessage(new Buffer([k.OBCIRadioKey, k.OBCIRadioCmdChannelSet, newChanNum]));
|
||||
});
|
||||
it('should not set the channel number if out of bounds', done => {
|
||||
var newChanNum = 26;
|
||||
var buf = new Buffer(0);
|
||||
var dataEmit = data => {
|
||||
buf = Buffer.concat([buf, data]);
|
||||
if (openBCISample.doesBufferHaveEOT(buf)) {
|
||||
expect(openBCISample.isSuccessInBuffer(buf)).to.be.false;
|
||||
expect(openBCISample.isFailureInBuffer(buf)).to.be.true;
|
||||
simulator.removeListener('data', dataEmit);
|
||||
done();
|
||||
}
|
||||
};
|
||||
|
||||
simulator.on('data', dataEmit);
|
||||
|
||||
simulator._processPrivateRadioMessage(new Buffer([k.OBCIRadioKey, k.OBCIRadioCmdChannelSet, newChanNum]));
|
||||
});
|
||||
it('should emit failure if board failure', done => {
|
||||
// Turn board failure mode
|
||||
simulator.options.boardFailure = true;
|
||||
var buf = new Buffer(0);
|
||||
var dataEmit = data => {
|
||||
buf = Buffer.concat([buf, data]);
|
||||
if (openBCISample.doesBufferHaveEOT(buf)) {
|
||||
expect(openBCISample.isSuccessInBuffer(buf)).to.be.false;
|
||||
expect(openBCISample.isFailureInBuffer(buf)).to.be.true;
|
||||
simulator.removeListener('data', dataEmit);
|
||||
done();
|
||||
}
|
||||
};
|
||||
|
||||
simulator.on('data', dataEmit);
|
||||
simulator._processPrivateRadioMessage(new Buffer([k.OBCIRadioKey, k.OBCIRadioCmdChannelSet, 7]));
|
||||
});
|
||||
});
|
||||
describe('OBCIRadioCmdChannelSetOverride', function () {
|
||||
it('should change just the hosts channel number and not the systems channel number and force a board comms failure', done => {
|
||||
var systemChannelNumber = 0;
|
||||
var newHostChannelNumber = 1;
|
||||
simulator.channelNumber = systemChannelNumber;
|
||||
var buf = new Buffer(0);
|
||||
var dataEmit = data => {
|
||||
buf = Buffer.concat([buf, data]);
|
||||
if (openBCISample.doesBufferHaveEOT(buf)) {
|
||||
expect(openBCISample.isSuccessInBuffer(buf)).to.be.true;
|
||||
expect(openBCISample.isFailureInBuffer(buf)).to.be.false;
|
||||
expect(buf[buf.length - 4]).to.equal(newHostChannelNumber);
|
||||
expect(simulator.options.boardFailure).to.be.true;
|
||||
expect(simulator.channelNumber).to.equal(systemChannelNumber);
|
||||
expect(simulator.hostChannelNumber).to.equal(newHostChannelNumber);
|
||||
simulator.removeListener('data', dataEmit);
|
||||
done();
|
||||
}
|
||||
};
|
||||
|
||||
simulator.on('data', dataEmit);
|
||||
|
||||
simulator._processPrivateRadioMessage(new Buffer([k.OBCIRadioKey, k.OBCIRadioCmdChannelSetOverride, newHostChannelNumber]));
|
||||
});
|
||||
it('should change just the hosts channel number and not the systems channel number and fix a board failure', done => {
|
||||
var systemChannelNumber = 0;
|
||||
var oldHostChannelNumber = 1;
|
||||
simulator.channelNumber = systemChannelNumber;
|
||||
simulator.hostChannelNumber = oldHostChannelNumber;
|
||||
var buf = new Buffer(0);
|
||||
var dataEmit = data => {
|
||||
buf = Buffer.concat([buf, data]);
|
||||
if (openBCISample.doesBufferHaveEOT(buf)) {
|
||||
expect(openBCISample.isSuccessInBuffer(buf)).to.be.true;
|
||||
expect(openBCISample.isFailureInBuffer(buf)).to.be.false;
|
||||
expect(buf[buf.length - 4]).to.equal(systemChannelNumber);
|
||||
expect(simulator.options.boardFailure).to.be.false;
|
||||
expect(simulator.channelNumber).to.equal(systemChannelNumber);
|
||||
expect(simulator.hostChannelNumber).to.equal(systemChannelNumber);
|
||||
simulator.removeListener('data', dataEmit);
|
||||
done();
|
||||
}
|
||||
};
|
||||
|
||||
simulator.on('data', dataEmit);
|
||||
|
||||
simulator._processPrivateRadioMessage(new Buffer([k.OBCIRadioKey, k.OBCIRadioCmdChannelSetOverride, systemChannelNumber]));
|
||||
});
|
||||
it('should not set the channel number if out of bounds', done => {
|
||||
var newChanNum = 26;
|
||||
var buf = new Buffer(0);
|
||||
var dataEmit = data => {
|
||||
buf = Buffer.concat([buf, data]);
|
||||
if (openBCISample.doesBufferHaveEOT(buf)) {
|
||||
expect(openBCISample.isSuccessInBuffer(buf)).to.be.false;
|
||||
expect(openBCISample.isFailureInBuffer(buf)).to.be.true;
|
||||
simulator.removeListener('data', dataEmit);
|
||||
done();
|
||||
}
|
||||
};
|
||||
|
||||
simulator.on('data', dataEmit);
|
||||
|
||||
simulator._processPrivateRadioMessage(new Buffer([k.OBCIRadioKey, k.OBCIRadioCmdChannelSetOverride, newChanNum]));
|
||||
});
|
||||
});
|
||||
describe('OBCIRadioCmdPollTimeGet', function () {
|
||||
it('should emit success if firmware version 2 with poll time', done => {
|
||||
var expectedPollTime = 80;
|
||||
simulator.pollTime = expectedPollTime;
|
||||
var buf = new Buffer(0);
|
||||
var dataEmit = data => {
|
||||
buf = Buffer.concat([buf, data]);
|
||||
if (openBCISample.doesBufferHaveEOT(buf)) {
|
||||
expect(openBCISample.isSuccessInBuffer(buf)).to.be.true;
|
||||
expect(openBCISample.isFailureInBuffer(buf)).to.be.false;
|
||||
expect(buf[buf.length - 4]).to.equal(expectedPollTime);
|
||||
simulator.removeListener('data', dataEmit);
|
||||
done();
|
||||
}
|
||||
};
|
||||
|
||||
simulator.on('data', dataEmit);
|
||||
|
||||
simulator._processPrivateRadioMessage(new Buffer([k.OBCIRadioKey, k.OBCIRadioCmdPollTimeGet]));
|
||||
});
|
||||
it('should emit failure if board failure', done => {
|
||||
// Turn board failure mode
|
||||
simulator.options.boardFailure = true;
|
||||
var buf = new Buffer(0);
|
||||
var dataEmit = data => {
|
||||
buf = Buffer.concat([buf, data]);
|
||||
if (openBCISample.doesBufferHaveEOT(buf)) {
|
||||
expect(openBCISample.isSuccessInBuffer(buf)).to.be.false;
|
||||
expect(openBCISample.isFailureInBuffer(buf)).to.be.true;
|
||||
simulator.removeListener('data', dataEmit);
|
||||
done();
|
||||
}
|
||||
};
|
||||
|
||||
simulator.on('data', dataEmit);
|
||||
|
||||
simulator._processPrivateRadioMessage(new Buffer([k.OBCIRadioKey, k.OBCIRadioCmdPollTimeGet]));
|
||||
});
|
||||
});
|
||||
describe('OBCIRadioCmdPollTimeSet', function () {
|
||||
it('should set the poll time if in bounds', done => {
|
||||
var newPollTime = 20;
|
||||
var buf = new Buffer(0);
|
||||
var dataEmit = data => {
|
||||
buf = Buffer.concat([buf, data]);
|
||||
if (openBCISample.doesBufferHaveEOT(buf)) {
|
||||
expect(openBCISample.isSuccessInBuffer(buf)).to.be.true;
|
||||
expect(openBCISample.isFailureInBuffer(buf)).to.be.false;
|
||||
expect(buf[buf.length - 4]).to.equal(newPollTime);
|
||||
simulator.removeListener('data', dataEmit);
|
||||
done();
|
||||
}
|
||||
};
|
||||
|
||||
simulator.on('data', dataEmit);
|
||||
|
||||
simulator._processPrivateRadioMessage(new Buffer([k.OBCIRadioKey, k.OBCIRadioCmdPollTimeSet, newPollTime]));
|
||||
});
|
||||
it('should emit failure if board failure', done => {
|
||||
// Turn board failure mode
|
||||
simulator.options.boardFailure = true;
|
||||
var buf = new Buffer(0);
|
||||
var dataEmit = data => {
|
||||
buf = Buffer.concat([buf, data]);
|
||||
if (openBCISample.doesBufferHaveEOT(buf)) {
|
||||
expect(openBCISample.isSuccessInBuffer(buf)).to.be.false;
|
||||
expect(openBCISample.isFailureInBuffer(buf)).to.be.true;
|
||||
simulator.removeListener('data', dataEmit);
|
||||
done();
|
||||
}
|
||||
};
|
||||
|
||||
simulator.on('data', dataEmit);
|
||||
simulator._processPrivateRadioMessage(new Buffer([k.OBCIRadioKey, k.OBCIRadioCmdPollTimeSet, 7]));
|
||||
});
|
||||
});
|
||||
describe('OBCIRadioCmdBaudRateSetDefault', function () {
|
||||
it('should emit success if firmware version 2 with proper baud rate', done => {
|
||||
var buf = new Buffer(0);
|
||||
var dataEmit = data => {
|
||||
buf = Buffer.concat([buf, data]);
|
||||
if (openBCISample.doesBufferHaveEOT(buf)) {
|
||||
expect(openBCISample.isSuccessInBuffer(buf)).to.be.true;
|
||||
expect(openBCISample.isFailureInBuffer(buf)).to.be.false;
|
||||
var eotBuf = new Buffer('$$$');
|
||||
var newBaudRateBuf;
|
||||
for (var i = buf.length; i > 3; i--) {
|
||||
if (bufferEqual(buf.slice(i - 3, i), eotBuf)) {
|
||||
newBaudRateBuf = buf.slice(i - 9, i - 3);
|
||||
break;
|
||||
}
|
||||
}
|
||||
var newBaudRateNum = Number(newBaudRateBuf.toString());
|
||||
expect(newBaudRateNum).to.equal(k.OBCIRadioBaudRateDefault);
|
||||
simulator.removeListener('data', dataEmit);
|
||||
done();
|
||||
}
|
||||
};
|
||||
|
||||
simulator.on('data', dataEmit);
|
||||
|
||||
simulator._processPrivateRadioMessage(new Buffer([k.OBCIRadioKey, k.OBCIRadioCmdBaudRateSetDefault]));
|
||||
});
|
||||
it('should emit success if board failure', done => {
|
||||
// Turn board failure mode
|
||||
simulator.options.boardFailure = true;
|
||||
var buf = new Buffer(0);
|
||||
var dataEmit = data => {
|
||||
buf = Buffer.concat([buf, data]);
|
||||
if (openBCISample.doesBufferHaveEOT(buf)) {
|
||||
expect(openBCISample.isSuccessInBuffer(buf)).to.be.true;
|
||||
expect(openBCISample.isFailureInBuffer(buf)).to.be.false;
|
||||
simulator.removeListener('data', dataEmit);
|
||||
done();
|
||||
}
|
||||
};
|
||||
|
||||
simulator.on('data', dataEmit);
|
||||
|
||||
simulator._processPrivateRadioMessage(new Buffer([k.OBCIRadioKey, k.OBCIRadioCmdBaudRateSetDefault]));
|
||||
});
|
||||
});
|
||||
describe('OBCIRadioCmdBaudRateSetFast', function () {
|
||||
it('should emit success if firmware version 2 with proper baud rate', done => {
|
||||
var buf = new Buffer(0);
|
||||
var dataEmit = data => {
|
||||
buf = Buffer.concat([buf, data]);
|
||||
if (openBCISample.doesBufferHaveEOT(buf)) {
|
||||
expect(openBCISample.isSuccessInBuffer(buf)).to.be.true;
|
||||
expect(openBCISample.isFailureInBuffer(buf)).to.be.false;
|
||||
var eotBuf = new Buffer(`$$$`);
|
||||
var newBaudRateBuf;
|
||||
for (var i = buf.length; i > 3; i--) {
|
||||
if (bufferEqual(buf.slice(i - 3, i), eotBuf)) {
|
||||
newBaudRateBuf = buf.slice(i - 9, i - 3);
|
||||
break;
|
||||
}
|
||||
}
|
||||
var newBaudRateNum = Number(newBaudRateBuf.toString());
|
||||
expect(newBaudRateNum).to.equal(k.OBCIRadioBaudRateFast);
|
||||
simulator.removeListener('data', dataEmit);
|
||||
done();
|
||||
}
|
||||
};
|
||||
|
||||
simulator.on('data', dataEmit);
|
||||
|
||||
simulator._processPrivateRadioMessage(new Buffer([k.OBCIRadioKey, k.OBCIRadioCmdBaudRateSetFast]));
|
||||
});
|
||||
it('should emit success if board failure', done => {
|
||||
// Turn board failure mode
|
||||
simulator.options.boardFailure = true;
|
||||
var buf = new Buffer(0);
|
||||
var dataEmit = data => {
|
||||
buf = Buffer.concat([buf, data]);
|
||||
if (openBCISample.doesBufferHaveEOT(buf)) {
|
||||
expect(openBCISample.isSuccessInBuffer(buf)).to.be.true;
|
||||
expect(openBCISample.isFailureInBuffer(buf)).to.be.false;
|
||||
simulator.removeListener('data', dataEmit);
|
||||
done();
|
||||
}
|
||||
};
|
||||
|
||||
simulator.on('data', dataEmit);
|
||||
|
||||
simulator._processPrivateRadioMessage(new Buffer([k.OBCIRadioKey, k.OBCIRadioCmdBaudRateSetFast]));
|
||||
});
|
||||
});
|
||||
describe('OBCIRadioCmdSystemStatus', function () {
|
||||
it('should emit success if firmware version 2', done => {
|
||||
var buf = new Buffer(0);
|
||||
var dataEmit = data => {
|
||||
buf = Buffer.concat([buf, data]);
|
||||
if (openBCISample.doesBufferHaveEOT(buf)) {
|
||||
expect(openBCISample.isSuccessInBuffer(buf)).to.be.true;
|
||||
expect(openBCISample.isFailureInBuffer(buf)).to.be.false;
|
||||
simulator.removeListener('data', dataEmit);
|
||||
done();
|
||||
}
|
||||
};
|
||||
|
||||
simulator.on('data', dataEmit);
|
||||
|
||||
simulator._processPrivateRadioMessage(new Buffer([k.OBCIRadioKey, k.OBCIRadioCmdSystemStatus]));
|
||||
});
|
||||
it('should emit failure if board failure', done => {
|
||||
// Turn board failure mode
|
||||
simulator.options.boardFailure = true;
|
||||
var buf = new Buffer(0);
|
||||
var dataEmit = data => {
|
||||
buf = Buffer.concat([buf, data]);
|
||||
if (openBCISample.doesBufferHaveEOT(buf)) {
|
||||
expect(openBCISample.isSuccessInBuffer(buf)).to.be.false;
|
||||
expect(openBCISample.isFailureInBuffer(buf)).to.be.true;
|
||||
simulator.removeListener('data', dataEmit);
|
||||
done();
|
||||
}
|
||||
};
|
||||
|
||||
simulator.on('data', dataEmit);
|
||||
|
||||
simulator._processPrivateRadioMessage(new Buffer([k.OBCIRadioKey, k.OBCIRadioCmdSystemStatus]));
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
describe('fragmentation', function () {
|
||||
var simulator;
|
||||
afterEach(done => {
|
||||
simulator.removeAllListeners();
|
||||
simulator.write(k.OBCIStreamStop);
|
||||
simulator.close(done);
|
||||
});
|
||||
it('Should accumulate packets if set to FullBuffers', function (done) {
|
||||
var bufferSize = 64;
|
||||
simulator = new openBCISimulator.OpenBCISimulator(portName, {
|
||||
fragmentation: k.OBCISimulatorFragmentationFullBuffers,
|
||||
bufferSize: bufferSize,
|
||||
latencyTime: 1000
|
||||
});
|
||||
simulator.once('data', function (buffer) {
|
||||
expect(buffer.length).to.equal(bufferSize);
|
||||
done();
|
||||
});
|
||||
simulator.once('open', () => simulator.write(k.OBCIStreamStart));
|
||||
});
|
||||
it('Should emit partial packets after latencyTime', function (done) {
|
||||
var bufferSize = 4096;
|
||||
simulator = new openBCISimulator.OpenBCISimulator(portName, {
|
||||
fragmentation: k.OBCISimulatorFragmentationFullBuffers,
|
||||
bufferSize: 4096,
|
||||
latencyTime: 0
|
||||
});
|
||||
simulator.once('data', function (buffer) {
|
||||
expect(buffer.length).to.be.lessThan(bufferSize);
|
||||
done();
|
||||
});
|
||||
simulator.once('open', () => simulator.write(k.OBCIStreamStart));
|
||||
});
|
||||
it('Should emit single bytes if set to OneByOne', function (done) {
|
||||
simulator = new openBCISimulator.OpenBCISimulator(portName, {
|
||||
fragmentation: k.OBCISimulatorFragmentationOneByOne
|
||||
});
|
||||
var counter = 0;
|
||||
simulator.on('data', function (buffer) {
|
||||
expect(buffer.length).to.equal(1);
|
||||
++counter;
|
||||
|
||||
if (counter === 5) done();
|
||||
});
|
||||
simulator.once('open', () => simulator.write(k.OBCIStreamStart));
|
||||
});
|
||||
it('should properly split packets, retaining valid packets', function (done) {
|
||||
simulator = new openBCISimulator.OpenBCISimulator(portName, {
|
||||
fragmentation: k.OBCISimulatorFragmentationRandom
|
||||
});
|
||||
var buffer = new Buffer(0);
|
||||
var counter = 0;
|
||||
simulator.on('data', function (data) {
|
||||
buffer = Buffer.concat([buffer, data], buffer.length + data.length);
|
||||
if (buffer.length >= 33) {
|
||||
openBCISample.parseRawPacketStandard(buffer.slice(0, 33));
|
||||
buffer = buffer.slice(33);
|
||||
++counter;
|
||||
if (counter === 5) done();
|
||||
}
|
||||
});
|
||||
simulator.once('open', () => simulator.write(k.OBCIStreamStart));
|
||||
});
|
||||
});
|
||||
describe(`boardFailure`, function () {});
|
||||
|
||||
describe(`#sync`, function () {
|
||||
this.timeout(2000);
|
||||
var simulator;
|
||||
beforeEach(function (done) {
|
||||
simulator = new openBCISimulator.OpenBCISimulator(portName, {
|
||||
firmwareVersion: 'v2'
|
||||
});
|
||||
simulator.once('open', () => {
|
||||
done();
|
||||
});
|
||||
});
|
||||
afterEach(function () {
|
||||
simulator = null;
|
||||
});
|
||||
it(`should emit the time sync sent command`, function (done) {
|
||||
simulator.once('data', data => {
|
||||
expect(openBCISample.isTimeSyncSetConfirmationInBuffer(data)).to.be.true;
|
||||
done();
|
||||
});
|
||||
simulator.write(k.OBCISyncTimeSet, (err, msg) => {
|
||||
if (err) {
|
||||
done(err);
|
||||
}
|
||||
});
|
||||
});
|
||||
it(`should set synced to true`, function (done) {
|
||||
simulator.synced = false;
|
||||
var newData = data => {
|
||||
expect(simulator.synced).to.be.true;
|
||||
simulator.removeListener('data', newData);
|
||||
done();
|
||||
};
|
||||
|
||||
simulator.on('data', data => {
|
||||
newData(data);
|
||||
});
|
||||
|
||||
simulator.write(k.OBCISyncTimeSet, (err, msg) => {
|
||||
if (err) {
|
||||
done(err);
|
||||
}
|
||||
});
|
||||
});
|
||||
it(`should emit a time sync set packet followed by a time synced accel packet after sync up call`, function (done) {
|
||||
simulator.synced = false;
|
||||
var emitCounter = 0;
|
||||
var maxPacketsBetweenSetPacket = 5;
|
||||
var newData = data => {
|
||||
if (emitCounter === 0) { // the time sync packet is emitted here
|
||||
// Make a call to start streaming
|
||||
simulator.write(k.OBCIStreamStart, err => {
|
||||
if (err) done(err);
|
||||
});
|
||||
} else if (emitCounter < maxPacketsBetweenSetPacket) {
|
||||
if (openBCISample.getRawPacketType(data[k.OBCIPacketPositionStopByte]) === k.OBCIStreamPacketAccelTimeSyncSet) {
|
||||
simulator.removeListener('data', newData);
|
||||
simulator.write(k.OBCIStreamStop, err => {
|
||||
if (err) done(err);
|
||||
done();
|
||||
});
|
||||
} else {
|
||||
expect(openBCISample.getRawPacketType(data[k.OBCIPacketPositionStopByte])).to.equal(k.OBCIStreamPacketAccelTimeSynced);
|
||||
}
|
||||
} else {
|
||||
done(`Failed to get set packet in time`);
|
||||
}
|
||||
emitCounter++;
|
||||
};
|
||||
|
||||
simulator.on('data', newData);
|
||||
|
||||
simulator.write(k.OBCISyncTimeSet, (err, msg) => {
|
||||
if (err) {
|
||||
done(err);
|
||||
}
|
||||
});
|
||||
});
|
||||
it(`should emit a time sync set raw aux, then time synced raw aux packet after sync up call`, function (done) {
|
||||
simulator.synced = false;
|
||||
simulator.options.accel = false;
|
||||
var emitCounter = 0;
|
||||
var maxPacketsBetweenSetPacket = 5;
|
||||
var newData = data => {
|
||||
if (emitCounter === 0) { // the time sync packet is emitted here
|
||||
// Make a call to start streaming
|
||||
simulator.write(k.OBCIStreamStart, err => {
|
||||
if (err) done(err);
|
||||
});
|
||||
} else if (emitCounter < maxPacketsBetweenSetPacket) {
|
||||
if (openBCISample.getRawPacketType(data[k.OBCIPacketPositionStopByte]) === k.OBCIStreamPacketRawAuxTimeSyncSet) {
|
||||
simulator.removeListener('data', newData);
|
||||
simulator.write(k.OBCIStreamStop, err => {
|
||||
if (err) done(err);
|
||||
done();
|
||||
});
|
||||
} else {
|
||||
expect(openBCISample.getRawPacketType(data[k.OBCIPacketPositionStopByte])).to.equal(k.OBCIStreamPacketRawAuxTimeSynced);
|
||||
}
|
||||
} else {
|
||||
done(`Failed to get set packet in time`);
|
||||
}
|
||||
|
||||
emitCounter++;
|
||||
};
|
||||
|
||||
simulator.on('data', newData);
|
||||
|
||||
simulator.write(k.OBCISyncTimeSet, (err, msg) => {
|
||||
if (err) {
|
||||
done(err);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,331 +0,0 @@
|
||||
var sinon = require('sinon');
|
||||
var chai = require('chai'),
|
||||
should = chai.should(),
|
||||
expect = chai.expect,
|
||||
openBCIBoard = require('../openBCIBoard'),
|
||||
OpenBCISample = openBCIBoard.OpenBCISample;
|
||||
|
||||
var fs = require('fs');
|
||||
var wstream = fs.createWriteStream('myOutput.txt');
|
||||
|
||||
|
||||
describe('openbci-sdk',function() {
|
||||
describe('#testsWithBoard', function() {
|
||||
this.timeout(10000);
|
||||
describe('#connect', function() {
|
||||
var running = false;
|
||||
beforeEach(function(done) {
|
||||
var ourBoard = new openBCIBoard.OpenBCIBoard({
|
||||
verbose: true
|
||||
});
|
||||
|
||||
ourBoard.autoFindOpenBCIBoard().then((value) => {
|
||||
if(Array.isArray(value)) {
|
||||
/**Unable to auto find OpenBCI board*/
|
||||
console.log('NO BOARD CONNECTED!, AUTO PASSING TEST!');
|
||||
running = true;
|
||||
done();
|
||||
} else {
|
||||
return ourBoard.connect(value).then(function() {
|
||||
console.log('board connected on path: ' + value);
|
||||
ourBoard.on('ready',function() {
|
||||
console.log('Ready to start streaming!');
|
||||
ourBoard.streamStart();
|
||||
ourBoard.on('sample',function(sample) {
|
||||
//wstream.write('Master Count: ' + sample._count + ' Sample Count: ' + sample.sampleNumber + '\n');
|
||||
//console.log('Master Count: ' + sample._count + ' Sample Count: ' + sample.sampleNumber);
|
||||
OpenBCISample.debugPrettyPrint(sample);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
}).catch(function(err) {
|
||||
console.log('Error [setup]: ' + err);
|
||||
done();
|
||||
});
|
||||
setTimeout(function() {
|
||||
ourBoard.disconnect().then(function(msg) {
|
||||
running = true;
|
||||
setTimeout(function(){
|
||||
done();
|
||||
},50);
|
||||
}, function(err) {
|
||||
console.log('Error: ' + err);
|
||||
done();
|
||||
});
|
||||
},9000);
|
||||
});
|
||||
it('should stop the simulator after 5 seconds', function() {
|
||||
expect(running).equals(true);
|
||||
});
|
||||
});
|
||||
xdescribe('#imdenceCheck', function() {
|
||||
var running = false;
|
||||
beforeEach(function(done) {
|
||||
var ourBoard = new openBCIBoard.OpenBCIBoard({
|
||||
verbose: true
|
||||
});
|
||||
|
||||
ourBoard.autoFindOpenBCIBoard().then((value) => {
|
||||
if(Array.isArray(value)) {
|
||||
/**Unable to auto find OpenBCI board*/
|
||||
console.log('NO BOARD CONNECTED!, AUTO PASSING TEST!');
|
||||
running = true;
|
||||
done();
|
||||
} else {
|
||||
return ourBoard.connect(value).then(function() {
|
||||
console.log('board connected on path: ' + value);
|
||||
ourBoard.on('ready',function() {
|
||||
console.log('Ready to start streaming!');
|
||||
//ourBoard.channelOff(1);
|
||||
//ourBoard.channelOff(2);
|
||||
//ourBoard.channelOff(3);
|
||||
//ourBoard.channelOff(4);
|
||||
//ourBoard.channelOff(5);
|
||||
//ourBoard.channelOff(6);
|
||||
//ourBoard.channelOff(7);
|
||||
ourBoard.streamStart();
|
||||
//ourBoard.on('sample',function(sample) {
|
||||
// //wstream.write('Master Count: ' + sample._count + ' Sample Count: ' + sample.sampleNumber + '\n');
|
||||
// //console.log('Master Count: ' + sample._count + ' Sample Count: ' + sample.sampleNumber);
|
||||
// OpenBCISample.debugPrettyPrint(sample);
|
||||
//});
|
||||
setTimeout(() => {
|
||||
ourBoard.impedanceTestStartAll().then(() => {
|
||||
console.log('good start');
|
||||
},(err) => {
|
||||
console.log(err);
|
||||
});
|
||||
},50);
|
||||
ourBoard.on('sample',function(sample) {
|
||||
//wstream.write(' Sample Count: ' + sample.sampleNumber + ' impedance: ' + JSON.stringify(sample.impedanceArray) + '\n');
|
||||
//console.log('Sample!');
|
||||
if(sample.impedanceArray) {
|
||||
wstream.write('Impedance\'s for channels: 1: ' + sample.impedanceArray[1] + ' 2: ' + sample.impedanceArray[2] + ' 3: ' + sample.impedanceArray[3] + ' 4: ' + sample.impedanceArray[4] + ' 5: ' + sample.impedanceArray[5] + ' 6: ' + sample.impedanceArray[6] + ' 7: ' + sample.impedanceArray[7] + ' 8: ' + sample.impedanceArray[8] + '\n');
|
||||
console.log('Impedance: ' + sample.impedanceArray.toString());
|
||||
//console.log('Impedance\'s for channels: 1: ' + sample.impedanceArray[1] + ' 2: ' + sample.impedanceArray[2] + ' 3: ' + sample.impedanceArray[3] + ' 4: ' + sample.impedanceArray[4] + ' 5: ' + sample.impedanceArray[5] + ' 6: ' + sample.impedanceArray[6] + ' 7: ' + sample.impedanceArray[7] + ' 8: ' + sample.impedanceArray[8]);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
}).catch(function(err) {
|
||||
console.log('Error [setup]: ' + err);
|
||||
done();
|
||||
});
|
||||
setTimeout(() => {
|
||||
if(ourBoard.isCalculatingImpedance) {
|
||||
ourBoard.impedanceTestStopAll()
|
||||
.then(function() {
|
||||
console.log('Impedance test stopped!');
|
||||
});
|
||||
} else {
|
||||
done();
|
||||
}
|
||||
},6000);
|
||||
setTimeout(function() {
|
||||
ourBoard.disconnect().then(function(msg) {
|
||||
running = true;
|
||||
setTimeout(function(){
|
||||
done();
|
||||
},50);
|
||||
}, function(err) {
|
||||
console.log('Error: ' + err);
|
||||
done();
|
||||
});
|
||||
},9000);
|
||||
});
|
||||
it('should stop the simulator after 5 seconds', function() {
|
||||
expect(running).equals(true);
|
||||
});
|
||||
});
|
||||
xdescribe('#confirm channel 1 off with query register settings', function() {
|
||||
var channelIsOn = false;
|
||||
var didTryToSendPrintCommand = false;
|
||||
var didTryToTurnChannel1Off = false;
|
||||
beforeEach(function(done) {
|
||||
var ourBoard = new openBCIBoard.OpenBCIBoard();
|
||||
|
||||
ourBoard.autoFindOpenBCIBoard(function (portName, ports) {
|
||||
if (portName) {
|
||||
ourBoard.connect(portName).then(function (boardSerial) {
|
||||
//console.log('board connected');
|
||||
ourBoard.on('ready', function () {
|
||||
//console.log('Ready to print register settings!');
|
||||
if (!didTryToSendPrintCommand) {
|
||||
didTryToSendPrintCommand = true;
|
||||
ourBoard.getSettingsForChannel(1); //sets isChannelOn to true
|
||||
} else if (!didTryToTurnChannel1Off) {
|
||||
didTryToTurnChannel1Off = true;
|
||||
//console.log('Tried to turn channel 1 off');
|
||||
ourBoard.channelOff(1);
|
||||
setTimeout(function() {
|
||||
//console.log('Re print register settings');
|
||||
ourBoard.getSettingsForChannel(1);
|
||||
},100);
|
||||
}
|
||||
ourBoard.on('query',function(channelSettingsObject) {
|
||||
//ourBoard.debugPrintChannelSettings(channelSettingsObject);
|
||||
channelIsOn = ourBoard.channelIsOnFromChannelSettingsObject(channelSettingsObject);
|
||||
});
|
||||
});
|
||||
}).catch(function (err) {
|
||||
console.log('Error [setup]: ' + err);
|
||||
done();
|
||||
});
|
||||
|
||||
} else {
|
||||
/** Display list of ports*/
|
||||
console.log('Port not found... check ports for other ports');
|
||||
done();
|
||||
}
|
||||
});
|
||||
setTimeout(function () {
|
||||
ourBoard.streamStop().then(ourBoard.disconnect).then(function (msg) {
|
||||
done();
|
||||
}, function (err) {
|
||||
console.log('Error: ' + err);
|
||||
done();
|
||||
});
|
||||
}, 6000);
|
||||
});
|
||||
it('should turn channel off', function() {
|
||||
expect(channelIsOn).equals(false);
|
||||
});
|
||||
});
|
||||
xdescribe('#confirm channel 2 off with query register settings', function() {
|
||||
var channelIsOn = true;
|
||||
var didTryToSendPrintCommand = false;
|
||||
var didTryToTurnChannel1Off = false;
|
||||
beforeEach(function(done) {
|
||||
var ourBoard = new openBCIBoard.OpenBCIBoard();
|
||||
|
||||
ourBoard.autoFindOpenBCIBoard(function (portName, ports) {
|
||||
if (portName) {
|
||||
ourBoard.connect(portName).then(function (boardSerial) {
|
||||
//console.log('board connected');
|
||||
ourBoard.on('ready', function () {
|
||||
//console.log('Ready to print register settings!');
|
||||
if (!didTryToSendPrintCommand) {
|
||||
didTryToSendPrintCommand = true;
|
||||
ourBoard.getSettingsForChannel(2); //set isChannelOn to true
|
||||
} else if (!didTryToTurnChannel1Off) {
|
||||
didTryToTurnChannel1Off = true;
|
||||
//console.log('Tried to turn channel 1 off');
|
||||
ourBoard.channelOff(2);
|
||||
setTimeout(function() {
|
||||
//console.log('Re print register settings');
|
||||
ourBoard.getSettingsForChannel(2);
|
||||
},100);
|
||||
}
|
||||
ourBoard.on('query',function(channelSettingsObject) {
|
||||
//ourBoard.debugPrintChannelSettings(channelSettingsObject);
|
||||
channelIsOn = ourBoard.channelIsOnFromChannelSettingsObject(channelSettingsObject);
|
||||
});
|
||||
});
|
||||
}).catch(function (err) {
|
||||
console.log('Error [setup]: ' + err);
|
||||
done();
|
||||
});
|
||||
|
||||
} else {
|
||||
/** Display list of ports*/
|
||||
console.log('Port not found... check ports for other ports');
|
||||
done();
|
||||
}
|
||||
});
|
||||
setTimeout(function () {
|
||||
ourBoard.streamStop().then(ourBoard.disconnect).then(function (msg) {
|
||||
done();
|
||||
}, function (err) {
|
||||
console.log('Error: ' + err);
|
||||
done();
|
||||
});
|
||||
}, 6000);
|
||||
});
|
||||
it('should turn channel off', function() {
|
||||
expect(channelIsOn).equals(false);
|
||||
});
|
||||
});
|
||||
});
|
||||
xdescribe('#simulator', function() {
|
||||
var running = false;
|
||||
beforeEach(function(done) {
|
||||
var ourBoard = new openBCIBoard.OpenBCIBoard();
|
||||
|
||||
ourBoard.simulatorStart().then(function() {
|
||||
console.log('Simulator started');
|
||||
ourBoard.on('sample',function(sample) {
|
||||
//OpenBCISample.debugPrettyPrint(sample);
|
||||
});
|
||||
}).catch(function(err) {
|
||||
console.log('Error [simulator]: ' + err);
|
||||
});
|
||||
setTimeout(function() {
|
||||
ourBoard.simulatorStop().then(function() {
|
||||
running = true;
|
||||
done();
|
||||
},function(err) {
|
||||
console.log('Error: ' + err);
|
||||
done();
|
||||
});
|
||||
},1000);
|
||||
});
|
||||
it('should stop the simulator after 1 second', function() {
|
||||
expect(running).equals(true);
|
||||
});
|
||||
});
|
||||
//describe('write with different calls', function() {
|
||||
// this.timeout(10000);
|
||||
// //var running = false;
|
||||
// var ourBoard = new openBCIBoard.OpenBCIBoard();
|
||||
// var k = openBCIBoard.OpenBCIConstants;
|
||||
// //console.log(ourBoard.writeAndDrain.toString());
|
||||
// ourBoard.serial = 'taco';
|
||||
// //var sandbox = sinon.sandbox.create();//(ourBoard.writeAndDrain);
|
||||
// var mock = sinon.mock(ourBoard.writeAndDrain());
|
||||
// //console.log(JSON.stringify(mock));
|
||||
//
|
||||
// //ourBoard.write('1');
|
||||
// //ourBoard.write('2');
|
||||
// beforeEach(function(done) {
|
||||
// setTimeout(function() {
|
||||
// done();
|
||||
// },k.OBCIWriteIntervalDelayMS * 3);
|
||||
// });
|
||||
// afterEach(function() {
|
||||
// mock.restore();
|
||||
// });
|
||||
// it('should send command to writeAndDrain three times', function() {
|
||||
// //console.log(JSON.stringify(ourBoard));
|
||||
// expect(mock.calledThrice);
|
||||
// //expect(running).equals(true);
|
||||
// });
|
||||
//});
|
||||
//describe('write with array', function() {
|
||||
// this.timeout(10000);
|
||||
// var running = false;
|
||||
// var ourBoard = new openBCIBoard.OpenBCIBoard();
|
||||
//
|
||||
// ourBoard.serial = 'taco';
|
||||
//
|
||||
// ourBoard.write(['1','2','3']);
|
||||
// ourBoard.write('4');
|
||||
// ourBoard.write('5');
|
||||
// ourBoard.write('6');
|
||||
// ourBoard.write('7');
|
||||
// ourBoard.write('8');
|
||||
// ourBoard.write(['9','10','11']);
|
||||
//
|
||||
// beforeEach(function(done) {
|
||||
// setTimeout(function() {
|
||||
// running = true;
|
||||
// done();
|
||||
// },8000);
|
||||
// });
|
||||
// it('should send command to writeAndDrain three times', function() {
|
||||
// expect(running).equals(true);
|
||||
// });
|
||||
//});
|
||||
|
||||
});
|
||||
@@ -0,0 +1,108 @@
|
||||
// Converts timing events to use promises, to gain bluebird's checks
|
||||
|
||||
function instrumentTimingEvents (module, type) {
|
||||
// replaces module[type] with a function that does the same thing but uses a promise
|
||||
// assumes the first argument will be to a callback function
|
||||
|
||||
// if this a setSomething function with a clearSomething partner, the partner will also be instrumented
|
||||
var setName = type;
|
||||
var clearName = null;
|
||||
if (type.substring(0, 3) === 'set') {
|
||||
clearName = 'clear' + type.substring(3);
|
||||
}
|
||||
|
||||
if (!module[setName]) return;
|
||||
|
||||
// store original functions
|
||||
var originalSet = module[setName];
|
||||
var originalClear = module[clearName];
|
||||
exports[setName + 'Ignored'] = originalSet;
|
||||
|
||||
// dictionary to store promise details for each call
|
||||
var events = {};
|
||||
|
||||
// setAsPromise() is the brunt of the function. It replaces the previous global function,
|
||||
// and sets up a promise to resolve when the callback is called
|
||||
var eventCount = 0;
|
||||
var setAsPromise = function (callback) {
|
||||
var args = [].slice.call(arguments);
|
||||
|
||||
var eventNum = ++eventCount;
|
||||
var eventHandle;
|
||||
|
||||
if (setAsPromise._ignoreCount > 0) {
|
||||
--setAsPromise._ignoreCount;
|
||||
|
||||
return originalSet.apply(this, args);
|
||||
}
|
||||
|
||||
// actual callback is replaced by promise resolve
|
||||
args[0] = function () {
|
||||
if (!events[eventNum]) throw new Error(setName + ' ' + eventNum + ' disappeared');
|
||||
events[eventNum].resolve([].slice.call(arguments));
|
||||
};
|
||||
|
||||
eventHandle = originalSet.apply(this, args) || eventNum;
|
||||
|
||||
// this portion is a function so that setInterval may be handled via recursion
|
||||
function dispatch () {
|
||||
var handlerDetails = { handle: eventHandle };
|
||||
|
||||
var promise = new Promise((resolve, reject) => {
|
||||
handlerDetails.resolve = resolve;
|
||||
handlerDetails.reject = reject;
|
||||
});
|
||||
|
||||
handlerDetails.promise = promise;
|
||||
events[eventNum] = handlerDetails;
|
||||
|
||||
promise.then(function (argumentArray) {
|
||||
if (type !== 'setInterval') {
|
||||
delete events[eventNum];
|
||||
} else {
|
||||
dispatch();
|
||||
}
|
||||
|
||||
// call original handler
|
||||
callback.apply(this, argumentArray);
|
||||
}, () => {
|
||||
originalClear(eventHandle);
|
||||
delete events[eventNum];
|
||||
});
|
||||
|
||||
return promise;
|
||||
}
|
||||
|
||||
dispatch();
|
||||
|
||||
return eventNum;
|
||||
};
|
||||
|
||||
// actually replace functions with instrumented ones
|
||||
setAsPromise._ignoreCount = 0;
|
||||
module[setName] = setAsPromise;
|
||||
Object.defineProperty(setAsPromise, 'name', { value: setName + 'AsPromise' });
|
||||
|
||||
if (clearName) {
|
||||
module[clearName] = (eventNum) => {
|
||||
if (!events[eventNum]) {
|
||||
originalClear(eventNum);
|
||||
} else {
|
||||
events[eventNum].reject(new Error('cleared'));
|
||||
}
|
||||
};
|
||||
Object.defineProperty(module[clearName], 'name', { value: clearName + 'AsPromise' });
|
||||
}
|
||||
}
|
||||
|
||||
instrumentTimingEvents(global, 'setTimeout');
|
||||
instrumentTimingEvents(global, 'setInterval');
|
||||
instrumentTimingEvents(global, 'setImmediate');
|
||||
// // Possible TODO: nextTick needs some exceptions included to prevent infinite recursion
|
||||
// instrumentTimingEvents(process, 'nextTick');
|
||||
|
||||
// the next call to the passed function should not be promisified
|
||||
// may be queued multiple times
|
||||
exports.ignoreOnce = (ignored) => {
|
||||
ignored._ignoreCount ++;
|
||||
};
|
||||
@@ -1,135 +0,0 @@
|
||||
// This takes a openbci-sdk factory and mocks the shit out of it in complete isolation per require of this file
|
||||
|
||||
"use strict";
|
||||
|
||||
var Hardware = function () {
|
||||
this.bciBoard = {};
|
||||
//this.mockBinding = {
|
||||
// connect: this.connect.bind(this),
|
||||
// disconnect: this.disconnect.bind(this),
|
||||
// streamStart: this.streamStart.bind(this),
|
||||
// streamStop: this.streamStop.bind(this),
|
||||
// write: this.write.bind(this),
|
||||
// softReset: this.softReset.bind(this),
|
||||
// autoFindOpenBCIBoard: this.autoFindOpenBCIBoard.bind(this),
|
||||
// simulatorStart: this.simulatorStart.bind(this),
|
||||
// simulatorStop: this.simulatorStop.bind(this)
|
||||
//};
|
||||
};
|
||||
|
||||
Hardware.prototype.reset = function () {
|
||||
this.bciBoard = {};
|
||||
};
|
||||
|
||||
Hardware.prototype.createBoard = function () {
|
||||
this.bciBoard = {
|
||||
serial: null,
|
||||
connected: false,
|
||||
streaming: false,
|
||||
isSimulating: false,
|
||||
badPackets: 0,
|
||||
bytesIn: 0,
|
||||
commandsToWrite: 0,
|
||||
sampleCount: 0
|
||||
}
|
||||
};
|
||||
|
||||
Hardware.prototype.connect = function (portName) {
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
if(!this.bciBoard) reject('Board does not exist - call hardware.createBoard() first');
|
||||
|
||||
this.bciBoard.connected = true;
|
||||
this.bciBoard.serial = {
|
||||
portName:portName,
|
||||
baudRate:115200
|
||||
};
|
||||
resolve(this.bciBoard.serial);
|
||||
});
|
||||
};
|
||||
|
||||
Hardware.prototype.disconnect = function () {
|
||||
return new Promise((resolve,reject) => {
|
||||
if(!this.bciBoard) reject('Board does not exist - call hardware.createBoard() first');
|
||||
|
||||
this.bciBoard.connected = false;
|
||||
this.bciBoard.serial = null;
|
||||
});
|
||||
};
|
||||
|
||||
Hardware.prototype.streamStart = function () {
|
||||
return new Promise((resolve,reject) => {
|
||||
if(!this.bciBoard) reject('Board does not exist - call hardware.createBoard() first');
|
||||
|
||||
this.bciBoard.streaming = true;
|
||||
resolve();
|
||||
});
|
||||
};
|
||||
|
||||
Hardware.prototype.streamStop = function () {
|
||||
return new Promise((resolve,reject) => {
|
||||
if(!this.bciBoard) reject('Board does not exist - call hardware.createBoard() first');
|
||||
|
||||
this.bciBoard.streaming = false;
|
||||
resolve();
|
||||
});
|
||||
};
|
||||
|
||||
Hardware.prototype.simulatorStart = function () {
|
||||
return new Promise((resolve,reject) => {
|
||||
if(!this.bciBoard) reject('Board does not exist - call hardware.createBoard() first');
|
||||
|
||||
this.bciBoard.isSimulating = true;
|
||||
resolve();
|
||||
});
|
||||
};
|
||||
|
||||
Hardware.prototype.simulatorStop = function () {
|
||||
return new Promise((resolve,reject) => {
|
||||
if(!this.bciBoard) reject('Board does not exist - call hardware.createBoard() first');
|
||||
|
||||
this.bciBoard.isSimulating = false;
|
||||
resolve();
|
||||
});
|
||||
};
|
||||
|
||||
Hardware.prototype.autoFindOpenBCIBoard = function () {
|
||||
return new Promise((resolve,reject) => {
|
||||
resolve('/dev/tty.usbserial-D069XXX');
|
||||
});
|
||||
};
|
||||
|
||||
Hardware.prototype.emitSample = function (data) {
|
||||
return new Promise((resolve,reject) => {
|
||||
if(!this.bciBoard) reject('Board does not exist - call hardware.createBoard() first');
|
||||
|
||||
this.bciBoard.isSimulating = false;
|
||||
resolve();
|
||||
});
|
||||
};
|
||||
|
||||
Hardware.prototype.fakeData = function (data) {
|
||||
//do something, not quite sure what yet...
|
||||
};
|
||||
|
||||
var hardware = new Hardware();
|
||||
|
||||
var SandboxedModule = require('sandboxed-module');
|
||||
|
||||
var openBCIBoard = SandboxedModule.require('../openBCIBoard', {
|
||||
requires: {
|
||||
fs: {
|
||||
read: hardware.fakeData.bind(hardware)
|
||||
}
|
||||
},
|
||||
globals: {
|
||||
process: {
|
||||
platform: 'darwin',
|
||||
nextTick: process.nextTick
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
openBCIBoard.hardware = hardware;
|
||||
|
||||
module.exports = openBCIBoard;
|
||||
Referência em uma Nova Issue
Bloquear um usuário