Separate UI and control logic with WebSocket communication
- Create UI client (src/ui_client.py) with MIDI controller integration - Create control server (src/control_server.py) with lighting logic - Implement WebSocket protocol between UI and control server - Add startup script (start_lighting_controller.py) for all components - Update Pipfile with new scripts for separated architecture - Add comprehensive documentation (README_SEPARATED.md) - Fix LED connection stability with heartbeat mechanism - Fix UI knob display and button highlighting - Maintain backward compatibility with existing MIDI mappings
This commit is contained in:
116
start_lighting_controller.py
Normal file
116
start_lighting_controller.py
Normal file
@@ -0,0 +1,116 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Startup script for the separated lighting controller architecture.
|
||||
Starts the control server, sound detector, and UI client.
|
||||
"""
|
||||
|
||||
import subprocess
|
||||
import sys
|
||||
import time
|
||||
import signal
|
||||
import os
|
||||
from pathlib import Path
|
||||
|
||||
def start_process(command, name, cwd=None):
|
||||
"""Start a subprocess and return the process object."""
|
||||
print(f"Starting {name}...")
|
||||
try:
|
||||
process = subprocess.Popen(
|
||||
command,
|
||||
shell=True,
|
||||
cwd=cwd,
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE,
|
||||
preexec_fn=os.setsid if os.name != 'nt' else None
|
||||
)
|
||||
print(f"{name} started with PID {process.pid}")
|
||||
return process
|
||||
except Exception as e:
|
||||
print(f"Failed to start {name}: {e}")
|
||||
return None
|
||||
|
||||
def main():
|
||||
"""Main startup function."""
|
||||
print("Starting Lighting Controller (Separated Architecture)")
|
||||
print("=" * 50)
|
||||
|
||||
# Get the project directory
|
||||
project_dir = Path(__file__).parent
|
||||
|
||||
processes = []
|
||||
|
||||
try:
|
||||
# Start control server
|
||||
control_process = start_process(
|
||||
"python src/control_server.py",
|
||||
"Control Server",
|
||||
cwd=project_dir
|
||||
)
|
||||
if control_process:
|
||||
processes.append(("Control Server", control_process))
|
||||
|
||||
# Wait a moment for the control server to start
|
||||
time.sleep(2)
|
||||
|
||||
# Start sound detector
|
||||
sound_process = start_process(
|
||||
"python src/sound.py",
|
||||
"Sound Detector",
|
||||
cwd=project_dir
|
||||
)
|
||||
if sound_process:
|
||||
processes.append(("Sound Detector", sound_process))
|
||||
|
||||
# Wait a moment for the sound detector to start
|
||||
time.sleep(1)
|
||||
|
||||
# Start UI client
|
||||
ui_process = start_process(
|
||||
"python src/ui_client.py",
|
||||
"UI Client",
|
||||
cwd=project_dir
|
||||
)
|
||||
if ui_process:
|
||||
processes.append(("UI Client", ui_process))
|
||||
|
||||
print("\nAll components started successfully!")
|
||||
print("Press Ctrl+C to stop all components...")
|
||||
|
||||
# Wait for processes
|
||||
try:
|
||||
while True:
|
||||
time.sleep(1)
|
||||
# Check if any process has died
|
||||
for name, process in processes:
|
||||
if process.poll() is not None:
|
||||
print(f"Warning: {name} has stopped unexpectedly")
|
||||
except KeyboardInterrupt:
|
||||
print("\nShutting down all components...")
|
||||
|
||||
except Exception as e:
|
||||
print(f"Error during startup: {e}")
|
||||
|
||||
finally:
|
||||
# Clean up all processes
|
||||
for name, process in processes:
|
||||
if process and process.poll() is None:
|
||||
print(f"Stopping {name}...")
|
||||
try:
|
||||
if os.name != 'nt':
|
||||
os.killpg(os.getpgid(process.pid), signal.SIGTERM)
|
||||
else:
|
||||
process.terminate()
|
||||
process.wait(timeout=5)
|
||||
except subprocess.TimeoutExpired:
|
||||
print(f"Force killing {name}...")
|
||||
if os.name != 'nt':
|
||||
os.killpg(os.getpgid(process.pid), signal.SIGKILL)
|
||||
else:
|
||||
process.kill()
|
||||
except Exception as e:
|
||||
print(f"Error stopping {name}: {e}")
|
||||
|
||||
print("All components stopped.")
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
Reference in New Issue
Block a user