-
Notifications
You must be signed in to change notification settings - Fork 0
Troubleshooting
Common issues and how to fix them.
The four issues most likely to bite you. Read this section first.
Symptom: You pushed new code, ran ./lightsctl.sh update, hard-refreshed the browser — and the Pi is still running the old version.
Diagnosis: update only runs sudo apt update && apt upgrade on the Pi. It's an OS-package updater, not a code deployer. There is no git pull happening on the Pi.
Fix: Deploy from your workstation:
bash scripts/deploy.shThis rsyncs control-server/, scripts/, and lightsctl.sh to the Pi and restarts lighting-control.service.
Symptom: Code deployed, service restarted, but the browser still shows the old layout / old colors / missing tab.
Diagnosis: The PWA service worker (and ordinary browser cache) is serving cached CSS and JS.
Fix: Hard refresh — ⌘⇧R (Mac) or Ctrl⇧R (Windows/Linux). On iOS Safari, close the tab and reopen, or use Settings → Safari → Advanced → Website Data to clear lights.local.
Symptom: The Diagnostics tab shows lighting-mcp: not installed in a muted/grey state.
Diagnosis: Expected behavior if you haven't installed the MCP server. As of v2.13.1, the diagnostics distinguish "not installed" (the systemd unit doesn't exist) from "inactive" (the unit exists but is stopped) — the former is muted, the latter is red.
Fix: Only install MCP if you actually want to drive the rig from Claude Desktop / ChatGPT / Cursor / a custom agent:
./lightsctl.sh mcp-installIf you're happy with the Chat tab in the web UI, leave it uninstalled.
Symptom: You edited a Jinja template under control-server/templates/, ran bash scripts/deploy.sh, and the page still renders the old template.
Diagnosis: Flask caches templates in memory at process start. The deploy script restarts the service automatically, but if you rsynced manually you'll need to restart yourself.
Fix:
ssh lights.local 'sudo systemctl restart lighting-control'(Or just use bash scripts/deploy.sh, which does this for you.)
Start with these commands to identify issues:
./lightsctl.sh doctor # Full health check
./lightsctl.sh validate # Pre-flight validation
./lightsctl.sh diagnose # Detailed diagnostic dumpIf you've installed the MCP server (mcp-install), three diagnostic tools are available to any connected LLM client:
| Tool | What it checks |
|---|---|
test_dmx |
Runs a known-good R → G → B sweep across every fixture's color channels and restores prior state. Visible confirmation that DMX is reaching the rig. |
get_logs(service, n?) |
Tails the systemd journal for qlcplus-web, lighting-control, lighting-mcp, or nginx. |
get_system_info() |
Pi-level health: CPU temperature, load, memory, disk, uptime, USB devices, service status. |
Tell your agent "the lights aren't responding, what's wrong?" — it can call all three in sequence to triage without SSHing in.
Symptoms:
-
test-dmxcommand fails - No DMX output from fixtures
- USB device not showing in
lsusb
Solutions:
./lightsctl.sh test-dmx
./lightsctl.sh lsusb./lightsctl.sh ssh
groups $USER # should include dialoutUnplug and replug the ENTTEC. If harden was run, it should appear at /dev/dmx0.
Symptoms:
- Web UI not accessible
- Service status shows failed
- Logs show Qt platform errors
Solutions:
./lightsctl.sh logs
./lightsctl.sh logs-errors./lightsctl.sh qlc-headless
./lightsctl.sh restart./lightsctl.sh doctor
./lightsctl.sh healthSymptoms:
-
lights.localdoesn't resolve - SSH connection fails
- Can't access web UI
Solutions:
./lightsctl.sh scan
./lightsctl.sh checkEnsure WiFi credentials were set correctly during SD card preparation.
Check your router's DHCP leases to find the Pi's IP address, then update PI_HOST in .env.
Symptoms:
- Browser connects but page never loads
- Spinning wheel forever
- Interface unresponsive
Solutions:
./lightsctl.sh ssh
sudo sed -i 's/--operate//' /etc/systemd/system/qlcplus-web.service
sudo systemctl daemon-reload
sudo systemctl restart qlcplus-web./lightsctl.sh restart
./lightsctl.sh healthSymptoms:
- DMX fixtures don't respond
- Scenes don't affect lights
- Everything else works
Solutions:
- Check Universe Output — In QLC+ web UI, go to Inputs/Outputs and ensure universe output is enabled
- Verify ENTTEC Selection — Confirm ENTTEC is selected as the output plugin for the correct universe
- Check DMX Addresses — Verify fixture DMX addresses in QLC+ match their physical DIP switch settings
- Test DMX Output:
./lightsctl.sh test-dmxSymptoms:
- Service is active (
systemctl is-active qlcplus-webreturnsactive) - Browser connects to port 9999 but shows an empty page
- No fixtures, scenes, or virtual console visible
Solutions:
The most common cause is a workspace saved in QLC+ 5.x format on a Pi running 4.14.1:
ssh pi@lights.local "head -10 ~/.qlcplus/default.qxw"If you see <Version>5.x.x</Version>, the workspace needs converting. See
Customization#qlc-workspace-compatibility for the full conversion guide.
QLC+ 4.14.1 ignores symlinks for autostart. Ensure it's a real file:
ssh pi@lights.local "ls -la ~/.qlcplus/autostart.qxw"
# Should be a regular file (-rw-r--r--), NOT a symlink (l→)Fix with:
ssh pi@lights.local "cp ~/.qlcplus/default.qxw ~/.qlcplus/autostart.qxw"
sudo systemctl restart qlcplus-webVerify QLC+ has fixtures loaded in memory:
ssh pi@lights.local "python3 scripts/debug/probe_qlc_ws.py"If getChannelsValues returns zero channels, the workspace didn't load.
Symptoms:
- ENTTEC / FTDI device drops from
/dev/ttyUSB0 - Chauvet D-Fi hub stops blinking
-
dmesgshows repeated connect/disconnect messages
Solutions:
When QLC+ starts and binds the DMX USB output, it uses libftdi which detaches
the kernel ftdi_sio driver. The device disappearing from /dev/ttyUSB* is
expected — QLC+ talks to the chip directly via libusb.
If the device drops randomly (common on Pi 3 with USB power limits), reset the port via sysfs:
# Find the USB path
grep -l 0403 /sys/bus/usb/devices/*/idVendor
# Reset (replace 1-1.2 with your path)
sudo sh -c 'echo 0 > /sys/bus/usb/devices/1-1.2/authorized && sleep 1 && echo 1 > /sys/bus/usb/devices/1-1.2/authorized'The libftdi library needs raw USB access. Add this udev rule:
# /etc/udev/rules.d/98-ftdi-dmx.rules
SUBSYSTEM=="usb", ATTR{idVendor}=="0403", ATTR{idProduct}=="6001", MODE="0666", GROUP="plugdev"Then reload:
sudo udevadm control --reload-rules
sudo udevadm trigger- Report an issue on GitHub
- Join the community on Discord