Files
kawa/kawa-voice-install.sh
Debian 46d9c852ab Security: Replace hardcoded passwords with placeholders
- Replace kawa:kawa123@100.64.0.1:4222 with NATS placeholders
- Replace initialPassword 'kawa2026' with <INITIAL_PASSWORD>
- Update README with password placeholders
- Add security notes for default credentials

Safe for public release.
2026-03-17 02:00:37 +00:00

225 lines
7.0 KiB
Bash
Executable File

#!/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://<NATS_USER>:<NATS_PASSWORD>@<NATS_SERVER>"
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 <question>' - Interroger Ollama"
echo "═══════════════════════════════════════════════════════════════"