Alexander Smart Speaker
Что это
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 <URL_ВАШЕГО_РЕПОЗИТОРИЯ>
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 |
Нет | ~/Music/alisa-golosovoj-pomoschnik.mp3 |
Короткий звук после wake word и перед стартом STT (wav/mp3) |
STT_START_SOUND_VOLUME |
Нет | 0.25 |
Громкость звука старта STT (0..1) |
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-Провайдер
- Приложение проверяет, какие AI API key реально активны в
.env. - Если активен ровно один ключ, используется именно он.
- Если активны несколько ключей, ассистент возвращает ошибку конфигурации.
- Если активных ключей нет, приложение ориентируется на
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.