Skip to content

Commit c922213

Browse files
Darth-RaaziMichael LiBluCodeGHDAQ Computeritslinotlie
authored
Omnibus Launcher (#141)
* Rewrote launcher to support macOS * Fixed KeyError * Added prompt menu and new profiles * Terminate all processes when any of them exits * Added stderr printing * Updated stdout and stderr printing, changed how programs are terminated * Added signal for Windows * Potential fix for signal on Windows * I hate Windows * proof of concept works * Misc WDR fixes * dynamic text dash item, fix errors and dynamic sizing * More fixes * Limit title length * Found better alternative than QTimer now we listen to all can messages (acts as our interrupt function) and then check if the specified peiod has changed, in which case, send the can message. * Update DAQ config * Live fixes * Add printing to replay log * Fix parsley performance * Remove CAN message table * Clean up wdr nitpicks * Clean up parsley source * Fix unit tests, autopep8 * Add duplicate item button, optional filter on dynamic text and sorted item keys (#111) * Update RLCS source * RLCS source improvements * Update parsley for live telemetry * Update requirements.txt to fix imageitem * Let RLCS control valves * Add better dashboard error and reset handling * Autocomplete dashitems * add general board table item * wip: use QItemDelegate to add dropdown instead * improve copy pasting and add deleting to general boards widget * finish new dropdown implementation and add save/restore support * improve finding list of paths * make table rows draggable * rename general boards to table view * prevent cell deletion when none is selected * add store/restore header for table view and ctrl-x for cut * add support for binary telemetry message * wip: switch to new binary encoding for telemetry * support for new binary encoding * Add dynamic_text background colour change (#113) * dynamic_text: Added button param to make new params * dynamic_text: Add conditions to change background color * dynamic_text: Made requested changes * dynamic_text: Removed float casting to allow CAN messages * dynamic_text: Casting condition param to str for comparison * correct typo * Format --------- Co-authored-by: Kavin Satheeskumar <[email protected]> Co-authored-by: Kavin <[email protected]> * add support for binary telemetry message * wip: switch to new binary encoding for telemetry * support for new binary encoding * fix some bugs * Add the ability to select which parsley instance you want to send to * omnibus to gpsd converter * Revert "Add the ability to select which parsley instance you want to send to" This reverts commit 923bcb4. * Drive changes Fixes a few bugs, light mode, adds parsley selection * Fix parsley * change parsely names to telemetry/none-telemetry; add keep alive bytes for telemetry * increase table widget margin * remove commented code project-wide (#117) * Fix exception caused by empty series * Fixed plot scaling issue (#119) Fixed plot scaling issue, removed broken tests and downgraded parsley. * Added and fixed clear button (#121) Added a dashboard 'Clear' button * Rewrote launcher to support macOS * Fixed KeyError * Added prompt menu and new profiles * Terminate all processes when any of them exits * Added stderr printing * Updated stdout and stderr printing, changed how programs are terminated * Added signal for Windows * Potential fix for signal on Windows * I hate Windows * Rewrote launcher to dynamically get all sources and sinks * Added comment * Deal with 1920x1080 screen resolution on Wayland (#143) * Another Wayland fix (for dynamic text) (#144) * Deal with 1920x1080 screen resolution on Wayland * Fix dynamic text for Wayland * Added finally section to ensure all spawned process are killed no matter how the program exits * Removed flakey replay_log unit test * Ran format.sh to enforce autopep * Python executable and signal changes for Windows --------- Co-authored-by: Michael Li <[email protected]> Co-authored-by: BluCodeGH <[email protected]> Co-authored-by: DAQ Computer <[email protected]> Co-authored-by: Michael <[email protected]> Co-authored-by: Kavin Satheeskumar <[email protected]> Co-authored-by: Robert Cai <[email protected]> Co-authored-by: Rio Liu <[email protected]> Co-authored-by: Rio <[email protected]> Co-authored-by: Fayzulloh Ergashev <[email protected]> Co-authored-by: Kavin <[email protected]> Co-authored-by: Anthony Chen <[email protected]> Co-authored-by: MaisimZaman <[email protected]>
1 parent 5aa6533 commit c922213

File tree

1 file changed

+75
-27
lines changed

1 file changed

+75
-27
lines changed

launcher.py

Lines changed: 75 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,85 @@
1+
import os
2+
import signal
3+
import subprocess
14
import sys
2-
from subprocess import Popen, CREATE_NEW_CONSOLE
5+
import time
36

7+
# Some specific commands are needed for Windows vs macOS/Linux
8+
if sys.platform == "win32":
9+
from subprocess import CREATE_NEW_PROCESS_GROUP
10+
python_executable = "venv/Scripts/python"
11+
else:
12+
python_executable = "python"
413

5-
profiles = {
6-
"test": ['python -m omnibus',
7-
'python sinks/plot/main.py',
8-
'python sources/ni/main.py'],
9-
"texas": ['python sources/parsley/main.py $arg',
10-
'python sources/ni/main.py',
11-
'python -m omnibus']
12-
# Add other profiles in here
13-
# If any commands require arguments to be passed in, write $arg in its place
14+
# Parse folders for sources and sinks
15+
modules = {"sources" : os.listdir('sources'), "sinks" : os.listdir('sinks')}
1416

15-
}
17+
# Remove dot files
18+
for module in modules.keys():
19+
for item in modules[module]:
20+
if item.startswith("."):
21+
modules[module].remove(item)
1622

23+
for module in modules.keys():
24+
print(f"{module.capitalize()}:")
25+
for i, item in enumerate(modules[module]):
26+
print(f"\t{i+1}. {item.capitalize()}")
1727

18-
try:
19-
if sys.argv[1] == "_wrap":
20-
p = Popen(sys.argv[2])
21-
if p.wait() != 0:
22-
input('Press enter to quit')
28+
# Construct CLI commands to start Omnibus
29+
source_selection = input(f"\nPlease enter your Source choice [1-{len(modules['sources'])}]: ")
30+
sink_selection = input(f"Please enter your Sink choice [1-{len(modules['sinks'])}]: ")
31+
omnibus = [python_executable, "-m", "omnibus"]
32+
source = [python_executable, f"sources/{modules['sources'][int(source_selection) - 1]}/main.py"]
33+
sink = [python_executable, f"sinks/{modules['sinks'][int(sink_selection) - 1]}/main.py"]
34+
35+
commands = [omnibus, source, sink]
36+
processes = []
37+
print("Launching... ", end="")
2338

39+
# Execute commands as subprocesses
40+
for command in commands:
41+
if sys.platform == "win32":
42+
process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE,
43+
creationflags=CREATE_NEW_PROCESS_GROUP)
2444
else:
25-
selection = sys.argv[1]
26-
processes = profiles[selection]
27-
args = sys.argv[2:]
45+
process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
46+
47+
time.sleep(0.5)
48+
processes.append(process)
49+
50+
print("Done!")
2851

52+
# Blank exception just for processes to throw
53+
class Finished(Exception):
54+
pass
55+
56+
# If any file exits or the user presses control + c,
57+
# terminate all other files that are running
58+
try:
59+
while True:
2960
for process in processes:
30-
while '$arg' in process:
31-
process = process.replace('$arg', args[0], 1)
32-
args.pop(0)
33-
Popen(f'python launcher.py _wrap "{process}"', creationflags=CREATE_NEW_CONSOLE)
34-
35-
except (KeyError, IndexError):
36-
print('Please enter a single valid profile selection (ex. python launcher.py texas)')
37-
print('Ensure that you have entered the correct amount of args required for each script in the right order')
61+
if process.poll() != None:
62+
raise Finished
63+
except (Finished, KeyboardInterrupt, Exception):
64+
for process in processes:
65+
if sys.platform == "win32":
66+
os.kill(process.pid, signal.CTRL_BREAK_EVENT)
67+
else:
68+
process.send_signal(signal.SIGINT)
69+
70+
# Dump output and error (if exists) from every
71+
# process to the shell
72+
output, err = process.communicate()
73+
output, err = output.decode(), err.decode()
74+
print(f"\nOutput from {process.args}:")
75+
print(output)
76+
77+
if err and "KeyboardInterrupt" not in err:
78+
print(f"\nError from {process.args}:")
79+
print(err)
80+
finally:
81+
for process in processes:
82+
if sys.platform == "win32":
83+
os.kill(process.pid, signal.CTRL_BREAK_EVENT)
84+
else:
85+
process.send_signal(signal.SIGINT)

0 commit comments

Comments
 (0)