Async FastAPI-based LED matrix controller for Raspberry Pi with a lightweight browser UI, Art-Net/DMX input, and fixture presets. The web app can run from any desktop browser; the render loop runs on the Pi.
- Async render loop with modes:
TEXT_SCROLL,STATIC_TEXT,RAINBOW,NOISE,ARTNET_DIRECT. - Art-Net listener (port 6454) with priority timeout; universe 0 for control, additional universes for pixel passthrough.
- FastAPI REST + WebSocket API, single-page HTML/CSS UI (no frameworks).
- Fixtures with per-fixture state, optional parent sync, and persistence in
config_store.json. - Fixture hardware fields (matrix size, chain length, panel rows/cols, scan rate, RGB order) editable from the browser; Pi rebuilds HUB75 output when fixtures change. Chain length is multiplied by panel_cols for the HUB75 chain length; panel_rows sets parallel outputs.
- Additional hzeller options are exposed per fixture: hardware mapping, pixel mapper config, GPIO slowdown, limit refresh rate, row address type, and multiplex override.
- Browser modal lets you register a remote Pi, save fixtures, set active, and test connectivity directly from Confirm.
python3 -m venv .venv
source .venv/bin/activate
pip install fastapi uvicorn[standard] httpx
# For HUB75 output: install hzeller/rpi-rgb-led-matrix (build from source); the Python binding is picked up automatically.
python main.py
# browse to http://<pi-ip>:8000If you just want to work on the UI without the Pi:
- Open
static/index.htmldirectly (file://) or servestatic(e.g.,cd static && python -m http.server 8080). - The page uses demo fixtures locally; it will not control LEDs until you point a fixture
remote_urlat a Pi API (e.g.,http://<pi-ip>:8000).
main.py– Pi service entrypoint (render loop, Art-Net listener, API).static/index.html– browser UI (usesstatic/style.css), can be served from desktop.config_store.json– generated on first run; stores fixtures, per-fixture state, sync map.ledpi.service– systemd unit example for/home/pi/lighting-controller/main.py.- Requires
rgbmatrix(hzeller/rpi-rgb-led-matrix Python binding) for hardware output; the app will error if it cannot load it.
- Pull From URL: query a remote Pi at the provided URL and register it as a fixture.
- Try Connect: ping the remote URL to check status.
- Set Active: make the selected fixture the one you’re controlling.
- Confirm: run everything in one go—register from URL (if provided), save fixtures, set it active, and run a connectivity check. Any errors are shown in the modal status. In demo/file mode, it just updates the local list.
- Delete: remove the selected fixture.
- Ch1: mode (0=OFF, 1=TEXT_SCROLL, 2=RAINBOW, 3=NOISE, 255=ARTNET_DIRECT)
- Ch2: brightness (0–255)
- Ch3: speed (0–127 maps to 0.1–5.0)
- Ch4–6: text color RGB
- Ch7+: ASCII text
Additional universes feed pixel data for
ARTNET_DIRECT(passthrough). Art-Net activity overrides manual control until timeout (artnet_timeout).
- Install deps:
sudo apt-get install python3-venvthen set up venv andpip install fastapi uvicorn[standard] httpx. - Place code in
/home/pi/lighting-controller. - Adjust
ledpi.servicepaths/user if needed;sudo cp ledpi.service /etc/systemd/system/ && sudo systemctl enable --now ledpi. - HUB75: install hzeller/rpi-rgb-led-matrix; the service will enable
RgbMatrixLedOutputwhenrgbmatrixis importable. If it cannot loadrgbmatrix, the app will error instead of silently using a dummy sink. When you edit fixture hardware settings in the web UI (width/height, chain, panel rows/cols, RGB order, scan), the Pi rebuilds the output for the active fixture on the fly.
- Ensure hat model, pin swaps/jumpers, scan rate, and RGB order match panel config.
- If multiple outputs are needed, map each output as its own fixture; use sync if they should mirror a parent.
- Manual: run
python main.py, open the UI, verify fixture switching/sync, and Art-Net override if available.
MIT. See LICENSE.