101 lines
2.1 KiB
Markdown
101 lines
2.1 KiB
Markdown
# 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()
|
|
```
|