Asistente de IA 100% privado con visión y voz usando SenseCAP Watcher + servidor local Python + OpenAI GPT-4o.
- Resumen
- Arquitectura
- Requisitos
- Instalación Rápida
- Configuración Actual
- Funcionalidades Implementadas
- Comandos de Flasheo
- Archivos Modificados
- API Keys y Secretos
- Troubleshooting
Este proyecto convierte un SenseCAP Watcher 1A en un asistente de IA que:
- Escucha comandos de voz en español
- Responde con TTS en español (voz Elvira)
- Ve a través de su cámara y describe imágenes
- Busca información en tiempo real en la web
- Retroalimentación sonora inmediata (beeps, "Te escucho")
| Componente | Tecnología | Proveedor |
|---|---|---|
| LLM | GPT-4o-mini | OpenAI |
| Vision (VLLM) | GPT-4o | OpenAI |
| ASR (Voz→Texto) | Whisper | OpenAI |
| TTS (Texto→Voz) | EdgeTTS | Microsoft (es-ES-ElviraNeural) |
| Web Search | Tavily API | Tavily |
| Firmware | XiaoZhi ESP32 | Personalizado |
┌─────────────────────┐ ┌─────────────────────────────────────┐
│ SenseCAP Watcher │ WiFi │ Servidor Local │
│ (ESP32-S3) │◄───────►│ (minis.local / 192.168.0.65) │
│ │ │ │
│ • Micrófono │ │ xiaozhi-server (Python) │
│ • Cámara 2MP │ │ ├── ASR: OpenAI Whisper │
│ • Parlante │ │ ├── LLM: GPT-4o-mini │
│ • Pantalla LCD │ │ ├── TTS: EdgeTTS (español) │
│ • Botón (knob) │ │ ├── VLLM: GPT-4o (visión) │
└─────────────────────┘ │ └── Web Search: Tavily │
└─────────────────────────────────────┘
- Usuario habla → Micrófono captura audio
- Audio enviado → WebSocket al servidor (ws://192.168.0.65:8000)
- ASR (Whisper) → Convierte audio a texto
- LLM (GPT-4o-mini) → Procesa texto y genera respuesta
- TTS (EdgeTTS) → Convierte respuesta a audio español
- Audio devuelto → Parlante del Watcher reproduce
- SenseCAP Watcher 1A (ESP32-S3 + Himax AI)
- Servidor: PC con Python 3.10+ (probado en Ubuntu 24.04)
- Red WiFi 2.4GHz (5GHz no soportado por ESP32)
# Dependencias del sistema
sudo apt install python3 python3-pip python3-venv ffmpeg
# ESP-IDF 5.5.2 (para compilar firmware)
# Ver: https://docs.espressif.com/projects/esp-idf/en/latest/esp32s3/get-started/git clone https://github.com/TU_USUARIO/esp32-local-llm-assistant.git
cd esp32-local-llm-assistantpython3 -m venv venv
source venv/bin/activate
pip install -r server-bridge/main/xiaozhi-server/requirements.txtEditar server-bridge/main/xiaozhi-server/data/.config.yaml:
# Ver sección "API Keys y Secretos" para los valorescd server-bridge/main/xiaozhi-server
python app.py# Ver sección "Comandos de Flasheo"server:
ip: 0.0.0.0
port: 8000
websocket: ws://192.168.0.65:8000/xiaozhi/v1/
vision_explain: http://192.168.0.65:8003/mcp/vision/explain
selected_module:
VAD: SileroVAD
ASR: OpenaiASR
LLM: OpenAILLM
TTS: EdgeTTS
VLLM: OpenAIVLLM
ASR:
OpenaiASR:
type: openai
api_key: sk-proj-XXXXXXX # Tu API Key de OpenAI
base_url: https://api.openai.com/v1/audio/transcriptions
model_name: whisper-1
output_dir: tmp/
enable_asr_start_notify: true
asr_start_notify_voice: "config/assets/tts_notify.mp3"
LLM:
OpenAILLM:
type: openai
model_name: gpt-4o-mini
api_key: sk-proj-XXXXXXX # Tu API Key de OpenAI
base_url: https://api.openai.com/v1
TTS:
EdgeTTS:
type: edge
voice: es-ES-ElviraNeural # Voz española femenina
VLLM:
OpenAIVLLM:
type: openai
model_name: gpt-4o
api_key: sk-proj-XXXXXXX # Tu API Key de OpenAI
base_url: https://api.openai.com/v1
prompt: |
Eres un asistente de IA amable llamado Watcher.
Respondes siempre en español de forma muy breve (1-2 oraciones máximo).
Tienes una cámara. Cuando te pregunten "¿Qué ves?", usa la herramienta `self.camera.take_photo`.
También puedes buscar información en la web usando la herramienta `web_search`.
Intent:
function_call:
functions:
- change_role
- get_weather
- get_news_from_newsnow
- play_music
- web_search# Idioma: Español
CONFIG_LANGUAGE_ES_ES=y
# Board: SenseCAP Watcher
CONFIG_BOARD_TYPE_SEEED_STUDIO_SENSECAP_WATCHER=y
# OTA URL (servidor local)
CONFIG_OTA_URL="http://192.168.0.65:8003/xiaozhi/ota/"Cuando el usuario presiona el botón para hablar, el Watcher dice "Te escucho" antes de comenzar a escuchar.
Archivos modificados:
firmware-src/main/assets/locales/es-ES/listening.ogg(audio generado con EdgeTTS)firmware-src/main/assets/lang_config.h(registro del nuevo sonido)firmware-src/main/application.cc(SetListeningModereproduce el audio)
Cuando el usuario deja de hablar, suena un beep para indicar que se está procesando.
Configuración:
ASR:
enable_asr_start_notify: true
asr_start_notify_voice: "config/assets/tts_notify.mp3"Al hacer doble clic en el knob del Watcher:
- 📸 Captura foto de la cámara
- 🔔 Suena beep de "obturador"
- 🔁 Beeps cada segundo mientras espera respuesta
- 🗣️ Habla la descripción de la imagen (GPT-4o Vision)
- 👂 Queda escuchando para preguntas adicionales sobre la foto
Archivos modificados:
firmware-src/main/boards/sensecap-watcher/sensecap_watcher.cc(handler de doble clic)firmware-src/main/protocols/protocol.cc(nuevo métodoSendSpeak)firmware-src/main/application.cc(nuevo métodoApplication::SendSpeak)server-bridge/main/xiaozhi-server/core/handle/textHandler/speakMessageHandler.py(nuevo handler)
El asistente puede buscar información actual en internet usando Tavily API.
Ejemplo de uso:
- "¿Cuál es el precio del dólar hoy?"
- "¿Qué noticias hay de México?"
Archivo:
server-bridge/main/xiaozhi-server/plugins_func/functions/web_search.py
Cuando el usuario pregunta "¿Qué ves?", el asistente:
- Toma una foto con la cámara
- Envía al endpoint de visión
- GPT-4o describe la imagen en español
- TTS habla la descripción
Archivo modificado:
server-bridge/main/xiaozhi-server/core/providers/vllm/openai.py(respuesta en español)
- Mantener presionado BOOT
- Presionar y soltar RESET
- Soltar BOOT
- El LED debería parpadear indicando modo download
ls /dev/ttyACM*
# Usualmente: /dev/ttyACM0 o /dev/ttyACM1source ~/esp/esp-idf/export.sh
cd firmware-src
idf.py build# ~43 segundos de flasheo
sudo ~/.espressif/python_env/idf5.5_py3.12_env/bin/python -m esptool \
--chip esp32s3 \
-p /dev/ttyACM1 \
-b 460800 \
--before default_reset \
--after hard_reset \
write_flash \
--flash_mode dio \
--flash_size 16MB \
--flash_freq 80m \
0x20000 build/xiaozhi.bin| Velocidad | Tiempo | Estabilidad |
|---|---|---|
| 115200 | ~155s | ✅ Muy estable |
| 230400 | ~78s | ✅ Estable |
| 460800 | ~43s | ✅ Recomendada |
| 921600 | - | ❌ Falla conexión |
python -m esptool --chip esp32s3 -b 460800 \
--before default_reset --after hard_reset \
write_flash --flash_mode dio --flash_size 16MB --flash_freq 80m \
0x0 build/bootloader/bootloader.bin \
0x8000 build/partition_table/partition-table.bin \
0xd000 build/ota_data_initial.bin \
0x20000 build/xiaozhi.bin \
0x800000 build/generated_assets.bin| Archivo | Descripción |
|---|---|
main/boards/sensecap-watcher/sensecap_watcher.cc |
Handler doble clic para cámara |
main/application.cc |
Método SendSpeak(), sonido "Te escucho" |
main/application.h |
Declaración SendSpeak() |
main/protocols/protocol.cc |
Implementación SendSpeak() |
main/protocols/protocol.h |
Declaración SendSpeak() |
main/assets/lang_config.h |
Registro sonido OGG_LISTENING |
main/assets/locales/es-ES/listening.ogg |
Audio "Te escucho" |
build/sdkconfig |
Idioma español, board type, OTA URL |
| Archivo | Descripción |
|---|---|
data/.config.yaml |
Configuración principal (API keys, módulos) |
core/handle/textMessageType.py |
Nuevo tipo SPEAK |
core/handle/textHandler/speakMessageHandler.py |
Handler para TTS directo |
core/handle/textMessageHandlerRegistry.py |
Registro del handler SPEAK |
core/providers/vllm/openai.py |
Respuestas de visión en español |
plugins_func/functions/web_search.py |
Búsqueda web con Tavily |
Ubicación: server-bridge/main/xiaozhi-server/data/.config.yaml
api_key: sk-proj-XXXXXXXXXUsado para: ASR (Whisper), LLM (GPT-4o-mini), VLLM (GPT-4o)
Ubicación: server-bridge/main/xiaozhi-server/plugins_func/functions/web_search.py
TAVILY_API_KEY = "tvly-dev-XXXXXXXXX"Usado para: Búsqueda web en tiempo real
Ubicación: server-bridge/main/xiaozhi-server/data/.config.yaml
websocket: ws://192.168.0.65:8000/xiaozhi/v1/
vision_explain: http://192.168.0.65:8003/mcp/vision/explain- Verificar que es red 2.4GHz (no 5GHz)
- Contraseña correcta
- Reiniciar el Watcher
- Asegurar modo bootloader (BOOT + RESET)
- Probar otro puerto USB
- Reducir velocidad a 115200
# Verificar dependencias
pip install -r requirements.txt
# Ver logs
tail -f /tmp/xiaozhi-server.log- Verificar
CONFIG_LANGUAGE_ES_ES=yen sdkconfig - Verificar
voice: es-ES-ElviraNeuralen config.yaml
- ASR local (Vosk) es lento → usar OpenAI Whisper
- LLM local (Ollama) es lento → usar OpenAI GPT-4o-mini
MIT License - Ver LICENSE
- Seeed Studio: Hardware SenseCAP Watcher
- XiaoZhi Team: Firmware base ESP32
- OpenAI: GPT-4o, Whisper
- Microsoft: EdgeTTS
- Tavily: API de búsqueda web