docs: redesign project README
This commit is contained in:
376
README.md
376
README.md
@@ -1,261 +1,83 @@
|
|||||||
|
# Alexander Smart Speaker
|
||||||
|
|
||||||
<div align="center">
|
<div align="center">
|
||||||
|
|
||||||
# 🎙️ Alexander Smart Speaker
|
Голосовой ассистент для Linux: wake word, STT/TTS, AI-диалог и полезные голосовые навыки.
|
||||||
|
|
||||||
**Голосовой ассистент для Linux с wake word, STT/TTS и набором голосовых навыков**
|
[](https://www.python.org/)
|
||||||
|
[](https://www.linux.org/)
|
||||||
[](https://www.python.org/downloads/)
|
[](LICENSE.txt)
|
||||||
[](https://www.linux.org/)
|
[](https://picovoice.ai/platform/porcupine/)
|
||||||
[](LICENSE.txt)
|
[](https://deepgram.com/)
|
||||||
|
[](https://github.com/snakers4/silero-models)
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
## ✨ Возможности
|
## Что это
|
||||||
|
|
||||||
| Функция | Описание |
|
`Alexander Smart Speaker` слушает ключевое слово `Alexandr`, распознает речь, маршрутизирует команду в нужный модуль и озвучивает ответ.
|
||||||
|--------|----------|
|
Проект оптимизирован под русский язык, но поддерживает RU/EN сценарии (включая перевод и mixed-language TTS).
|
||||||
| 🔊 **Активация по ключевому слову** | Активация по команде `Alexandr` |
|
|
||||||
| 🧠 **Диалог с AI** | Взаимодействие с Perplexity с сохранением контекста |
|
|
||||||
| 🌐 **Перевод** | Перевод RU ↔ EN с озвучиванием |
|
|
||||||
| 🌤️ **Погода** | Информация о погоде по умолчанию и по названию города |
|
|
||||||
| ⏰ **Таймеры и будильники** | Управление таймерами, будильниками и секундомерами |
|
|
||||||
| 🔊 **Управление громкостью** | Регулировка системной громкости |
|
|
||||||
| 🎵 **Spotify интеграция** | Управление воспроизведением (play/pause/next/current track) |
|
|
||||||
| 🌍 **Игра в города** | Классическая игра в города |
|
|
||||||
|
|
||||||
## 🏗️ Архитектура проекта
|
## Возможности
|
||||||
|
|
||||||
### Диаграмма взаимодействия компонентов
|
- Активация по wake word `Alexandr` (Porcupine).
|
||||||
|
- Распознавание речи через Deepgram (WebSocket, VAD, fast stop).
|
||||||
|
- Озвучка через Silero TTS (RU + EN, с прерыванием по wake word).
|
||||||
|
- AI-диалог через Perplexity API со streaming-ответом и контекстом.
|
||||||
|
- Перевод RU -> EN и EN -> RU.
|
||||||
|
- Погода: текущий прогноз по городу по умолчанию или по названию города.
|
||||||
|
- Таймеры, будильники (включая будни/выходные), секундомеры.
|
||||||
|
- Управление громкостью системы (через `pactl`/`amixer`).
|
||||||
|
- Управление Spotify (play/pause/next/what's playing).
|
||||||
|
- Мини-игра "Города".
|
||||||
|
|
||||||
|
## Как это работает
|
||||||
|
|
||||||
```mermaid
|
```mermaid
|
||||||
graph TB
|
flowchart TD
|
||||||
subgraph "Основной цикл"
|
A[Wake Word: Alexandr] --> B[STT: Deepgram]
|
||||||
A[main() - основной цикл] --> B{Режим активации}
|
B --> C{Маршрутизация команды}
|
||||||
B -->|Ожидание wake word| C[wait_for_wakeword()]
|
C --> D[Feature modules]
|
||||||
B -->|Режим диалога| D[listen() в режиме follow-up]
|
C --> E[AI/Translation]
|
||||||
C --> E[Прослушивание команды]
|
D --> F[TTS: Silero]
|
||||||
D --> E
|
E --> F
|
||||||
E --> F[Анализ команды]
|
F --> G[Follow-up режим или ожидание wake word]
|
||||||
end
|
|
||||||
|
|
||||||
subgraph "Аудио подсистема"
|
|
||||||
C1[wait_for_wakeword()<br/>wakeword.py<br/>check_wakeword_once()]
|
|
||||||
E1[listen()<br/>stt.py<br/>get_recognizer()]
|
|
||||||
G1[speak()<br/>tts.py<br/>initialize()]
|
|
||||||
H1[parse_volume_text()<br/>sound_level.py<br/>set_volume()]
|
|
||||||
|
|
||||||
C1 -.-> E1
|
|
||||||
E1 -.-> G1
|
|
||||||
H1 -.-> G1
|
|
||||||
end
|
|
||||||
|
|
||||||
subgraph "Ядро"
|
|
||||||
F1[is_stop_command()<br/>commands.py<br/>_normalize_text()]
|
|
||||||
F2[ask_ai_stream()<br/>ai.py<br/>translate_text()]
|
|
||||||
F3[clean_response()<br/>cleaner.py]
|
|
||||||
F5[get_smalltalk_response()<br/>smalltalk.py]
|
|
||||||
|
|
||||||
F --> F1
|
|
||||||
F --> F2
|
|
||||||
F --> F3
|
|
||||||
F --> F5
|
|
||||||
end
|
|
||||||
|
|
||||||
subgraph "Функции"
|
|
||||||
I1[get_weather_report()<br/>weather.py]
|
|
||||||
I2[get_timer_manager()<br/>timer.py]
|
|
||||||
I3[get_alarm_clock()<br/>alarm.py]
|
|
||||||
I4[get_stopwatch_manager()<br/>stopwatch.py]
|
|
||||||
I5[get_music_controller()<br/>music.py]
|
|
||||||
I6[get_cities_game()<br/>cities_game.py]
|
|
||||||
|
|
||||||
F --> I1
|
|
||||||
F --> I2
|
|
||||||
F --> I3
|
|
||||||
F --> I4
|
|
||||||
F --> I5
|
|
||||||
F --> I6
|
|
||||||
end
|
|
||||||
|
|
||||||
subgraph "Обработка команд"
|
|
||||||
F --> J{Тип команды}
|
|
||||||
J -->|Small talk| K[get_smalltalk_response()]
|
|
||||||
J -->|Повтор| L[Повтор последнего ответа]
|
|
||||||
J -->|Стоп| M[is_stop_command()]
|
|
||||||
J -->|Таймер| N[parse_command() timer]
|
|
||||||
J -->|Будильник| O[parse_command() alarm]
|
|
||||||
J -->|Секундомер| P[parse_command() stopwatch]
|
|
||||||
J -->|Громкость| Q[parse_volume_text() + set_volume()]
|
|
||||||
J -->|Погода| R[get_weather_report()]
|
|
||||||
J -->|Музыка| S[parse_command() music]
|
|
||||||
J -->|Перевод| T[parse_translation_request()]
|
|
||||||
J -->|Города| U[handle() cities_game]
|
|
||||||
J -->|AI| V[ask_ai_stream()]
|
|
||||||
end
|
|
||||||
|
|
||||||
subgraph "Ответ пользователю"
|
|
||||||
K --> W[clean_response()]
|
|
||||||
L --> W
|
|
||||||
M --> W
|
|
||||||
N --> W
|
|
||||||
O --> W
|
|
||||||
P --> W
|
|
||||||
Q --> W
|
|
||||||
R --> W
|
|
||||||
S --> W
|
|
||||||
T --> W
|
|
||||||
U --> W
|
|
||||||
V --> W
|
|
||||||
|
|
||||||
W --> X[speak()]
|
|
||||||
X --> Y[Возврат в режим ожидания]
|
|
||||||
Y --> A
|
|
||||||
end
|
|
||||||
|
|
||||||
%% Connections
|
|
||||||
C1 -.-> A
|
|
||||||
E1 -.-> F
|
|
||||||
G1 -.-> X
|
|
||||||
F2 -.-> V
|
|
||||||
F3 -.-> W
|
|
||||||
I1 -.-> R
|
|
||||||
I2 -.-> N
|
|
||||||
I3 -.-> O
|
|
||||||
I4 -.-> P
|
|
||||||
I5 -.-> S
|
|
||||||
I6 -.-> U
|
|
||||||
|
|
||||||
style A fill:#e1f5fe
|
|
||||||
style F fill:#f3e5f5
|
|
||||||
style X fill:#e8f5e8
|
|
||||||
style Y fill:#fff3e0
|
|
||||||
</graph>
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Диаграмма потока команд от wake word до функций
|
## Быстрый старт
|
||||||
|
|
||||||
```mermaid
|
### 1) Системные зависимости (Ubuntu/Debian)
|
||||||
graph TD
|
|
||||||
subgraph "Активация и распознавание"
|
|
||||||
A[wait_for_wakeword()<br/>wakeword.py] --> B[listen()<br/>stt.py]
|
|
||||||
B --> C[Распознанный текст]
|
|
||||||
end
|
|
||||||
|
|
||||||
subgraph "Анализ команды"
|
|
||||||
C --> D{Тип команды}
|
|
||||||
end
|
|
||||||
|
|
||||||
subgraph "Обработка специфических команд"
|
|
||||||
D -->|Small talk| E[get_smalltalk_response()<br/>smalltalk.py]
|
|
||||||
D -->|Стоп команда| F[is_stop_command()<br/>commands.py]
|
|
||||||
D -->|Таймер| G[parse_command()<br/>timer.py]
|
|
||||||
D -->|Будильник| H[parse_command()<br/>alarm.py]
|
|
||||||
D -->|Секундомер| I[parse_command()<br/>stopwatch.py]
|
|
||||||
D -->|Громкость| J[parse_volume_text()<br/>sound_level.py<br/>set_volume()]
|
|
||||||
D -->|Погода| K[get_weather_report()<br/>weather.py]
|
|
||||||
D -->|Музыка| L[parse_command()<br/>music.py]
|
|
||||||
D -->|Перевод| M[parse_translation_request()<br/>ai.py<br/>translate_text()]
|
|
||||||
D -->|Города| N[handle()<br/>cities_game.py]
|
|
||||||
D -->|Обычный вопрос| O[ask_ai_stream()<br/>ai.py]
|
|
||||||
end
|
|
||||||
|
|
||||||
subgraph "Ответ пользователю"
|
|
||||||
E --> P[clean_response()<br/>cleaner.py]
|
|
||||||
F --> P
|
|
||||||
G --> P
|
|
||||||
H --> P
|
|
||||||
I --> P
|
|
||||||
J --> P
|
|
||||||
K --> P
|
|
||||||
L --> P
|
|
||||||
M --> P
|
|
||||||
N --> P
|
|
||||||
O --> P
|
|
||||||
P --> Q[speak()<br/>tts.py]
|
|
||||||
end
|
|
||||||
|
|
||||||
subgraph "Цикл управления"
|
|
||||||
Q --> R{Продолжить диалог?}
|
|
||||||
R -->|Да| S[Остаться в режиме ожидания]
|
|
||||||
R -->|Нет| T[Ждать wake word снова]
|
|
||||||
S --> B
|
|
||||||
T --> A
|
|
||||||
end
|
|
||||||
</graph>
|
|
||||||
```
|
|
||||||
|
|
||||||
## 🛠️ Технологии
|
|
||||||
|
|
||||||
| Компонент | Технология |
|
|
||||||
|-----------|------------|
|
|
||||||
| **Wake word** | `pvporcupine` |
|
|
||||||
| **STT** | `deepgram-sdk` |
|
|
||||||
| **TTS** | `Silero` (`torch`, `torchaudio`) |
|
|
||||||
| **AI** | Perplexity API |
|
|
||||||
| **Погода** | Open-Meteo |
|
|
||||||
| **Музыка** | Spotify Web API (`spotipy`) |
|
|
||||||
|
|
||||||
## 📋 Требования
|
|
||||||
|
|
||||||
- **ОС**: Linux
|
|
||||||
- **Python**: 3.9+
|
|
||||||
- **Системные пакеты**:
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
sudo apt-get update
|
sudo apt-get update
|
||||||
sudo apt-get install -y portaudio19-dev libasound2-dev mpg123
|
sudo apt-get install -y portaudio19-dev libasound2-dev mpg123 pulseaudio-utils alsa-utils
|
||||||
```
|
```
|
||||||
|
|
||||||
> 💡 Для управления громкостью необходим `pactl` или `amixer` (обычно из `pulseaudio-utils`/`alsa-utils`).
|
### 2) Установка Python-зависимостей
|
||||||
|
|
||||||
## 🚀 Установка
|
|
||||||
|
|
||||||
1. **Клонируйте репозиторий**:
|
|
||||||
```bash
|
```bash
|
||||||
git clone https://github.com/your-username/alexander_smart-speaker.git
|
git clone <URL_ВАШЕГО_РЕПОЗИТОРИЯ>
|
||||||
cd alexander_smart-speaker
|
cd alexander_smart-speaker
|
||||||
```
|
python3 -m venv venv
|
||||||
|
source venv/bin/activate
|
||||||
2. **Настройте виртуальное окружение**:
|
|
||||||
```bash
|
|
||||||
python -m venv venv
|
|
||||||
source venv/bin/activate # или venv\Scripts\activate на Windows
|
|
||||||
pip install -r requirements.txt
|
pip install -r requirements.txt
|
||||||
```
|
```
|
||||||
|
|
||||||
## ⚙️ Настройка
|
### 3) Настройка `.env`
|
||||||
|
|
||||||
1. **Создайте файл конфигурации**:
|
|
||||||
```bash
|
```bash
|
||||||
cp .env.example .env
|
cp .env.example .env
|
||||||
```
|
```
|
||||||
|
|
||||||
2. **Обязательные переменные окружения**:
|
Минимально обязательные переменные:
|
||||||
|
|
||||||
```ini
|
```ini
|
||||||
PERPLEXITY_API_KEY=your_perplexity_api_key_here
|
PERPLEXITY_API_KEY=...
|
||||||
DEEPGRAM_API_KEY=your_deepgram_api_key_here
|
DEEPGRAM_API_KEY=...
|
||||||
PORCUPINE_ACCESS_KEY=your_porcupine_access_key_here
|
PORCUPINE_ACCESS_KEY=...
|
||||||
```
|
```
|
||||||
|
|
||||||
3. **Полная конфигурация** (как в `.env.example`):
|
### 4) Запуск
|
||||||
|
|
||||||
```ini
|
|
||||||
PERPLEXITY_API_KEY=your_perplexity_api_key_here
|
|
||||||
PERPLEXITY_MODEL=llama-3.1-sonar-small-128k-chat
|
|
||||||
DEEPGRAM_API_KEY=your_deepgram_api_key_here
|
|
||||||
PORCUPINE_ACCESS_KEY=your_porcupine_access_key_here
|
|
||||||
PORCUPINE_SENSITIVITY=0.8
|
|
||||||
TTS_EN_SPEAKER=en_0
|
|
||||||
WEATHER_LAT=63.56
|
|
||||||
WEATHER_LON=53.69
|
|
||||||
WEATHER_CITY=Ухта
|
|
||||||
SPOTIFY_CLIENT_ID=your_spotify_client_id
|
|
||||||
SPOTIFY_CLIENT_SECRET=your_spotify_client_secret
|
|
||||||
SPOTIFY_REDIRECT_URI=http://localhost:8888/callback
|
|
||||||
```
|
|
||||||
|
|
||||||
## ▶️ Запуск
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
make run
|
make run
|
||||||
@@ -263,62 +85,76 @@ make run
|
|||||||
python run.py
|
python run.py
|
||||||
```
|
```
|
||||||
|
|
||||||
## 🗣️ Примеры голосовых команд
|
После запуска ассистент перейдет в режим ожидания фразы `Alexandr`.
|
||||||
|
|
||||||
| Категория | Команды |
|
## Конфигурация `.env`
|
||||||
|-----------|---------|
|
|
||||||
| **Активация** | `Alexandr` |
|
|
||||||
| **Диалог** | `Почему небо голубое?` |
|
|
||||||
| **Погода** | `Какая сейчас погода?`, `Погода в Москве` |
|
|
||||||
| **Перевод** | `Переведи на английский: как дела` |
|
|
||||||
| **Таймер** | `Поставь таймер на 5 минут` |
|
|
||||||
| **Будильник** | `Поставь будильник на 7:30`, `Будильник по будням в 8:00` |
|
|
||||||
| **Секундомер** | `Запусти секундомер`, `Покажи активные секундомеры` |
|
|
||||||
| **Громкость** | `Громкость 5` |
|
|
||||||
| **Spotify** | `Включи музыку`, `Пауза`, `Что сейчас играет` |
|
|
||||||
| **Игра** | `Давай сыграем в города` |
|
|
||||||
| **Остановка** | `Стоп`, `Хватит`, `Повтори` |
|
|
||||||
|
|
||||||
## 🛠️ Полезные команды
|
| Переменная | Обязательно | По умолчанию | Назначение |
|
||||||
|
|---|---|---|---|
|
||||||
|
| `PERPLEXITY_API_KEY` | Да | - | Ключ Perplexity API |
|
||||||
|
| `PERPLEXITY_MODEL` | Нет | `llama-3.1-sonar-small-128k-chat` | Модель Perplexity |
|
||||||
|
| `DEEPGRAM_API_KEY` | Да | - | Ключ Deepgram STT |
|
||||||
|
| `PORCUPINE_ACCESS_KEY` | Да | - | Ключ PicoVoice Porcupine |
|
||||||
|
| `PORCUPINE_SENSITIVITY` | Нет | `0.8` | Чувствительность wake word |
|
||||||
|
| `TTS_EN_SPEAKER` | Нет | `en_0` | Английский голос TTS |
|
||||||
|
| `WEATHER_LAT` | Нет | - | Широта города по умолчанию |
|
||||||
|
| `WEATHER_LON` | Нет | - | Долгота города по умолчанию |
|
||||||
|
| `WEATHER_CITY` | Нет | `Ухта` | Город по умолчанию для погоды |
|
||||||
|
| `SPOTIFY_CLIENT_ID` | Нет | - | Spotify OAuth Client ID |
|
||||||
|
| `SPOTIFY_CLIENT_SECRET` | Нет | - | Spotify OAuth Client Secret |
|
||||||
|
| `SPOTIFY_REDIRECT_URI` | Нет | `http://localhost:8888/callback` | Redirect URI для Spotify |
|
||||||
|
|
||||||
| Команда | Назначение |
|
## Примеры голосовых команд
|
||||||
|---------|------------|
|
|
||||||
|
| Категория | Примеры |
|
||||||
|
|---|---|
|
||||||
|
| Активация | `Alexandr` |
|
||||||
|
| AI-диалог | `Почему небо голубое?` |
|
||||||
|
| Перевод | `Переведи на английский: как дела` |
|
||||||
|
| Погода | `Какая погода?`, `Погода в Москве` |
|
||||||
|
| Таймер | `Поставь таймер на 5 минут` |
|
||||||
|
| Будильник | `Поставь будильник на 7:30`, `Будильник по будням в 8:00` |
|
||||||
|
| Секундомер | `Запусти секундомер`, `Покажи активные секундомеры` |
|
||||||
|
| Громкость | `Громкость 7` |
|
||||||
|
| Spotify | `Включи музыку`, `Пауза`, `Что сейчас играет` |
|
||||||
|
| Игра | `Давай сыграем в города` |
|
||||||
|
| Управление диалогом | `Повтори`, `Стоп`, `Хватит` |
|
||||||
|
|
||||||
|
## Полезные команды
|
||||||
|
|
||||||
|
| Команда | Что делает |
|
||||||
|
|---|---|
|
||||||
| `make run` | Запуск ассистента |
|
| `make run` | Запуск ассистента |
|
||||||
| `make check` | Базовая проверка проекта |
|
| `make check` | Локальная проверка проекта (`scripts/qwen-check.sh`) |
|
||||||
| `make qwen-context` | Собрать контекст проекта |
|
| `make qwen-context` | Сбор контекста проекта (`scripts/qwen-context.sh`) |
|
||||||
|
|
||||||
## 📁 Структура проекта
|
## Структура проекта
|
||||||
|
|
||||||
```
|
```text
|
||||||
alexander_smart-speaker/
|
alexander_smart-speaker/
|
||||||
├── run.py # точка входа
|
├── run.py
|
||||||
├── app/
|
├── app/
|
||||||
│ ├── main.py # главный цикл ассистента
|
│ ├── main.py
|
||||||
│ ├── audio/ # wake word, STT, TTS, громкость
|
│ ├── audio/ # wakeword, stt, tts, volume
|
||||||
│ ├── core/ # конфиг, AI, роутинг команд, утилиты
|
│ ├── core/ # config, ai, command helpers, cleaner
|
||||||
│ └── features/ # погода, будильник, таймер, секундомер, музыка, города
|
│ └── features/ # weather, timer, alarm, stopwatch, music, cities game
|
||||||
├── assets/ # модели и звуки
|
├── assets/
|
||||||
├── data/ # сохраненные будильники/таймеры/секундомеры
|
│ ├── models/ # Porcupine keyword model (.ppn)
|
||||||
└── scripts/ # скрипты для установки и обслуживания
|
│ └── sounds/ # звуки уведомлений и будильника
|
||||||
|
├── data/ # persisted JSON: alarms, timers, stopwatches
|
||||||
|
└── scripts/
|
||||||
```
|
```
|
||||||
|
|
||||||
## 🔧 Диагностика проблем
|
## Диагностика
|
||||||
|
|
||||||
| Проблема | Решение |
|
| Проблема | Что проверить |
|
||||||
|----------|---------|
|
|---|---|
|
||||||
| Ошибки STT/AI | Проверьте ключи в `.env` |
|
| Не реагирует на `Alexandr` | `PORCUPINE_ACCESS_KEY`, микрофон, чувствительность `PORCUPINE_SENSITIVITY` |
|
||||||
| Нет звука | Проверьте системное устройство вывода и утилиты `pactl`/`amixer` |
|
| STT не распознает речь | `DEEPGRAM_API_KEY`, сетевой доступ, выбранный микрофон |
|
||||||
| Не играет будильник/таймер | Убедитесь, что установлен `mpg123` |
|
| Нет звука | корректное аудиоустройство и доступность `pactl`/`amixer` |
|
||||||
| Spotify не управляется | Проверьте `SPOTIFY_*`, авторизацию и наличие активного устройства |
|
| Будильник/таймер не звонит | наличие `mpg123` в системе |
|
||||||
|
| Spotify не управляется | заполнены `SPOTIFY_*`, есть активное устройство, Premium-аккаунт |
|
||||||
|
|
||||||
## 📄 Лицензия
|
## Лицензия
|
||||||
|
|
||||||
MIT, см. [LICENSE.txt](LICENSE.txt).
|
Проект распространяется по лицензии MIT. См. `LICENSE.txt`.
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
<div align="center">
|
|
||||||
|
|
||||||
**Если вам понравился проект, поставьте ⭐ звезду!**
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|||||||
Reference in New Issue
Block a user