Initial commit: HA Voice Control MCP server
This commit is contained in:
@@ -0,0 +1,238 @@
|
||||
# HA Voice Control — MCP Server + Webinterface
|
||||
|
||||
Spraakgestuurde Home Assistant bediening via Whisper voice-to-text.
|
||||
Druk op een knop, spreek je commando, en stuur je smarthome aan.
|
||||
|
||||
## Architectuur
|
||||
|
||||
```
|
||||
┌──────────────┐ ┌──────────────────┐ ┌─────────────────┐
|
||||
│ Browser │────▶│ nginx (SSL) │────▶│ FastAPI │
|
||||
│ (microfoon) │ │ ha.el-kadi.nl │ │ :8765 │
|
||||
└──────────────┘ └──────────────────┘ │ │
|
||||
│ ┌─────────────┐ │
|
||||
┌──────────────┐ │ │ Whisper │ │
|
||||
│ Claude / │──▶ MCP stdio ───────────────▶│ │ (spraak→tekst)│ │
|
||||
│ DeepSeek │ │ └─────────────┘ │
|
||||
└──────────────┘ │ ┌─────────────┐ │
|
||||
│ │ HA REST API │ │
|
||||
│ │ 192.168... │ │
|
||||
│ └─────────────┘ │
|
||||
└──────────────────┘
|
||||
```
|
||||
|
||||
Twee interfaces:
|
||||
1. **Web UI** op `www.ha.el-kadi.nl` — push-to-talk knop in de browser
|
||||
2. **MCP Server** — via Claude Desktop / DeepSeek TUI (stdio)
|
||||
|
||||
Beide gebruiken dezelfde Whisper-transcriptie en Home Assistant client.
|
||||
|
||||
## Vereisten
|
||||
|
||||
- Python 3.10+
|
||||
- Home Assistant met een [long-lived access token](https://www.home-assistant.io/docs/authentication/#your-account-profile)
|
||||
- nginx (voor SSL en domein)
|
||||
- Een domein (hier: `ha.el-kadi.nl`) met DNS die naar jouw server wijst
|
||||
- Optioneel: CUDA-compatibele GPU voor snellere lokale Whisper
|
||||
|
||||
## Installatie
|
||||
|
||||
### 1. Clone en installeer dependencies
|
||||
|
||||
```bash
|
||||
cd /opt # of een andere gewenste locatie
|
||||
git clone <jouw-repo> ha-voice-control
|
||||
cd ha-voice-control
|
||||
python -m venv venv
|
||||
source venv/bin/activate # Windows: venv\Scripts\activate
|
||||
pip install -r requirements.txt
|
||||
```
|
||||
|
||||
### 2. Configuratie
|
||||
|
||||
Kopieer het voorbeeld en vul je gegevens in:
|
||||
|
||||
```bash
|
||||
cp .env.example .env
|
||||
```
|
||||
|
||||
Bewerk `.env`:
|
||||
|
||||
```env
|
||||
# Home Assistant
|
||||
HA_URL=http://192.168.1.235:8123
|
||||
HA_TOKEN=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
|
||||
|
||||
# Whisper: "local" (faster-whisper, offline) of "openai" (API)
|
||||
WHISPER_MODE=local
|
||||
WHISPER_MODEL=base
|
||||
|
||||
# Web server
|
||||
WEB_HOST=127.0.0.1
|
||||
WEB_PORT=8765
|
||||
```
|
||||
|
||||
De Home Assistant token maak je aan via:
|
||||
**Home Assistant → Profiel (linksonder) → Beveiliging → Lange-levensduur toegangstokens**
|
||||
|
||||
### 3. Eerste keer Whisper model downloaden
|
||||
|
||||
Bij de eerste start met `WHISPER_MODE=local` downloadt faster-whisper automatisch het model.
|
||||
Beschikbare modellen (oplopend in grootte/nauwkeurigheid):
|
||||
- `tiny` / `tiny.en` — ~75 MB, snelste
|
||||
- `base` / `base.en` — ~145 MB, aanbevolen voor NL
|
||||
- `small` / `small.en` — ~488 MB
|
||||
- `medium` / `medium.en` — ~1.5 GB
|
||||
- `large-v3` — ~3 GB, meest accuraat
|
||||
|
||||
`.en` varianten zijn alleen voor Engels. Voor Nederlands gebruik je de meertalige versies.
|
||||
|
||||
### 4. Start de web server
|
||||
|
||||
```bash
|
||||
source venv/bin/activate
|
||||
python -m src.web_server
|
||||
# Of direct met uvicorn:
|
||||
uvicorn src.web_server:app --host 127.0.0.1 --port 8765
|
||||
```
|
||||
|
||||
Test of het werkt: `curl http://127.0.0.1:8765/api/health`
|
||||
|
||||
### 5. nginx + SSL configureren
|
||||
|
||||
```bash
|
||||
# Kopieer de nginx config
|
||||
sudo cp nginx/ha.el-kadi.nl.conf /etc/nginx/sites-available/
|
||||
sudo ln -s /etc/nginx/sites-available/ha.el-kadi.nl.conf /etc/nginx/sites-enabled/
|
||||
|
||||
# SSL certificaten met Let's Encrypt (certbot)
|
||||
sudo certbot --nginx -d ha.el-kadi.nl -d www.ha.el-kadi.nl
|
||||
|
||||
# Pas de ssl_certificate paden aan in de config indien nodig
|
||||
# Herlaad nginx
|
||||
sudo nginx -t && sudo systemctl reload nginx
|
||||
```
|
||||
|
||||
### 6. Systemd service (zodat de server automatisch start)
|
||||
|
||||
Maak `/etc/systemd/system/ha-voice-control.service`:
|
||||
|
||||
```ini
|
||||
[Unit]
|
||||
Description=HA Voice Control Web Server
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=www-data
|
||||
WorkingDirectory=/opt/ha-voice-control
|
||||
EnvironmentFile=/opt/ha-voice-control/.env
|
||||
ExecStart=/opt/ha-voice-control/venv/bin/python -m src.web_server
|
||||
Restart=always
|
||||
RestartSec=5
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
```
|
||||
|
||||
```bash
|
||||
sudo systemctl daemon-reload
|
||||
sudo systemctl enable --now ha-voice-control
|
||||
```
|
||||
|
||||
## MCP Server gebruiken
|
||||
|
||||
### Claude Desktop
|
||||
|
||||
Voeg toe aan je `claude_desktop_config.json`:
|
||||
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"ha-voice": {
|
||||
"command": "python",
|
||||
"args": ["-m", "src.mcp_server"],
|
||||
"cwd": "/opt/ha-voice-control",
|
||||
"env": {
|
||||
"HA_TOKEN": "jouw-token-hier",
|
||||
"WHISPER_MODE": "local"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### DeepSeek TUI
|
||||
|
||||
In je `config.toml`:
|
||||
|
||||
```toml
|
||||
[[mcp_servers]]
|
||||
name = "ha-voice"
|
||||
command = "python"
|
||||
args = ["-m", "src.mcp_server"]
|
||||
cwd = "/opt/ha-voice-control"
|
||||
env = { HA_TOKEN = "jouw-token-hier", WHISPER_MODE = "local" }
|
||||
```
|
||||
|
||||
### Beschikbare MCP tools
|
||||
|
||||
| Tool | Beschrijving |
|
||||
|------|-------------|
|
||||
| `speak_command` | Base64 audio → transcribeer → voer uit via HA |
|
||||
| `transcribe_audio` | Alleen transcriberen, geen actie |
|
||||
| `send_text_command` | Stuur tekst naar HA conversation agent |
|
||||
| `list_lights` | Toon alle lampen en hun status |
|
||||
| `control_light` | Zet een lamp aan/uit/toggle met helderheid |
|
||||
| `list_all_entities` | Toon alle HA entities |
|
||||
| `get_entity_state` | State van één entity opvragen |
|
||||
| `call_ha_service` | Roep een willekeurige HA service aan |
|
||||
|
||||
## API endpoints (web server)
|
||||
|
||||
| Methode | Pad | Beschrijving |
|
||||
|---------|-----|-------------|
|
||||
| `GET` | `/api/health` | Health check |
|
||||
| `POST` | `/api/transcribe` | Upload audio (multipart), krijg transcriptie + HA resultaat |
|
||||
| `POST` | `/api/command` | `{"text": "doe de lampen uit"}` → HA |
|
||||
| `GET` | `/api/lights` | Alle lampen met status |
|
||||
| `POST` | `/api/light/control` | `{"entity_id": "...", "action": "turn_on"}` |
|
||||
| `GET` | `/api/entities?domain=light` | Entities (optioneel gefilterd) |
|
||||
| `GET` | `/api/entity/{entity_id}` | Volledige state van één entity |
|
||||
| `POST` | `/api/service` | `{"domain": "light", "service": "turn_on", "entity_id": "..."}` |
|
||||
|
||||
## Gebruik
|
||||
|
||||
1. Open `https://www.ha.el-kadi.nl` in je browser (Chrome/Edge/Safari op desktop of mobiel)
|
||||
2. Geef de browser toestemming voor de microfoon
|
||||
3. Houd de microfoonknop ingedrukt en spreek je commando:
|
||||
- "Doe de lampen in de woonkamer aan"
|
||||
- "Zet alle lichten uit"
|
||||
- "Dim de slaapkamer naar 50 procent"
|
||||
4. Laat de knop los — je commando wordt getranscribeerd en uitgevoerd
|
||||
5. Je ziet het resultaat verschijnen
|
||||
|
||||
De lampen onderaan de pagina kun je ook direct met de toggle-schakelaars bedienen.
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
**"Microfoon niet beschikbaar"**
|
||||
- De site moet via HTTPS geladen worden (browsers vereisen dit voor `getUserMedia`)
|
||||
- Controleer of nginx SSL correct is ingesteld
|
||||
- Lokaal testen op `localhost` werkt ook zonder HTTPS
|
||||
|
||||
**Transcriptie werkt niet / foutmelding**
|
||||
- Check of `faster-whisper` correct is geïnstalleerd: `pip list | grep faster`
|
||||
- Controleer de logs: `journalctl -u ha-voice-control -f`
|
||||
- Bij Open AI-modus: check of `OPENAI_API_KEY` is ingesteld
|
||||
- Het model wordt de eerste keer gedownload; dit kan even duren
|
||||
|
||||
**"Fout bij uitvoeren" / Home Assistant niet bereikbaar**
|
||||
- Controleer of `HA_URL` klopt en bereikbaar is vanaf de server
|
||||
- Verifieer de token: `curl -H "Authorization: Bearer $HA_TOKEN" $HA_URL/api/`
|
||||
- Check of de conversation agent in HA is ingeschakeld (Standaard is `conversation` integratie actief)
|
||||
|
||||
**Audio wordt niet goed herkend**
|
||||
- Gebruik een groter Whisper-model (`small` of `medium`) voor betere NL herkenning
|
||||
- Spreek duidelijk en dicht bij de microfoon
|
||||
- Verminder achtergrondgeluid
|
||||
Reference in New Issue
Block a user