···11-import React, { Component } from 'react';
22-import { isNil, debounce } from 'lodash';
11+import React, { Component } from "react";
22+import { isNil, debounce } from "lodash";
33import {
44 Modal,
55 Button,
66 Segment,
77- // Image,
87 List,
98 Grid,
109 Divider
1111-} from 'semantic-ui-react';
1010+} from "semantic-ui-react";
1211import {
1312 DEVICES,
1413 DEVICE_AVAILABILITY,
1514 CONNECTION_STATUS,
1615 SCREENS
1717-} from '../../constants/constants';
1818-import styles from '../styles/collect.css';
1616+} from "../../constants/constants";
1717+import styles from "../styles/collect.css";
19182019interface Props {
2120 history: Object;
···4645 handleStartTutorial: () => void;
47464847 static getDeviceName(device: any) {
4949- return isNil(device.name) ? device.id : device.name;
4848+ if (!isNil(device)) {
4949+ return isNil(device.name) ? device.id : device.name;
5050+ }
5151+ return "";
5052 }
51535254 constructor(props: Props) {
···110112 link
111113 name={
112114 this.state.selectedDevice === device
113113- ? 'check circle outline'
114114- : 'circle outline'
115115+ ? "check circle outline"
116116+ : "circle outline"
115117 }
116118 size="large"
117119 verticalAlign="middle"
···131133 if (this.props.deviceAvailability === DEVICE_AVAILABILITY.SEARCHING) {
132134 return (
133135 <React.Fragment>
134134- {/* <Modal.Content image>
135135- <Image src={blake} size="tiny" centered />
136136- </Modal.Content> */}
137136 <Modal.Content className={styles.searchingText}>
138137 Searching for available headset(s)...
139138 </Modal.Content>
···143142 if (this.props.connectionStatus === CONNECTION_STATUS.CONNECTING) {
144143 return (
145144 <React.Fragment>
146146- {/* <Modal.Content image>
147147- <Image src={blake} size="tiny" centered />
148148- </Modal.Content> */}
149145 <Modal.Content className={styles.searchingText}>
150150- Connecting to{' '}
146146+ Connecting to{" "}
151147 {ConnectModal.getDeviceName(this.state.selectedDevice)}
152148 ...
153149 </Modal.Content>
···205201 Insert the USB Receiver
206202 </Modal.Header>
207203 <Modal.Content>
208208- Inser the USB receiver into a USB port on your computer. Ensure that
204204+ Insert the USB receiver into a USB port on your computer. Ensure that
209205 the LED on the receiver is continously lit or flickering rapidly. If
210206 it is blinking slowly or not illuminated, remove and reinsert the
211207 receiver
+3-4
app/components/HomeComponent/index.js
···171171 <Image src={faceHouseIcon} />
172172 <Header as="h1">Faces and Houses</Header>
173173 <p>
174174- Explore the N170 ERP that is produce in response to viewing
175175- faces (as compared to non human objects). It is called the
176176- N170 because it is a negative deflection that occurs around
177177- 170ms after perceiving a face.
174174+ Explore the N170 event-related potential that is produced in response to viewing
175175+ faces. It is called the N170 because it is a negative, downwards-facing wave that occurs around
176176+ 170 milliseconds after perceiving a face.
178177 </p>
179178 <Button
180179 secondary
···66 * We use it both in the browser and NodeJS code.
77 *
88 * It makes extensive use of Promises for flow control; all requests return a
99- * Promise with their result.
1010- *
99+ * Promise with their result.
1010+ *
1111 * For the subscription types in Cortex, we use an event emitter. Each kind of
1212 * event (mot, eeg, etc) is emitted as its own event that you can listen for
1313 * whether or not there are any active subscriptions at the time.
+37-22
app/utils/eeg/emotiv.js
···33 * an RxJS Observable of raw EEG data
44 *
55 */
66-import { fromEvent } from 'rxjs';
77-import { map, withLatestFrom, share } from 'rxjs/operators';
88-import { addInfo, epoch, bandpassFilter } from '@neurosity/pipes';
99-import { toast } from 'react-toastify';
1010-import { parseEmotivSignalQuality } from './pipes';
66+import { fromEvent } from "rxjs";
77+import { map, withLatestFrom, share } from "rxjs/operators";
88+import { addInfo, epoch, bandpassFilter } from "@neurosity/pipes";
99+import { toast } from "react-toastify";
1010+import { parseEmotivSignalQuality } from "./pipes";
1111import {
1212 USERNAME,
1313 PASSWORD,
1414 CLIENT_ID,
1515 CLIENT_SECRET,
1616 LICENSE_ID
1717-} from '../../../keys';
1818-import { EMOTIV_CHANNELS, PLOTTING_INTERVAL } from '../../constants/constants';
1919-import Cortex from './cortex';
1717+} from "../../../keys";
1818+import { EMOTIV_CHANNELS, PLOTTING_INTERVAL } from "../../constants/constants";
1919+import Cortex from "./cortex";
20202121-// Just returns the Cortex object from SDK
2121+// Creates the Cortex object from SDK
2222const verbose = process.env.LOG_LEVEL || 1;
2323const options = { verbose };
2424const client = new Cortex(options);
···4242 debit: 1
4343 })
4444 )
4545+ .catch(err => {
4646+ toast.error(`Authentication failed. ${err}`);
4747+ return err;
4848+ })
4549 .then(() =>
4650 client.createSession({
4747- status: 'active',
5151+ status: "active",
4852 headset: device.id
4953 })
5054 )
5151- .then(session => ({
5252- name: session.headset.id,
5353- samplingRate: session.headset.settings.eegRate,
5454- channels: EMOTIV_CHANNELS
5555- }))
5555+ .catch(err => {
5656+ toast.error(`Session creation failed. ${err} `);
5757+ return err;
5858+ })
5959+ .then(session => {
6060+ if (session.headset === undefined) {
6161+ return new Error("Session does not exist");
6262+ }
6363+ return {
6464+ name: session.headset.id,
6565+ samplingRate: session.headset.settings.eegRate,
6666+ channels: EMOTIV_CHANNELS
6767+ };
6868+ })
5669 .catch(err => {
5757- toast.error(`Couldn't connect to device ${device.id}`);
7070+ toast.error(`Couldn't connect to device ${device.id}: ${err}`);
5871 return err;
5972 });
60736174export const disconnectFromEmotiv = async () => {
6262- const sessionStatus = await client.updateSession({ status: 'close' });
7575+ const sessionStatus = await client.updateSession({ status: "close" });
6376 return sessionStatus;
6477};
65786679// Returns an observable that will handle both connecting to Client and providing a source of EEG data
6780export const createRawEmotivObservable = async () => {
6868- const subs = await client.subscribe({ streams: ['eeg', 'dev'] });
6969- if (!subs[0].eeg) throw new Error('failed to subscribe');
7070- return fromEvent(client, 'eeg').pipe(map(createEEGSample));
8181+ const subs = await client.subscribe({ streams: ["eeg", "dev"] });
8282+ if (!subs[0].eeg) {
8383+ toast.error(`Subscription to Session data failed`);
8484+ }
8585+ return fromEvent(client, "eeg").pipe(map(createEEGSample));
7186};
72877388// Creates an observable that will epoch, filter, and add signal quality to EEG stream
7489export const createEmotivSignalQualityObservable = rawObservable => {
7575- const signalQualityObservable = fromEvent(client, 'dev');
9090+ const signalQualityObservable = fromEvent(client, "dev");
7691 const samplingRate = 128;
7792 const channels = EMOTIV_CHANNELS;
7893 const intervalSamples = (PLOTTING_INTERVAL * samplingRate) / 1000;
···97112};
9811399114export const injectEmotivMarker = (value, time) => {
100100- client.injectMarker({ label: 'event', value, time });
115115+ client.injectMarker({ label: "event", value, time });
101116};
102117103118// ---------------------------------------------------------------------
+8-9
app/utils/eeg/muse.js
···77 addSignalQuality
88} from "@neurosity/pipes";
99import { release } from "os";
1010-import { MUSE_SERVICE, MuseClient, zipSamples } from "muse-js"
1111-import { from } from "rxjs"
1010+import { MUSE_SERVICE, MuseClient, zipSamples } from "muse-js";
1111+import { from } from "rxjs";
1212import { parseMuseSignalQuality } from "./pipes";
1313import {
1414 MUSE_SAMPLING_RATE,
···18181919const INTER_SAMPLE_INTERVAL = -(1 / 256) * 1000;
20202121-let bluetooth = {}
2121+let bluetooth = {};
2222let client = {};
2323if (process.platform !== "win32" || release().split(".")[0] >= 10) {
2424 // Just returns the client object from Muse JS
···3232 let device = {};
3333 if (process.platform === "win32") {
3434 if (release().split(".")[0] < 10) {
3535- console.log('win 7 ')
3636- return null
3535+ console.log("win 7 ");
3636+ return null;
3737 }
3838- device = await bluetooth.requestDevice({
3939- filters: [{ services: [MUSE_SERVICE] }]
4040- });
4141-3838+ device = await bluetooth.requestDevice({
3939+ filters: [{ services: [MUSE_SERVICE] }]
4040+ });
4241 } else {
4342 device = await navigator.bluetooth.requestDevice({
4443 filters: [{ services: [MUSE_SERVICE] }]