Обновлено описание установки
This commit is contained in:
@@ -3,189 +3,311 @@
|
|||||||
Remote voice satellite using the [Wyoming protocol](https://github.com/rhasspy/wyoming).
|
Remote voice satellite using the [Wyoming protocol](https://github.com/rhasspy/wyoming).
|
||||||
|
|
||||||
* Works with [Home Assistant](https://www.home-assistant.io/integrations/wyoming)
|
* Works with [Home Assistant](https://www.home-assistant.io/integrations/wyoming)
|
||||||
* Local wake word detection using [Wyoming services](https://github.com/rhasspy/wyoming#wyoming-projects)
|
* Local wake word detection using [Vosk](https://alphacephei.com/vosk/)
|
||||||
* Audio enhancements using [webrtc](https://github.com/rhasspy/webrtc-noise-gain/)
|
* Audio enhancements using [webrtc](https://github.com/rhasspy/webrtc-noise-gain/)
|
||||||
|
* MQTT integration for LED control and Home Assistant discovery
|
||||||
See [the tutorial](docs/tutorial_2mic.md) to build a 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).
|
|
||||||
|
|
||||||
Video tutorials:
|
|
||||||
|
|
||||||
* [Wyoming Voice Satellite with ChatGPT](https://www.youtube.com/watch?v=eTKgc0YDCwE)
|
|
||||||
* [Local ChatGPT Voice Assistant](https://www.youtube.com/watch?v=pAKqKTkx5X4)
|
|
||||||
|
|
||||||
[](https://www.openhomefoundation.org/)
|
[](https://www.openhomefoundation.org/)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
Requires:
|
## 📋 Requirements
|
||||||
|
|
||||||
* Python 3.7+ (tested on 3.9+)
|
* Python 3.9+
|
||||||
* A microphone
|
* Linux (tested on Raspberry Pi OS)
|
||||||
|
* Microphone (USB or HAT)
|
||||||
|
* Optional: ReSpeaker XVF3800 USB 4-MIC Array (for LED control)
|
||||||
|
|
||||||
## Installation
|
---
|
||||||
|
|
||||||
Install the necessary system dependencies:
|
## 🚀 Quick Start
|
||||||
|
|
||||||
``` sh
|
### 1. Clone and Install
|
||||||
sudo apt-get install python3-venv python3-pip
|
|
||||||
|
```bash
|
||||||
|
git clone <repository-url> ~/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
|
||||||
```
|
```
|
||||||
|
|
||||||
Then run the install script:
|
### 2. Install systemd Services
|
||||||
|
|
||||||
``` sh
|
```bash
|
||||||
script/setup
|
sudo ./install_systemd_services.sh
|
||||||
```
|
```
|
||||||
|
|
||||||
The examples below uses `alsa-utils` to record and play audio:
|
This script automatically:
|
||||||
|
- Detects your virtual environment location
|
||||||
|
- Substitutes correct paths in service files
|
||||||
|
- Installs the `satellite-python` wrapper
|
||||||
|
|
||||||
``` sh
|
### 3. Start Services
|
||||||
sudo apt-get install alsa-utils
|
|
||||||
|
```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
|
||||||
|
|
||||||
## Remote Wake Word Detection
|
```bash
|
||||||
|
sudo systemctl status wyoming-satelite-vosk.service
|
||||||
|
journalctl -u wyoming-satelite-vosk.service -f
|
||||||
|
```
|
||||||
|
|
||||||
Run the satellite with remote wake word detection:
|
---
|
||||||
|
|
||||||
``` sh
|
## 📦 Installation
|
||||||
cd wyoming-satellite/
|
|
||||||
script/run \
|
### System Dependencies
|
||||||
--name 'my satellite' \
|
|
||||||
|
```bash
|
||||||
|
sudo apt-get install python3-venv python3-pip alsa-utils
|
||||||
|
```
|
||||||
|
|
||||||
|
### Python Dependencies
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Create and activate venv
|
||||||
|
python3 -m venv ~/.venv_satellite
|
||||||
|
source ~/.venv_satellite/bin/activate
|
||||||
|
|
||||||
|
# Install requirements
|
||||||
|
pip install -r requirements.txt
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🔧 Configuration
|
||||||
|
|
||||||
|
### 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) |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🎤 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' \
|
--uri 'tcp://0.0.0.0:10700' \
|
||||||
--mic-command 'arecord -r 16000 -c 1 -f S16_LE -t raw' \
|
--mic-command 'arecord -r 16000 -c 1 -f S16_LE -t raw' \
|
||||||
--snd-command 'aplay -r 22050 -c 1 -f S16_LE -t raw'
|
--snd-command 'aplay -r 22050 -c 1 -f S16_LE -t raw'
|
||||||
```
|
```
|
||||||
|
|
||||||
This will use the default microphone and playback devices.
|
### Wake Word Configuration
|
||||||
|
|
||||||
Use `arecord -D <DEVICE> ...` if you need to use a different microphone (list them with `arecord -L` and prefer `plughw:` devices).
|
Edit `local/vosk-wake-dev/wyoming_vosk_wake/config.yaml`:
|
||||||
Use `aplay -D <DEVICE> ...` if you need to use a different playback device (list them with `aplay -L` and prefer `plughw:` devices).
|
|
||||||
|
|
||||||
Add `--debug` to print additional logs.
|
```yaml
|
||||||
|
vad:
|
||||||
|
vad_enabled: true
|
||||||
|
energy_threshold: 800
|
||||||
|
speech_threshold: 0.5
|
||||||
|
min_speech_duration_ms: 200
|
||||||
|
|
||||||
In the [Home Assistant](https://www.home-assistant.io/) settings "Devices & services" page, you should see the satellite discovered automatically. If not, click "Add Integration", choose "Wyoming Protocol", and enter the IP address of the satellite (port 10700).
|
logging_level: debug # debug, info, warning, error
|
||||||
|
|
||||||
Audio will be continuously streamed to the server, where wake word detection, etc. will occur.
|
|
||||||
|
|
||||||
### Voice Activity Detection
|
|
||||||
|
|
||||||
Rather than always streaming audio to Home Assistant, the satellite can wait until speech is detected.
|
|
||||||
|
|
||||||
**NOTE:** This will not work on the 32-bit version of Raspberry Pi OS.
|
|
||||||
|
|
||||||
Install the dependencies for silero VAD:
|
|
||||||
|
|
||||||
``` sh
|
|
||||||
.venv/bin/pip3 install 'pysilero-vad==1.0.0'
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Run the satellite with VAD enabled:
|
### LED Control (ReSpeaker)
|
||||||
|
|
||||||
``` sh
|
The LED service requires the [ReSpeaker XVF3800 control scripts](https://github.com/respeaker/usb_4mic_array):
|
||||||
script/run \
|
|
||||||
... \
|
```bash
|
||||||
--vad
|
# 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
|
||||||
```
|
```
|
||||||
|
|
||||||
Now, audio will only start streaming once speech has been detected.
|
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
|
||||||
|
|
||||||
## Local Wake Word Detection
|
---
|
||||||
|
|
||||||
Install a wake word detection service, such as [wyoming-openwakeword](https://github.com/rhasspy/wyoming-openwakeword/) and start it:
|
## 🔍 Examples
|
||||||
|
|
||||||
``` sh
|
See `examples/` directory for additional scripts:
|
||||||
cd wyoming-openwakeword/
|
|
||||||
script/run \
|
| File | Description |
|
||||||
--uri 'tcp://0.0.0.0:10400' \
|
|------|-------------|
|
||||||
--preload-model 'ok_nabu'
|
| `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
|
||||||
|
|
||||||
|
```
|
||||||
|
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
|
||||||
```
|
```
|
||||||
|
|
||||||
Add `--debug` to print additional logs. See `--help` for more information.
|
### Running Tests
|
||||||
|
|
||||||
Included wake words are:
|
```bash
|
||||||
|
# Run linters
|
||||||
|
pylint wyoming_satellite/
|
||||||
|
mypy wyoming_satellite/
|
||||||
|
|
||||||
* `ok_nabu`
|
# Run tests (if available)
|
||||||
* `hey_jarvis`
|
pytest tests/
|
||||||
* `alexa`
|
|
||||||
* `hey_mycroft`
|
|
||||||
* `hey_rhasspy`
|
|
||||||
|
|
||||||
[Community trained wake words](https://github.com/fwartner/home-assistant-wakewords-collection) are also available and can be included with `--custom-model-dir <DIR>` where `<DIR>` contains `.tflite` file(s).
|
|
||||||
|
|
||||||
Next, start the satellite with some additional arguments:
|
|
||||||
|
|
||||||
``` sh
|
|
||||||
cd wyoming-satellite/
|
|
||||||
script/run \
|
|
||||||
--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-uri 'tcp://127.0.0.1:10400' \
|
|
||||||
--wake-word-name 'ok_nabu'
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Audio will only be streamed to the server after the wake word has been detected.
|
### Updating Dependencies
|
||||||
|
|
||||||
Once a wake word has been detected, it can not be detected again for several seconds (called the "refractory period"). You can change this with `--wake-refractory-seconds <SECONDS>`.
|
```bash
|
||||||
|
# Update requirements.txt from current venv
|
||||||
Note that `--vad` is unnecessary when connecting to a local instance of openwakeword.
|
pip freeze > requirements.txt
|
||||||
|
|
||||||
## Sounds
|
|
||||||
|
|
||||||
You can play a WAV file when the wake word is detected (locally or remotely), and when speech-to-text has completed:
|
|
||||||
|
|
||||||
* `--awake-wav <WAV>` - played when the wake word is detected
|
|
||||||
* `--done-wav <WAV>` - played when the voice command is finished
|
|
||||||
* `--timer-finished-wav <WAV>` - played when a timer is finished
|
|
||||||
|
|
||||||
If you want to play audio files other than WAV, use [event commands](#event-commands). Specifically, the `--detection-command` to replace `--awake-wav` and `--transcript-command` to replace `--done-wav`.
|
|
||||||
|
|
||||||
The timer finished sound can be repeated with `--timer-finished-wav-repeat <repeats> <delay>` where `<repeats>` is the number of times to repeat the WAV, and `<delay>` is the number of seconds to wait between repeats.
|
|
||||||
|
|
||||||
## Audio Enhancements
|
|
||||||
|
|
||||||
Install the dependencies for webrtc:
|
|
||||||
|
|
||||||
``` sh
|
|
||||||
.venv/bin/pip3 install 'webrtc-noise-gain==1.2.3'
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Run the satellite with automatic gain control and noise suppression:
|
---
|
||||||
|
|
||||||
``` sh
|
## 📖 Documentation
|
||||||
script/run \
|
|
||||||
... \
|
* [Deployment Guide](DEPLOY.md) - Full deployment instructions
|
||||||
--mic-auto-gain 5 \
|
* [Wyoming Protocol](https://github.com/rhasspy/wyoming) - Protocol documentation
|
||||||
--mic-noise-suppression 2
|
* [Home Assistant Integration](https://www.home-assistant.io/integrations/wyoming) - HA setup
|
||||||
|
* [Vosk](https://alphacephei.com/vosk/) - Wake word recognition
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🎥 Video Tutorials
|
||||||
|
|
||||||
|
* [Wyoming Voice Satellite with ChatGPT](https://www.youtube.com/watch?v=eTKgc0YDCwE)
|
||||||
|
* [Local ChatGPT Voice Assistant](https://www.youtube.com/watch?v=pAKqKTkx5X4)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ⚙️ 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
|
||||||
```
|
```
|
||||||
|
|
||||||
Automatic gain control is between 0-31 dbFS, which 31 being the loudest.
|
### VAD (Voice Activity Detection)
|
||||||
Noise suppression is from 0-4, with 4 being maximum suppression (may cause audio distortion).
|
|
||||||
|
|
||||||
You can also use `--mic-volume-multiplier X` to multiply all audio samples by `X`. For example, using 2 for `X` will double the microphone volume (but may cause audio distortion). The corresponding `--snd-volume-multiplier` does the same for audio playback.
|
Configured in `config.yaml`:
|
||||||
|
```yaml
|
||||||
|
vad:
|
||||||
|
vad_enabled: true
|
||||||
|
mode: 3 # 0-3, higher = more aggressive
|
||||||
|
sample_rate: 16000
|
||||||
|
```
|
||||||
|
|
||||||
## Event Commands
|
---
|
||||||
|
|
||||||
Satellites can respond to events from the server by running commands:
|
## 🐛 Troubleshooting
|
||||||
|
|
||||||
* `--startup-command` - run when satellite starts (no stdin)
|
### Service won't start
|
||||||
* `--detect-command` - wake word detection has started, but not detected yet (no stdin)
|
|
||||||
* `--streaming-start-command` - audio has started streaming to server (no stdin)
|
|
||||||
* `--streaming-stop-command` - audio has stopped streaming to server (no stdin)
|
|
||||||
* `--detection-command` - wake word is detected (wake word name on stdin)
|
|
||||||
* `--transcript-command` - speech-to-text transcript is returned (text on stdin)
|
|
||||||
* `--stt-start-command` - user started speaking (no stdin)
|
|
||||||
* `--stt-stop-command` - user stopped speaking (no stdin)
|
|
||||||
* `--synthesize-command` - text-to-speech text is returned (text on stdin)
|
|
||||||
* `--tts-start-command` - text-to-speech response started streaming from server (no stdin)
|
|
||||||
* `--tts-stop-command` - text-to-speech response stopped streaming from server. Can still being played by snd service (no stdin)
|
|
||||||
* `--tts-played-command` - text-to-speech audio finished playing (no stdin)
|
|
||||||
* `--error-command` - an error was sent from the server (text on stdin)
|
|
||||||
* `--connected-command` - satellite connected to server
|
|
||||||
* `--disconnected-command` - satellite disconnected from server
|
|
||||||
* `--timer-started-command` - new timer has started (json on stdin)
|
|
||||||
* `--timer-updated-command` - timer has been paused/unpaused or has time added/removed (json on stdin)
|
|
||||||
* `--timer-cancelled-command` - timer has been cancelled (timer id on stdin)
|
|
||||||
* `--timer-finished-command` - timer has finished (timer id on stdin)
|
|
||||||
|
|
||||||
For more advanced scenarios, use an event service (`--event-uri`). See `wyoming_satellite/example_event_client.py` for a basic client that just logs events.
|
```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
|
||||||
|
|
||||||
|
This project is part of the Open Home Foundation ecosystem.
|
||||||
|
|
||||||
|
[](https://www.openhomefoundation.org/)
|
||||||
|
|||||||
Reference in New Issue
Block a user