-
Notifications
You must be signed in to change notification settings - Fork 0
Control Server
The custom control server runs on the Pi at port 5000 and provides a richer interface on top of QLC+'s native web UI.
Access it at http://lights.local:5000
The control server provides:
- AI Chat — Natural language commands ("make it warmer", "party mode", "fade to black over 5 seconds")
-
Virtual Console — Per-fixture channel sliders with correct labels from
.qxfdefinitions - Scene Management — Activate existing scenes, save AI-generated ones permanently
- Fixture Groups — Organize fixtures into named zones, target commands to specific groups
- Health Dashboard — Live status of QLC+, WebSocket connection, AI provider, and workspace
./lightsctl.sh control-installThis creates a Python venv on the Pi, installs dependencies, and sets up lighting-control.service.
The server maintains a single persistent WebSocket to QLC+ on a dedicated background thread. All HTTP requests dispatch channel commands through this one connection. This avoids the CLOSE_WAIT socket leak that occurs when each request opens its own short-lived connection (QLC+ 4.14.x has a hard limit of ~50 concurrent WebSocket clients).
See CONTROL_SERVER_ARCHITECTURE.md for the full technical deep-dive.
| Method | Path | Purpose |
|---|---|---|
| POST | /api/command |
AI natural-language command |
| GET | /api/status |
Multi-service health JSON |
| GET | /api/scenes |
List workspace scenes |
| POST | /api/scenes/<id>/activate |
Apply a scene live |
| POST | /api/scenes/save |
Save scene XML to workspace permanently |
| POST | /api/scenes/snapshot |
Capture current state as a new scene |
| GET | /api/fixtures |
List fixtures with channel_info |
| GET | /api/fixture_channels/<id> |
Per-fixture channel breakdown |
| GET | /api/groups |
List fixture groups |
| POST | /api/channel |
Set a single channel value |
| GET | /api/channel_values |
Live DMX values from QLC+ |
The save feature lets you persist any AI-generated scene (or the current live state) into the QLC+ workspace permanently:
# Via API
curl -X POST http://lights.local:5000/api/scenes/save \
-H "Content-Type: application/json" \
-d '{"name": "My Scene", "snapshot": true}'
# Or with scene XML from a previous generate
curl -X POST http://lights.local:5000/api/scenes/save \
-H "Content-Type: application/json" \
-d '{"name": "Warm Sunset", "scene_xml": "<Function Type=\"Scene\" ...>...</Function>"}'Saved scenes appear in the Scenes tab immediately and persist through reboots.
The server reads QLC+ .qxf fixture definition files to resolve each channel's semantic role. This means:
- Channel sliders show correct labels (e.g. "Warm White" not "Ch 2")
- The AI knows which channels are color vs strobe vs configuration
- Color commands drive the right channels per fixture type
The parser checks /usr/share/qlcplus/fixtures/ (system) and ~/.qlcplus/fixtures/ (user overrides).
./lightsctl.sh control-status # Service status
./lightsctl.sh control-logs # Recent logs
./lightsctl.sh control-restart # Restart the server
./lightsctl.sh control-uninstall # Remove the server
./lightsctl.sh env-sync # Push .env to Pi and restart