From 68877a5b20ad64f60be13dc8fe4b067edfb56b71 Mon Sep 17 00:00:00 2001 From: Debian Date: Mon, 16 Mar 2026 20:14:16 +0000 Subject: [PATCH] Add kawa-voice-install.sh - Voice interface for KAWA nodes - Vosk for offline speech recognition (French) - pyttsx3 for text-to-speech - NATS integration for voice commands - Ollama integration for AI responses - Works on Debian/Ubuntu/NixOS --- kawa-voice-install.sh | 224 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 224 insertions(+) create mode 100755 kawa-voice-install.sh diff --git a/kawa-voice-install.sh b/kawa-voice-install.sh new file mode 100755 index 0000000..9f9bcaa --- /dev/null +++ b/kawa-voice-install.sh @@ -0,0 +1,224 @@ +#!/bin/bash +# KAWA Voice - Installation de l'accès vocal +# Pour machines Linux (Debian/Ubuntu/NixOS) + +set -e + +echo "═══════════════════════════════════════════════════════════════" +echo " KAWA Voice - Accès Vocal" +echo "═══════════════════════════════════════════════════════════════" +echo "" + +# Détection du système +if [ -f /etc/NIXOS ]; then + echo "Système: NixOS détecté" + SYSTEM="nixos" +elif [ -f /etc/debian_version ]; then + echo "Système: Debian/Ubuntu détecté" + SYSTEM="debian" +else + echo "Système: Linux générique" + SYSTEM="linux" +fi + +# Installation des dépendances +echo "" +echo "=== Installation des dépendances ===" + +if [ "$SYSTEM" = "debian" ]; then + sudo apt update + sudo apt install -y python3 python3-pip python3-venv \ + portaudio19-dev ffmpeg espeak-ng \ + libportaudio2 libportaudiocpp0 \ + pulseaudio alsa-utils +elif [ "$SYSTEM" = "nixos" ]; then + echo "Pour NixOS, ajoutez à configuration.nix:" + echo ' environment.systemPackages = with pkgs; [' + echo ' python3 python3Packages.pip' + echo ' portaudio ffmpeg espeak-ng' + echo ' pulseaudio alsa-utils' + echo ' ];' + echo ' services.pulseaudio.enable = true;' +fi + +# Création de l'environnement Python +echo "" +echo "=== Environnement Python ===" +python3 -m venv ~/.venv/kawa-voice +source ~/.venv/kawa-voice/bin/activate + +pip install --upgrade pip +pip install vosk pyttsx3 pyaudio requests websocket-client + +# Téléchargement du modèle Vosk (français) +echo "" +echo "=== Téléchargement du modèle Vosk français ===" +mkdir -p ~/.local/share/vosk +cd ~/.local/share/vosk + +if [ ! -d "vosk-model-fr" ]; then + wget -q https://alphacephei.com/vosk/models/vosk-model-fr-0.6-linto-2.2.0.zip + unzip -q vosk-model-fr-0.6-linto-2.2.0.zip + mv vosk-model-fr-0.6-linto-2.2.0 vosk-model-fr + rm vosk-model-fr-0.6-linto-2.2.0.zip + echo "✓ Modèle français téléchargé" +else + echo "✓ Modèle déjà présent" +fi + +# Création du script kawa-voice +echo "" +echo "=== Création de kawa-voice ===" +mkdir -p ~/.local/bin + +cat > ~/.local/bin/kawa-voice << 'KAWA_VOICE' +#!/usr/bin/env python3 +""" +KAWA Voice - Interface vocale pour le réseau KAWA +""" + +import json +import queue +import threading +import requests +import websocket +from vosk import Model, KaldiRecognizer +import pyaudio +import pyttsx3 + +# Configuration +NATS_SERVER = "ws://kawa:kawa123@100.64.0.1:4222" +OLLAMA_SERVER = "http://100.64.0.7:11434" +MODEL_PATH = os.path.expanduser("~/.local/share/vosk/vosk-model-fr") + +class KawaVoice: + def __init__(self): + self.model = Model(MODEL_PATH) + self.recognizer = KaldiRecognizer(self.model, 16000) + self.engine = pyttsx3.init() + self.engine.setProperty('rate', 150) + self.engine.setProperty('voice', 'french') + + # Audio + self.p = pyaudio.PyAudio() + self.stream = self.p.open( + format=pyaudio.paInt16, + channels=1, + rate=16000, + input=True, + frames_per_buffer=8000 + ) + + # NATS + self.ws = None + self.connect_nats() + + def connect_nats(self): + """Connexion au bus NATS KAWA""" + try: + self.ws = websocket.WebSocket() + self.ws.connect("ws://100.64.0.1:4222") + # Subscribe aux commandes vocales + self.ws.send(json.dumps({ + "type": "subscribe", + "topic": "kawa.voice.command" + })) + except Exception as e: + print(f"Erreur NATS: {e}") + + def listen(self): + """Écoute en continue""" + print("🎤 En écoute... (dit 'KAWA' pour activer)") + + while True: + data = self.stream.read(4096) + if self.recognizer.AcceptWaveform(data): + result = json.loads(self.recognizer.Result()) + text = result.get('text', '').lower() + + if 'kawa' in text: + self.engine.say("Oui?") + self.engine.runAndWait() + self.process_command(text.replace('kawa', '').strip()) + + def process_command(self, command): + """Traite une commande vocale""" + print(f"Commande: {command}") + + # Commander NATS + if 'status' in command: + self.ws.send(json.dumps({ + "type": "publish", + "topic": "kawa.voice.command", + "message": {"command": "status"} + })) + response = "Statut envoyé" + + # Interroger Ollama + elif any(word in command for word in ['que', 'quoi', 'comment', 'pourquoi']): + response = self.query_ollama(command) + + else: + response = f"Commande reçue: {command}" + + self.engine.say(response) + self.engine.runAndWait() + + def query_ollama(self, question): + """Interroge Ollama pour une réponse""" + try: + response = requests.post( + f"{OLLAMA_SERVER}/api/generate", + json={ + "model": "glm-4.7-flash:q4_K_M", + "prompt": question, + "stream": False + } + ) + return response.json().get('response', 'Je ne sais pas') + except Exception as e: + return f"Erreur: {str(e)}" + +if __name__ == "__main__": + import os + voice = KawaVoice() + voice.listen() +KAWA_VOICE + +chmod +x ~/.local/bin/kawa-voice + +# Création du service systemd +echo "" +echo "=== Service systemd ===" +mkdir -p ~/.config/systemd/user + +cat > ~/.config/systemd/user/kawa-voice.service << 'SERVICE' +[Unit] +Description=KAWA Voice - Interface vocale +After=network.target pulseaudio.service + +[Service] +Type=simple +ExecStart=/home/%u/.local/bin/kawa-voice +Restart=on-failure +RestartSec=10 + +[Install] +WantedBy=default.target +SERVICE + +echo "" +echo "═══════════════════════════════════════════════════════════════" +echo "✅ KAWA Voice installé!" +echo "═══════════════════════════════════════════════════════════════" +echo "" +echo "Pour démarrer:" +echo " systemctl --user start kawa-voice" +echo "" +echo "Pour activer au démarrage:" +echo " systemctl --user enable kawa-voice" +echo "" +echo "Commandes vocales:" +echo " 'KAWA status' - Statut du réseau" +echo " 'KAWA ' - Interroger Ollama" +echo "═══════════════════════════════════════════════════════════════"