Skip to content

Commit 9449369

Browse files
authored
Merge pull request #24 from PayalLakra/bio_amptool
Web Interface is created to run all applications by starting lsl stream
2 parents 853cf79 + bab280f commit 9449369

14 files changed

+263
-4
lines changed

app.py

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
from flask import Flask, render_template, jsonify, request
2+
import subprocess
3+
import psutil
4+
import os
5+
import signal
6+
import sys
7+
8+
app = Flask(__name__)
9+
lsl_process = None
10+
app_processes = {}
11+
12+
def is_process_running(name):
13+
for proc in psutil.process_iter(['pid', 'name']):
14+
if name in proc.info['name']:
15+
return True
16+
return False
17+
18+
@app.route("/")
19+
def home():
20+
return render_template("index.html", lsl_started=False, lsl_status="Stopped", lsl_color="red")
21+
22+
@app.route("/start_lsl", methods=["POST"])
23+
def start_lsl():
24+
global lsl_process
25+
if lsl_process and lsl_process.poll() is None:
26+
return jsonify({"status": "LSL stream already running", "lsl_started": True})
27+
try:
28+
# Start the LSL stream as a subprocess
29+
if sys.platform == "win32":
30+
lsl_process = subprocess.Popen(["python", "chords.py", "--lsl"], creationflags=subprocess.CREATE_NO_WINDOW)
31+
else:
32+
lsl_process = subprocess.Popen(["python", "chords.py", "--lsl"])
33+
34+
if lsl_process.poll() is None:
35+
return render_template("index.html", lsl_started=True, lsl_status="Running", lsl_color="green")
36+
else:
37+
return render_template("index.html", lsl_started=False, lsl_status="Failed to Start", lsl_color="red")
38+
except Exception as e:
39+
return render_template("index.html", lsl_started=False, lsl_status=f"Error: {e}", lsl_color="red")
40+
41+
@app.route("/run_app", methods=["POST"])
42+
def run_app():
43+
app_name = request.form.get("app_name")
44+
45+
# Check if the app is already running
46+
if app_name in app_processes and app_processes[app_name].poll() is None:
47+
return render_template("index.html", lsl_started=True, lsl_status="Running", lsl_color="green", message=f"{app_name} is already Running")
48+
49+
try:
50+
# Start the app subprocess
51+
if sys.platform == "win32":
52+
process = subprocess.Popen(["python", f"{app_name}.py"], creationflags=subprocess.CREATE_NO_WINDOW)
53+
else:
54+
process = subprocess.Popen(["python", f"{app_name}.py"])
55+
56+
app_processes[app_name] = process
57+
return render_template("index.html", lsl_started=True, lsl_status="Running", lsl_color="green", message=None)
58+
except Exception as e:
59+
return render_template("index.html", lsl_started=True, lsl_status="Running", lsl_color="green", message=f"Error starting {app_name}: {e}")
60+
61+
@app.route("/stop_lsl", methods=['POST'])
62+
def stop_lsl():
63+
# Terminate LSL process
64+
if lsl_process and lsl_process.poll() is None:
65+
lsl_process.terminate()
66+
67+
# Terminate all app processes
68+
for app_name, process in app_processes.items():
69+
if process.poll() is None:
70+
process.terminate()
71+
72+
# Shutdown the server gracefully
73+
os._exit(0)
74+
return jsonify({'status': 'LSL Stream and applications stopped and server is shutting down.'})
75+
76+
if __name__ == "__main__":
77+
app.run(debug=True)

app_requirements.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,5 @@ pygame==2.6.1
66
neurokit2==0.2.10
77
plotly==5.24.1
88
pandas==2.2.3
9-
tk==0.1.0
9+
tk==0.1.0
10+
PyAutoGUI==0.9.54

chords.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,9 +54,10 @@
5454
board = "" # Variable for Connected Arduino Board
5555
supported_boards = {
5656
"UNO-R3": {"sampling_rate": 250, "Num_channels": 6},
57-
"UNO-CLONE": {"sampling_rate": 250, "Num_channels": 6},
57+
"UNO-CLONE": {"sampling_rate": 250, "Num_channels": 6}, # Baud Rate 115200
5858
"UNO-R4": {"sampling_rate": 500, "Num_channels": 6},
5959
"RPI-PICO-RP2040": {"sampling_rate": 500, "Num_channels": 3},
60+
"NANO-CLONE": {"sampling_rate": 250, "Num_channels": 8}, # Baud Rate 115200
6061
}
6162

6263
# Initialize gloabal variables for Incoming Data
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.

applications/gui.py renamed to gui.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ def init_gui():
5151
global plots, curves
5252
plots = []
5353
curves = []
54-
colors = ['#FF3B3B', '#00FF66', '#FF1493', '#007BFF', '#FFA500', '#FF00FF'] # Different colors for each channel
54+
colors = ['#D10054', '#007A8C', '#0A6847', '#674188', '#E65C19', '#2E073F' ] # Different colors for each channel
5555
for i in range(6):
5656
plot = pg.PlotWidget(title=f"Channel {i + 1}") # Create a plot widget for each channel
5757
layout.addWidget(plot) # Add the plot to the layout
File renamed without changes.

applications/keystroke.py renamed to keystroke.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,7 @@ def move(event):
170170
horizontal_frame = tk.Frame(popup)
171171
horizontal_frame.pack(expand=True, pady=10)
172172

173-
eye_icon = PhotoImage(file="media/icons8-eye-30.png")
173+
eye_icon = PhotoImage(file="media\\icons8-eye-30.png")
174174

175175
blink_button = tk.Button(horizontal_frame, image=eye_icon, width=70, height=38, bg="#FFFFFF")
176176
blink_button.image = eye_icon

0 commit comments

Comments
 (0)