- Shell 100%
| README.md | ||
| setup.sh | ||
Pi HID Mouse & Keyboard (Web-controlled)
Steuere eine USB-Maus und USB-Tastatur (HID) über einen Raspberry Pi Zero 2 W – bequem via Weboberfläche oder REST-API aus deinem Netzwerk.
Der Pi meldet sich am Host (z. B. Windows) als Composite USB-Device (Maus + Tastatur) an.
Die Web-App bietet Buttons, Trackpad-Feld, Tippen/Key-Events und eine minimalistische API.
✨ Features
- Dual-Maus:
/dev/hidg0→ 3-Byte Boot-Mouse (max. Kompatibilität)/dev/hidg1→ 4-Byte Maus mit Scrollrad (Web-API)
- Tastatur:
/dev/hidg2→ Boot-Keyboard (8-Byte Report)
- Web-UI (AJAX, kein Seitenreload): bewegen, klicken, scrollen, Typing, Key press/release
- REST-API für Maus & Tastatur (siehe unten)
- Autostart & Autorestart via systemd
- Robuster Boot: wartet auf USB Device Controller (UDC), bind-retry
- Ohne root nutzbar (udev-Regel → Gruppe
input)
🧰 Hardware & Voraussetzungen
- Raspberry Pi Zero 2 W
- Raspberry Pi OS Bookworm Lite (32-bit)
- USB-OTG Datenkabel (Micro-USB ↔ USB-A/C)
- Anschluss am USB-OTG-Port “USB” des Pi (nicht „PWR IN“!)
Stromversorgung entweder separat über „PWR IN“ oder Bus-Power über den OTG-Port (je nach Setup/Kabel).
🚀 Quick Start (One-Go Wizard)
- Skript speichern und ausführen:
nano setup.sh # Inhalt aus diesem Repo einfügen
chmod +x setup.sh
sudo ./setup.sh
-
Pi per USB-OTG (Datenkabel) an den Host anschließen (Port USB, nicht PWR IN).
-
Web-UI öffnen:
http://<PI-IP>:5000
(z. B. http://raspberrypi.local:5000 oder http://192.168.1.23:5000)
🗂️ Was das Script einrichtet
- Kernel-Overlay:
dwc2,dr_mode=peripheral configfsMount in/sys/kernel/config- udev-Regel:
/dev/hidg*→ Gruppeinput(0660) - USB Gadget (Composite):
- HID Maus (3B, 4B+Wheel)
- HID Tastatur (Boot)
- Dienste (systemd):
hid-mouse.service– erstellt/bindet Gadget, robustes UDC-Waitmouse-web.service– Web-API + UI (wartet auf/dev/hidg1&/dev/hidg2)
🌐 Web-UI
- Bewegen (Trackpad-Feld & Buttons)
- Klicks (links/rechts/mittig), Scrollrad
- Tastatur: Text tippen, Key Tap, Key Press/Release
🧩 API (Kurz-Doku)
Base URL: http://<PI-IP>:5000
Antwort: 204 No Content (bei Erfolg, leerer Body)
Wertebereiche: Deltas ∈ −127..127
Button-Maske: 1=Left, 2=Right, 4=Middle (kombinierbar)
Maus
POST /api/move{ "x": 20, "y": -10 }POST /api/scroll{ "w": 3 }POST /api/click{ "b": 1 }POST /api/button{ "b": 1, "action": "down" } // oder "up"POST /api/press→ nur drücken{ "b": 1 }POST /api/release→ alles loslassen{}
Tastatur
POST /api/kbd/tap– Taste tippen{ "key": "ENTER" }POST /api/kbd/press– Taste halten{ "key": "A" }POST /api/kbd/release– alle Tasten loslassen{}POST /api/kbd/type– Text tippen (US-Layout){ "text": "Hello World!", "delay": 0.01 }
Hinweis Layout: Mapping ist US-ANSI. Das Host-Layout (Windows/macOS/Linux) wendet seine Regeln auf die HID Usage Codes an. Ein DE-Mapping (ä/ö/ü/ß etc.) kann leicht ergänzt werden.
🧪 Beispiele
curl
# Maus: 50 rechts, 20 runter
curl -X POST -H "Content-Type: application/json" \
-d '{"x":50,"y":20}' http://<PI-IP>:5000/api/move
# Linksklick
curl -X POST -H "Content-Type: application/json" \
-d '{"b":1}' http://<PI-IP>:5000/api/click
# Drag & Drop: press → moves → release
curl -X POST -H "Content-Type: application/json" \
-d '{"b":1,"action":"down"}' http://<PI-IP>:5000/api/button
curl -X POST -H "Content-Type: application/json" \
-d '{"x":120,"y":-30}' http://<PI-IP>:5000/api/move
curl -X POST -H "Content-Type: application/json" \
-d '{"b":1,"action":"up"}' http://<PI-IP>:5000/api/button
# Tastatur: ENTER tippen
curl -X POST -H "Content-Type: application/json" \
-d '{"key":"ENTER"}' http://<PI-IP>:5000/api/kbd/tap
# Tastatur: "Hello" tippen
curl -X POST -H "Content-Type: application/json" \
-d '{"text":"Hello"}' http://<PI-IP>:5000/api/kbd/type
Python (Client-Snippet)
import requests
BASE = "http://<PI-IP>:5000"
def post(path, data):
r = requests.post(BASE + path, json=data, timeout=2)
r.raise_for_status()
post("/api/move", {"x": 40, "y": 0})
post("/api/click", {"b": 1})
post("/api/kbd/tap", {"key": "ENTER"})
post("/api/kbd/type", {"text": "Hello World!", "delay": 0.01})
🔧 Betrieb & Services
- Status prüfen:
systemctl status hid-mouse.service --no-pager systemctl status mouse-web.service --no-pager - Logs:
journalctl -u hid-mouse.service -b --no-pager journalctl -u mouse-web.service -b --no-pager - Nach Code-Änderungen:
sudo systemctl restart mouse-web.service
🩺 Troubleshooting
- Web nicht erreichbar: Lauscht etwas auf Port 5000?
ss -lntp | grep :5000 || echo "kein Prozess auf :5000" - Keine Aktion am Host:
- OTG-Kabel am USB-Port (nicht PWR IN)?
- UDC-Status:
ls /sys/class/udc cat /sys/class/udc/$(ls /sys/class/udc)/state - Geräte vorhanden:
ls -l /dev/hidg0 /dev/hidg1 /dev/hidg2
- Windows „zickt“:
- Im Geräte-Manager unter dem USB-Hub die „HID-kompatible Maus/Tastatur“ entfernen, USB neu anstecken.
- Berechtigungen:
- Nutzer ist in Gruppe
input?
id→ sollteinputenthalten. - udev-Regel vorhanden:
/etc/udev/rules.d/99-hidg.rules
- Nutzer ist in Gruppe
🔒 Sicherheit
- API ist im LAN standardmäßig offen (ohne Auth).
Empfehlung:- Netz segmentieren (nur vertrauenswürdiges LAN), oder
- Simple Bearer-Token-Prüfung in Flask ergänzen (Header
Authorization: Bearer <TOKEN>), - Optional: Reverse Proxy (nginx) mit Basic-Auth / mTLS.
⚠️ Rechtliches / VID/PID
- Beispiel-VID/PID (Logitech) dienen ausschließlich der Kompatibilität in Tests.
Für Produkte oder umfangreichere Verteilung verwende eigene IDs oder die Standard-Linux-Gadget-IDs.