Skip to content

Instantly share code, notes, and snippets.

@jhschwartz
Last active May 5, 2019 16:38
Show Gist options
  • Save jhschwartz/f24f50bdf576f82f39fabe7df4328959 to your computer and use it in GitHub Desktop.
Save jhschwartz/f24f50bdf576f82f39fabe7df4328959 to your computer and use it in GitHub Desktop.
Example Socket for Emotiv EPOC+ Wireless EEG (emotiv.com/epoc)
// Written by Jacob Schwartz, jaschwa@umich.edu, September 2018, edited & published May 2019
// In September 2018, I worked with the EPOC+ as part of a project for the MedHacks Hackathon.
// It was extremely counterintuitive to work with, and if anyone else comes across issues with
// it I figure this code might be helpful. It was awhile ago but I'd be willing to try to to help
// if anyone experiences issues with the device - just open an issue on my project's repo
// (github.com/jhschwartz/medhacks-zzg) and I'll see if I can help.
// EMOTIV docs: https://emotiv.github.io/cortex-docs/
// see https://github.com/jhschwartz/medhacks-zzg for my failed project that used the EPOC+
var token = 'YOUR-TOKEN-HERE'
var headset_id = 'YOUR-HEADSET-ID'
// Get references to elements on the page.
// Might not be useful to anyone else.
var form = document.getElementById('message-form')
var messageField = document.getElementById('message')
var messagesList = document.getElementById('messages')
var socketStatus = document.getElementById('status')
var closeBtn = document.getElementById('close')
// These IDs are how you jump into the websocket
const ID_GET_USER_LOGIN = 1
const ID_AUTHORIZE = 2
const ID_LICENSE_ACCEPT = 3
const ID_QUERY_HEADSETS = 4
const ID_CREATE_SESSION = 5
const ID_UPDATE_SESSION = 6
const ID_QUERY_SESSIONS = 7
const ID_SUBSCRIBE = 8
const ID_OTHER = 999
// socket opens on load of the page
var run_socket = (socket, streams) => {
// Thanks SO user user3215378: https://stackoverflow.com/a/21394730/4176019
function waitForSocketConnection(socket, callback) {
setTimeout(
function () {
if (socket.readyState === 1) {
console.log("Connection is made")
if(callback != null){
callback()
}
return
} else {
console.log("wait for connection...")
waitForSocketConnection(socket, callback)
}
}, 5) // wait 5 milisecond for the connection...
}
// connect socket
var socket = new WebSocket('wss://emotivcortex.com:54321')
// send user login on load
waitForSocketConnection(socket, function() {
socket.send(JSON.stringify({
'jsonrpc': '2.0',
'method': 'getUserLogin',
'id': ID_GET_USER_LOGIN
}))
})
// every time the socket receives data from the headset it includes an id
// that corresponds to certain events defined in the consts (lines 24-32)
socket.onmessage = function(event) {
var data = JSON.parse(event.data)
// the switch statement lets you go from a generic reception of a headset "message"
// to specific methods defined in this file.
switch (data['id']) {
case ID_GET_USER_LOGIN:
console.log('received user login')
console.log(data)
authorize()
break
case ID_AUTHORIZE:
console.log('received authorize')
console.log(data)
token = data['result']['_auth']
license(token)
break
case ID_LICENSE_ACCEPT:
console.log('received license')
console.log(data)
query_headsets()
break
case ID_QUERY_HEADSETS:
console.log('received query headsets')
console.log(data)
headset_id = data['result'][0]['id']
console.log(headset_id)
create_session(headset_id)
break
case ID_CREATE_SESSION:
console.log('received create session')
console.log(data)
update_session()
break
case ID_UPDATE_SESSION:
console.log('received update session')
console.log(data)
query_sessions()
// break
case ID_QUERY_SESSIONS:
console.log('received query session')
console.log(data)
subscribe()
break
case ID_SUBSCRIBE:
console.log('received subscribe')
console.log(data)
handle_message(data)
break
case ID_OTHER:
console.log('received other')
handle_message(data)
break
default:
// default no id so we are collecting data -- this is specific to your project/where
// you get to do what you actually get to do something with the headset
process_data(data)
}
}
// specific parts of authorization, license, etc. are outlined by the EPOC+ docs.
function authorize() {
socket.send(JSON.stringify({
'jsonrpc': '2.0',
'method': 'authorize',
'id': ID_AUTHORIZE,
'params': {
'username': username,
'password': password,
'client_id': client_id,
'client_secret': client_secret
}
}))
}
function license(token) {
console.log(token)
socket.send(JSON.stringify({
'jsonrpc': '2.0',
'method': 'acceptLicense',
'id': ID_LICENSE_ACCEPT,
'params': {
'_auth': token
}
}))
}
function query_headsets() {
socket.send(JSON.stringify({
'jsonrpc': '2.0',
'method': 'queryHeadsets',
'id': ID_QUERY_HEADSETS,
'params': {
'wilcard': 'EPOCPLUS-*'
}
}))
}
function create_session(headset_id) {
socket.send(JSON.stringify({
'jsonrpc': '2.0',
'method': 'createSession',
'id': ID_CREATE_SESSION,
'params': {
'_auth': token,
'headset': headset_id,
'status': 'open'
}
}))
}
function update_session() {
socket.send(JSON.stringify({
"jsonrpc": "2.0",
"method": "updateSession",
"params": {
"_auth": token,
"status": 'active'
},
"id": ID_UPDATE_SESSION
}))
}
function query_sessions() {
socket.send(JSON.stringify({
'jsonrpc': '2.0',
'method': 'querySessions',
'id': ID_QUERY_SESSIONS,
'params': {
'_auth': token
}
}))
}
function subscribe() {
socket.send(JSON.stringify({
'jsonrpc': '2.0',
'method': 'subscribe',
'id': ID_SUBSCRIBE,
'params': {
'_auth': token,
'streams': streams
}
}))
}
var handle_message = data => {
console.log(data)
}
// --- BELOW THIS LINE IS WHERE YOU ACTUALLY GET TO DO STUFF WITH THE HEADSET BEYOND JUST CONNECTING --- //
// the stuff in data, like 'pow', 'time', 'eeg' are provided by the headset and were used by my project.
var process_data = data => {
// pow: band data
// using this to interpret sleep
// needs to be stored in sets for analysis
if (data['pow'] != undefined) {
var date = new Date()
data['time'] = date.getTime()
pow_data.push(data) // method was specific to my project
update_pow(data) // method was specific to my project
}
// met: health metrics (stress, excitement, etc)
// using this to associate with sleep
// needs to be stored in sets for analysis
if (data['met'] != undefined && data != undefined) {
met_data.push(data) // method was specific to my project
update_met(data) // method was specific to my project
}
// eeg: health metrics (stress, excitement, etc)
// using this to associate with sleep
// needs to be stored in sets for analysis
if (data['eeg'] != undefined && data != undefined) {
eeg_data.push(data) // method was specific to my project
update_eeg(data) // method was specific to my project
}
// mot: motion data
// using this to look pretty/stand in for our lack of real-time eeg
// needs to trigger an update event all the time
if (data['pow'] != undefined) {
update_mot(data) // method was specific to my project
}
}
socket.onclose = function(event) {
console.log('socket closed!')
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment