#!/usr/bin/env bash # # Path: quick_start_hey_mycroft.sh # # Purpose and usage: # Zero-training quick start using pre-trained "Hey Mycroft" model # Gets you a working voice assistant in 5 minutes! # # Requirements: # - Heimdall already setup (ran setup_voice_assistant.sh) # - Mycroft Precise installed (ran setup_precise.sh) # # Usage: # ./quick_start_hey_mycroft.sh [--test-only] # # Author: PRbL Library # ----- PRbL Color and output functions ----- RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[0;33m' BLUE='\033[0;34m' PURPLE='\033[0;35m' CYAN='\033[0;36m' NC='\033[0m' print_status() { local level="$1" shift case "$level" in "info") echo -e "${BLUE}[INFO]${NC} $*" >&2 ;; "success") echo -e "${GREEN}[SUCCESS]${NC} $*" >&2 ;; "warning") echo -e "${YELLOW}[WARNING]${NC} $*" >&2 ;; "error") echo -e "${RED}[ERROR]${NC} $*" >&2 ;; *) echo -e "$*" >&2 ;; esac } # ----- Configuration ----- MODELS_DIR="$HOME/precise-models/pretrained" MODEL_URL="https://github.com/MycroftAI/precise-data/raw/models-dev/hey-mycroft.tar.gz" MODEL_NAME="hey-mycroft" TEST_ONLY=false # ----- Parse arguments ----- parse_args() { while [[ $# -gt 0 ]]; do case "$1" in --test-only) TEST_ONLY=true shift ;; -h|--help) cat << EOF Usage: $(basename "$0") [OPTIONS] Quick start with pre-trained "Hey Mycroft" wake word model. No training required! Options: --test-only Just test the model, don't start server -h, --help Show this help Examples: $(basename "$0") # Download, test, and run server $(basename "$0") --test-only # Just download and test EOF exit 0 ;; *) print_status error "Unknown option: $1" exit 1 ;; esac done } # ----- Functions ----- check_prerequisites() { print_status info "Checking prerequisites..." # Check conda if ! command -v conda &> /dev/null; then print_status error "conda not found" return 1 fi # Check precise environment if ! conda env list | grep -q "^precise\s"; then print_status error "Precise environment not found" print_status info "Run: ./setup_precise.sh first" return 1 fi # Check voice-assistant directory if [[ ! -d "$HOME/voice-assistant" ]]; then print_status error "Voice assistant not setup" print_status info "Run: ./setup_voice_assistant.sh first" return 1 fi print_status success "Prerequisites OK" return 0 } download_pretrained_model() { print_status info "Downloading pre-trained 'Hey Mycroft' model..." # Create directory mkdir -p "$MODELS_DIR" # Check if already downloaded if [[ -f "$MODELS_DIR/${MODEL_NAME}.net" ]]; then print_status info "Model already downloaded" return 0 fi # Download cd "$MODELS_DIR" || return 1 print_status info "Fetching from GitHub..." wget -q --show-progress "$MODEL_URL" || { print_status error "Failed to download model" return 1 } # Extract print_status info "Extracting model..." tar xzf hey-mycroft.tar.gz || { print_status error "Failed to extract model" return 1 } # Verify if [[ ! -f "${MODEL_NAME}.net" ]]; then print_status error "Model file not found after extraction" return 1 fi print_status success "Model downloaded: $MODELS_DIR/${MODEL_NAME}.net" return 0 } test_model() { print_status info "Testing wake word model..." cd "$MODELS_DIR" || return 1 # Activate conda eval "$(conda shell.bash hook)" conda activate precise || { print_status error "Failed to activate precise environment" return 1 } cat << EOF ${CYAN}═══════════════════════════════════════════════════${NC} ${CYAN} Wake Word Test: "Hey Mycroft"${NC} ${CYAN}═══════════════════════════════════════════════════${NC} ${YELLOW}Instructions:${NC} 1. Speak "Hey Mycroft" into your microphone 2. You should see ${GREEN}"!"${NC} when detected 3. Try other phrases - should ${RED}not${NC} trigger 4. Press ${RED}Ctrl+C${NC} when done testing ${CYAN}Starting in 3 seconds...${NC} EOF sleep 3 # Test the model precise-listen "${MODEL_NAME}.net" || { print_status error "Model test failed" return 1 } print_status success "Model test complete!" return 0 } update_config() { print_status info "Updating voice assistant configuration..." local config_file="$HOME/voice-assistant/config/.env" if [[ ! -f "$config_file" ]]; then print_status error "Config file not found: $config_file" return 1 fi # Update PRECISE_MODEL if exists, otherwise add it if grep -q "^PRECISE_MODEL=" "$config_file"; then sed -i "s|^PRECISE_MODEL=.*|PRECISE_MODEL=$MODELS_DIR/${MODEL_NAME}.net|" "$config_file" else echo "PRECISE_MODEL=$MODELS_DIR/${MODEL_NAME}.net" >> "$config_file" fi # Update sensitivity if not set if ! grep -q "^PRECISE_SENSITIVITY=" "$config_file"; then echo "PRECISE_SENSITIVITY=0.5" >> "$config_file" fi print_status success "Configuration updated" return 0 } start_server() { print_status info "Starting voice assistant server..." cd "$HOME/voice-assistant" || return 1 # Activate conda eval "$(conda shell.bash hook)" conda activate precise || { print_status error "Failed to activate environment" return 1 } cat << EOF ${CYAN}═══════════════════════════════════════════════════${NC} ${GREEN} Starting Voice Assistant Server${NC} ${CYAN}═══════════════════════════════════════════════════${NC} ${YELLOW}Configuration:${NC} Wake word: ${GREEN}Hey Mycroft${NC} Model: ${MODEL_NAME}.net Server: http://0.0.0.0:5000 ${YELLOW}What to do next:${NC} 1. Wait for "Precise listening started" message 2. Say ${GREEN}"Hey Mycroft"${NC} to test wake word 3. Say a command like ${GREEN}"turn on the lights"${NC} 4. Check server logs for activity ${YELLOW}Press Ctrl+C to stop the server${NC} ${CYAN}Starting server...${NC} EOF # Check if HA token is set if ! grep -q "^HA_TOKEN=..*" config/.env; then print_status warning "Home Assistant token not set!" print_status warning "Commands won't execute without it." print_status info "Edit config/.env and add your HA token" echo read -p "Continue anyway? (y/N): " -n 1 -r echo if [[ ! $REPLY =~ ^[Yy]$ ]]; then return 1 fi fi # Start server python voice_server.py \ --enable-precise \ --precise-model "$MODELS_DIR/${MODEL_NAME}.net" \ --precise-sensitivity 0.5 return $? } create_systemd_service() { print_status info "Creating systemd service..." local service_file="/etc/systemd/system/voice-assistant.service" # Check if we should update existing service if [[ -f "$service_file" ]]; then print_status warning "Service file already exists" read -p "Update with Hey Mycroft configuration? (y/N): " -n 1 -r echo if [[ ! $REPLY =~ ^[Yy]$ ]]; then return 0 fi fi # Create service file sudo tee "$service_file" > /dev/null << EOF [Unit] Description=Voice Assistant with Hey Mycroft Wake Word After=network.target [Service] Type=simple User=$USER WorkingDirectory=$HOME/voice-assistant Environment="PATH=$HOME/miniconda3/envs/precise/bin:/usr/local/bin:/usr/bin:/bin" EnvironmentFile=$HOME/voice-assistant/config/.env ExecStart=$HOME/miniconda3/envs/precise/bin/python voice_server.py \\ --enable-precise \\ --precise-model $MODELS_DIR/${MODEL_NAME}.net \\ --precise-sensitivity 0.5 Restart=on-failure RestartSec=10 StandardOutput=append:$HOME/voice-assistant/logs/voice_assistant.log StandardError=append:$HOME/voice-assistant/logs/voice_assistant_error.log [Install] WantedBy=multi-user.target EOF # Reload systemd sudo systemctl daemon-reload print_status success "Systemd service created" cat << EOF ${CYAN}To enable and start the service:${NC} sudo systemctl enable voice-assistant sudo systemctl start voice-assistant sudo systemctl status voice-assistant ${CYAN}To view logs:${NC} journalctl -u voice-assistant -f EOF read -p "Enable service now? (y/N): " -n 1 -r echo if [[ $REPLY =~ ^[Yy]$ ]]; then sudo systemctl enable voice-assistant sudo systemctl start voice-assistant sleep 2 sudo systemctl status voice-assistant fi } print_next_steps() { cat << EOF ${GREEN}═══════════════════════════════════════════════════${NC} ${GREEN} Success! Your voice assistant is ready!${NC} ${GREEN}═══════════════════════════════════════════════════${NC} ${CYAN}What you have:${NC} ✓ Pre-trained "Hey Mycroft" wake word ✓ Voice assistant server configured ✓ Ready to control Home Assistant ${CYAN}Quick test:${NC} 1. Say: ${GREEN}"Hey Mycroft"${NC} 2. Say: ${GREEN}"Turn on the living room lights"${NC} 3. Check if command executed ${CYAN}Next steps:${NC} 1. ${YELLOW}Configure Home Assistant entities${NC} Edit: ~/voice-assistant/config/.env Add: HA_TOKEN=your_token_here 2. ${YELLOW}Add more entity mappings${NC} Edit: voice_server.py Update: IntentParser.ENTITY_MAP 3. ${YELLOW}Fine-tune for your voice (optional)${NC} cd ~/precise-models/hey-mycroft-custom ./1-record-wake-word.sh # Record 20-30 samples precise-train -e 30 hey-mycroft-custom.net . \\ --from-checkpoint $MODELS_DIR/${MODEL_NAME}.net 4. ${YELLOW}Setup Maix Duino${NC} See: QUICKSTART.md Phase 2 ${CYAN}Useful commands:${NC} # Test wake word only cd $MODELS_DIR && conda activate precise precise-listen ${MODEL_NAME}.net # Check server health curl http://localhost:5000/health # Monitor logs journalctl -u voice-assistant -f ${CYAN}Documentation:${NC} README.md - Project overview WAKE_WORD_ADVANCED.md - Multiple wake words guide QUICKSTART.md - Complete setup guide ${GREEN}Happy voice assisting! 🎙️${NC} EOF } # ----- Main ----- main() { cat << EOF ${CYAN}═══════════════════════════════════════════════════${NC} ${CYAN} Quick Start: Hey Mycroft Wake Word${NC} ${CYAN}═══════════════════════════════════════════════════${NC} ${YELLOW}This script will:${NC} 1. Download pre-trained "Hey Mycroft" model 2. Test wake word detection 3. Configure voice assistant server 4. Start the server (optional) ${YELLOW}Total time: ~5 minutes (no training!)${NC} EOF # Parse arguments parse_args "$@" # Check prerequisites check_prerequisites || exit 1 # Download model download_pretrained_model || exit 1 # Test model print_status info "Ready to test wake word" read -p "Test now? (Y/n): " -n 1 -r echo if [[ ! $REPLY =~ ^[Nn]$ ]]; then test_model fi # If test-only mode, stop here if [[ "$TEST_ONLY" == "true" ]]; then print_status success "Test complete!" print_status info "Model location: $MODELS_DIR/${MODEL_NAME}.net" exit 0 fi # Update configuration update_config || exit 1 # Start server read -p "Start voice assistant server now? (Y/n): " -n 1 -r echo if [[ ! $REPLY =~ ^[Nn]$ ]]; then start_server else # Offer to create systemd service read -p "Create systemd service instead? (y/N): " -n 1 -r echo if [[ $REPLY =~ ^[Yy]$ ]]; then create_systemd_service fi fi # Print next steps print_next_steps } # Run main main "$@"