A configurator and controller for Elgato Stream Deck devices.
Find a file
SBDeveloper 3000c44b84
All checks were successful
Build / build-linux (push) Successful in 1m10s
Cloud improvements
2026-04-11 14:20:44 +02:00
.forgejo/workflows Fixed build 2026-04-09 21:47:03 +02:00
streamdeck_controller Cloud improvements 2026-04-11 14:20:44 +02:00
.gitignore Small improvement 2026-04-08 21:50:48 +02:00
.pre-commit-config.yaml Cleanup of the UI and some new features 2026-04-09 21:36:16 +02:00
app.py Cleanup of the UI and some new features 2026-04-09 21:36:16 +02:00
CLAUDE.md Prepared cloud management and small fixes 2026-04-11 10:49:03 +02:00
CONTRIBUTING.md Implemented plugin system 2026-04-10 19:38:57 +02:00
icon.ico Repo cleanup, improved install / uninstall steps 2026-04-08 20:18:49 +02:00
icon.png Allow display in tray and start from boot 2026-04-03 12:36:26 +02:00
install.py Cleanup of the UI and some new features 2026-04-09 21:36:16 +02:00
pyproject.toml Prepared cloud management and small fixes 2026-04-11 10:49:03 +02:00
README.md Implemented plugin system 2026-04-10 19:38:57 +02:00
streamdeck.spec Fixed build 2026-04-09 21:47:03 +02:00
uninstall.py Cleanup of the UI and some new features 2026-04-09 21:36:16 +02:00
uv.lock Prepared cloud management and small fixes 2026-04-11 10:49:03 +02:00

Stream Deck Controller

A configurator and controller for Elgato Stream Deck devices, written in Python.

Platform

Supported devices

Device Keys Layout
Stream Deck Original V2 15 5×3
Stream Deck MK.2 15 5×3
Stream Deck XL 32 8×4
Stream Deck Mini 6 3×2
Stream Deck + 8 4×2

Features

  • 6 always-on core plugins + 7 optional built-in plugins covering media, home automation, shortcuts, and system tools
  • Plugin Manager — enable/disable optional plugins and install external .py plugins without touching source code
  • Multi-page layouts with tab or button navigation
  • Undo/redo, import/export (.sdc), and live button preview
  • Icon picker, custom backgrounds, and multi-key actions
  • Multi-device support
  • Credentials stored in the OS keychain
  • System tray with close-to-tray, start-on-boot, and start-minimized options
  • Automatic updates on startup

Getting started

Prerequisites

Windows

Install the WinUSB driver with Zadig. This is a one-time setup per machine:

  1. Open Zadig and select Options → List All Devices
  2. Select your Stream Deck
  3. Choose WinUSB and click Install Driver

Once WinUSB is installed, Elgato's own software can no longer see the device. To revert, uninstall the WinUSB device in Device Manager and Windows will reinstall the HID driver automatically.

Linux

# USB access
sudo apt install libusb-1.0-0

# Tray icon (GNOME / Wayland)
sudo apt install python3-gobject python3-gi gir1.2-ayatanaappindicator3-0.1

# Media controls (Audio plugin)
sudo apt install playerctl

# Keyboard hotkeys on Wayland — ydotool injects at the kernel level (recommended)
sudo apt install ydotool
sudo usermod -aG input $USER   # log out and back in after this
systemctl --user enable --now ydotoold

# Keyboard hotkeys on X11 / XWayland only — lighter alternative
sudo apt install xdotool

Install

Windows

  1. Download the latest StreamDeckController.zip from the Releases page
  2. Extract it anywhere and run StreamDeckController.exe

The setup wizard opens on first launch.

Linux

  1. Download the latest StreamDeckController-linux.tar.gz from the Releases page
  2. Extract and run:
tar -xzf StreamDeckController-linux.tar.gz
cd StreamDeckController
./StreamDeckController

The setup wizard opens on first launch and installs the udev USB rule automatically.

Using the app

The configurator window opens and registers in the system tray. If no deck is connected, the app retries every few seconds — buttons can be configured offline.

Closing the window sends the app to the tray. To quit fully, right-click the tray icon and select Quit.

Keyboard shortcuts:

Shortcut Action
Ctrl+Z Undo
Ctrl+Y Redo
Ctrl+S Save config
Ctrl+N New page
Ctrl+E Export layout
Ctrl+I Import layout
Delete Clear selected

Configuration

Settings are stored in:

  • Windows: %LOCALAPPDATA%\streamdeck-controller\config.json
  • Linux: ~/.config/streamdeck-controller/config.json

App Settings

Open Settings → App Settings to configure:

Setting Description
Brightness Deck display brightness (10100%)
Close to tray Minimize to the system tray instead of quitting when the window closes
Start on boot Launch automatically on login
Start minimized Start with the window hidden in the tray

Plugins

Plugin Manager

Open Settings → Manage Plugins to control which plugins are active.

Tier Description
Core Always active — Navigation, Shell, Keyboard, Audio, Launcher, Clipboard
Optional Bundled with the app, enabled/disabled via Plugin Manager
External Your own .py files, installed via "Install from file…"

Changes take effect immediately without a restart.

To install an external plugin, click + Install from file… and pick your .py file. The app validates it, copies it to the plugins directory, and makes it available straight away.

External plugins directory:

  • Windows: %LOCALAPPDATA%\streamdeck-controller\plugins
  • Linux: ~/.config/streamdeck-controller/plugins

Open Settings → Plugin Settings to enter credentials where required.

Spotify

Requires a Spotify developer app. Set client_id and client_secret, and use http://127.0.0.1:8888/callback as the redirect URI.

Action Description
Play / Pause Toggle playback
Previous Skip to the previous track
Next Skip to the next track
Album Cover Display current album art across a configurable group of keys

Home Assistant

Requires the instance URL and a long-lived access token.

Action Description
Toggle Entity Toggle any light, switch, or entity. Button shows green when on, grey when off.
Sensor Display Live sensor value (temperature, humidity, etc.). Unit comes from HA but can be overridden. Polls every 10 s.
Activate Scene Trigger a scene on press (e.g. scene.gaming).

OBS Studio

Requires OBS 28+ with obs-websocket v5 (Tools → WebSocket Server Settings). Set host, port (default 4455), and password. Reconnects automatically when OBS is unavailable.

Action Description
Start / Stop Recording Toggle recording. Button turns red while recording.
Start / Stop Streaming Toggle stream. Button turns green while live.
Switch Scene Jump to a named scene on press.
Toggle Source Mute Mute or unmute a named audio source. Shows live mute state.

Navigation

Action Description
Go To Page Jump directly to another configured page
Go Back Return to the previous page

Shell

Uses cmd /c on Windows and bash -c on Linux.

Action Description
Run Command Execute any command on press. Green on success, red on failure. Optional toggle command for two-state buttons.

Dynamic variables, expanded at press time:

Variable Expands to
{time} Current time (HH:MM)
{date} Current date
{datetime} Date and time
{hostname} Machine hostname
{user} Current username

Enable Show output to display the last line of stdout on the button itself.

Keyboard

Action Description
Send Hotkey Send a key combination (e.g. ctrl+shift+t, super+l, f5). Green on success, red on failure.
Type Text Type a string as if entered on a keyboard.

Modifier names: ctrl, shift, alt, super / win / cmd. On Wayland, ydotool is required (see Prerequisites).

Clipboard

Action Description
Paste Text Type text via keyboard simulation
Copy to Clipboard Copy a fixed string to the clipboard

Launcher

Action Description
Open URL Open any URL in the default browser. Green on success, red on failure.
Launch App Launch any application or command.

Audio

Volume and mute use Windows Core Audio (pycaw) on Windows and pactl (PulseAudio / PipeWire) on Linux. Media transport uses Win32 media keys on Windows and playerctl on Linux.

Action Description
Volume Up Increase master volume by 5%. Shows current level.
Volume Down Decrease master volume by 5%. Shows current level.
Mute Toggle Toggle mute. Shows current mute state.
Volume Display Read-only volume and mute display. Press to toggle mute.
Media Play/Pause Play or pause the active media player.
Media Next Skip to the next track.
Media Previous Skip to the previous track.

Pomodoro

The timer is shared across all Pomodoro buttons on a page.

Action Description
Start / Pause Live countdown (25 min work, 5 min break). Red during work, blue during break, gold flash on phase end.
Reset Reset to 25:00.

Countdown

Each button has its own independent timer.

Action Description
Countdown Timer Configurable duration, label, and optional shell command on completion. Press to start, pause, or reset. Flashes gold when done.

System Stats

Action Description
CPU Usage Live CPU %. Green below 50%, yellow 5080%, red above 80%.
RAM Usage Live RAM %. Same color coding.
Disk Usage Disk usage % for a configured mount point or drive. Updates every 10 s.

Weather

No credentials required. Configure city name and temperature unit.

Action Description
Current Weather Icon, temperature, and city name. Refreshes every 10 minutes.

Development

See CONTRIBUTING.md for the full setup guide, plugin development walkthrough, and PR process.

Quick start

git clone <repo>
cd StreamDeckController

# Linux: create a venv with system-site-packages so PyGObject is available
uv venv --system-site-packages
uv sync

# Run
uv run streamdeck-controller

On Windows, a plain uv sync is sufficient (no --system-site-packages needed).

Project layout

StreamDeckController/
├── streamdeck_controller/
│   ├── __main__.py            # entry point
│   ├── config_io.py           # config load / save / validation
│   ├── credentials.py         # OS keychain helpers (keyring)
│   ├── deck_runner.py         # Stream Deck polling & rendering loop
│   ├── plugin_loader.py       # plugin discovery & loading (core / optional / external)
│   ├── logging_setup.py       # centralized logging (file + stderr)
│   ├── pyusb_transport.py     # custom PyUSB HID transport
│   ├── _build.py              # PyInstaller build helper
│   ├── plugins/               # action plugins (one file per plugin)
│   │   ├── base.py            # BasePlugin / BaseAction API
│   │   ├── _template.py       # annotated plugin skeleton
│   │   └── *.py               # built-in plugins
│   └── ui/
│       ├── app.py             # main window
│       ├── plugin_manager.py  # Manage Plugins dialog
│       ├── action_editor.py   # button assignment dialog
│       ├── deck_grid.py       # visual deck grid widget
│       ├── icon_picker.py     # emoji / symbol picker
│       ├── plugin_settings_dialog.py
│       ├── app_settings_dialog.py
│       └── setup_wizard.py    # first-run wizard
├── pyproject.toml
└── streamdeck.spec            # PyInstaller spec

Building a release

uv run streamdeck-build

Produces a self-contained dist/StreamDeckController/ folder requiring neither Python nor uv on the target machine. Zip it and publish as a release.

Linting and formatting

uv run ruff format .
uv run ruff check .
uv run mypy streamdeck_controller

Writing a plugin

See CONTRIBUTING.md for a full walkthrough.

Quick start:

  1. Copy streamdeck_controller/plugins/_template.py anywhere on your system and fill in the TODOs
  2. Open Settings → Manage Plugins → + Install from file… and select your .py file
  3. The plugin is installed, enabled, and available immediately

To contribute a plugin back to the project, see the contributing guide.