diff --git a/.gitignore b/.gitignore index 8798bff..8632312 100755 --- a/.gitignore +++ b/.gitignore @@ -15,3 +15,20 @@ __pycache__/ /dist/ /local/ + +# LED brightness config (auto-generated, user-specific) +examples/led_brightness_config.json + +# Qwen Code settings +.qwen/settings.json.orig + +# Backup files +*.old +*.bak +*~ + +# Archives +*.zip + +# Empty files +*.lgd-* diff --git a/.qwen/settings.json b/.qwen/settings.json index e2c4a76..e406cf1 100644 --- a/.qwen/settings.json +++ b/.qwen/settings.json @@ -2,7 +2,8 @@ "permissions": { "allow": [ "Bash(/home/sirmrak/projects/.venv_satellite/bin/pip *)", - "Bash(find *)" + "Bash(find *)", + "Bash(ls *)" ] }, "$version": 4 diff --git a/.qwen/settings.json.orig b/.qwen/settings.json.orig deleted file mode 100644 index 5fcfbf4..0000000 --- a/.qwen/settings.json.orig +++ /dev/null @@ -1,8 +0,0 @@ -{ - "permissions": { - "allow": [ - "Bash(/home/sirmrak/projects/.venv_satellite/bin/pip *)" - ] - }, - "$version": 4 -} \ No newline at end of file diff --git a/DEPLOY.md b/DEPLOY.md index 620d61d..41b8ae4 100644 --- a/DEPLOY.md +++ b/DEPLOY.md @@ -1,93 +1,73 @@ -# Развёртывание Wyoming Satellite +# Deployment Guide -## Быстрый старт на новом сервере +Quick start guide for deploying Wyoming Satellite. + +## Quick Start + +### 1. Clone and Install -### 1. Клонирование репозитория ```bash -git clone /path/to/Satellite -cd Satellite -``` +git clone ~/projects/Satellite +cd ~/projects/Satellite -### 2. Создание виртуального окружения -```bash -# Вариант A: в домашней директории (рекомендуется) +# Create virtual environment python3 -m venv ~/.venv_satellite source ~/.venv_satellite/bin/activate -# Вариант B: в projects -python3 -m venv ~/projects/.venv_satellite -source ~/projects/.venv_satellite/bin/activate -``` - -### 3. Установка зависимостей -```bash +# Install dependencies pip install -r requirements.txt ``` -### 4. Установка systemd сервисов +### 2. Install systemd Services + ```bash sudo ./install_systemd_services.sh ``` -Скрипт автоматически: -- Найдёт виртуальное окружение -- Определит текущего пользователя -- Подставит правильные пути в service файлы -- Установит wrapper `satellite-python` в `/usr/local/bin/` +### 3. Start Services -### 5. Запуск сервисов ```bash -# LED сервис (опционально) -sudo systemctl enable wyoming-event.service -sudo systemctl start wyoming-event.service +# LED control (optional, requires ReSpeaker) +sudo systemctl enable --now wyoming-event.service # Wyoming Satellite -sudo systemctl enable wyoming-satelite-vosk.service -sudo systemctl start wyoming-satelite-vosk.service +sudo systemctl enable --now wyoming-satelite-vosk.service -# Wake Word сервис -sudo systemctl enable wyoming-wakeword-vosk.service -sudo systemctl start wyoming-wakeword-vosk.service +# Wake word detection (Vosk) +sudo systemctl enable --now wyoming-wakeword-vosk.service ``` -### 6. Проверка статуса +### 4. Verify + ```bash -sudo systemctl status wyoming-event.service -journalctl -u wyoming-event.service -f +sudo systemctl status wyoming-satelite-vosk.service +journalctl -u wyoming-satelite-vosk.service -f ``` --- -## Структура service файлов +## Full Documentation -Все service файлы используют плейсхолдеры, которые заменяются при установке: - -| Плейсхолдер | Описание | -|-------------|----------| -| `__SAT_BASE_DIR__` | Путь к репозиторию Satellite | -| `__SAT_VENV__` | Путь к виртуальному окружению | -| `__CURRENT_USER__` | Имя пользователя | -| `__HOME_DIR__` | Домашняя директория пользователя | +- [**systemd Services**](deployment/systemd-services.md) — Detailed service configuration +- [**Tutorials**](tutorials/installer.md) — Step-by-step installation guides --- -## Ручная установка (альтернатива) +## Service Overview -Если скрипт не работает, можно вручную: +| Service | Port | Description | +|---------|------|-------------| +| `wyoming-satelite-vosk.service` | 10700 | Main Wyoming satellite | +| `wyoming-wakeword-vosk.service` | 10400 | Vosk wake word detection | +| `wyoming-event.service` | 10500 | LED control + MQTT events | -1. Отредактировать файлы в `service/`, заменив плейсхолдеры -2. Скопировать в `/etc/systemd/system/` -3. Выполнить `sudo systemctl daemon-reload` +## Configuration ---- +Service files use placeholders that are auto-replaced during installation: -## Wrapper `satellite-python` - -Глобальный скрипт `/usr/local/bin/satellite-python` позволяет запускать Python из venv без указания полного пути: - -```ini -# В systemd сервисе -ExecStart=satellite-python /path/to/script.py -``` - -Это избавляет от необходимости прописывать пути к `.venv` в каждом сервисе. +| Placeholder | Description | +|-------------|-------------| +| `__SAT_BASE_DIR__` | Path to Satellite repository | +| `__SAT_VENV__` | Path to virtual environment | +| `__CURRENT_USER__` | Current username | +| `__HOME_DIR__` | User home directory | diff --git a/QWEN.md b/QWEN.md new file mode 100644 index 0000000..9083f67 --- /dev/null +++ b/QWEN.md @@ -0,0 +1,190 @@ +# VoskWyoming Satellite — Project Context + +## Project Overview + +**VoskWyoming Satellite** is a remote voice satellite implementation using the [Wyoming protocol](https://github.com/rhasspy/wyoming) for Home Assistant voice control. It provides: + +- **Home Assistant integration** via Wyoming protocol +- **Local wake word detection** using Vosk (Russian wake words: "привет дроид", etc.) +- **Audio enhancements** via WebRTC noise suppression and gain control +- **MQTT integration** for LED control (ReSpeaker XVF3800 4-MIC array) and Home Assistant discovery +- **Voice Activity Detection (VAD)** using Silero or WebRTC + +**Key technologies:** Python 3.9+, Wyoming protocol, Vosk, WebRTC, MQTT, systemd + +--- + +## Building and Running + +### Prerequisites + +```bash +sudo apt-get install python3-venv python3-pip alsa-utils +``` + +### Setup + +```bash +# Clone and setup +cd ~/projects/Satellite +python3 -m venv ~/.venv_satellite +source ~/.venv_satellite/bin/activate +pip install -r requirements.txt +``` + +### Run (Development) + +```bash +# From project root +./start_satellite.sh # Uses systemd-style config +./start-dev.sh # Development mode +python3 -m wyoming_satellite # Direct module run +``` + +**Main script:** `wyoming_satellite/__main__.py` — argparse-based CLI with extensive options for mic, sound, wake word, VAD, and event handling. + +### Run (Production — systemd) + +```bash +sudo ./install_systemd_services.sh # Auto-installs services + +# Start services +sudo systemctl enable --now wyoming-event.service +sudo systemctl enable --now wyoming-satelite-vosk.service +sudo systemctl enable --now wyoming-wakeword-vosk.service + +# Check status +journalctl -u wyoming-satelite-vosk.service -f +``` + +### Services + +| Service | Port | Description | +|---------|------|-------------| +| `wyoming-satelite-vosk.service` | 10700 | Main Wyoming satellite | +| `wyoming-wakeword-vosk.service` | 10400 | Vosk wake word detection | +| `wyoming-event.service` | 10500 | LED control + MQTT events | + +--- + +## Development + +### Code Quality + +```bash +# Linting +pylint wyoming_satellite/ +mypy wyoming_satellite/ + +# Formatting +black wyoming_satellite/ +isort wyoming_satellite/ + +# Tests +pytest tests/ +tox # Multi-version testing +``` + +**Config files:** +- `pylintrc` — Pylint with many disabled checks (pragmatic approach) +- `mypy.ini` — Permissive, ignores missing imports +- `.isort.cfg` — Import sorting +- `tox.ini` — pytest-based test runner for Python 3.9–3.13 + +### Project Structure + +``` +Satellite/ +├── wyoming_satellite/ # Main package +│ ├── __main__.py # CLI entry point +│ ├── satellite.py # Satellite implementations +│ ├── settings.py # Dataclass-based settings +│ ├── event_handler.py # Wyoming event handling +│ ├── vad.py # Voice activity detection +│ └── webrtc.py # WebRTC audio processing +├── services/ # systemd service files +├── examples/ # Example scripts (LED, MQTT) +├── scripts/ # Helper scripts +├── tests/ # pytest tests +├── sounds/ # Audio files (awake.wav, etc.) +├── start_satellite.sh # Main startup script +├── install_systemd_services.sh # Service installer +└── requirements.txt # Dependencies +``` + +### Key Files + +| File | Purpose | +|------|---------| +| `wyoming_satellite/__main__.py` | Main entry point, CLI parsing | +| `wyoming_satellite/satellite.py` | `SatelliteBase`, `AlwaysStreamingSatellite`, `VadStreamingSatellite`, `WakeStreamingSatellite` | +| `wyoming_satellite/settings.py` | Settings dataclasses (`MicSettings`, `SndSettings`, `VadSettings`, `WakeSettings`, etc.) | +| `start_satellite.sh` | Production startup script (wake/vad modes) | +| `services/*.service` | systemd unit files with placeholders | + +--- + +## Configuration + +### Wake Words (Russian) + +Configured in `start_satellite.sh`: +```bash +--wake-word-name "привет дроид" +--wake-word-name "привет придурок" +--wake-word-name "привет жопа с ушами" +``` + +### VAD Settings + +```yaml +# local/vosk-wake-dev/wyoming_vosk_wake/config.yaml +vad: + vad_enabled: true + energy_threshold: 800 + speech_threshold: 0.5 + min_speech_duration_ms: 200 +``` + +### MQTT (LED Control) + +Topics in `examples/wyoming-led.py`: +- `wyoming/led/command` +- `wyoming/led/brightness/set` +- `wyoming/led/brightness/state` +- `wyoming/led/state` +- `wyoming/led/availability` + +--- + +## Testing Practices + +- **Framework:** pytest + pytest-asyncio +- **Test files:** `tests/test_satellite.py`, `tests/test_wake_streaming.py` +- **Shared fixtures:** `tests/shared.py` +- **Multi-version:** tox runs tests on Python 3.9–3.13 + +--- + +## Deployment Notes + +- **Virtual env location:** `~/.venv_satellite` or `~/projects/.venv_satellite` +- **Service installer:** `install_systemd_services.sh` auto-detects venv path and substitutes placeholders (`__SAT_BASE_DIR__`, `__SAT_VENV__`, `__CURRENT_USER__`) +- **Wrapper script:** `satellite-python` installed to `/usr/local/bin/` for systemd services + +--- + +## External Resources + +- [Wyoming Protocol](https://github.com/rhasspy/wyoming) +- [Home Assistant Wyoming Integration](https://www.home-assistant.io/integrations/wyoming) +- [Vosk](https://alphacephei.com/vosk/) +- [ReSpeaker 4-MIC Array](https://github.com/respeaker/usb_4mic_array) + +--- + +## Known Issues / Workarounds + +- **pylintrc:** Many checks disabled — pragmatic approach, focus on functionality over strict linting +- **mypy:** `ignore_missing_imports = true` — third-party stubs not always available +- **Audio:** Uses `arecord`/`aplay` with specific hardware (`plughw:CARD=Array,DEV=0`) — adjust for different microphones diff --git a/README.md b/README.md index 964a499..56a5348 100755 --- a/README.md +++ b/README.md @@ -1,38 +1,27 @@ -# VoskWyoming Satellite +# README — VoskWyoming Satellite -Remote voice satellite using the [Wyoming protocol](https://github.com/rhasspy/wyoming). - -* Works with [Home Assistant](https://www.home-assistant.io/integrations/wyoming) -* Local wake word detection using [Vosk](https://alphacephei.com/vosk/) -* Audio enhancements using [webrtc](https://github.com/rhasspy/webrtc-noise-gain/) -* MQTT integration for LED control and Home Assistant discovery +Remote voice satellite using the [Wyoming protocol](https://github.com/rhasspy/wyoming) for Home Assistant. [![An open standard from the Open Home Foundation](https://www.openhomefoundation.org/badges/ohf-open-standard.png)](https://www.openhomefoundation.org/) ---- +## Features -## 📋 Requirements +- 🏠 **Home Assistant integration** — Native Wyoming protocol support +- 🎤 **Local wake word detection** — Vosk-based Russian wake words ("привет дроид", etc.) +- 🔇 **Audio enhancements** — WebRTC noise suppression and automatic gain control +- 💡 **MQTT LED control** — ReSpeaker XVF3800 4-MIC array support with HA discovery +- 🎯 **Voice Activity Detection** — Silero or WebRTC VAD for privacy-focused operation -* Python 3.9+ -* Linux (tested on Raspberry Pi OS) -* Microphone (USB or HAT) -* Optional: ReSpeaker XVF3800 USB 4-MIC Array (for LED control) +## Quick Start ---- - -## 🚀 Quick Start - -### 1. Clone and Install +### 1. Install ```bash git clone ~/projects/Satellite cd ~/projects/Satellite -# Create virtual environment python3 -m venv ~/.venv_satellite source ~/.venv_satellite/bin/activate - -# Install dependencies pip install -r requirements.txt ``` @@ -42,271 +31,125 @@ pip install -r requirements.txt sudo ./install_systemd_services.sh ``` -This script automatically: -- Detects your virtual environment location -- Substitutes correct paths in service files -- Installs the `satellite-python` wrapper - -### 3. Start Services - -```bash -# LED control (optional, requires ReSpeaker) -sudo systemctl enable wyoming-event.service -sudo systemctl start wyoming-event.service - -# Wyoming Satellite -sudo systemctl enable wyoming-satelite-vosk.service -sudo systemctl start wyoming-satelite-vosk.service - -# Wake word detection (Vosk) -sudo systemctl enable wyoming-wakeword-vosk.service -sudo systemctl start wyoming-wakeword-vosk.service -``` - -### 4. Verify +### 3. Start ```bash +sudo systemctl enable --now wyoming-satelite-vosk.service sudo systemctl status wyoming-satelite-vosk.service -journalctl -u wyoming-satelite-vosk.service -f ``` +In Home Assistant: **Settings → Devices & Services → Discovered → Wyoming Satellite → Configure** + --- -## 📦 Installation +## Documentation -### System Dependencies +| Guide | Description | +|-------|-------------| +| [**Deployment**](DEPLOY.md) | Full deployment guide with systemd services | +| [**Tutorials**](docs/tutorials/) | Step-by-step setup for different hardware | +| [**Architecture**](docs/architecture/overview.md) | How Wyoming Satellite works | +| [**MQTT LED**](docs/integration/mqtt-led.md) | LED control with Home Assistant | +| [**VAD Integration**](docs/integration/vad-wakeword.md) | Technical integration guide | -```bash -sudo apt-get install python3-venv python3-pip alsa-utils -``` +### Tutorials -### Python Dependencies - -```bash -# Create and activate venv -python3 -m venv ~/.venv_satellite -source ~/.venv_satellite/bin/activate - -# Install requirements -pip install -r requirements.txt -``` +- [**2-MIC HAT**](docs/tutorials/2mic-hat.md) — Raspberry Pi + ReSpeaker 2-MIC HAT +- [**Installer**](docs/tutorials/installer.md) — Interactive installer guide --- -## 🔧 Configuration +## Requirements -### Service Files - -All service files are in `service/` directory and use placeholders that are automatically replaced during installation: - -| Placeholder | Description | -|-------------|-------------| -| `__SAT_BASE_DIR__` | Path to Satellite repository | -| `__SAT_VENV__` | Path to virtual environment | -| `__CURRENT_USER__` | Current username | -| `__HOME_DIR__` | User home directory | - -### Available Services - -| Service | Description | Port | -|---------|-------------|------| -| `wyoming-satelite-vosk.service` | Main Wyoming satellite | 10700 | -| `wyoming-wakeword-vosk.service` | Vosk wake word detection | 10400 | -| `wyoming-event.service` | LED control + MQTT | 10500 | - -### Configuration Files - -| File | Location | Description | -|------|----------|-------------| -| `config.yaml` | `local/vosk-wake-dev/wyoming_vosk_wake/` | VAD and wake word settings | -| `led_brightness_config.json` | `examples/` | LED brightness levels (auto-created) | +- **Python 3.9+** +- **Linux** (tested on Raspberry Pi OS) +- **Microphone** (USB or HAT) +- **Optional:** ReSpeaker XVF3800 USB 4-MIC Array (for LED control) --- -## 🎤 Usage - -### Manual Start (without systemd) - -```bash -# Activate venv -source ~/.venv_satellite/bin/activate - -# Start satellite -./start_satellite.sh - -# Or directly -python3 -m wyoming_satellite \ - --name 'my-satellite' \ - --uri 'tcp://0.0.0.0:10700' \ - --mic-command 'arecord -r 16000 -c 1 -f S16_LE -t raw' \ - --snd-command 'aplay -r 22050 -c 1 -f S16_LE -t raw' -``` - -### Wake Word Configuration - -Edit `local/vosk-wake-dev/wyoming_vosk_wake/config.yaml`: - -```yaml -vad: - vad_enabled: true - energy_threshold: 800 - speech_threshold: 0.5 - min_speech_duration_ms: 200 - -logging_level: debug # debug, info, warning, error -``` - -### LED Control (ReSpeaker) - -The LED service requires the [ReSpeaker XVF3800 control scripts](https://github.com/respeaker/usb_4mic_array): - -```bash -# Clone ReSpeaker repo -git clone https://github.com/respeaker/usb_4mic_array.git ~/projects/reSpeaker_XVF3800_USB_4MIC_ARRAY - -# The LED service will automatically find xvf_host.py -``` - -MQTT Topics: -- `wyoming/led/command` - Send commands -- `wyoming/led/brightness/set` - Set brightness (0-255) -- `wyoming/led/brightness/state` - Brightness state -- `wyoming/led/state` - Current LED state -- `wyoming/led/availability` - Online/offline status - ---- - -## 🔍 Examples - -See `examples/` directory for additional scripts: - -| File | Description | -|------|-------------| -| `wyoming-led.py` | LED control with MQTT and Home Assistant discovery | -| `2mic_service.py` | Configuration for 2-mic HAT | -| `4mic_service.py` | Configuration for 4-mic array | -| `usbmic_service.py` | Configuration for USB microphone | - ---- - -## 🛠️ Development - -### Project Structure +## Project Structure ``` Satellite/ -├── service/ # systemd service files -├── examples/ # Example scripts -├── local/ # Local wake word services -│ └── vosk-wake-dev/ # Vosk wake word detection -├── scripts/ # Helper scripts -├── install_systemd_services.sh # Auto-install services -├── requirements.txt # Python dependencies -├── start_satellite.sh # Main startup script -└── DEPLOY.md # Deployment guide +├── wyoming_satellite/ # Main Python package +├── examples/ # Example scripts (LED, MQTT, configs) +├── services/ # systemd service files +├── docs/ # Documentation +│ ├── tutorials/ # Hardware-specific guides +│ ├── integration/ # Technical integration guides +│ ├── deployment/ # Deployment guides +│ └── architecture/ # Architecture documentation +├── sounds/ # Audio files (awake.wav, etc.) +├── scripts/ # Helper scripts +└── tests/ # Unit tests ``` -### Running Tests +--- + +## Configuration + +### Wake Words (Russian) + +Edit `start_satellite.sh`: ```bash -# Run linters +--wake-word-name "привет дроид" +--wake-word-name "привет придурок" +--wake-word-name "привет жопа с ушами" +``` + +### Audio Settings + +```bash +--mic-noise-suppression 2 +--mic-auto-gain 5 +``` + +### VAD Settings + +```bash +--vad +--vad-system webrtc +--vad-threshold 0.5 +``` + +--- + +## Development + +```bash +# Linting pylint wyoming_satellite/ mypy wyoming_satellite/ -# Run tests (if available) +# Tests pytest tests/ -``` -### Updating Dependencies - -```bash -# Update requirements.txt from current venv -pip freeze > requirements.txt +# Format +black wyoming_satellite/ +isort wyoming_satellite/ ``` --- -## 📖 Documentation +## Video Tutorials -* [Deployment Guide](DEPLOY.md) - Full deployment instructions -* [Wyoming Protocol](https://github.com/rhasspy/wyoming) - Protocol documentation -* [Home Assistant Integration](https://www.home-assistant.io/integrations/wyoming) - HA setup -* [Vosk](https://alphacephei.com/vosk/) - Wake word recognition +- [Wyoming Voice Satellite with ChatGPT](https://www.youtube.com/watch?v=eTKgc0YDCwE) +- [Local ChatGPT Voice Assistant](https://www.youtube.com/watch?v=pAKqKTkx5X4) --- -## 🎥 Video Tutorials +## External Resources -* [Wyoming Voice Satellite with ChatGPT](https://www.youtube.com/watch?v=eTKgc0YDCwE) -* [Local ChatGPT Voice Assistant](https://www.youtube.com/watch?v=pAKqKTkx5X4) +- [Wyoming Protocol](https://github.com/rhasspy/wyoming) +- [Home Assistant Integration](https://www.home-assistant.io/integrations/wyoming) +- [Vosk](https://alphacephei.com/vosk/) +- [ReSpeaker 4-MIC Array](https://github.com/respeaker/usb_4mic_array) --- -## ⚙️ Audio Enhancements - -### WebRTC Noise Suppression - -Enabled by default via `requirements.txt` (webrtc-noise-gain==1.2.3) - -Configure in satellite startup: -```bash ---mic-auto-gain 5 \ ---mic-noise-suppression 2 -``` - -### VAD (Voice Activity Detection) - -Configured in `config.yaml`: -```yaml -vad: - vad_enabled: true - mode: 3 # 0-3, higher = more aggressive - sample_rate: 16000 -``` - ---- - -## 🐛 Troubleshooting - -### Service won't start - -```bash -# Check status -sudo systemctl status wyoming-satelite-vosk.service - -# View logs -journalctl -u wyoming-satelite-vosk.service -f - -# Check Python path -which satellite-python -satellite-python --version -``` - -### Microphone not detected - -```bash -# List audio devices -arecord -L -aplay -L - -# Test recording -arecord -r 16000 -c 1 -f S16_LE -t raw -d 5 test.wav -aplay test.wav -``` - -### MQTT Connection Issues - -Check broker settings in `examples/wyoming-led.py`: -```python -MQTT_BROKER = "192.168.200.100" -MQTT_PORT = 1883 -MQTT_USER = "mqtt" -MQTT_PASS = "mqtt" -``` - ---- - -## 📝 License +## License This project is part of the Open Home Foundation ecosystem. diff --git a/docker/run b/docker/run deleted file mode 100755 index 2e6876d..0000000 --- a/docker/run +++ /dev/null @@ -1,3 +0,0 @@ -#!/usr/bin/env bash -/app/script/run \ - --uri tcp://0.0.0.0:10700 "$@" diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 0000000..eeaee06 --- /dev/null +++ b/docs/README.md @@ -0,0 +1,35 @@ +# Documentation Index + +## 📖 For Users + +| Guide | Description | +|-------|-------------| +| [**Deployment**](../../DEPLOY.md) | Quick start and systemd services | +| [**2-MIC HAT**](tutorials/2mic-hat.md) | Raspberry Pi + ReSpeaker 2-MIC HAT | +| [**Installer**](tutorials/installer.md) | Interactive installer guide | + +## 🔧 For Developers + +| Document | Description | +|----------|-------------| +| [**Architecture**](architecture/overview.md) | How Wyoming Satellite works | +| [**VAD/Wake Integration**](integration/vad-wakeword.md) | Technical integration guide | +| [**MQTT LED Control**](integration/mqtt-led.md) | LED control with Home Assistant | +| [**systemd Services**](deployment/systemd-services.md) | Service configuration details | + +## 📁 Structure + +``` +docs/ +├── README.md # This file +├── tutorials/ +│ ├── 2mic-hat.md # 2-MIC HAT setup +│ └── installer.md # Interactive installer +├── integration/ +│ ├── vad-wakeword.md # VAD/Wake technical guide +│ └── mqtt-led.md # LED/MQTT integration +├── deployment/ +│ └── systemd-services.md # systemd configuration +└── architecture/ + └── overview.md # High-level architecture +``` diff --git a/docs/architecture/overview.md b/docs/architecture/overview.md new file mode 100644 index 0000000..83d16c9 --- /dev/null +++ b/docs/architecture/overview.md @@ -0,0 +1,175 @@ +# Architecture Overview + +High-level architecture of Wyoming Satellite. + +## Core Components + +``` +┌─────────────────────────────────────────────────────────────┐ +│ Home Assistant │ +│ (Wyoming Integration) │ +└──────────────────────┬──────────────────────────────────────┘ + │ Wyoming Protocol (TCP) + │ Port 10700 +┌──────────────────────▼──────────────────────────────────────┐ +│ Wyoming Satellite │ +│ ┌─────────────────────────────────────────────────────┐ │ +│ │ SatelliteBase │ │ +│ │ ├─ AlwaysStreamingSatellite │ │ +│ │ ├─ VadStreamingSatellite │ │ +│ │ └─ WakeStreamingSatellite │ │ +│ └─────────────────────────────────────────────────────┘ │ +│ │ +│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │ +│ │ MicSettings │ │ SndSettings │ │ WakeSettings │ │ +│ └──────────────┘ └──────────────┘ └──────────────┘ │ +│ │ +│ ┌─────────────────────────────────────────────────────┐ │ +│ │ EventHandler │ │ +│ └─────────────────────────────────────────────────────┘ │ +└──────────┬─────────────────────┬───────────────────────────┘ + │ │ + │ Audio In │ Audio Out + │ (arecord) │ (aplay) +┌──────────▼──────┐ ┌────────▼──────────┐ +│ Microphone │ │ Speaker │ +│ USB/HAT │ │ USB/HAT │ +└─────────────────┘ └───────────────────┘ + +┌─────────────────────────────────────────────────────────────┐ +│ Local Services (Optional) │ +├─────────────────────────────────────────────────────────────┤ +│ ┌─────────────────────┐ ┌─────────────────────┐ │ +│ │ Wake Word Service │ │ Event Service │ │ +│ │ (Vosk, port 10400) │ │ (MQTT, port 10500) │ │ +│ └─────────────────────┘ └─────────────────────┘ │ +└─────────────────────────────────────────────────────────────┘ +``` + +## Satellite Modes + +### AlwaysStreamingSatellite + +Continuously streams audio to Home Assistant. + +- **Pros:** Lowest latency, simplest +- **Cons:** Highest bandwidth, no local processing +- **Use case:** Fast LAN, no privacy concerns + +### VadStreamingSatellite + +Uses Voice Activity Detection to start streaming only when speech is detected. + +- **VAD Systems:** + - **Silero:** Neural network-based, more accurate + - **WebRTC:** Lightweight, faster +- **Features:** + - Pre-roll buffer (sends audio before VAD trigger) + - Wake word timeout (wait for wake word after VAD) +- **Use case:** Privacy-focused, bandwidth-constrained + +### WakeStreamingSatellite + +Uses local wake word detection before streaming. + +- **Wake Word Systems:** + - **Vosk:** Grammar-based (Russian phrases) + - **openWakeWord:** Neural network + - **Porcupine:** Commercial KWS +- **Flow:** + 1. Continuously listen for wake word + 2. On detection → start streaming to HA + 3. Process command → stop streaming +- **Use case:** Full local wake word, "Hey Google" style + +## Audio Pipeline + +``` +Microphone + │ + ▼ +┌─────────────────┐ +│ Audio Capture │ arecord -r 16000 -c 1 -f S16_LE +└────────┬────────┘ + │ + ▼ +┌─────────────────┐ +│ Pre-processing │ Volume, AGC, Noise Suppression +└────────┬────────┘ + │ + ▼ +┌─────────────────┐ +│ VAD / Wake │ Decision: stream or not? +└────────┬────────┘ + │ + ▼ +┌─────────────────┐ +│ Wyoming Protocol│ Encode to Wyoming messages +└────────┬────────┘ + │ + ▼ + Home Assistant +``` + +## Key Files + +| File | Purpose | +|------|---------| +| `wyoming_satellite/__main__.py` | CLI entry point, argument parsing | +| `wyoming_satellite/satellite.py` | Satellite implementations | +| `wyoming_satellite/settings.py` | Settings dataclasses | +| `wyoming_satellite/event_handler.py` | Wyoming event handling | +| `wyoming_satellite/vad.py` | VAD implementations (Silero, WebRTC) | +| `wyoming_satellite/webrtc.py` | WebRTC audio processing | + +## Configuration + +Main configuration via CLI arguments (see `__main__.py`): + +```bash +# Microphone +--mic-command 'arecord -r 16000 -c 1 -f S16_LE -t raw' +--mic-noise-suppression 2 +--mic-auto-gain 5 + +# Wake word +--wake-uri tcp://127.0.0.1:10400 +--wake-word-name "привет дроид" + +# VAD +--vad +--vad-system webrtc +--vad-threshold 0.5 + +# Events (LED, MQTT) +--event-uri tcp://127.0.0.1:10500 +``` + +## State Machine + +``` + ┌──────────────┐ + │ Stopped │ + └──────┬───────┘ + │ Start + ▼ + ┌──────────────┐ + ┌────────│ Listening │────────┐ + │ └──────┬───────┘ │ + │ │ │ + VAD trigger Wake detection Streaming + │ │ │ + ▼ ▼ ▼ + ┌──────────┐ ┌──────────┐ ┌──────────┐ + │ VAD │ │ Wake │ │Streaming │ + │ Active │ │ Active │ │ Audio │ + └────┬─────┘ └────┬─────┘ └────┬─────┘ + │ │ │ + └───────────────┴───────────────┘ + │ + AudioStop + ▼ + ┌──────────────┐ + │ Listening │ + └──────────────┘ +``` diff --git a/docs/deployment/systemd-services.md b/docs/deployment/systemd-services.md new file mode 100644 index 0000000..104dba5 --- /dev/null +++ b/docs/deployment/systemd-services.md @@ -0,0 +1,140 @@ +# systemd Services Configuration + +Detailed guide for configuring and managing Wyoming Satellite systemd services. + +## Service Files Location + +Service files are in the `services/` directory: + +``` +services/ +├── wyoming-event.service # LED control + MQTT +├── wyoming-satelite-vosk.service # Main satellite +└── wyoming-wakeword-vosk.service # Wake word detection +``` + +## Installation Script + +The `install_systemd_services.sh` script automatically: + +1. Detects your virtual environment path +2. Determines the current user +3. Substitutes placeholders in service files +4. Copies services to `/etc/systemd/system/` +5. Installs the `satellite-python` wrapper to `/usr/local/bin/` + +### Manual Installation + +If the script doesn't work, install manually: + +```bash +# 1. Edit service files, replacing placeholders: +# __SAT_BASE_DIR__ → /home/sirmrak/projects/Satellite +# __SAT_VENV__ → /home/sirmrak/.venv_satellite +# __CURRENT_USER__ → sirmrak + +# 2. Copy to systemd directory +sudo cp services/*.service /etc/systemd/system/ + +# 3. Reload systemd +sudo systemctl daemon-reload + +# 4. Enable and start +sudo systemctl enable --now wyoming-satelite-vosk.service +``` + +## Service Details + +### wyoming-satelite-vosk.service + +Main Wyoming satellite service. Connects to: +- Microphone (arecord) +- Speaker (aplay) +- Wake word service (optional, port 10400) +- Event service (optional, port 10500) + +**Ports:** 10700 (Wyoming protocol) + +**Dependencies:** network.target + +### wyoming-wakeword-vosk.service + +Vosk-based wake word detection service. Listens for Russian wake words: +- "привет дроид" +- "привет придурок" +- "привет жопа с ушами" + +**Ports:** 10400 (Wyoming protocol) + +**Configuration:** `local/vosk-wake-dev/wyoming_vosk_wake/config.yaml` + +### wyoming-event.service + +LED control and MQTT integration for ReSpeaker XVF3800. + +**Ports:** 10500 (Wyoming event protocol) + +**MQTT Topics:** +- `wyoming/led/command` — Commands from Home Assistant +- `wyoming/led/brightness/set` — Set brightness (0-255) +- `wyoming/led/brightness/state` — Current brightness state +- `wyoming/led/state` — LED state +- `wyoming/led/availability` — Online/offline status + +## Management Commands + +```bash +# Check status +sudo systemctl status wyoming-satelite-vosk.service + +# View logs (real-time) +journalctl -u wyoming-satelite-vosk.service -f + +# Restart service +sudo systemctl restart wyoming-satelite-vosk.service + +# Disable service +sudo systemctl disable --now wyoming-satelite-vosk.service + +# Reload systemd after changes +sudo systemctl daemon-reload +``` + +## Troubleshooting + +### Service won't start + +```bash +# Check status and recent errors +sudo systemctl status wyoming-satelite-vosk.service + +# View full logs +journalctl -u wyoming-satelite-vosk.service -n 100 + +# Check Python path +which satellite-python +satellite-python --version +``` + +### Common Issues + +| Issue | Solution | +|-------|----------| +| `ModuleNotFoundError` | Check venv path in service file | +| `arecord: command not found` | Install `alsa-utils` | +| Permission denied | Check `User=` directive matches your username | +| Port already in use | Check if another instance is running | + +## Wrapper Script + +The `satellite-python` wrapper allows running Python from venv without full path: + +```bash +# Installed to /usr/local/bin/satellite-python +satellite-python --version # Uses venv Python +``` + +Used in service files: +```ini +ExecStart=satellite-python -m wyoming_satellite ... +``` diff --git a/docs/integration/mqtt-led.md b/docs/integration/mqtt-led.md new file mode 100644 index 0000000..b65b9e1 --- /dev/null +++ b/docs/integration/mqtt-led.md @@ -0,0 +1,175 @@ +# MQTT LED Control + +Integration guide for ReSpeaker LED control via MQTT and Home Assistant. + +## Overview + +The LED service (`examples/wyoming-led.py`) provides: + +- **Light entity** — Control LED brightness and color +- **Sensor entity** — Satellite state (idle, listening, speaking) +- **Number entities** — 7 sliders for fine-grained control +- **MQTT Discovery** — Auto-configuration in Home Assistant + +## Architecture + +``` +┌──────────────────┐ MQTT ┌──────────────────┐ +│ Home Assistant │◄─────────────►│ wyoming-led.py │ +│ │ │ (port 10501) │ +└──────────────────┘ └────────┬─────────┘ + │ + │ Wyoming Events + │ (port 10500) + ┌────────▼─────────┐ + │ Satellite │ + │ (port 10700) │ + └──────────────────┘ +``` + +## Installation + +### 1. Install Dependencies + +```bash +cd ~/projects/Satellite +source ~/.venv_satellite/bin/activate +pip install paho-mqtt +``` + +### 2. Configure MQTT Settings + +Edit `examples/wyoming-led.py`: + +```python +MQTT_BROKER = "192.168.200.100" # Your MQTT broker +MQTT_PORT = 1883 +MQTT_USER = "mqtt" +MQTT_PASS = "mqtt" +``` + +### 3. Create systemd Service + +```bash +sudo nano /etc/systemd/system/wyoming-led.service +``` + +```ini +[Unit] +Description=Wyoming LED Service with MQTT +After=network.target mosquitto.service + +[Service] +Type=simple +User=sirmrak +WorkingDirectory=/home/sirmrak/projects/Satellite +Environment="PATH=/home/sirmrak/projects/.venv_satellite/bin" +ExecStart=/home/sirmrak/projects/.venv_satellite/bin/python3 /home/sirmrak/projects/Satellite/examples/wyoming-led.py --host 0.0.0.0 --port 10501 +Restart=always + +[Install] +WantedBy=multi-user.target +``` + +### 4. Enable Service + +```bash +sudo systemctl daemon-reload +sudo systemctl enable --now wyoming-led.service +``` + +## MQTT Topics + +| Topic | Direction | Description | +|-------|-----------|-------------| +| `wyoming/led/command` | HA → Script | Light commands (on/off, color, brightness) | +| `wyoming/led/brightness/set` | HA → Script | Set brightness (0-255) | +| `wyoming/led/brightness/state` | Script → HA | Current brightness | +| `wyoming/led/state` | Script → HA | LED state (on/off) | +| `wyoming/led/availability` | Script → HA | Online/offline | +| `wyoming/satellite/state` | Script → HA | Satellite state | + +## Home Assistant Entities + +After discovery, you'll see: + +- **Light:** `light.wyoming_led` — RGB control +- **Sensor:** `sensor.wyoming_satellite_state` — Current state +- **Number:** `number.wyoming_led_brightness` — Brightness slider +- **Number:** `number.wyoming_led_red/green/blue` — Color sliders +- **Number:** `number.wyoming_led_idle/listening/speaking` — State colors + +## LED States + +| State | Color | Behavior | +|-------|-------|----------| +| Idle | Blue (dim) | Breathing effect | +| Listening | Cyan | Solid | +| Speaking | Green | Solid | +| Error | Red | Blinking | + +## Brightness Configuration + +LED brightness is stored in `examples/led_brightness_config.json`: + +```json +{ + "idle": 50, + "listening": 100, + "speaking": 150, + "error": 200 +} +``` + +This file is auto-created and should be excluded from git tracking: + +```bash +git update-index --assume-unchanged examples/led_brightness_config.json +``` + +## Troubleshooting + +### LEDs not responding + +```bash +# Check service status +sudo systemctl status wyoming-led.service + +# View logs +journalctl -u wyoming-led.service -f + +# Test manually +python3 examples/wyoming-led.py --debug +``` + +### MQTT connection failed + +- Verify broker is running: `sudo systemctl status mosquitto` +- Check credentials in `wyoming-led.py` +- Test connection: `mosquitto_sub -t 'wyoming/led/#' -v` + +### ReSpeaker not detected + +```bash +# Check USB devices +lsusb | grep -i respeaker + +# Test xvf_host.py +python3 examples/xvf_host.py --help +``` + +## Hardware Support + +| Device | Support | Notes | +|--------|---------|-------| +| ReSpeaker XVF3800 (USB 4-MIC) | ✅ Full | Recommended | +| ReSpeaker 2-MIC HAT | ✅ Full | Requires GPIO | +| ReSpeaker 4-MIC HAT | ✅ Full | Requires GPIO | +| Generic USB mic | ⚠️ Partial | No LED control | + +## Related Files + +- `examples/wyoming-led.py` — Main LED control script +- `examples/xvf_host.py` — ReSpeaker XVF3800 driver +- `examples/led_brightness_config.json` — Brightness settings +- `services/wyoming-event.service` — Event service (alternative) diff --git a/integrate.md b/docs/integration/vad-wakeword.md similarity index 100% rename from integrate.md rename to docs/integration/vad-wakeword.md diff --git a/docs/tutorial_2mic.md b/docs/tutorials/2mic-hat.md similarity index 98% rename from docs/tutorial_2mic.md rename to docs/tutorials/2mic-hat.md index 21ffd86..9a82f65 100755 --- a/docs/tutorial_2mic.md +++ b/docs/tutorials/2mic-hat.md @@ -1,8 +1,8 @@ -# Tutorial with 2mic HAT +# 2-MIC HAT Tutorial Create a voice satellite using a [Raspberry Pi Zero 2 W](https://www.raspberrypi.com/products/raspberry-pi-zero-2-w/) and a [ReSpeaker 2Mic HAT](https://wiki.keyestudio.com/Ks0314_keyestudio_ReSpeaker_2-Mic_Pi_HAT_V1.0). -This tutorial should work for almost any Raspberry Pi and USB microphone. Audio enhancements and local wake word detection may require a 64-bit operating system, however. +**Prerequisites:** See [Deployment Guide](../../DEPLOY.md) for base installation. ## Install OS diff --git a/docs/tutorial_installer.md b/docs/tutorials/installer.md similarity index 95% rename from docs/tutorial_installer.md rename to docs/tutorials/installer.md index c6b16af..de556f9 100755 --- a/docs/tutorial_installer.md +++ b/docs/tutorials/installer.md @@ -1,7 +1,9 @@ -# Tutorial with Installer +# Interactive Installer Tutorial Create a voice satellite using a Raspberry Pi 3+ and USB microphone and speakers. +**Prerequisites:** See [Deployment Guide](../../DEPLOY.md) for base installation. + ## Install OS Follow instructions to [install Raspberry Pi OS](https://www.raspberrypi.com/software/). Under "Choose OS", pick "Raspberry Pi OS (other)" and "Raspberry Pi OS (**64-bit**) Lite". diff --git a/wyoming-led.service b/wyoming-led.service deleted file mode 100644 index 7e80dc7..0000000 --- a/wyoming-led.service +++ /dev/null @@ -1,20 +0,0 @@ -[Unit] -Description=Wyoming LED Service with MQTT (ReSpeaker XVF3800) -After=network.target mosquitto.service -Wants=mosquitto.service - -[Service] -Type=simple -User=sirmrak -Group=sirmrak -WorkingDirectory=/home/sirmrak/projects/Satellite -Environment="PATH=/home/sirmrak/projects/.venv_satellite/bin" -ExecStart=/home/sirmrak/projects/.venv_satellite/bin/python3 /home/sirmrak/projects/Satellite/examples/wyoming-led.py --host 0.0.0.0 --port 10701 -Restart=always -RestartSec=5 -StandardOutput=journal -StandardError=journal -SyslogIdentifier=wyoming-led - -[Install] -WantedBy=multi-user.target diff --git a/wyoming-satellite.service b/wyoming-satellite.service deleted file mode 100755 index 630cd81..0000000 --- a/wyoming-satellite.service +++ /dev/null @@ -1,18 +0,0 @@ -[Unit] -Description=Wyoming Satellite Service (Wake Mode) -Requires=network.target -After=network.target - -[Service] -Type=simple -User=sirmrak -WorkingDirectory=/home/sirmrak/wyoming-satellite -ExecStart=/home/sirmrak/wyoming-satellite/start_satellite.sh -Environment="PYTHONUNBUFFERED=1" -Restart=on-failure -RestartSec=5 -StandardOutput=journal -StandardError=journal - -[Install] -WantedBy=multi-user.target \ No newline at end of file diff --git a/wyoming_satellite.zip b/wyoming_satellite.zip deleted file mode 100755 index 4e60663..0000000 Binary files a/wyoming_satellite.zip and /dev/null differ