-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathapp.py
288 lines (230 loc) · 7.8 KB
/
app.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
from flask import Flask
from flask import render_template
from flask import request
from flask import session
from flask.ext.socketio import SocketIO, send, emit
import open_bci_v3 as bci
import os
import time
import threading
from udp_server import UDPServer
from oscserver import OSCServer
import argparse
#global variables:
#bciboard -> the link to the openbci board over UART
#bciboard_thread -> the secondary thread that runs the board
#bciboard_stopsignal -> Set True if the board should be stopped next second
#sock_server -> udp_ser
#latest_string -> Temporary string to pass data
#bciboard_callbacks -> array of all call back functions
#docallback_osc -> boolean to stream over osc
#docallback_udp -> boolean to stream over udp
#docallback_socket -> boolean to stream over socket (works with hub)
#docallback_csv -> to csv (not currently implement)
#docallback_toconsole -> print to python log?
HOST_IP = "0.0.0.0"
app = Flask(__name__)
app.config['SECRET_KEY'] = 'secret!'
socketio = SocketIO(app)
OUTPUT_OPTIONS = {"csv":False, "udp":False,"osc":True}
STREAM_TIMEOUTLAPSE = 10 #In seconds
def printData(sample):
#Sample callback that can be passed into the openbci board
global latest_string
#print "Called!"
#os.system('clear')
output = ""
output += "----------------"
output += ("%f" %(sample.id))
output += str(sample.channel_data)
output += str(sample.aux_data)
output += "----------------"
print output
latest_string = output
def boardDoContinueCallback():
#The openbci board periodically checks to see if it should shut off
global bciboard_stopsignal
if bciboard_stopsignal:
bciboard_stopsignal = False
return False
else:
return True
def boardErrorCallback():
#The openbci board periodically checks to see if it should shut off
print "Sees that the board exited."
def modify_bcicallbacks(string_command,do_set):
global bciboard_callbacks
global docallback_toconsole, docallback_csv,docallback_socket,docallback_osc, docallback_udp
if string_command =="udp":
docallback_udp = do_set
elif string_command == "csv":
docallback_csv = do_set
elif string_command == "socket":
docallback_socket = do_set
elif string_command == "osc":
docallback_osc = do_set
elif string_command == "console":
docallback_toconsole = do_set
else:
#We don't know this input
return None
cbacks = []
if docallback_osc:
cbacks.append(osc_server.handle_sample)
if docallback_udp:
cbacks.append(sock_server.handle_sample)
if docallback_udp:
cbacks.append(sendSocketMessage)
if docallback_toconsole:
cbacks.append(printData)
#TODO: finish the CSV streaming option
#write to the global variable (used by the streaming loop)
bciboard_callbacks = cbacks
return 1
@app.route("/")
def hello():
global bciboard
try:
output = "From board: " + latest_string + "And is streaming: " + str(bciboard.streaming)
except Exception as e:
print e
output = "ERROR"
return render_template('index.html',status = output)
@app.route("/board/", methods=["POST","GET"])
def board_general():
global bciboard
return "Nothing here yet"
@app.route("/board/channel/<channel_num>/<command>", methods=["POST","GET"])
def board_command_handler(channel_num,command):
global bciboard
if command == "on":
return "turning channel " + str(channel_num) + "on "
elif command == "off":
return "turning channel " + str(channel_num) + "off"
#Filters, etc. are handled in this block
@app.route("/board/<field>/<command>", methods=["POST","GET"])
def startstop_handler(field,command):
global bciboard
if field=="stream":
try:
if command == "start":
return set_boardstreaming(True)
else:
return set_boardstreaming(False)
except Exception as e:
print e
return e
elif field == "filter":
try:
if command == "start":
return bciboard.enable_filters()
else:
return bciboard.disable_filters()
except Exception as e:
print e
return e
elif field == "connection":
return (bciboard is not None)
@app.route("/output/<streamtype>/<onoffread>", methods=["POST","GET"])
def streamoutput_handler(streamtype,onoffread):
try:
if onoffread=="read":
output = ""
if streamtype =="udp":
output += str(docallback_udp)
elif streamtype == "csv":
output += str(docallback_csv)
elif streamtype == "socket":
output += str(docallback_socket)
elif streamtype == "osc":
output += str(docallback_osc)
elif streamtype == "console":
output += docallback_toconsole
return output
res = modify_bcicallbacks(streamtype,onoffread=="on")
if not res:
return "ERROR: STREAMTYPE NOT CORRECT."
else:
return "SUCCESS"
except Exception as e:
print e
return e
def sendSocketMessage(sample):
try:
print "socket message"
socketio.emit('stream', {'data': sample.channel_data,'t':sample.t}, namespace='/test')
except Exception as e:
print e
# @socketio.on('test event', namespace='/test')
# def test_message(message):
# print 'test recieved'
@socketio.on('connect', namespace='/test')
def test_connect():
emit('my response', {'data': 'Connected'})
@socketio.on('disconnect', namespace='/test')
def test_disconnect():
print('Client disconnected')
def set_boardstreaming(doStart):
global latest_string, bciboard,bciboard_thread,bciboard_stopsignal
output = ""
if doStart and not bciboard.streaming:
#initialize the thread
#,sendSocketMessage
bciboard_thread = threading.Thread(target=bciboard.start_streaming, args=[bciboard_callbacks,boardDoContinueCallback,boardErrorCallback,STREAM_TIMEOUTLAPSE])
#set daemon to true so the app.py can still be ended with a single ^C
bciboard_thread.daemon = True
#spawn the thread
bciboard_thread.start()
output = "STARTING STREAMING"
elif not doStart:
bciboard_stopsignal = True
#bciboard_thread = None
output = "STOPPING STREAMING"
else:
output = "DID NOTHING: Likely trying to start while aleady streaming"
return output
if __name__ == '__main__':
global latest_string, bciboard, bciboard_stopsignal
global sock_server, osc_server
global bciboard_callbacks
global docallback_toconsole, docallback_csv,docallback_socket,docallback_osc, docallback_udp
parser = argparse.ArgumentParser(description="OpenBCI 'user'")
parser.add_argument('-sim', '--simulator', action='store_true',
help="Run the openbci simulator, rather than real data")
parser.add_argument('-p', '--port',
help="Port to connect to OpenBCI Dongle " +
"( ex /dev/ttyUSB0 or /dev/tty.usbserial-* )")
args = parser.parse_args()
#initialize the stop signal for the repeate streaming data
bciboard_stopsignal = False
available_ports = bci.serial_ports()
print "Sees the following port options: " + str(available_ports)
print "It is currently strongly advised to specify the port in code"
#port = available_ports[1]
if args.port:
print "Using manually specific port: " + str(args.port)
specific_port = args.port
else:
specific_port = None
use_sim= False
if args.simulator:
print "Initializing the simulator board"
use_sim = True
bciboard = bci.OpenBCIBoard(is_simulator=use_sim, port=specific_port)
latest_string = "none yet"
args = {
"host": HOST_IP,
"port": '8888',
"json": True,
}
print args
sock_server = UDPServer(args["host"], int(args["port"]), args["json"])
osc_server = OSCServer(args["host"], 12345)
#define the list of callback functions now:
docallback_toconsole = True
docallback_csv = False
docallback_socket = True
docallback_osc = True
docallback_udp = True
bciboard_callbacks = [sock_server.handle_sample,osc_server.handle_sample,sendSocketMessage,printData]
socketio.run(app)