Dateien nach "/" hochladen
This commit is contained in:
1 parent
17b034e8f6
commit
debc2a0bc8
5 files changed
+141
No files matched your search
@@ -0,0 +1,28 @@
|
|||||||
|
# Generate token: openssl rand -hex 32
|
||||||
|
API_TOKEN=CHANGE_ME_LONG_RANDOM_TOKEN
|
||||||
|
|
||||||
|
HOST=0.0.0.0
|
||||||
|
PORT=8090
|
||||||
|
|
||||||
|
# MQTT – same host/port as your openHAB Mosquitto
|
||||||
|
MQTT_HOST=192.168.178.60
|
||||||
|
MQTT_PORT=1884
|
||||||
|
MQTT_USERNAME=
|
||||||
|
MQTT_PASSWORD=
|
||||||
|
MQTT_TLS=false
|
||||||
|
MQTT_PREFIX=openhab/ai_bridge
|
||||||
|
|
||||||
|
DB_PATH=/data/bridge.db
|
||||||
|
MAX_HISTORY_MESSAGES=16
|
||||||
|
SESSION_TTL_SECONDS=7200
|
||||||
|
MAX_SESSIONS=20
|
||||||
|
LOG_LEVEL=INFO
|
||||||
|
|
||||||
|
# Pi speaker (ALSA)
|
||||||
|
ALSA_PLAYBACK_DEVICE=default
|
||||||
|
AUDIO_GID=29
|
||||||
|
|
||||||
|
# Free Edge TTS (German)
|
||||||
|
TTS_VOICE=de-DE-ConradNeural
|
||||||
|
TTS_RATE=+0%
|
||||||
|
TTS_VOLUME=+0%
|
||||||
+14
@@ -0,0 +1,14 @@
|
|||||||
|
FROM python:3.12-slim-bookworm
|
||||||
|
ENV PYTHONDONTWRITEBYTECODE=1 PYTHONUNBUFFERED=1 PIP_NO_CACHE_DIR=1
|
||||||
|
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||||
|
alsa-utils libasound2 ffmpeg libatomic1 \
|
||||||
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
RUN useradd --create-home --uid 10001 --shell /usr/sbin/nologin bridge
|
||||||
|
WORKDIR /app
|
||||||
|
COPY requirements.txt .
|
||||||
|
RUN pip install -r requirements.txt
|
||||||
|
COPY app ./app
|
||||||
|
RUN mkdir -p /data /data/audio && chown -R bridge:bridge /app /data
|
||||||
|
USER bridge
|
||||||
|
EXPOSE 8090
|
||||||
|
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8090"]
|
||||||
@@ -0,0 +1,62 @@
|
|||||||
|
# openHAB AI Bridge – Simple (Text + Claude + Edge TTS)
|
||||||
|
|
||||||
|
Kostenlose KI-Anbindung über **Ask Claude** (iOS Shortcut), ohne API-Key.
|
||||||
|
|
||||||
|
## Ablauf
|
||||||
|
|
||||||
|
```
|
||||||
|
openHAB Textfeld
|
||||||
|
→ Bridge (Session + Kontext in SQLite)
|
||||||
|
→ MQTT notify
|
||||||
|
→ openHAB Cloud Push ans iPhone
|
||||||
|
→ Shortcut: Ask Claude
|
||||||
|
→ Antwort zurück an Bridge
|
||||||
|
→ Edge TTS → Lautsprecher am Pi
|
||||||
|
```
|
||||||
|
|
||||||
|
Rückfragen nutzen denselben Session-Kontext (Standard: 2 Stunden).
|
||||||
|
|
||||||
|
## Schnellstart (Raspberry Pi)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd ~/openhab-ai-bridge-simple
|
||||||
|
cp .env.example .env
|
||||||
|
openssl rand -hex 32 # → in .env als API_TOKEN eintragen
|
||||||
|
getent group audio | cut -d: -f3 # → AUDIO_GID setzen
|
||||||
|
|
||||||
|
docker compose build
|
||||||
|
docker compose up -d
|
||||||
|
curl http://127.0.0.1:8090/health
|
||||||
|
```
|
||||||
|
|
||||||
|
## openHAB
|
||||||
|
|
||||||
|
1. Thing + Items aus `openhab/` übernehmen (Broker-UID anpassen).
|
||||||
|
2. JS-Regel aus `openhab/ai_bridge.rules.js` (Token + IP eintragen).
|
||||||
|
3. Regel „AI Bridge Notify → Push“ sendet die Cloud-Notification.
|
||||||
|
|
||||||
|
## iOS Shortcut
|
||||||
|
|
||||||
|
1. Trigger: openHAB-Notification mit Text `KI_DIALOG`
|
||||||
|
2. GET `http://PI:8090/api/v1/active` (Header: `Authorization: Bearer TOKEN`)
|
||||||
|
3. GET `/api/v1/sessions/{session_id}/context`
|
||||||
|
4. Prompt aus Messages bauen → **Ask Claude**
|
||||||
|
5. POST `/api/v1/sessions/{session_id}/answer` `{"content":"..."}`
|
||||||
|
6. POST `/api/v1/audio/speak` `{"text":"..."}` (Pi spricht)
|
||||||
|
|
||||||
|
## API (alle außer /health brauchen Bearer-Token)
|
||||||
|
|
||||||
|
| Methode | Pfad | Zweck |
|
||||||
|
|---------|------|--------|
|
||||||
|
| POST | /api/v1/dialog | Frage aus openHAB |
|
||||||
|
| GET | /api/v1/active | Aktive Session |
|
||||||
|
| GET | /api/v1/sessions/{id}/context | Gesprächsverlauf |
|
||||||
|
| POST | /api/v1/sessions/{id}/answer | Claude-Antwort speichern |
|
||||||
|
| POST | /api/v1/audio/speak | Edge TTS abspielen |
|
||||||
|
| POST | /api/v1/sessions/{id}/end | Session beenden |
|
||||||
|
|
||||||
|
## Sicherheit
|
||||||
|
|
||||||
|
- Nur LAN, Port 8090 nicht nach außen freigeben
|
||||||
|
- Langer zufälliger API_TOKEN
|
||||||
|
- Docker: non-root, read-only root, dropped capabilities
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
services:
|
||||||
|
openhab-ai-bridge:
|
||||||
|
build: .
|
||||||
|
container_name: openhab-ai-bridge
|
||||||
|
restart: unless-stopped
|
||||||
|
env_file: .env
|
||||||
|
ports:
|
||||||
|
- "8090:8090"
|
||||||
|
volumes:
|
||||||
|
- ./data:/data
|
||||||
|
devices:
|
||||||
|
- /dev/snd:/dev/snd
|
||||||
|
group_add:
|
||||||
|
- "${AUDIO_GID:-29}"
|
||||||
|
read_only: true
|
||||||
|
tmpfs:
|
||||||
|
- /tmp:size=32m,noexec,nosuid,nodev
|
||||||
|
security_opt:
|
||||||
|
- no-new-privileges:true
|
||||||
|
cap_drop:
|
||||||
|
- ALL
|
||||||
|
healthcheck:
|
||||||
|
test:
|
||||||
|
[
|
||||||
|
"CMD",
|
||||||
|
"python",
|
||||||
|
"-c",
|
||||||
|
"import urllib.request; urllib.request.urlopen('http://127.0.0.1:8090/health',timeout=2).read()",
|
||||||
|
]
|
||||||
|
interval: 30s
|
||||||
|
timeout: 5s
|
||||||
|
retries: 3
|
||||||
|
start_period: 10s
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
fastapi==0.116.1
|
||||||
|
uvicorn[standard]==0.35.0
|
||||||
|
paho-mqtt==2.1.0
|
||||||
|
edge-tts==7.2.7
|
||||||
Reference in new issue
Block a user