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:
296
README_SEPARATED.md
Normal file
296
README_SEPARATED.md
Normal file
@@ -0,0 +1,296 @@
|
||||
# Lighting Controller - Separated Architecture
|
||||
|
||||
This version of the lighting controller separates the UI and control logic, communicating via WebSocket. The MIDI controller is now integrated with the UI client.
|
||||
|
||||
## Architecture Overview
|
||||
|
||||
```
|
||||
┌─────────────────┐ WebSocket ┌─────────────────┐ WebSocket ┌─────────────────┐
|
||||
│ UI Client │◄─────────────────►│ Control Server │◄─────────────────►│ LED Server │
|
||||
│ │ │ │ │ │
|
||||
│ - MIDI Input │ │ - Lighting Logic│ │ - LED Bars │
|
||||
│ - User Interface│ │ - Pattern Logic │ │ - ESP-NOW │
|
||||
│ - Status Display│ │ - Beat Handling │ │ │
|
||||
└─────────────────┘ └─────────────────┘ └─────────────────┘
|
||||
│ │
|
||||
│ │ TCP
|
||||
│ ▼
|
||||
│ ┌─────────────────┐
|
||||
│ │ Sound Detector │
|
||||
│ │ │
|
||||
│ │ - Audio Input │
|
||||
│ │ - Beat Detection│
|
||||
│ │ - BPM Analysis │
|
||||
│ └─────────────────┘
|
||||
│
|
||||
│ MIDI
|
||||
▼
|
||||
┌─────────────────┐
|
||||
│ MIDI Controller │
|
||||
│ │
|
||||
│ - Knobs/Dials │
|
||||
│ - Buttons │
|
||||
│ - Pattern Select│
|
||||
└─────────────────┘
|
||||
```
|
||||
|
||||
## Components
|
||||
|
||||
### 1. UI Client (`src/ui_client.py`)
|
||||
- **Purpose**: User interface and MIDI controller integration
|
||||
- **Features**:
|
||||
- MIDI controller input handling
|
||||
- Real-time status display
|
||||
- Pattern selection visualization
|
||||
- Connection status monitoring
|
||||
- **Communication**: WebSocket client to control server
|
||||
|
||||
### 2. Control Server (`src/control_server.py`)
|
||||
- **Purpose**: Core lighting control logic
|
||||
- **Features**:
|
||||
- Pattern execution
|
||||
- Beat synchronization
|
||||
- Parameter management
|
||||
- LED bar communication
|
||||
- **Communication**:
|
||||
- WebSocket server for UI clients
|
||||
- TCP server for sound detector
|
||||
- WebSocket client to LED server
|
||||
|
||||
### 3. Sound Detector (`src/sound.py`)
|
||||
- **Purpose**: Audio beat detection and BPM analysis
|
||||
- **Features**:
|
||||
- Real-time audio processing
|
||||
- Beat detection
|
||||
- BPM calculation
|
||||
- Tempo reset functionality
|
||||
- **Communication**: TCP client to control server
|
||||
|
||||
## WebSocket Protocol
|
||||
|
||||
### UI Client → Control Server Messages
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "pattern_change",
|
||||
"data": {
|
||||
"pattern": "pulse"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "color_change",
|
||||
"data": {
|
||||
"r": 255,
|
||||
"g": 0,
|
||||
"b": 0
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "brightness_change",
|
||||
"data": {
|
||||
"brightness": 80
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "parameter_change",
|
||||
"data": {
|
||||
"n1": 15,
|
||||
"n2": 20
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "delay_change",
|
||||
"data": {
|
||||
"delay": 150
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "beat_toggle",
|
||||
"data": {
|
||||
"enabled": true
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "reset_tempo",
|
||||
"data": {}
|
||||
}
|
||||
```
|
||||
|
||||
## Running the System
|
||||
|
||||
### Option 1: Use the startup script (Recommended)
|
||||
```bash
|
||||
python start_lighting_controller.py
|
||||
```
|
||||
|
||||
### Option 2: Start components individually
|
||||
|
||||
1. **Start Control Server**:
|
||||
```bash
|
||||
pipenv run control
|
||||
# or
|
||||
python src/control_server.py
|
||||
```
|
||||
|
||||
2. **Start Sound Detector** (in another terminal):
|
||||
```bash
|
||||
pipenv run sound
|
||||
# or
|
||||
python src/sound.py
|
||||
```
|
||||
|
||||
3. **Start UI Client** (in another terminal):
|
||||
```bash
|
||||
pipenv run ui
|
||||
# or
|
||||
python src/ui_client.py
|
||||
```
|
||||
|
||||
### Option 3: Development mode with auto-reload
|
||||
```bash
|
||||
# Terminal 1 - Control Server
|
||||
pipenv run dev-control
|
||||
|
||||
# Terminal 2 - Sound Detector
|
||||
pipenv run sound
|
||||
|
||||
# Terminal 3 - UI Client
|
||||
pipenv run dev-ui
|
||||
```
|
||||
|
||||
## Configuration
|
||||
|
||||
### MIDI Controller
|
||||
- MIDI device preferences are saved in `config.json`
|
||||
- The UI client automatically detects and connects to MIDI devices
|
||||
- Use the dropdown to select different MIDI ports
|
||||
|
||||
### Network Settings
|
||||
- **Control Server**: `localhost:8765` (WebSocket)
|
||||
- **Sound Detector**: `127.0.0.1:65432` (TCP)
|
||||
- **LED Server**: `192.168.4.1:80/ws` (WebSocket)
|
||||
|
||||
### Audio Settings
|
||||
- Audio input device index: 7 (modify in `src/sound.py`)
|
||||
- Buffer size: 512 samples
|
||||
- Sample rate: Auto-detected from device
|
||||
|
||||
## MIDI Controller Mapping
|
||||
|
||||
### Buttons (Notes 36-51)
|
||||
- **Row 1**: Pulse, Sequential Pulse
|
||||
- **Row 2**: Alternating, Alternating Phase
|
||||
- **Row 3**: N Chase, Rainbow
|
||||
- **Row 4**: Flicker, Radiate
|
||||
|
||||
### Dials (CC30-37)
|
||||
- **CC30**: Red (0-255)
|
||||
- **CC31**: Green (0-255)
|
||||
- **CC32**: Blue (0-255)
|
||||
- **CC33**: Brightness (0-100)
|
||||
- **CC34**: N1 parameter
|
||||
- **CC35**: N2 parameter
|
||||
- **CC36**: N3 parameter
|
||||
- **CC37**: Delay (0-508ms)
|
||||
|
||||
### Additional Knobs (CC38-45)
|
||||
- **CC38**: Pulse N1
|
||||
- **CC39**: Pulse N2
|
||||
- **CC40**: Alternating N1
|
||||
- **CC41**: Alternating N2
|
||||
- **CC42**: Radiate N1
|
||||
- **CC43**: Radiate Delay
|
||||
- **CC44**: Knob 7
|
||||
- **CC45**: Knob 8
|
||||
|
||||
### Control Buttons
|
||||
- **CC27**: Beat sending toggle (127=on, 0=off)
|
||||
- **CC29**: Reset tempo detection
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Connection Issues
|
||||
1. **UI Client can't connect to Control Server**:
|
||||
- Ensure control server is running first
|
||||
- Check firewall settings
|
||||
- Verify port 8765 is available
|
||||
|
||||
2. **Control Server can't connect to LED Server**:
|
||||
- Check LED server IP address (192.168.4.1)
|
||||
- Verify LED server is running
|
||||
- Check network connectivity
|
||||
|
||||
3. **Sound Detector can't connect to Control Server**:
|
||||
- Ensure control server is running
|
||||
- Check TCP port 65432 is available
|
||||
|
||||
### MIDI Issues
|
||||
1. **No MIDI devices detected**:
|
||||
- Check MIDI controller connection
|
||||
- Install MIDI drivers if needed
|
||||
- Use "Refresh MIDI Ports" button
|
||||
|
||||
2. **MIDI input not working**:
|
||||
- Verify correct MIDI port is selected
|
||||
- Check MIDI controller is sending data
|
||||
- Look for error messages in console
|
||||
|
||||
### Performance Issues
|
||||
1. **High CPU usage**:
|
||||
- Reduce audio buffer size in sound.py
|
||||
- Increase parameter update interval
|
||||
- Check for network latency
|
||||
|
||||
2. **Audio dropouts**:
|
||||
- Increase audio buffer size
|
||||
- Check audio device settings
|
||||
- Reduce system load
|
||||
|
||||
## Development
|
||||
|
||||
### Adding New Patterns
|
||||
1. Add pattern name to `PATTERN_NAMES` in `control_server.py`
|
||||
2. Implement pattern logic in `LightingController` class
|
||||
3. Add pattern to MIDI button mapping in `ui_client.py`
|
||||
|
||||
### Adding New MIDI Controls
|
||||
1. Add control change handler in `MidiController.handle_midi_message()`
|
||||
2. Add corresponding WebSocket message type
|
||||
3. Implement handler in `LightingController.handle_ui_command()`
|
||||
|
||||
### Modifying UI
|
||||
- Edit `src/ui_client.py` for UI changes
|
||||
- Use `pipenv run dev-ui` for auto-reload during development
|
||||
- UI uses tkinter with dark theme
|
||||
|
||||
## Migration from Monolithic Version
|
||||
|
||||
The separated architecture maintains compatibility with:
|
||||
- Existing MIDI controller mappings
|
||||
- LED bar communication protocol
|
||||
- Sound detection functionality
|
||||
- Configuration files
|
||||
|
||||
Key differences:
|
||||
- MIDI controller is now part of UI client
|
||||
- Control logic is isolated in control server
|
||||
- Communication via WebSocket instead of direct function calls
|
||||
- Better separation of concerns and modularity
|
Reference in New Issue
Block a user