2026-05-10 12:46:33 +02:00
2026-05-10 12:46:33 +02:00
2026-05-10 12:46:33 +02:00
2026-05-10 12:46:33 +02:00
2026-05-10 12:46:33 +02:00
2026-05-10 12:46:33 +02:00
2026-05-10 12:46:33 +02:00
2026-05-10 12:46:33 +02:00
2026-05-10 12:46:33 +02:00
2026-05-10 12:46:33 +02:00
2026-05-10 12:46:33 +02:00
2026-05-10 12:46:33 +02:00
2026-05-10 12:46:33 +02:00
2026-05-10 12:46:33 +02:00

Custom Streamdeck Button Prototype

This project is now a local Stream Deck-style control app for the 10-button Pico prototype.

The Pico firmware still prints the same USB serial JSON events. The new backend consumes those events, stores configuration in SQLite, executes actions, loads backend plugins, and serves the built React UI.

Button Wiring

Button order is the order you gave:

  1. GP28
  2. GP27
  3. GP26
  4. GP22
  5. GP21
  6. GP20
  7. GP18
  8. GP19
  9. GP17
  10. GP16

The other leg of every button goes to GND. The Pico script uses internal pull-ups, so a pressed button reads as LOW.

Files

  • pico/main.py: MicroPython code that runs on the Pico and prints button events over USB serial.
  • pc/listen_buttons.py: PC listener that reads serial events and appends them to button_log.txt.
  • backend/: FastAPI backend, WebSocket events, SQLite state, action engine, app discovery, plugin loading.
  • frontend/: React + Vite + Tailwind UI.
  • plugins/: Backend Python plugins. Each plugin exposes a top-level PLUGIN object.

Run The App

Install Python dependencies:

python -m pip install -r requirements.txt

Install and build the UI:

cd frontend
npm install
npm run build
cd ..

Start the backend and open http://127.0.0.1:8000/:

python -m uvicorn backend.main:app --host 127.0.0.1 --port 8000

For frontend dev mode, run the backend above and then:

cd frontend
npm run dev

Legacy Listener

python .\pc\listen_buttons.py

If auto-detect fails:

python .\pc\listen_buttons.py --port COM5

Plugin Shape

Backend plugins live in plugins/ and expose PLUGIN.

class MyPlugin:
    name = "My Plugin"
    desc = "Does a thing"
    actions = [
        {
            "id": "do_thing",
            "name": "Do Thing",
            "fields": [{"id": "value", "label": "Value", "type": "text"}],
        }
    ]

    def on_load(self, ctx):
        pass

    def on_event(self, ctx, event):
        pass

    def execute_action(self, ctx, action_id, config, event):
        pass

PLUGIN = MyPlugin()
Description
No description provided
Readme 510 KiB
Languages
Python 58.5%
TypeScript 32%
CSS 5.8%
PowerShell 2.9%
HTML 0.6%
Other 0.2%