Autonomous DJ rotation system for Raspberry Pi. Cycles between DJ sets (countdown timer) and shuffle tracks (random pre-recorded audio), controlling audio faders, lighting, and a display.
Two-state machine: IDLE -> DJ_SET <-> SHUFFLE
app.py— Main controller (ShuffleParty), state machine, coordinates all subsystemsmixer.py— Behringer XR12 fader control via OSC (non-blocking crossfades)lighting.py— QLC+ lighting scene control via OSCdisplay.py— Countdown timer logic (pygame rendering separate)track_picker.py— Random track selection fromtracks/directory, no repeats until all playedbuttons.py— reTerminal front-panel button input via evdev (non-blocking, graceful no-op on non-Linux)config.py— Environment-variable-based configuration with defaults
- Python 3.12+, managed with
uv pygame-cefor audio/displaypython-oscfor QLC+ lightingxair-apifor Behringer XR12 mixermutagenfor audio metadataevdevfor reTerminal button input (Linux only)
uv run pytest # run tests
uv run ruff check # lint
uv run mypy src/ # type check (strict mode)- Ruff for linting (line-length 100, rules: E/F/I/N/W/UP)
- mypy strict mode enabled
- Hardware dependencies (XR12, QLC+) degrade gracefully when unreachable
- Tests mock all hardware; use
pytest(not unittest runner)
- Commit after every logically complete unit of work without asking permission
- Only
git addfiles you actually modified — never stage files changed by the user, linters, or other processes (use explicit file paths, nevergit add -Aorgit add .)