# 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: ```powershell python -m pip install -r requirements.txt ``` Install and build the UI: ```powershell cd frontend npm install npm run build cd .. ``` Start the backend and open `http://127.0.0.1:8000/`: ```powershell python -m uvicorn backend.main:app --host 127.0.0.1 --port 8000 ``` For frontend dev mode, run the backend above and then: ```powershell cd frontend npm run dev ``` ## Legacy Listener ```powershell python .\pc\listen_buttons.py ``` If auto-detect fails: ```powershell python .\pc\listen_buttons.py --port COM5 ``` ## Plugin Shape Backend plugins live in `plugins/` and expose `PLUGIN`. ```python 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() ```