Skip to content

Repository files navigation

UCE Hub

UCE is a self-hosted, real-time lighting and show-control platform for studios and small venues. UCE Hub is its main application: a Rust runtime that drives DMX in real time over the network, a REST + WebSocket API, SQLite persistence, and a Vue 3 web interface for patching, scenes, floorplans, and system management.

The Hub is modular. Domain features are maintained in separate repositories (uce-light, uce-resolume) and injected into the Hub at build time, so the core stays small while capabilities are added as modules.

Features

  • Networked DMX output over Art-Net and sACN (E1.31), with configurable output nodes, discovery, and per-node routing.
  • Real-time runtime driven by a dedicated actor loop (40 Hz / 25 ms tick) designed to stay responsive under bursts of user commands and high-frequency DMX updates.
  • Live control over WebSocket — the frontend streams light values (with optional fades) to the backend and receives dmx_update frames back; DMX payloads are serialized once at the source and broadcast to all clients.
  • Fixture library backed by the public Open Fixture Library — browse the catalog, download OFL profiles, and manage a local fixture set. No account or API key required.
  • Scenes & gradients — save, apply, import, and export scenes and gradient scenes.
  • Floorplan & patching — visual floorplan (dots/beams), soft-patch editing, rooms, and a live patch visualizer.
  • Zigbee lighting via Zigbee2MQTT — device discovery, pairing, renaming, capability sync, and color/gradient commands.
  • Elgato Key Light control — discovery and command of Elgato devices on the LAN.
  • Resolume integration — connect to Resolume, fetch compositions, detect screens, and send commands (runs as a standalone sidecar backend, see below).
  • Import / export of DMX config, scenes, floorplans, full projects, and backups.
  • System management — service status/control, log access, update check/apply/rollback, DMX interface configuration, local domain settings, and reboot.
  • Persistence in SQLite, with optional HTTP Basic auth for the API and token auth for the WebSocket.

Architecture

UCE Hub is the host application. It owns the runtime, the API router, persistence, networking, and the web shell, and it composes modules directly into its own build:

  • Backend (core/) — the Hub compiles module source into its own crate using Rust #[path] module declarations that point at modules/uce-light/core/src/... and, where relevant, the Resolume module. UCE Light (DMX/MQTT/library/scenes/floorplan/Elgato) is statically linked into the Hub this way. UCE Resolume's backend instead runs as a separate sidecar binary that the Hub launches and proxies to at runtime.
  • Frontend (web/) — before dev/build, a bootstrap step copies each module's web/src into web/modules/<module>/src, which Vite exposes through path aliases (@uce-light, @uce-resolume, @hub). Module Vue components are therefore imported and bundled as part of the single-page app.

Because the modules are injected rather than published as packages, you must fetch them into modules/ before building (see Build & Run). A missing UCE Light checkout will fail the build early with a clear message.

uce-hub/
├─ core/           Rust backend (Axum + Tokio runtime, API, persistence, DMX)
├─ web/            Vue 3 frontend (Vite, Pinia, TypeScript)
├─ modules/        Injected module checkouts (uce-light, uce-resolume)
├─ scripts/        Module bootstrap scripts
├─ docs/           Additional documentation
├─ LICENSE
└─ README.md
Path Description
core/src/main.rs Bootstrap; declares injected UCE Light modules via #[path]
core/src/routes.rs REST + WebSocket router composition
core/src/state.rs Runtime actor, command channel, frame fetch, broadcast
core/src/network.rs Art-Net / sACN output
core/src/module_runtime.rs Resolume sidecar lifecycle and proxy target
core/src/handlers/ HTTP/WebSocket handlers (Hub + injected module handlers)
web/src/ Vue app shell, stores, floorplan, patch UI
web/scripts/ensure-light-module.mjs Copies module web/src into the build

Tech Stack

  • Backend: Rust (edition 2024), Tokio async runtime, Axum 0.7 (HTTP + WebSocket), tower-http, SQLx + SQLite, redb, artnet_protocol, sacn, rumqttc (MQTT/Zigbee2MQTT), reqwest, parking_lot, clap.
  • Frontend: Vue 3 (<script setup> Composition API), Pinia, TypeScript, Vite, ESLint.

Build & Run

Prerequisites

  • Rust toolchain (stable) with Cargo
  • Node.js (18+; CI uses 20/22) and npm

1. Bootstrap the modules

The Hub needs the UCE Light and UCE Resolume sources under modules/ before it can build. Run from the repo root:

# Linux / macOS
./scripts/bootstrap-light-module.sh
./scripts/bootstrap-resolume-module.sh

# Windows PowerShell
./scripts/bootstrap-light-module.ps1
./scripts/bootstrap-resolume-module.ps1

These scripts sync from a local sibling checkout if present, otherwise clone from the module repositories.

2. Backend

cd core
cargo run              # dev run
cargo build --release  # release binary (target/release/uce-hub-core)

By default the backend serves the API and WebSocket on http://localhost:3000.

3. Frontend

cd web
npm install
npm run dev            # Vite dev server on http://localhost:5173
npm run build          # type-check + production build into web/dist

The dev, build, and lint npm scripts automatically run the module-injection step, so make sure step 1 has been completed first.

Checks

# Backend
cd core && cargo fmt -- --check && cargo clippy -- -D warnings && cargo test

# Frontend
cd web && npm run lint && npm run build

Configuration

Configuration is persisted in SQLite (not a runtime JSON file):

  • Default DB: OS app-data directory (com/uce/uce-hub/uce-hub.db), fallback data/uce-hub.db
  • UCE_DB_PATH — override the database path

Useful environment variables:

  • UCE_FRONTEND_PATH — static frontend directory served by the backend
  • UCE_API_AUTH — API credentials as username:password (HTTP Basic auth)
  • UCE_RUNTIME_PERSIST_MS / UCE_RUNTIME_DEBOUNCE_MS — runtime snapshot persistence tuning
  • UCE_DEV_MODE — enable DEV mode (1/true/on) for simulated features

WebSocket auth accepts a token via Sec-WebSocket-Protocol (uce-hub-auth.<token>), with a ?token=... query fallback.

Fixtures

Fixture profiles come from the Open Fixture Library, a public, open-data project. The Hub enumerates the OFL catalog and downloads profiles as raw OFL JSON directly from GitHub — no license key or account is needed. Downloaded profiles are cached in your local fixture library and can be managed from the UI.

Updates

Releases are published to GitHub Releases. Tagging hub-v* builds an OTA package (release binary + web/dist) with a SHA-256 checksum and publishes it as a GitHub release. Modules ship on their own tags (light-v*, resolume-v*): the Resolume sidecar updates independently, while the statically linked UCE Light backend ships with the Hub. Frontend-only module changes can be released via their module tags.

Contributing

Contributions are welcome. Please open an issue to discuss substantial changes first, keep the CI checks green (cargo fmt/clippy/test and npm run lint/build), and note that all contributions are accepted under the project's license. See docs/ for additional developer notes.

License

This project is distributed under the GNU General Public License, version 3 or later (GPL-3.0-or-later). See the LICENSE file for the full text.

Copyright (C) 2026 Maxime Deprince

About

Self-hosted, real-time DMX lighting and show-control platform. Rust runtime (Art-Net, sACN, Zigbee2MQTT) with a Vue 3 interface for patching, scenes, floorplans and system management. Modular architecture.

Topics

Resources

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages