Files
smart-speaker/README.md
2026-04-09 21:03:02 +03:00

15 KiB
Raw Permalink Blame History

Alexander Smart Speaker

Голосовой ассистент для Linux: wake word, STT/TTS, AI-диалог и полезные голосовые навыки.

Python 3.9+ Linux MIT License Wake Word STT TTS

Что это

Alexander Smart Speaker слушает ключевое слово Waltron, распознает речь, маршрутизирует команду в нужный модуль и озвучивает ответ. Проект оптимизирован под русский язык, но поддерживает RU/EN сценарии (включая перевод и mixed-language TTS).

Проект собран как локальная голосовая колонка под Linux: активация по wake word, распознавание речи, маршрутизация команд, ответ через AI или встроенные модули и затем озвучка результата.

Возможности

  • Активация по wake word Waltron (Porcupine).
  • Follow-up окно 4 секунды после ответа: если пользователь молчит, ассистент возвращается к ожиданию wake word.
  • Распознавание речи через Deepgram (WebSocket, VAD, fast stop).
  • Озвучка через Silero TTS (RU + EN, с прерыванием по wake word).
  • AI-диалог через OpenRouter, OpenAI, Gemini, Z.ai и Anthropic Claude API со streaming-ответом и контекстом.
  • Перевод RU -> EN и EN -> RU.
  • Погода: текущий прогноз по городу по умолчанию или по названию города.
  • Таймеры, будильники (включая будни/выходные), секундомеры.
  • Управление громкостью системы (через pactl/amixer).
  • Управление музыкой через Navidrome (приоритет) с fallback на Spotify.
  • Persistent resume: пауза/продолжи продолжают с сохранённой позиции даже после перезапуска колонки.
  • Мини-игра "Города".

Как это работает

flowchart TD
    A[Wake Word: Waltron] --> B[STT: Deepgram]
    B --> C{Маршрутизация команды}
    C --> D[Feature modules]
    C --> E[AI/Translation]
    D --> F[TTS: Silero]
    E --> F
    F --> G[Follow-up режим или ожидание wake word]

Что важно в этой реализации

  • Контекст диалога хранится в памяти текущей сессии, поэтому после первого вопроса можно продолжать разговор без потери нити.
  • Системная роль ассистента и ROLE_JSON сохраняются для всех поддерживаемых AI-провайдеров.
  • Для AI используется строго один активный API key. Если в .env оставить несколько ключей, ассистент покажет ошибку конфигурации вместо случайного выбора.
  • Поддержка провайдеров сделана внутри одного модуля, но с разным форматом запросов для OpenAI-compatible API и Anthropic.
  • Локальные модели через Ollama поддерживаются без API key (через OpenAI-compatible endpoint).

Быстрый старт

1) Системные зависимости (Ubuntu/Debian)

sudo apt-get update
sudo apt-get install -y portaudio19-dev libasound2-dev mpg123 mpv pulseaudio-utils alsa-utils

2) Установка Python-зависимостей

git clone https://gitea.futuree.ru/future/alexander_smart-speaker.git
cd alexander_smart-speaker
python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt

3) Настройка .env

cp .env.example .env

Минимально обязательные переменные:

AI_PROVIDER=            # опционально; можно оставить пустым
# Раскомментируйте только один AI API KEY:
# OPENROUTER_API_KEY=...
# OPENAI_API_KEY=...
# GEMINI_API_KEY=...
# ZAI_API_KEY=...
# ANTHROPIC_API_KEY=...
DEEPGRAM_API_KEY=...
PORCUPINE_ACCESS_KEY=...

Если одновременно оставить несколько AI API key, ассистент вернет ошибку: он не будет выбирать провайдера наугад.

Пример:

# правильно
OPENAI_API_KEY=sk-...
# GEMINI_API_KEY=...
# ANTHROPIC_API_KEY=...

# неправильно
OPENAI_API_KEY=sk-...
GEMINI_API_KEY=AIza...

4) Запуск

make run
# или
python run.py

После запуска ассистент перейдет в режим ожидания фразы Waltron.

Кросс-платформенный аудио режим

  • Приложение автоматически подбирает рабочий микрофон/динамик через PortAudio.
  • Если основное аудио-устройство не подходит, включается fallback по другим устройствам и sample rate.
  • При проблемах можно явно задать устройство через .env (AUDIO_*_DEVICE_NAME или AUDIO_*_DEVICE_INDEX).

Конфигурация .env

Переменная Обязательно По умолчанию Назначение
AI_PROVIDER Нет openrouter Опциональный провайдер AI (openrouter, openai, gemini, zai, anthropic, ollama; также понимает claude)
OPENROUTER_API_KEY Да* - Ключ OpenRouter API (*если выбран OpenRouter и только этот AI ключ активен)
OPENROUTER_MODEL Нет openai/gpt-4o-mini Модель OpenRouter
OPENROUTER_API_URL Нет https://openrouter.ai/api/v1/chat/completions Endpoint OpenRouter Chat Completions
OPENAI_API_KEY Да* - Ключ OpenAI API (*если выбран OpenAI и только этот AI ключ активен)
OPENAI_MODEL Нет gpt-4o-mini Модель OpenAI
OPENAI_API_URL Нет https://api.openai.com/v1/chat/completions Endpoint OpenAI Chat Completions
GEMINI_API_KEY Да* - Ключ Google Gemini API (*если выбран Gemini и только этот AI ключ активен)
GEMINI_MODEL Нет gemini-2.5-flash Модель Gemini
GEMINI_API_URL Нет https://generativelanguage.googleapis.com/v1beta/openai/chat/completions OpenAI-compatible endpoint Gemini
ZAI_API_KEY Да* - Ключ Z.ai API (*если выбран Z.ai и только этот AI ключ активен)
ZAI_MODEL Нет glm-5 Модель Z.ai
ZAI_API_URL Нет https://api.z.ai/api/paas/v4/chat/completions Endpoint Z.ai Chat Completions
ANTHROPIC_API_KEY Да* - Ключ Anthropic API (*если выбран Anthropic и только этот AI ключ активен)
ANTHROPIC_MODEL Нет claude-sonnet-4-20250514 Модель Claude
ANTHROPIC_API_URL Нет https://api.anthropic.com/v1/messages Endpoint Anthropic Messages API
ANTHROPIC_API_VERSION Нет 2023-06-01 Версия Anthropic API
OLLAMA_MODEL Нет llama3.1:8b Модель Ollama (локально)
OLLAMA_API_URL Нет http://localhost:11434/v1/chat/completions OpenAI-compatible endpoint Ollama
DEEPGRAM_API_KEY Да - Ключ Deepgram STT
PORCUPINE_ACCESS_KEY Да - Ключ PicoVoice Porcupine
PORCUPINE_SENSITIVITY Нет 0.8 Чувствительность wake word
AUDIO_INPUT_DEVICE_NAME Нет auto Подстрока имени микрофона (например pulse), если нужно выбрать конкретный input device
AUDIO_INPUT_DEVICE_INDEX Нет auto Индекс PortAudio для микрофона (приоритетнее AUDIO_INPUT_DEVICE_NAME)
AUDIO_OUTPUT_DEVICE_NAME Нет auto Подстрока имени динамика/выхода (например pulse)
AUDIO_OUTPUT_DEVICE_INDEX Нет auto Индекс PortAudio для вывода (приоритетнее AUDIO_OUTPUT_DEVICE_NAME)
STT_START_SOUND_PATH Нет assets/sounds/alisa-golosovoj-pomoschnik.mp3 Короткий звук после wake word и перед стартом STT (wav/mp3)
STT_START_SOUND_VOLUME Нет 1.0 Громкость звука старта STT (в текущей версии фиксирована на 100%)
TTS_EN_SPEAKER Нет en_0 Английский голос TTS
WEATHER_LAT Нет - Широта города по умолчанию
WEATHER_LON Нет - Долгота города по умолчанию
WEATHER_CITY Нет Ухта Город по умолчанию для погоды
NAVIDROME_URL Нет - URL Navidrome (например https://navidrome.example.com)
NAVIDROME_USERNAME Нет - Логин Navidrome
NAVIDROME_PASSWORD Нет - Пароль Navidrome
SPOTIFY_CLIENT_ID Нет - Spotify OAuth Client ID
SPOTIFY_CLIENT_SECRET Нет - Spotify OAuth Client Secret
SPOTIFY_REDIRECT_URI Нет http://localhost:8888/callback Redirect URI для Spotify

Примеры голосовых команд

Категория Примеры
Активация Waltron
AI-диалог Почему небо голубое?
Перевод Переведи на английский: как дела
Погода Какая погода?, Погода в Москве
Таймер Поставь таймер на 5 минут
Будильник Поставь будильник на 7:30, Будильник по будням в 8:00
Секундомер Запусти секундомер, Покажи активные секундомеры
Громкость Громкость 7
Музыка (Navidrome first) Включи музыку, Пауза, Продолжи, Следующий, Предыдущий, Что играет, Включи жанр electronic, Включи папку crystal castles
Игра Давай сыграем в города
Управление диалогом Повтори, Стоп, Хватит

Память текущего диалога, история сообщений и ROLE_JSON системной роли сохраняются для всех поддерживаемых AI-провайдеров.

Как Выбирается AI-Провайдер

  1. Приложение проверяет, какие AI API key реально активны в .env.
  2. Если активен ровно один ключ, используется именно он.
  3. Если активны несколько ключей, ассистент возвращает ошибку конфигурации.
  4. Если активных ключей нет, приложение ориентируется на AI_PROVIDER, но без ключа работать не сможет.

Такое поведение сделано специально, чтобы конфигурация была предсказуемой и при демонстрации не возникало скрытого переключения между сервисами.

Полезные команды

Команда Что делает
make run Запуск ассистента
make check Локальная проверка проекта (scripts/qwen-check.sh)
make qwen-context Сбор контекста проекта (scripts/qwen-context.sh)

Структура проекта

alexander_smart-speaker/
├── run.py
├── app/
│   ├── main.py
│   ├── audio/      # wakeword, stt, tts, volume
│   ├── core/       # config, ai, command helpers, cleaner
│   └── features/   # weather, timer, alarm, stopwatch, music, cities game
├── assets/
│   ├── models/     # Porcupine keyword model (.ppn)
│   └── sounds/     # звуки уведомлений и будильника
├── data/           # persisted JSON: alarms, timers, stopwatches
└── scripts/

Диагностика

Проблема Что проверить
Не реагирует на Waltron PORCUPINE_ACCESS_KEY, микрофон, чувствительность PORCUPINE_SENSITIVITY
STT не распознает речь DEEPGRAM_API_KEY, сетевой доступ, выбранный микрофон
Нет звука корректное аудиоустройство и доступность pactl/amixer
Audio input/output initialization failed проверить, что звук-сервер запущен (PipeWire/PulseAudio), и при необходимости задать AUDIO_INPUT_DEVICE_NAME/AUDIO_OUTPUT_DEVICE_NAME
Будильник/таймер не звонит наличие mpg123 в системе
Ошибка про несколько AI API в .env должен остаться только один незакомментированный AI ключ
Navidrome не воспроизводит заполнены NAVIDROME_*, доступен NAVIDROME_URL, установлен mpv
Fallback ушёл в Spotify проверить доступность Navidrome, SSL и корректность NAVIDROME_USERNAME/NAVIDROME_PASSWORD
Spotify не управляется заполнены SPOTIFY_*, есть активное устройство, Premium-аккаунт

Лицензия

Проект распространяется по лицензии MIT. См. LICENSE.txt.