From 87502c55e0cc7bde33e114e3a63d795175060dd8 Mon Sep 17 00:00:00 2001 From: sirmrak Date: Sat, 9 May 2026 11:49:44 +0300 Subject: [PATCH] =?UTF-8?q?=D0=97=D0=B0=D0=B3=D1=80=D1=83=D0=B7=D0=BA?= =?UTF-8?q?=D0=B0=20=D0=B8=D1=81=D1=85=D0=BE=D0=B4=D0=BD=D0=B8=D0=BA=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .dockerignore | 9 + .gitignore | 17 + .isort.cfg | 6 + .projectile | 2 + CHANGELOG.md | 47 + Dockerfile | 23 + LICENSE.md | 21 + README.md | 191 +++ docker-compose.yml | 38 + docker/run | 3 + docs/tutorial_2mic.md | 396 +++++ docs/tutorial_installer.md | 75 + etc/install-respeaker-drivers.sh | 79 + examples/2mic_service.py | 282 +++ examples/4mic_service.py | 293 ++++ examples/commands/detection.sh | 4 + examples/commands/startup.sh | 3 + examples/commands/streaming_start.sh | 3 + examples/commands/streaming_stop.sh | 3 + examples/commands/stt_start.sh | 3 + examples/commands/stt_stop.sh | 3 + examples/commands/synthesize.sh | 4 + examples/commands/transcript.sh | 4 + examples/commands/tts_start.sh | 3 + examples/commands/tts_stop.sh | 3 + examples/usbmic_service.py | 104 ++ examples/websocket-service/requirements.txt | 1 + examples/websocket-service/server.py | 100 ++ examples/websocket-service/timer_finished.wav | Bin 0 -> 35874 bytes examples/websocket-service/timers.html | 244 +++ install_service.sh | 95 ++ installer/__init__.py | 1 + installer/__main__.py | 174 ++ installer/const.py | 114 ++ installer/dataclasses_json.py | 70 + installer/drivers.py | 50 + installer/microphone.py | 214 +++ installer/packages.py | 87 + installer/satellite.py | 120 ++ installer/services.py | 262 +++ installer/speakers.py | 150 ++ installer/wake_word.py | 468 +++++ installer/whiptail.py | 253 +++ integrate.md | 62 + mypy.ini | 5 + pylintrc | 37 + pyproject.toml | 61 + script/build_docker | 3 + script/format | 18 + script/lint | 20 + script/package | 11 + script/run | 12 + script/run_2mic | 15 + script/run_4mic | 15 + script/run_docker | 6 + script/run_usbmic | 15 + script/setup | 42 + script/test | 13 + setup.cfg | 22 + sounds/awake.wav | Bin 0 -> 17666 bytes sounds/done.wav | Bin 0 -> 49242 bytes sounds/listen.wav | Bin 0 -> 304206 bytes sounds/timer_finished.wav | Bin 0 -> 35874 bytes sounds/volume.wav | Bin 0 -> 35874 bytes start-dev.sh | 6 + start.sh | 6 + start_satellite.sh | 54 + test.wav | Bin 0 -> 232044 bytes tests/__init__.py | 1 + tests/shared.py | 64 + tests/test_satellite.py | 222 +++ tests/test_wake_streaming.py | 97 ++ tox.ini | 14 + wyoming-satellite.service | 18 + wyoming_satellite.zip | Bin 0 -> 75833 bytes wyoming_satellite/__init__.py | 36 + wyoming_satellite/__main__.py | 504 ++++++ wyoming_satellite/event_handler.py | 57 + wyoming_satellite/example_event_client.py | 67 + wyoming_satellite/satellite.7z | Bin 0 -> 9717 bytes wyoming_satellite/satellite.py | 1512 +++++++++++++++++ wyoming_satellite/settings.py | 222 +++ wyoming_satellite/utils/__init__.py | 30 + wyoming_satellite/utils/audio.py | 205 +++ wyoming_satellite/utils/misc.py | 90 + wyoming_satellite/vad.py | 88 + wyoming_satellite/webrtc.py | 28 + 87 files changed, 7700 insertions(+) create mode 100755 .dockerignore create mode 100755 .gitignore create mode 100755 .isort.cfg create mode 100755 .projectile create mode 100755 CHANGELOG.md create mode 100755 Dockerfile create mode 100755 LICENSE.md create mode 100755 README.md create mode 100755 docker-compose.yml create mode 100755 docker/run create mode 100755 docs/tutorial_2mic.md create mode 100755 docs/tutorial_installer.md create mode 100755 etc/install-respeaker-drivers.sh create mode 100755 examples/2mic_service.py create mode 100755 examples/4mic_service.py create mode 100755 examples/commands/detection.sh create mode 100755 examples/commands/startup.sh create mode 100755 examples/commands/streaming_start.sh create mode 100755 examples/commands/streaming_stop.sh create mode 100755 examples/commands/stt_start.sh create mode 100755 examples/commands/stt_stop.sh create mode 100755 examples/commands/synthesize.sh create mode 100755 examples/commands/transcript.sh create mode 100755 examples/commands/tts_start.sh create mode 100755 examples/commands/tts_stop.sh create mode 100755 examples/usbmic_service.py create mode 100755 examples/websocket-service/requirements.txt create mode 100755 examples/websocket-service/server.py create mode 100755 examples/websocket-service/timer_finished.wav create mode 100755 examples/websocket-service/timers.html create mode 100755 install_service.sh create mode 100755 installer/__init__.py create mode 100755 installer/__main__.py create mode 100755 installer/const.py create mode 100755 installer/dataclasses_json.py create mode 100755 installer/drivers.py create mode 100755 installer/microphone.py create mode 100755 installer/packages.py create mode 100755 installer/satellite.py create mode 100755 installer/services.py create mode 100755 installer/speakers.py create mode 100755 installer/wake_word.py create mode 100755 installer/whiptail.py create mode 100755 integrate.md create mode 100755 mypy.ini create mode 100755 pylintrc create mode 100755 pyproject.toml create mode 100755 script/build_docker create mode 100755 script/format create mode 100755 script/lint create mode 100755 script/package create mode 100755 script/run create mode 100755 script/run_2mic create mode 100755 script/run_4mic create mode 100755 script/run_docker create mode 100755 script/run_usbmic create mode 100755 script/setup create mode 100755 script/test create mode 100755 setup.cfg create mode 100755 sounds/awake.wav create mode 100755 sounds/done.wav create mode 100755 sounds/listen.wav create mode 100755 sounds/timer_finished.wav create mode 100755 sounds/volume.wav create mode 100755 start-dev.sh create mode 100755 start.sh create mode 100755 start_satellite.sh create mode 100755 test.wav create mode 100755 tests/__init__.py create mode 100755 tests/shared.py create mode 100755 tests/test_satellite.py create mode 100755 tests/test_wake_streaming.py create mode 100755 tox.ini create mode 100755 wyoming-satellite.service create mode 100755 wyoming_satellite.zip create mode 100755 wyoming_satellite/__init__.py create mode 100755 wyoming_satellite/__main__.py create mode 100755 wyoming_satellite/event_handler.py create mode 100755 wyoming_satellite/example_event_client.py create mode 100755 wyoming_satellite/satellite.7z create mode 100755 wyoming_satellite/satellite.py create mode 100755 wyoming_satellite/settings.py create mode 100755 wyoming_satellite/utils/__init__.py create mode 100755 wyoming_satellite/utils/audio.py create mode 100755 wyoming_satellite/utils/misc.py create mode 100755 wyoming_satellite/vad.py create mode 100755 wyoming_satellite/webrtc.py diff --git a/.dockerignore b/.dockerignore new file mode 100755 index 0000000..c53b52f --- /dev/null +++ b/.dockerignore @@ -0,0 +1,9 @@ +* +!pyproject.toml +!script/setup +!script/run +!wyoming_satellite/*.py +!wyoming_satellite/utils +!wyoming_satellite/VERSION +!docker/run +!sounds/*.wav diff --git a/.gitignore b/.gitignore new file mode 100755 index 0000000..8798bff --- /dev/null +++ b/.gitignore @@ -0,0 +1,17 @@ +.DS_Store +.idea +*.log +tmp/ + +*.py[cod] +*.egg +*.egg-info/ +build +htmlcov + +.venv/ +.mypy_cache/ +__pycache__/ + +/dist/ +/local/ diff --git a/.isort.cfg b/.isort.cfg new file mode 100755 index 0000000..ba2778d --- /dev/null +++ b/.isort.cfg @@ -0,0 +1,6 @@ +[settings] +multi_line_output=3 +include_trailing_comma=True +force_grid_wrap=0 +use_parentheses=True +line_length=88 diff --git a/.projectile b/.projectile new file mode 100755 index 0000000..ce66c37 --- /dev/null +++ b/.projectile @@ -0,0 +1,2 @@ +- /.venv/ +- /.mypy_cache/ diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100755 index 0000000..7c3fdf5 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,47 @@ +# Changelog + +## 1.4.1 + +- Send `played` event to server + +## 1.4.0 + +- Migrate to pyproject.toml + +## 1.3.1 + +- Send audio-start to wake service after detect + +## 1.3.0 + +- Bump to wyoming 1.5.4 (timers) +- Add support for voice timers +- Add `--timer-finished-wav` and `--timer-finished-wav-repeat` +- Add `--timer-started-command` +- Add `--timer-updated-command` +- Add `--timer-cancelled-command` +- Add `--timer-finished-command` + +## 1.2.0 + +- Add `--tts-played-command` +- Add `--mic-seconds-to-mute-after-awake-wav` and `--mic-no-mute-during-awake-wav` +- Send preferred sound format to server + +## 1.1.1 + +- Bump to wyoming 1.5.2 (package fix) + +## 1.1.0 + +- Bump to wyoming 1.5.1 +- Send wyoming-satellite version in `info` message +- Ping server if supported (faster awareness of disconnection) +- Support `pause-satellite` message +- Stop streaming/wake word detection as soon as `pause-satellite` is received or server disconnects +- Mute microphone when awake WAV is playing + +## 1.0.0 + +- Initial release + diff --git a/Dockerfile b/Dockerfile new file mode 100755 index 0000000..247f4f0 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,23 @@ +FROM python:3.11-slim-bookworm + +ENV LANG C.UTF-8 +ENV DEBIAN_FRONTEND=noninteractive + +RUN apt-get update && \ + apt-get install --yes --no-install-recommends avahi-utils + +WORKDIR /app + +COPY sounds/ ./sounds/ +COPY script/setup ./script/ +COPY pyproject.toml ./ +COPY wyoming_satellite/ ./wyoming_satellite/ + +RUN script/setup + +COPY script/run ./script/ +COPY docker/run ./ + +EXPOSE 10700 + +ENTRYPOINT ["/app/run"] diff --git a/LICENSE.md b/LICENSE.md new file mode 100755 index 0000000..0875822 --- /dev/null +++ b/LICENSE.md @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2023 Michael Hansen + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100755 index 0000000..1ba070b --- /dev/null +++ b/README.md @@ -0,0 +1,191 @@ +# Wyoming 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 [Wyoming services](https://github.com/rhasspy/wyoming#wyoming-projects) +* Audio enhancements using [webrtc](https://github.com/rhasspy/webrtc-noise-gain/) + +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) + +[![An open standard from the Open Home Foundation](https://www.openhomefoundation.org/badges/ohf-open-standard.png)](https://www.openhomefoundation.org/) +--- + +Requires: + +* Python 3.7+ (tested on 3.9+) +* A microphone + +## Installation + +Install the necessary system dependencies: + +``` sh +sudo apt-get install python3-venv python3-pip +``` + +Then run the install script: + +``` sh +script/setup +``` + +The examples below uses `alsa-utils` to record and play audio: + +``` sh +sudo apt-get install alsa-utils +``` + + +## Remote Wake Word Detection + +Run the satellite with remote wake word detection: + +``` 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' +``` + +This will use the default microphone and playback devices. + +Use `arecord -D ...` if you need to use a different microphone (list them with `arecord -L` and prefer `plughw:` devices). +Use `aplay -D ...` if you need to use a different playback device (list them with `aplay -L` and prefer `plughw:` devices). + +Add `--debug` to print additional logs. + +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). + +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: + +``` sh +script/run \ + ... \ + --vad +``` + +Now, audio will only start streaming once speech has been detected. + +## Local Wake Word Detection + +Install a wake word detection service, such as [wyoming-openwakeword](https://github.com/rhasspy/wyoming-openwakeword/) and start it: + +``` sh +cd wyoming-openwakeword/ +script/run \ + --uri 'tcp://0.0.0.0:10400' \ + --preload-model 'ok_nabu' +``` + +Add `--debug` to print additional logs. See `--help` for more information. + +Included wake words are: + +* `ok_nabu` +* `hey_jarvis` +* `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 ` where `` 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. + +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 `. + +Note that `--vad` is unnecessary when connecting to a local instance of openwakeword. + +## 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 ` - played when the wake word is detected +* `--done-wav ` - played when the voice command is finished +* `--timer-finished-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 ` where `` is the number of times to repeat the WAV, and `` 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 +script/run \ + ... \ + --mic-auto-gain 5 \ + --mic-noise-suppression 2 +``` + +Automatic gain control is between 0-31 dbFS, which 31 being the loudest. +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. + +## Event Commands + +Satellites can respond to events from the server by running commands: + +* `--startup-command` - run when satellite starts (no stdin) +* `--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. diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100755 index 0000000..664d016 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,38 @@ +version: "3.8" +services: + microphone: + image: "rhasspy/wyoming-mic-external" + ports: + - "10600:10600" + devices: + - /dev/snd:/dev/snd + group_add: + - audio + command: + - "--device" + - "sysdefault" + - "--debug" + playback: + image: "rhasspy/wyoming-snd-external" + ports: + - "10601:10601" + devices: + - /dev/snd:/dev/snd + group_add: + - audio + command: + - "--device" + - "sysdefault" + - "--debug" + satellite: + image: "rhasspy/wyoming-satellite" + ports: + - "10700:10700" + command: + - "--name" + - "my satellite" + - "--mic-uri" + - "tcp://microphone:10600" + - "--snd-uri" + - "tcp://playback:10601" + - "--debug" diff --git a/docker/run b/docker/run new file mode 100755 index 0000000..2e6876d --- /dev/null +++ b/docker/run @@ -0,0 +1,3 @@ +#!/usr/bin/env bash +/app/script/run \ + --uri tcp://0.0.0.0:10700 "$@" diff --git a/docs/tutorial_2mic.md b/docs/tutorial_2mic.md new file mode 100755 index 0000000..21ffd86 --- /dev/null +++ b/docs/tutorial_2mic.md @@ -0,0 +1,396 @@ +# Tutorial with 2mic HAT + +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. + +## 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". + +When asking if you'd like to apply customization settings, choose "Edit Settings" and: + +* Set a username/password +* Configure the wireless LAN +* Under the Services tab, enable SSH and use password authentication + +## Install Software + +After flashing and booting the satellite, connect to it over SSH using the username/password you configured during flashing. + +**On the satellite**, make sure system dependencies are installed: + +```sh +sudo apt-get update +sudo apt-get install --no-install-recommends \ + git \ + python3-venv +``` + +Clone the `wyoming-satellite` repository: + +```sh +git clone https://github.com/rhasspy/wyoming-satellite.git +``` + +If you have the ReSpeaker 2Mic or 4Mic HAT, recompile and install the drivers (this will take really long time): + +```sh +cd wyoming-satellite/ +sudo bash etc/install-respeaker-drivers.sh +``` + +After install the drivers, you must reboot the satellite: + +```sh +sudo reboot +``` + +Once the satellite has rebooted, reconnect over SSH and continue the installation: + +```sh +cd wyoming-satellite/ +python3 -m venv .venv +.venv/bin/pip3 install --upgrade pip +.venv/bin/pip3 install --upgrade wheel setuptools +.venv/bin/pip3 install \ + -f 'https://synesthesiam.github.io/prebuilt-apps/' \ + -e '.[all]' +``` + +If the installation was successful, you should be able to run: + +```sh +script/run --help +``` + +## Determine Audio Devices + +Picking the correct microphone/speaker devices is critical for the satellite to work. We'll do a test recording and playback in this section. + +List your available microphones with: + +```sh +arecord -L +``` + +If you have the ReSpeaker 2Mic HAT, you should see: + +``` +plughw:CARD=seeed2micvoicec,DEV=0 + seeed-2mic-voicecard, bcm2835-i2s-wm8960-hifi wm8960-hifi-0 + Hardware device with all software conversions +``` + +For other microphones, prefer ones that start with `plughw:` or just use `default` if you don't know what to use. + +Record a 5 second sample from your chosen microphone: + +```sh +arecord -D plughw:CARD=seeed2micvoicec,DEV=0 -r 16000 -c 1 -f S16_LE -t wav -d 5 test.wav +``` + +Say something while `arecord` is running. If you get errors, try a different microphone device by changing `-D `. + +List your available speakers with: + +```sh +aplay -L +``` + +If you have the ReSpeaker 2Mic HAT, you should see: + +``` +plughw:CARD=seeed2micvoicec,DEV=0 + seeed-2mic-voicecard, bcm2835-i2s-wm8960-hifi wm8960-hifi-0 + Hardware device with all software conversions +``` + +For other speakers, prefer ones that start with `plughw:` or just use `default` if you don't know what to use. + +Play back your recorded sample WAV: + +```sh +aplay -D plughw:CARD=seeed2micvoicec,DEV=0 test.wav +``` + +You should hear your recorded sample. If there are problems, try a different speaker device by changing `-D `. + +Make note of your microphone and speaker devices for the next step. + +## Running the Satellite + +In the `wyoming-satellite` directory, run: + +```sh +script/run \ + --debug \ + --name 'my satellite' \ + --uri 'tcp://0.0.0.0:10700' \ + --mic-command 'arecord -D plughw:CARD=seeed2micvoicec,DEV=0 -r 16000 -c 1 -f S16_LE -t raw' \ + --snd-command 'aplay -D plughw:CARD=seeed2micvoicec,DEV=0 -r 22050 -c 1 -f S16_LE -t raw' +``` + +Change the `-D ` for `arecord` and `aplay` to match the audio devices from the previous section. +You can set `--name ` to whatever you want, but it should stay the same every time you run the satellite. + +In Home Assistant, check the "Devices & services" section in Settings. After some time, you should see your satellite show up as "Discovered" (Wyoming Protocol). Click the "Configure" button and "Submit". Choose the area that your satellite is located, and click "Finish". + +Your satellite should say "Streaming audio", and you can use the wake word of your preferred pipeline. + +## Create Services + +You can run wyoming-satellite as a systemd service by first creating a service file: + +``` sh +sudo systemctl edit --force --full wyoming-satellite.service +``` + +Paste in the following template, and change both `/home/pi` and the `script/run` arguments to match your set up: + +```text +[Unit] +Description=Wyoming Satellite +Wants=network-online.target +After=network-online.target + +[Service] +Type=simple +ExecStart=/home/pi/wyoming-satellite/script/run --name 'my satellite' --uri 'tcp://0.0.0.0:10700' --mic-command 'arecord -D plughw:CARD=seeed2micvoicec,DEV=0 -r 16000 -c 1 -f S16_LE -t raw' --snd-command 'aplay -D plughw:CARD=seeed2micvoicec,DEV=0 -r 22050 -c 1 -f S16_LE -t raw' +WorkingDirectory=/home/pi/wyoming-satellite +Restart=always +RestartSec=1 + +[Install] +WantedBy=default.target +``` + +Save the file and exit your editor. Next, enable the service to start at boot and run it: + +``` sh +sudo systemctl enable --now wyoming-satellite.service +``` + +(you may need to hit CTRL+C to get back to a shell prompt) + +With the service running, you can view logs in real-time with: + +``` sh +journalctl -u wyoming-satellite.service -f +``` + +If needed, disable and stop the service with: + +``` sh +sudo systemctl disable --now wyoming-satellite.service +``` + +## Audio Enhancements + +You can run the satellite with automatic gain control and noise suppression: + +``` sh +script/run \ + ... \ + --mic-auto-gain 5 \ + --mic-noise-suppression 2 +``` + +Automatic gain control is between 0-31 dbFS, which 31 being the loudest. +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. + +## Local Wake Word Detection + +Install the necessary system dependencies: + +```sh +sudo apt-get update +sudo apt-get install --no-install-recommends \ + libopenblas-dev +``` + +From your home directory, install the openWakeWord Wyoming service: + +```sh +git clone https://github.com/rhasspy/wyoming-openwakeword.git +cd wyoming-openwakeword +script/setup +``` + +Create a systemd service for it: + +``` sh +sudo systemctl edit --force --full wyoming-openwakeword.service +``` + +Paste in the following template, and change both `/home/pi` and the `script/run` arguments to match your set up: + +```text +[Unit] +Description=Wyoming openWakeWord + +[Service] +Type=simple +ExecStart=/home/pi/wyoming-openwakeword/script/run --uri 'tcp://127.0.0.1:10400' +WorkingDirectory=/home/pi/wyoming-openwakeword +Restart=always +RestartSec=1 + +[Install] +WantedBy=default.target +``` + +Save the file and exit your editor. + +You can now update your satellite service: + +``` sh +sudo systemctl edit --force --full wyoming-satellite.service +``` + +Update just the parts below: + +```text +[Unit] +... +Requires=wyoming-openwakeword.service + +[Service] +... +ExecStart=/home/pi/wyoming-satellite/script/run ... --wake-uri 'tcp://127.0.0.1:10400' --wake-word-name 'ok_nabu' +... + +[Install] +... +``` + +Reload and restart the satellite service: + +``` sh +sudo systemctl daemon-reload +sudo systemctl restart wyoming-satellite.service +``` + +You should see the wake service get automatically loaded: + +``` sh +sudo systemctl status wyoming-satellite.service wyoming-openwakeword.service +``` + +They should all be "active (running)" and green. + +Test out your satellite by saying "ok, nabu" and a voice command. Use `journalctl` to check the logs of services for errors: + +``` sh +journalctl -u wyoming-openwakeword.service -f +``` + +Make sure to run `sudo systemctl daemon-reload` every time you make changes to the service. + +## LED Service + +Example event services for the ReSpeaker 2Mic and 4Mic HATs are included in `wyoming-satellite/examples` that will change the LED color depending on the satellite state. The example below is for the 2Mic HAT, using `2mic_service.py`. If you're using the 4Mic HAT, use `4mic_service.py` instead as the LEDs and GPIO pins are slightly different. + +Install it from your home directory: + +```sh +cd wyoming-satellite/examples +python3 -m venv --system-site-packages .venv +.venv/bin/pip3 install --upgrade pip +.venv/bin/pip3 install --upgrade wheel setuptools +.venv/bin/pip3 install 'wyoming==1.5.2' +``` + +In case you use a ReSpeaker USB 4mic array v2.0, additionally install pixel-ring: + +```sh +.venv/bin/pip3 install 'pixel-ring' +``` + + +The `--system-site-packages` argument is used to access the pre-installed `gpiozero` and `spidev` Python packages. If these are **not already installed** in your system, run: + +```sh +sudo apt-get install python3-spidev python3-gpiozero +``` + +Test the service with: + +```sh +.venv/bin/python3 2mic_service.py --help +``` + +Create a systemd service for it: + +``` sh +sudo systemctl edit --force --full 2mic_leds.service +``` + +Paste in the following template, and change both `/home/pi` and the `script/run` arguments to match your set up: + +```text +[Unit] +Description=2Mic LEDs + +[Service] +Type=simple +ExecStart=/home/pi/wyoming-satellite/examples/.venv/bin/python3 2mic_service.py --uri 'tcp://127.0.0.1:10500' +WorkingDirectory=/home/pi/wyoming-satellite/examples +Restart=always +RestartSec=1 + +[Install] +WantedBy=default.target +``` + +Save the file and exit your editor. + +You can now update your satellite service: + +``` sh +sudo systemctl edit --force --full wyoming-satellite.service +``` + +Update just the parts below: + +```text +[Unit] +... +Requires=2mic_leds.service + +[Service] +... +ExecStart=/home/pi/wyoming-satellite/script/run ... --event-uri 'tcp://127.0.0.1:10500' +... + +[Install] +... +``` + +Reload and restart the satellite service: + +``` sh +sudo systemctl daemon-reload +sudo systemctl restart wyoming-satellite.service +``` + +You should see the service get automatically loaded: + +``` sh +sudo systemctl status wyoming-satellite.service 2mic_leds.service +``` + +They should all be "active (running)" and green. + +Try a voice command and see if the LEDs change. Use `journalctl` to check the logs of services for errors: + +``` sh +journalctl -u 2mic_leds.service -f +``` + +If you encounter any issues, you can add the `--debug` argument to the command line to increase the log level. +To control the brightness of the LEDS, use the `--led-brightness ` argument, which accepts integer numbers from 1 to 31. + +Make sure to run `sudo systemctl daemon-reload` every time you make changes to the service. diff --git a/docs/tutorial_installer.md b/docs/tutorial_installer.md new file mode 100755 index 0000000..c6b16af --- /dev/null +++ b/docs/tutorial_installer.md @@ -0,0 +1,75 @@ +# Tutorial with Installer + +Create a voice satellite using a Raspberry Pi 3+ and USB microphone and speakers. + +## 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". + +When asking if you'd like to apply customization settings, choose "Edit Settings" and: + +* Set a username/password +* Configure the wireless LAN +* Under the Services tab, enable SSH and use password authentication + +## Install Dependencies + +After flashing and booting the satellite, connect to it over SSH using the username/password you configured during flashing. + +**On the satellite**, make sure system dependencies are installed: + +```sh +sudo apt-get update +sudo apt-get install --no-install-recommends \ + git \ + python3-venv +``` + +Clone the `wyoming-satellite` repository: + +```sh +git clone https://github.com/rhasspy/wyoming-satellite.git +``` + +Now you can run the installer: + +```sh +cd wyoming-satellite/ +python3 -m installer +``` + +## Satellite + +Under the "Satellite" menu, select "Satellite Type" and choose "Local wake word detection" (with the space bar). + +## Microphone + +Make sure you USB microphone is plugged in. + +Under the "Microphone" menu, select "Autodetect", and speak loudly into the microphone for a few seconds. + +In "Audio Settings", set "Noise Suppression" to "Medium" and "Auto Gain" to 15. + +## Speakers + +Make sure your USB speakers are plugged in. + +Under the "Speakers" menu, choose "Test All Speakers". For each device, choose "Play Sound" and listen. If you hear the sound, select "Choose This Device"; otherwise, select "Next Device". + +In "Toggle Feedback Sounds", enable "On wake-up" and "After voice command" (with the space bar). + +## Wake Word + +Under the "Wake Word" menu, select "Wake Word System" and choose "openWakeWord" (with the space bar). When prompted, install openWakeWord. + +In the "openWakeWord" menu, choose "Download Community Wake Words". Back in the "Wake Word" menu, select "Choose Wake Word" and select one (with the space bar). + +## Apply Settings + +From the main menu, select "Apply Settings" and enter your password. + +Check logs with: + +```sh +sudo journalctl -f -u wyoming-satellite.service +``` diff --git a/etc/install-respeaker-drivers.sh b/etc/install-respeaker-drivers.sh new file mode 100755 index 0000000..4e7ff22 --- /dev/null +++ b/etc/install-respeaker-drivers.sh @@ -0,0 +1,79 @@ +#!/usr/bin/env bash + +# Installs drivers for the ReSpeaker 2mic and 4mic HATs on Raspberry Pi OS. +# Must be run with sudo. +# Requires: curl raspberrypi-kernel-headers dkms i2c-tools libasound2-plugins alsa-utils + +set -eo pipefail + +kernel_formatted="$(uname -r | cut -f1,2 -d.)" +driver_url_status="$(curl -ILs https://github.com/HinTak/seeed-voicecard/archive/refs/heads/v$kernel_formatted.tar.gz | tac | grep -o "^HTTP.*" | cut -f 2 -d' ' | head -1)" + +if [ ! "$driver_url_status" = 200 ]; then +echo "Could not find driver for kernel $kernel_formatted" +exit 1 +fi + +apt-get update +apt-get install --no-install-recommends --yes \ + curl raspberrypi-kernel-headers dkms i2c-tools libasound2-plugins alsa-utils + +temp_dir="$(mktemp -d)" + +function finish { + rm -rf "${temp_dir}" +} + +trap finish EXIT + +pushd "${temp_dir}" + +# Download source code to temporary directory +# NOTE: There are different branches in the repo for different kernel versions. +echo 'Downloading source code' +curl -L -o - "https://github.com/HinTak/seeed-voicecard/archive/refs/heads/v$kernel_formatted.tar.gz" | \ + tar -xzf - + +cd seeed-voicecard-"$kernel_formatted"/ + +# 1. Build kernel module +echo 'Building kernel module' +ver='0.3' +mod='seeed-voicecard' +src='./' +kernel="$(uname -r)" +marker='0.0.0' +threads="$(getconf _NPROCESSORS_ONLN)" +memory="$(LANG=C free -m|awk '/^Mem:/{print $2}')" + +if [ "${memory}" -le 512 ] && [ "${threads}" -gt 2 ]; then +threads=2 +fi + +mkdir -p "/usr/src/${mod}-${ver}" +cp -a "${src}"/* "/usr/src/${mod}-${ver}/" + +dkms add -m "${mod}" -v "${ver}" +dkms build -k "${kernel}" -m "${mod}" -v "${ver}" -j "${threads}" && { + dkms install --force -k "${kernel}" -m "${mod}" -v "${ver}" +} + +mkdir -p "/var/lib/dkms/${mod}/${ver}/${marker}" + +# 2. Install kernel module and configure +echo 'Updating boot configuration' +config='/boot/config.txt' + +cp seeed-*-voicecard.dtbo /boot/overlays +grep -q "^snd-soc-ac108$" /etc/modules || echo "snd-soc-ac108" >> /etc/modules +sed -i -e 's:#dtparam=i2c_arm=on:dtparam=i2c_arm=on:g' "${config}" +echo "dtoverlay=i2s-mmap" >> "${config}" +echo "dtparam=i2s=on" >> "${config}" +mkdir -p /etc/voicecard +cp *.conf *.state /etc/voicecard +cp seeed-voicecard /usr/bin/ +cp seeed-voicecard.service /lib/systemd/system/ +systemctl enable --now seeed-voicecard.service + +echo 'Done. Please reboot the system.' +popd diff --git a/examples/2mic_service.py b/examples/2mic_service.py new file mode 100755 index 0000000..1195a60 --- /dev/null +++ b/examples/2mic_service.py @@ -0,0 +1,282 @@ +#!/usr/bin/env python3 +"""Controls the LEDs on the ReSpeaker 2mic HAT, inspired by smart speakers like Alexa and Alice.""" +import argparse +import asyncio +import logging +import time +from functools import partial +from math import ceil +from typing import Tuple, List, Optional +import gpiozero +import spidev +from wyoming.asr import Transcript +from wyoming.event import Event +from wyoming.satellite import ( + RunSatellite, + SatelliteConnected, + SatelliteDisconnected, + StreamingStarted, + StreamingStopped, +) +from wyoming.server import AsyncEventHandler, AsyncServer +from wyoming.vad import VoiceStarted, VoiceStopped +from wyoming.wake import Detection +_LOGGER = logging.getLogger() +NUM_LEDS = 3 +LEDS_GPIO = 12 +RGB_MAP = { + "rgb": [3, 2, 1], + "rbg": [3, 1, 2], + "grb": [2, 3, 1], + "gbr": [2, 1, 3], + "brg": [1, 3, 2], + "bgr": [1, 2, 3], +} +async def main() -> None: + """Main entry point.""" + parser = argparse.ArgumentParser() + parser.add_argument("--uri", required=True, help="unix:// or tcp://") + parser.add_argument("--debug", action="store_true", help="Log DEBUG messages") + parser.add_argument( + "--led-brightness", + type=int, + choices=range(1, 32), + default=31, + help="LED brightness (integer from 1 to 31)", + ) + args = parser.parse_args() + logging.basicConfig(level=logging.DEBUG if args.debug else logging.INFO) + _LOGGER.debug(args) + _LOGGER.info("Ready") + # Turn on power to LEDs + led_power = gpiozero.LED(LEDS_GPIO, active_high=False) + led_power.on() + leds = APA102(num_led=NUM_LEDS, global_brightness=args.led_brightness) + # Start server + server = AsyncServer.from_uri(args.uri) + try: + await server.run(partial(LEDsEventHandler, args, leds)) + except KeyboardInterrupt: + pass + finally: + leds.cleanup() + led_power.off() +# ----------------------------------------------------------------------------- +_BLACK = (0, 0, 0) +_WHITE = (255, 255, 255) +_RED = (255, 0, 0) +_YELLOW = (255, 255, 0) +_BLUE = (0, 0, 255) +_GREEN = (0, 255, 0) +_PURPLE = (128, 0, 128) +_ORANGE = (255, 165, 0) +_CYAN = (0, 255, 255) +class LEDsEventHandler(AsyncEventHandler): + """Event handler for clients, with animations inspired by Alexa and Alice.""" + def __init__( + self, + cli_args: argparse.Namespace, + leds: "APA102", + *args, + **kwargs, + ) -> None: + super().__init__(*args, **kwargs) + self.cli_args = cli_args + self.client_id = str(time.monotonic_ns()) + self.leds = leds + self.voice_active = False + self.voice_animation_task: Optional[asyncio.Task] = None + self.streaming_active = False + self.streaming_animation_task: Optional[asyncio.Task] = None + _LOGGER.debug("Client connected: %s", self.client_id) + async def handle_event(self, event: Event) -> bool: + _LOGGER.debug(event) + if StreamingStarted.is_type(event.type): + self.streaming_active = True + if self.streaming_animation_task is None or self.streaming_animation_task.done(): + self.streaming_animation_task = asyncio.create_task(self.streaming_animation_loop()) + elif Detection.is_type(event.type): + # Как Alexa: directional blue spotlight for wake/listening + await self.rotate_colors([_BLUE, _CYAN, _BLACK], rotations=5, delay=0.2) # Вращение для "просыпания" + self.color(_BLACK) + elif VoiceStarted.is_type(event.type): + self.voice_active = True + if self.voice_animation_task is None or self.voice_animation_task.done(): + self.voice_animation_task = asyncio.create_task(self.voice_animation_loop()) + elif Transcript.is_type(event.type): + # Как Alexa/Alice: Зеленый успех или эмоция (мигание зеленым для подтверждения) + await self.pulse_color(_GREEN, pulses=2, duration=0.8) + self.color(_BLACK) + elif VoiceStopped.is_type(event.type): + self.voice_active = False + if self.voice_animation_task: + self.voice_animation_task.cancel() + self.voice_animation_task = None + await self.fade_out(_BLUE, steps=10, delay=0.15) # Затухание синего, как конец обработки + elif StreamingStopped.is_type(event.type): + self.streaming_active = False + if self.streaming_animation_task: + self.streaming_animation_task.cancel() + self.streaming_animation_task = None + await self.fade_out(_BLUE, steps=10, delay=0.15) + elif RunSatellite.is_type(event.type): + self.color(_BLACK) + elif SatelliteConnected.is_type(event.type): + # Разовая анимация при подключении, без loop, чтобы в idle не светилось + await self.pulse_color(_GREEN, pulses=2, duration=1.5) + self.color(_BLACK) + elif SatelliteDisconnected.is_type(event.type): + await self.pulse_color(_RED, pulses=3, duration=0.5) # Красный пульс для ошибки, как Alexa purple/red + self.color(_BLACK) + return True + async def voice_animation_loop(self) -> None: + """Loop анимации для VoiceStarted: как Alexa listening/thinking - alternating blue/cyan.""" + try: + while self.voice_active: + await self.gradient([_BLUE, _CYAN, _BLUE], duration=1.5) # Градиент для "thinking" + await self.rotate_colors([_CYAN, _BLUE, _BLACK], rotations=1, delay=0.3) # Вращение для активности + await asyncio.sleep(0.2) + except asyncio.CancelledError: + self.color(_BLACK) + async def streaming_animation_loop(self) -> None: + """Loop для StreamingStarted: pulsing blue как Alexa processing.""" + try: + while self.streaming_active: + await self.pulse_color(_BLUE, pulses=1, duration=0.8) + await asyncio.sleep(0.2) + except asyncio.CancelledError: + self.color(_BLACK) + def color(self, rgb: Tuple[int, int, int]) -> None: + for i in range(NUM_LEDS): + self.leds.set_pixel(i, rgb[0], rgb[1], rgb[2]) + self.leds.show() + def set_colors(self, colors: List[Tuple[int, int, int]]) -> None: + for i in range(min(NUM_LEDS, len(colors))): + self.leds.set_pixel(i, colors[i][0], colors[i][1], colors[i][2]) + self.leds.show() + async def pulse_color(self, rgb: Tuple[int, int, int], pulses: int = 3, duration: float = 0.5) -> None: + steps = 10 + for _ in range(pulses): + for bright in range(steps): + self.set_pixel_bright(rgb, (bright + 1) / steps * 100) + await asyncio.sleep(duration / (2 * steps)) + for bright in range(steps, 0, -1): + self.set_pixel_bright(rgb, (bright - 1) / steps * 100) + await asyncio.sleep(duration / (2 * steps)) + def set_pixel_bright(self, rgb: Tuple[int, int, int], bright_percent: float) -> None: + for i in range(NUM_LEDS): + self.leds.set_pixel(i, rgb[0], rgb[1], rgb[2], bright_percent) + self.leds.show() + async def rainbow_cycle(self, steps: int = 20, delay: float = 0.05) -> None: + for step in range(steps): + colors = [] + for i in range(NUM_LEDS): + r = int((step + i * 85) % 255) + g = int((step + i * 85 + 85) % 255) + b = int((step + i * 85 + 170) % 255) + colors.append((r, g, b)) + self.set_colors(colors) + await asyncio.sleep(delay) + self.color(_BLACK) + async def gradient(self, colors: List[Tuple[int, int, int]], duration: float = 1.0) -> None: + steps = 10 + for step in range(steps): + blended_colors = [] + for i in range(NUM_LEDS): + idx = i % len(colors) + next_idx = (idx + 1) % len(colors) + r = int(colors[idx][0] + (colors[next_idx][0] - colors[idx][0]) * step / steps) + g = int(colors[idx][1] + (colors[next_idx][1] - colors[idx][1]) * step / steps) + b = int(colors[idx][2] + (colors[next_idx][2] - colors[idx][2]) * step / steps) + blended_colors.append((r, g, b)) + self.set_colors(blended_colors) + await asyncio.sleep(duration / steps) + async def fade_out(self, start_rgb: Tuple[int, int, int], steps: int = 10, delay: float = 0.1) -> None: + for step in range(steps, 0, -1): + r = int(start_rgb[0] * step / steps) + g = int(start_rgb[1] * step / steps) + b = int(start_rgb[2] * step / steps) + self.color((r, g, b)) + await asyncio.sleep(delay) + self.color(_BLACK) + async def rotate_colors(self, colors: List[Tuple[int, int, int]], rotations: int = 3, delay: float = 0.2) -> None: + current_colors = colors[:NUM_LEDS] + for _ in range(rotations): + self.set_colors(current_colors) + await asyncio.sleep(delay) + current_colors = current_colors[-1:] + current_colors[:-1] +# ----------------------------------------------------------------------------- +class APA102: + """ + Driver for APA102 LEDS (aka "DotStar"). + (c) Martin Erzberger 2016-2017 + """ + # Constants + MAX_BRIGHTNESS = 0b11111 # Safeguard: Set to a value appropriate for your setup + LED_START = 0b11100000 # Three "1" bits, followed by 5 brightness bits + def __init__( + self, + num_led, + global_brightness, + order="rgb", + bus=0, + device=1, + max_speed_hz=8000000, + ): + self.num_led = num_led # The number of LEDs in the Strip + order = order.lower() + self.rgb = RGB_MAP.get(order, RGB_MAP["rgb"]) + # Limit the brightness to the maximum if it's set higher + if global_brightness > self.MAX_BRIGHTNESS: + self.global_brightness = self.MAX_BRIGHTNESS + else: + self.global_brightness = global_brightness + _LOGGER.debug("LED brightness: %d", self.global_brightness) + self.leds = [self.LED_START, 0, 0, 0] * self.num_led # Pixel buffer + self.spi = spidev.SpiDev() # Init the SPI device + self.spi.open(bus, device) # Open SPI port 0, slave device (CS) 1 + # Up the speed a bit, so that the LEDs are painted faster + if max_speed_hz: + self.spi.max_speed_hz = max_speed_hz + def clock_start_frame(self): + self.spi.xfer2([0] * 4) # Start frame, 32 zero bits + def clock_end_frame(self): + self.spi.xfer2([0xFF] * 4) + def set_pixel(self, led_num, red, green, blue, bright_percent=100): + if led_num < 0: + return # Pixel is invisible, so ignore + if led_num >= self.num_led: + return # again, invisible + brightness = int(ceil(bright_percent * self.global_brightness / 100.0)) + ledstart = (brightness & 0b00011111) | self.LED_START + start_index = 4 * led_num + self.leds[start_index] = ledstart + self.leds[start_index + self.rgb[0]] = red + self.leds[start_index + self.rgb[1]] = green + self.leds[start_index + self.rgb[2]] = blue + def set_pixel_rgb(self, led_num, rgb_color, bright_percent=100): + self.set_pixel( + led_num, + (rgb_color & 0xFF0000) >> 16, + (rgb_color & 0x00FF00) >> 8, + rgb_color & 0x0000FF, + bright_percent, + ) + def rotate(self, positions=1): + cutoff = 4 * (positions % self.num_led) + self.leds = self.leds[cutoff:] + self.leds[:cutoff] + def show(self): + self.clock_start_frame() + data = list(self.leds) + while data: + self.spi.xfer2(data[:32]) + data = data[32:] + self.clock_end_frame() + def cleanup(self): + self.spi.close() # Close SPI port +# ----------------------------------------------------------------------------- +if __name__ == "__main__": + try: + asyncio.run(main()) + except KeyboardInterrupt: + pass \ No newline at end of file diff --git a/examples/4mic_service.py b/examples/4mic_service.py new file mode 100755 index 0000000..221528f --- /dev/null +++ b/examples/4mic_service.py @@ -0,0 +1,293 @@ +#!/usr/bin/env python3 +"""Controls the LEDs on the ReSpeaker 4mic HAT.""" +import argparse +import asyncio +import logging +import time +from functools import partial +from math import ceil +from typing import Tuple + +import gpiozero +import spidev +from wyoming.asr import Transcript +from wyoming.event import Event +from wyoming.satellite import ( + RunSatellite, + SatelliteConnected, + SatelliteDisconnected, + StreamingStarted, + StreamingStopped, +) +from wyoming.server import AsyncEventHandler, AsyncServer +from wyoming.vad import VoiceStarted +from wyoming.wake import Detection + +_LOGGER = logging.getLogger() + +NUM_LEDS = 12 +LEDS_GPIO = 5 +RGB_MAP = { + "rgb": [3, 2, 1], + "rbg": [3, 1, 2], + "grb": [2, 3, 1], + "gbr": [2, 1, 3], + "brg": [1, 3, 2], + "bgr": [1, 2, 3], +} + + +async def main() -> None: + """Main entry point.""" + parser = argparse.ArgumentParser() + parser.add_argument("--uri", required=True, help="unix:// or tcp://") + # + parser.add_argument("--debug", action="store_true", help="Log DEBUG messages") + args = parser.parse_args() + + logging.basicConfig(level=logging.DEBUG if args.debug else logging.INFO) + _LOGGER.debug(args) + + _LOGGER.info("Ready") + + # Turn on power to LEDs + led_power = gpiozero.LED(LEDS_GPIO, active_high=True) + led_power.on() + + leds = APA102(num_led=NUM_LEDS) + + # Start server + server = AsyncServer.from_uri(args.uri) + + try: + await server.run(partial(LEDsEventHandler, args, leds)) + except KeyboardInterrupt: + pass + finally: + leds.cleanup() + led_power.off() + + +# ----------------------------------------------------------------------------- + +_BLACK = (0, 0, 0) +_WHITE = (255, 255, 255) +_RED = (255, 0, 0) +_YELLOW = (255, 255, 0) +_BLUE = (0, 0, 255) +_GREEN = (0, 255, 0) + + +class LEDsEventHandler(AsyncEventHandler): + """Event handler for clients.""" + + def __init__( + self, + cli_args: argparse.Namespace, + leds: "APA102", + *args, + **kwargs, + ) -> None: + super().__init__(*args, **kwargs) + + self.cli_args = cli_args + self.client_id = str(time.monotonic_ns()) + self.leds = leds + + _LOGGER.debug("Client connected: %s", self.client_id) + + async def handle_event(self, event: Event) -> bool: + _LOGGER.debug(event) + + if StreamingStarted.is_type(event.type): + self.color(_YELLOW) + elif Detection.is_type(event.type): + self.color(_BLUE) + await asyncio.sleep(1.0) # show for 1 sec + elif VoiceStarted.is_type(event.type): + self.color(_YELLOW) + elif Transcript.is_type(event.type): + self.color(_GREEN) + await asyncio.sleep(1.0) # show for 1 sec + elif StreamingStopped.is_type(event.type): + self.color(_BLACK) + elif RunSatellite.is_type(event.type): + self.color(_BLACK) + elif SatelliteConnected.is_type(event.type): + # Flash + for _ in range(3): + self.color(_GREEN) + await asyncio.sleep(0.3) + self.color(_BLACK) + await asyncio.sleep(0.3) + elif SatelliteDisconnected.is_type(event.type): + self.color(_RED) + + return True + + def color(self, rgb: Tuple[int, int, int]) -> None: + for i in range(NUM_LEDS): + self.leds.set_pixel(i, rgb[0], rgb[1], rgb[2]) + + self.leds.show() + + +# ----------------------------------------------------------------------------- + + +class APA102: + """ + Driver for APA102 LEDS (aka "DotStar"). + (c) Martin Erzberger 2016-2017 + """ + + # Constants + MAX_BRIGHTNESS = 0b11111 # Safeguard: Set to a value appropriate for your setup + LED_START = 0b11100000 # Three "1" bits, followed by 5 brightness bits + + def __init__( + self, + num_led, + global_brightness=MAX_BRIGHTNESS, + order="rgb", + bus=0, + device=1, + max_speed_hz=8000000, + ): + self.num_led = num_led # The number of LEDs in the Strip + order = order.lower() + self.rgb = RGB_MAP.get(order, RGB_MAP["rgb"]) + # Limit the brightness to the maximum if it's set higher + if global_brightness > self.MAX_BRIGHTNESS: + self.global_brightness = self.MAX_BRIGHTNESS + else: + self.global_brightness = global_brightness + + self.leds = [self.LED_START, 0, 0, 0] * self.num_led # Pixel buffer + self.spi = spidev.SpiDev() # Init the SPI device + self.spi.open(bus, device) # Open SPI port 0, slave device (CS) 1 + # Up the speed a bit, so that the LEDs are painted faster + if max_speed_hz: + self.spi.max_speed_hz = max_speed_hz + + def clock_start_frame(self): + """Sends a start frame to the LED strip. + + This method clocks out a start frame, telling the receiving LED + that it must update its own color now. + """ + self.spi.xfer2([0] * 4) # Start frame, 32 zero bits + + def clock_end_frame(self): + """Sends an end frame to the LED strip. + + As explained above, dummy data must be sent after the last real colour + information so that all of the data can reach its destination down the line. + The delay is not as bad as with the human example above. + It is only 1/2 bit per LED. This is because the SPI clock line + needs to be inverted. + + Say a bit is ready on the SPI data line. The sender communicates + this by toggling the clock line. The bit is read by the LED + and immediately forwarded to the output data line. When the clock goes + down again on the input side, the LED will toggle the clock up + on the output to tell the next LED that the bit is ready. + + After one LED the clock is inverted, and after two LEDs it is in sync + again, but one cycle behind. Therefore, for every two LEDs, one bit + of delay gets accumulated. For 300 LEDs, 150 additional bits must be fed to + the input of LED one so that the data can reach the last LED. + + Ultimately, we need to send additional numLEDs/2 arbitrary data bits, + in order to trigger numLEDs/2 additional clock changes. This driver + sends zeroes, which has the benefit of getting LED one partially or + fully ready for the next update to the strip. An optimized version + of the driver could omit the "clockStartFrame" method if enough zeroes have + been sent as part of "clockEndFrame". + """ + + self.spi.xfer2([0xFF] * 4) + + # Round up num_led/2 bits (or num_led/16 bytes) + # for _ in range((self.num_led + 15) // 16): + # self.spi.xfer2([0x00]) + + def set_pixel(self, led_num, red, green, blue, bright_percent=100): + """Sets the color of one pixel in the LED stripe. + + The changed pixel is not shown yet on the Stripe, it is only + written to the pixel buffer. Colors are passed individually. + If brightness is not set the global brightness setting is used. + """ + if led_num < 0: + return # Pixel is invisible, so ignore + if led_num >= self.num_led: + return # again, invisible + + # Calculate pixel brightness as a percentage of the + # defined global_brightness. Round up to nearest integer + # as we expect some brightness unless set to 0 + brightness = int(ceil(bright_percent * self.global_brightness / 100.0)) + + # LED startframe is three "1" bits, followed by 5 brightness bits + ledstart = (brightness & 0b00011111) | self.LED_START + + start_index = 4 * led_num + self.leds[start_index] = ledstart + self.leds[start_index + self.rgb[0]] = red + self.leds[start_index + self.rgb[1]] = green + self.leds[start_index + self.rgb[2]] = blue + + def set_pixel_rgb(self, led_num, rgb_color, bright_percent=100): + """Sets the color of one pixel in the LED stripe. + + The changed pixel is not shown yet on the Stripe, it is only + written to the pixel buffer. + Colors are passed combined (3 bytes concatenated) + If brightness is not set the global brightness setting is used. + """ + self.set_pixel( + led_num, + (rgb_color & 0xFF0000) >> 16, + (rgb_color & 0x00FF00) >> 8, + rgb_color & 0x0000FF, + bright_percent, + ) + + def rotate(self, positions=1): + """Rotate the LEDs by the specified number of positions. + + Treating the internal LED array as a circular buffer, rotate it by + the specified number of positions. The number could be negative, + which means rotating in the opposite direction. + """ + cutoff = 4 * (positions % self.num_led) + self.leds = self.leds[cutoff:] + self.leds[:cutoff] + + def show(self): + """Sends the content of the pixel buffer to the strip. + + Todo: More than 1024 LEDs requires more than one xfer operation. + """ + self.clock_start_frame() + # xfer2 kills the list, unfortunately. So it must be copied first + # SPI takes up to 4096 Integers. So we are fine for up to 1024 LEDs. + data = list(self.leds) + while data: + self.spi.xfer2(data[:32]) + data = data[32:] + self.clock_end_frame() + + def cleanup(self): + """Release the SPI device; Call this method at the end""" + + self.spi.close() # Close SPI port + + +# ----------------------------------------------------------------------------- + +if __name__ == "__main__": + try: + asyncio.run(main()) + except KeyboardInterrupt: + pass diff --git a/examples/commands/detection.sh b/examples/commands/detection.sh new file mode 100755 index 0000000..f013b00 --- /dev/null +++ b/examples/commands/detection.sh @@ -0,0 +1,4 @@ +#!/usr/bin/env sh + +name="$(cat)" +echo "Wake word detected: ${name}" diff --git a/examples/commands/startup.sh b/examples/commands/startup.sh new file mode 100755 index 0000000..f03b925 --- /dev/null +++ b/examples/commands/startup.sh @@ -0,0 +1,3 @@ +#!/usr/bin/env sh + +echo 'Satellite has started.' diff --git a/examples/commands/streaming_start.sh b/examples/commands/streaming_start.sh new file mode 100755 index 0000000..cc6fd20 --- /dev/null +++ b/examples/commands/streaming_start.sh @@ -0,0 +1,3 @@ +#!/usr/bin/env sh + +echo 'Audio streaming to server has started' diff --git a/examples/commands/streaming_stop.sh b/examples/commands/streaming_stop.sh new file mode 100755 index 0000000..83e3c8e --- /dev/null +++ b/examples/commands/streaming_stop.sh @@ -0,0 +1,3 @@ +#!/usr/bin/env sh + +echo 'Audio streaming to server has stopped' diff --git a/examples/commands/stt_start.sh b/examples/commands/stt_start.sh new file mode 100755 index 0000000..941e8d0 --- /dev/null +++ b/examples/commands/stt_start.sh @@ -0,0 +1,3 @@ +#!/usr/bin/env sh + +echo 'User has started speaking' diff --git a/examples/commands/stt_stop.sh b/examples/commands/stt_stop.sh new file mode 100755 index 0000000..219f601 --- /dev/null +++ b/examples/commands/stt_stop.sh @@ -0,0 +1,3 @@ +#!/usr/bin/env sh + +echo 'User has stopped speaking' diff --git a/examples/commands/synthesize.sh b/examples/commands/synthesize.sh new file mode 100755 index 0000000..9a0da04 --- /dev/null +++ b/examples/commands/synthesize.sh @@ -0,0 +1,4 @@ +#!/usr/bin/env sh + +text="$(cat)" +echo "Text to speech text: ${text}" diff --git a/examples/commands/transcript.sh b/examples/commands/transcript.sh new file mode 100755 index 0000000..0c37b0f --- /dev/null +++ b/examples/commands/transcript.sh @@ -0,0 +1,4 @@ +#!/usr/bin/env sh + +text="$(cat)" +echo "Speech to text transcript: ${text}" diff --git a/examples/commands/tts_start.sh b/examples/commands/tts_start.sh new file mode 100755 index 0000000..c711c40 --- /dev/null +++ b/examples/commands/tts_start.sh @@ -0,0 +1,3 @@ +#!/usr/bin/env sh + +echo 'Text to speech response has started' diff --git a/examples/commands/tts_stop.sh b/examples/commands/tts_stop.sh new file mode 100755 index 0000000..cdbc1ce --- /dev/null +++ b/examples/commands/tts_stop.sh @@ -0,0 +1,3 @@ +#!/usr/bin/env sh + +echo 'Text to speech response has stopped' diff --git a/examples/usbmic_service.py b/examples/usbmic_service.py new file mode 100755 index 0000000..dbc7fd3 --- /dev/null +++ b/examples/usbmic_service.py @@ -0,0 +1,104 @@ +#!/usr/bin/env python3 +"""Controls the LEDs on the ReSpeaker Mic Array v2.0 (USB) .""" +import argparse +import asyncio +import logging +import time +from functools import partial + +from pixel_ring import pixel_ring +from wyoming.event import Event +from wyoming.satellite import ( + SatelliteConnected, + SatelliteDisconnected, + StreamingStarted, + StreamingStopped, +) +from wyoming.server import AsyncEventHandler, AsyncServer +from wyoming.snd import Played +from wyoming.vad import VoiceStarted, VoiceStopped +from wyoming.wake import Detection + +_LOGGER = logging.getLogger() + + +async def main() -> None: + """Main entry point.""" + parser = argparse.ArgumentParser() + parser.add_argument("--uri", required=True, help="unix:// or tcp://") + parser.add_argument("--debug", action="store_true", help="Log DEBUG messages") + args = parser.parse_args() + + logging.basicConfig(level=logging.DEBUG if args.debug else logging.INFO) + _LOGGER.debug(args) + + _LOGGER.info("Ready") + + # Turn on power to LEDs + pixel_ring.set_color_palette(0x0080FF, 0x007A37) + pixel_ring.think() + await asyncio.sleep(3) + pixel_ring.off() + + # Start server + server = AsyncServer.from_uri(args.uri) + + try: + await server.run(partial(LEDsEventHandler, args)) + except KeyboardInterrupt: + pass + finally: + pixel_ring.off() + + +class LEDsEventHandler(AsyncEventHandler): + """Event handler for clients.""" + + def __init__( + self, + cli_args: argparse.Namespace, + *args, + **kwargs, + ) -> None: + super().__init__(*args, **kwargs) + + self.cli_args = cli_args + self.client_id = str(time.monotonic_ns()) + + _LOGGER.debug("Client connected: %s", self.client_id) + + async def handle_event(self, event: Event) -> bool: + _LOGGER.debug(event) + + if Detection.is_type(event.type): + _LOGGER.debug("Detection") + pixel_ring.wakeup() + elif VoiceStarted.is_type(event.type): + _LOGGER.debug("VoiceStarted") + pixel_ring.speak() + elif VoiceStopped.is_type(event.type): + _LOGGER.debug("VoiceStopped") + pixel_ring.spin() + elif StreamingStopped.is_type(event.type): + _LOGGER.debug("StreamingStopped") + pixel_ring.off() + elif SatelliteConnected.is_type(event.type): + _LOGGER.debug("SatelliteConnected") + pixel_ring.think() + await asyncio.sleep(2) + pixel_ring.off() + elif Played.is_type(event.type): + _LOGGER.debug("Played") + pixel_ring.off() + elif SatelliteDisconnected.is_type(event.type): + _LOGGER.debug("SatelliteDisconnected") + pixel_ring.mono(0xFF0000) + + return True + + +if __name__ == "__main__": + try: + asyncio.run(main()) + except KeyboardInterrupt: + pass diff --git a/examples/websocket-service/requirements.txt b/examples/websocket-service/requirements.txt new file mode 100755 index 0000000..02e1832 --- /dev/null +++ b/examples/websocket-service/requirements.txt @@ -0,0 +1 @@ +websockets==12.0 diff --git a/examples/websocket-service/server.py b/examples/websocket-service/server.py new file mode 100755 index 0000000..6fbf84c --- /dev/null +++ b/examples/websocket-service/server.py @@ -0,0 +1,100 @@ +#!/usr/bin/env python3 +import argparse +import asyncio +import json +import logging +from functools import partial +from typing import Optional + +import websockets +from wyoming.event import Event +from wyoming.server import AsyncEventHandler, AsyncServer + +_LOGGER = logging.getLogger() + + +async def main() -> None: + """Main entry point.""" + parser = argparse.ArgumentParser() + parser.add_argument("--uri", required=True, help="unix:// or tcp://") + parser.add_argument("--websocket-host", default="localhost") + parser.add_argument("--websocket-port", type=int, default=8675) + # + parser.add_argument("--debug", action="store_true", help="Log DEBUG messages") + args = parser.parse_args() + + logging.basicConfig(level=logging.DEBUG if args.debug else logging.INFO) + _LOGGER.debug(args) + + _LOGGER.info("Ready") + + # Start server + server = AsyncServer.from_uri(args.uri) + queue: "asyncio.Queue[Optional[Event]]" = asyncio.Queue() + + try: + async with websockets.serve( + partial(websocket_connected, queue), + args.websocket_host, + args.websocket_port, + ): + await server.run(partial(WebsocketEventHandler, args, queue)) + finally: + queue.put_nowait(None) + + +# ----------------------------------------------------------------------------- + + +async def websocket_connected(queue: "asyncio.Queue[Optional[Event]]", websocket): + try: + while True: + event = await queue.get() + if event is None: + # Stop signal + break + + await websocket.send( + json.dumps( + {"type": event.type, "data": event.data or {}}, ensure_ascii=False + ) + ) + except websockets.ConnectionClosed: + pass + except Exception: + _LOGGER.exception("Error in websocket handler") + + +# ----------------------------------------------------------------------------- + + +class WebsocketEventHandler(AsyncEventHandler): + """Event handler for clients.""" + + def __init__( + self, + cli_args: argparse.Namespace, + queue: "asyncio.Queue[Optional[Event]]", + *args, + **kwargs, + ) -> None: + super().__init__(*args, **kwargs) + + self.cli_args = cli_args + self.queue = queue + + async def handle_event(self, event: Event) -> bool: + _LOGGER.debug(event) + self.queue.put_nowait(event) + + return True + + +# ----------------------------------------------------------------------------- + + +if __name__ == "__main__": + try: + asyncio.run(main()) + except KeyboardInterrupt: + pass diff --git a/examples/websocket-service/timer_finished.wav b/examples/websocket-service/timer_finished.wav new file mode 100755 index 0000000000000000000000000000000000000000..40a97bca6c5eafa4e113ebc076d48ded0d9c95a0 GIT binary patch literal 35874 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 literal 0 HcmV?d00001 diff --git a/examples/websocket-service/timers.html b/examples/websocket-service/timers.html new file mode 100755 index 0000000..0c6777b --- /dev/null +++ b/examples/websocket-service/timers.html @@ -0,0 +1,244 @@ + + + + + + + + + + + Wyoming Timer Example + + + + +
+
+ + + + + diff --git a/install_service.sh b/install_service.sh new file mode 100755 index 0000000..1d8da00 --- /dev/null +++ b/install_service.sh @@ -0,0 +1,95 @@ +#!/bin/bash +set -e + +# Путь к файлу службы +SERVICE_FILE="wyoming-satellite.service" +DEST_PATH="/etc/systemd/system/${SERVICE_FILE}" + +# Проверка прав суперпользователя +if [ "$(id -u)" -ne 0 ]; then + echo "Этот скрипт должен быть запущен с правами суперпользователя (sudo)" + exit 1 +fi + +# Функция для установки службы +install_service() { + echo "Устанавливаю службу Wyoming Satellite..." + + # Копируем файл службы + cp "${SERVICE_FILE}" "${DEST_PATH}" + chmod 644 "${DEST_PATH}" + + # Делаем скрипт запуска исполняемым + chmod +x "$(pwd)/start_satellite.sh" + + # Перезагружаем systemd + systemctl daemon-reload + + echo "Служба установлена. Используйте 'sudo systemctl start ${SERVICE_FILE}' для запуска." +} + +# Функция для удаления службы +remove_service() { + echo "Удаляю службу Wyoming Satellite..." + + # Останавливаем и отключаем службу + systemctl stop "${SERVICE_FILE}" 2>/dev/null || true + systemctl disable "${SERVICE_FILE}" 2>/dev/null || true + + # Удаляем файл службы + rm -f "${DEST_PATH}" + + # Перезагружаем systemd + systemctl daemon-reload + + echo "Служба удалена." +} + +# Функция для отображения статуса +show_status() { + echo "Статус службы Wyoming Satellite:" + systemctl status "${SERVICE_FILE}" +} + +# Обработка аргументов командной строки +case "$1" in + install) + install_service + ;; + remove) + remove_service + ;; + status) + show_status + ;; + start) + echo "Запускаю службу Wyoming Satellite..." + systemctl start "${SERVICE_FILE}" + ;; + stop) + echo "Останавливаю службу Wyoming Satellite..." + systemctl stop "${SERVICE_FILE}" + ;; + restart) + echo "Перезапускаю службу Wyoming Satellite..." + systemctl restart "${SERVICE_FILE}" + ;; + enable) + echo "Включаю автозапуск службы Wyoming Satellite..." + systemctl enable "${SERVICE_FILE}" + ;; + disable) + echo "Отключаю автозапуск службы Wyoming Satellite..." + systemctl disable "${SERVICE_FILE}" + ;; + logs) + echo "Журнал службы Wyoming Satellite:" + journalctl -u "${SERVICE_FILE}" -f + ;; + *) + echo "Использование: $0 {install|remove|status|start|stop|restart|enable|disable|logs}" + exit 1 + ;; +esac + +exit 0 \ No newline at end of file diff --git a/installer/__init__.py b/installer/__init__.py new file mode 100755 index 0000000..c776e30 --- /dev/null +++ b/installer/__init__.py @@ -0,0 +1 @@ +"""Command-line installer.""" diff --git a/installer/__main__.py b/installer/__main__.py new file mode 100755 index 0000000..9f43e84 --- /dev/null +++ b/installer/__main__.py @@ -0,0 +1,174 @@ +"""Command-line installer.""" +import logging +from typing import List, Optional + +from .const import LOCAL_DIR, PROGRAM_DIR, SatelliteType, Settings +from .drivers import install_drivers +from .microphone import configure_microphone +from .packages import ( + can_import, + install_packages, + install_packages_nogui, + packages_installed, +) +from .satellite import configure_satellite +from .services import generate_services, install_services, stop_services +from .speakers import configure_speakers +from .wake_word import configure_wake_word +from .whiptail import ItemType, error, menu, msgbox, passwordbox, run_with_gauge + +_LOGGER = logging.getLogger() + + +def main() -> None: + LOCAL_DIR.mkdir(parents=True, exist_ok=True) + logging.basicConfig( + filename=LOCAL_DIR / "installer.log", filemode="w", level=logging.DEBUG + ) + + settings = Settings.load() + + if not packages_installed("whiptail"): + install_packages_nogui("whiptail") + + choice: Optional[str] = None + while True: + choice = main_menu(choice) + + if choice == "satellite": + configure_satellite(settings) + elif choice == "microphone": + configure_microphone(settings) + elif choice == "speakers": + configure_speakers(settings) + elif choice == "wake": + configure_wake_word(settings) + elif choice == "drivers": + install_drivers(settings) + elif choice == "apply": + apply_settings(settings) + else: + break + + +def main_menu(last_choice: Optional[str]) -> Optional[str]: + items: List[ItemType] = [ + ("satellite", "Satellite"), + ("microphone", "Microphone"), + ("speakers", "Speakers"), + ("wake", "Wake Word"), + ("drivers", "Drivers"), + ("apply", "Apply Settings"), + ] + + return menu( + "Main", + items, + selected_item=last_choice, + menu_args=["--ok-button", "Select", "--cancel-button", "Exit"], + ) + + +# ----------------------------------------------------------------------------- + + +def pip_install(*args) -> List[str]: + return [ + str(PROGRAM_DIR / ".venv" / "bin" / "pip3"), + "install", + "--extra-index-url", + "https://www.piwheels.org/simple", + "-f", + "https://synesthesiam.github.io/prebuilt-apps/", + ] + list(args) + + +def apply_settings(settings: Settings) -> None: + if settings.mic.device is None: + msgbox("Please configure microphone") + return + + if (settings.satellite.type == SatelliteType.WAKE) and ( + settings.wake.system is None + ): + msgbox("Please set wake word system") + return + + password: Optional[str] = None + if not packages_installed("python3-pip", "python3-venv"): + password = passwordbox("sudo password:") + if not password: + return + + success = install_packages( + "Installing Python packages...", password, "python3-pip", "python3-venv" + ) + if not success: + error("installing pip/venv for Python") + return + + # Satellite venv + venv_dir = PROGRAM_DIR / ".venv" + if not venv_dir.exists(): + result = run_with_gauge( + "Creating virtual environment...", [str(PROGRAM_DIR / "script" / "setup")] + ) + if not result: + error("creating virtual environment") + return + + # silero (vad) + if (settings.satellite.type == SatelliteType.VAD) and ( + not can_import("pysilero_vad") + ): + result = run_with_gauge( + "Installing vad...", + [pip_install("-e", f"{PROGRAM_DIR}[silerovad]")], + ) + if not result: + error("installing vad") + return + + # webrtc (audio enhancements) + if ((settings.mic.noise_suppression > 0) or (settings.mic.auto_gain > 0)) and ( + not can_import("webrtc_noise_gain") + ): + result = run_with_gauge( + "Installing audio enhancements...", + [pip_install("-e", f"{PROGRAM_DIR}[webrtc]")], + ) + if not result: + error("installing audio enhancements") + return + + if ( + settings.satellite.event_service_command + and ( + ("2mic" in settings.satellite.event_service_command) + or ("4mic" in settings.satellite.event_service_command) + ) + ) and (not can_import("gpiozero", "spidev")): + result = run_with_gauge( + "Installing event requirements...", + [pip_install("-e", f"{PROGRAM_DIR}[respeaker]")], + ) + if not result: + error("installing event requirements") + return + + generate_services(settings) + + if password is None: + password = passwordbox("sudo password:") + if not password: + return + + stop_services(password) + install_services(settings, password) + + +# ----------------------------------------------------------------------------- + + +if __name__ == "__main__": + main() diff --git a/installer/const.py b/installer/const.py new file mode 100755 index 0000000..61318dc --- /dev/null +++ b/installer/const.py @@ -0,0 +1,114 @@ +"""Constants and dataclasses.""" +import json +import logging +from dataclasses import dataclass, field +from enum import Enum +from pathlib import Path +from typing import List, Optional + +from .dataclasses_json import DataClassJsonMixin + +_DIR = Path(__file__).parent +_LOGGER = logging.getLogger() + +PROGRAM_DIR = _DIR.parent +LOCAL_DIR = PROGRAM_DIR / "local" +SETTINGS_PATH = LOCAL_DIR / "settings.json" +SERVICES_DIR = LOCAL_DIR / "services" + +RECORD_SECONDS = 5 +RECORD_RMS_MIN = 30 + +TITLE = "Wyoming Satellite" +WIDTH = "75" +HEIGHT = "20" +LIST_HEIGHT = "12" + + +class SatelliteType(str, Enum): + ALWAYS_STREAMING = "always" + VAD = "vad" + WAKE = "wake" + + +@dataclass +class SatelliteSettings(DataClassJsonMixin): + name: str = "Wyoming Satellite" + type: SatelliteType = SatelliteType.ALWAYS_STREAMING + debug: bool = False + event_service_command: Optional[List[str]] = None + + +@dataclass +class MicrophoneSettings(DataClassJsonMixin): + device: Optional[str] = None + noise_suppression: int = 0 + auto_gain: int = 0 + volume_multiplier: float = 1.0 + + +@dataclass +class SpeakerSettings(DataClassJsonMixin): + device: Optional[str] = None + volume_multiplier: float = 1.0 + feedback_sounds: List[str] = field(default_factory=list) + + +@dataclass +class OpenWakeWordSettings(DataClassJsonMixin): + wake_word: str = "ok_nabu" + threshold: float = 0.5 + trigger_level: int = 1 + + +@dataclass +class Porcupine1Settings(DataClassJsonMixin): + wake_word: str = "porcupine" + sensitivity: float = 0.5 + + +@dataclass +class SnowboySettings(DataClassJsonMixin): + wake_word: str = "snowboy" + sensitivity: float = 0.5 + + +class WakeWordSystem(str, Enum): + OPENWAKEWORD = "openWakeWord" + PORCUPINE1 = "porcupine1" + SNOWBOY = "snowboy" + + +@dataclass +class WakeWordSettings(DataClassJsonMixin): + system: Optional[WakeWordSystem] = None + openwakeword: OpenWakeWordSettings = field(default_factory=OpenWakeWordSettings) + porcupine1: Porcupine1Settings = field(default_factory=Porcupine1Settings) + snowboy: SnowboySettings = field(default_factory=SnowboySettings) + + +@dataclass +class Settings(DataClassJsonMixin): + satellite: SatelliteSettings = field(default_factory=SatelliteSettings) + mic: MicrophoneSettings = field(default_factory=MicrophoneSettings) + snd: SpeakerSettings = field(default_factory=SpeakerSettings) + wake: WakeWordSettings = field(default_factory=WakeWordSettings) + + @staticmethod + def load() -> "Settings": + if SETTINGS_PATH.exists(): + _LOGGER.debug("Loading settings from %s", SETTINGS_PATH) + with open(SETTINGS_PATH, "r", encoding="utf-8") as settings_file: + settings_dict = json.load(settings_file) + return Settings.from_dict(settings_dict) + + return Settings() + + def save(self) -> None: + _LOGGER.debug("Saving settings to %s", SETTINGS_PATH) + + settings_dict = self.to_dict() + SETTINGS_PATH.parent.mkdir(parents=True, exist_ok=True) + + with open(SETTINGS_PATH, "w", encoding="utf-8") as settings_file: + json.dump(settings_dict, settings_file, ensure_ascii=False, indent=2) diff --git a/installer/dataclasses_json.py b/installer/dataclasses_json.py new file mode 100755 index 0000000..c2d1035 --- /dev/null +++ b/installer/dataclasses_json.py @@ -0,0 +1,70 @@ +"""Implement a tiny subset of dataclasses_json for config.""" +from collections.abc import Mapping, Sequence +from dataclasses import asdict, fields, is_dataclass +from typing import Any, Dict, Type + + +class DataClassJsonMixin: + """Adds from_dict to dataclass.""" + + @classmethod + def from_dict(cls, data: Dict[str, Any]) -> Any: + """Parse dataclasses recursively.""" + kwargs: Dict[str, Any] = {} + + cls_fields = {field.name: field for field in fields(cls)} + for key, value in data.items(): + if key not in cls_fields: + # Skip unknown fields + continue + + field = cls_fields[key] + if is_dataclass(field.type): + assert issubclass(field.type, DataClassJsonMixin), field.type + kwargs[key] = field.type.from_dict(value) + else: + kwargs[key] = _decode(value, field.type) + + # Fill in optional fields with None + for field in cls_fields.values(): + if (field.name not in kwargs) and _is_optional(field.type): + kwargs[field.name] = None + + return cls(**kwargs) + + def to_dict(self) -> Dict[str, Any]: + """Alias for asdict.""" + return asdict(self) + + +def _decode(value: Any, target_type: Type) -> Any: + """Decode value using (possibly generic) type.""" + if is_dataclass(target_type): + assert issubclass(target_type, DataClassJsonMixin), target_type + return target_type.from_dict(value) if value is not None else None + + if hasattr(target_type, "__args__"): + # Optional[T] + if type(None) in target_type.__args__: + optional_type = target_type.__args__[0] + return _decode(value, optional_type) + + # List[T] + if isinstance(value, Sequence): + list_type = target_type.__args__[0] + return [_decode(item, list_type) for item in value] + + # Dict[str, T] + if isinstance(value, Mapping): + value_type = target_type.__args__[1] + return { + map_key: _decode(map_value, value_type) + for map_key, map_value in value.items() + } + + return value + + +def _is_optional(target_type: Type): + """True if type is Optional""" + return hasattr(target_type, "__args__") and (type(None) in target_type.__args__) diff --git a/installer/drivers.py b/installer/drivers.py new file mode 100755 index 0000000..1d62227 --- /dev/null +++ b/installer/drivers.py @@ -0,0 +1,50 @@ +"""Hardware drivers.""" +import sys +from typing import Optional + +from .const import PROGRAM_DIR, Settings +from .whiptail import error, menu, msgbox, passwordbox, run_with_gauge, yesno + + +def install_drivers(settings: Settings) -> None: + choice: Optional[str] = None + while True: + choice = menu( + "Main > Drivers", + [("respeaker", "Install ReSpeaker Drivers")], + selected_item=choice, + menu_args=["--ok-button", "Select", "--cancel-button", "Back"], + ) + + if choice == "respeaker": + if yesno( + "ReSpeaker drivers for the Raspberry Pi will now be compiled and installed. " + "This will take a long time and require a reboot. " + "Continue?" + ): + password = passwordbox("sudo password:") + success = run_with_gauge( + "Installing drivers...", + [ + [ + "sudo", + "-S", + str(PROGRAM_DIR / "etc" / "install-respeaker-drivers.sh"), + ] + ], + sudo_password=password, + ) + + if not success: + error("installing ReSpeaker drivers") + return + + msgbox( + "Driver installation complete. " + "Please reboot your Raspberry Pi and re-run the installer. " + 'Once rebooted, select the "seeed" microphone.' + ) + + sys.exit(0) + else: + break diff --git a/installer/microphone.py b/installer/microphone.py new file mode 100755 index 0000000..a6b32e0 --- /dev/null +++ b/installer/microphone.py @@ -0,0 +1,214 @@ +"""Microphone settings.""" +import array +import logging +import math +import subprocess +from concurrent.futures import Future, ThreadPoolExecutor +from typing import Dict, List, Optional + +from .const import RECORD_RMS_MIN, RECORD_SECONDS, Settings +from .whiptail import gauge, inputbox, menu, msgbox, radiolist + +_LOGGER = logging.getLogger() + + +def configure_microphone(settings: Settings) -> None: + choice: Optional[str] = None + while True: + choice = microphone_menu(choice) + + if choice == "detect": + # Automatically detect microphone with hightest RMS + best_device: Optional[str] = None + best_rms: Optional[float] = None + + devices = get_microphone_devices() + with ThreadPoolExecutor() as executor: + futures: Dict[str, Future] = {} + for device in devices: + futures[device] = executor.submit(_record_proc, device) + + gauge("Speak loudly into the microphone.", RECORD_SECONDS) + for device, future in futures.items(): + device_rms = future.result() + if device_rms is None: + _LOGGER.warning("Failed to record from microphone %s", device) + continue + + _LOGGER.debug( + "Microphone %s got RMS %s (min: %s)", + device, + device_rms, + RECORD_RMS_MIN, + ) + if device_rms < RECORD_RMS_MIN: + continue + + if (best_rms is None) or (device_rms > best_rms): + best_device = device + best_rms = device_rms + + if best_device is not None: + msgbox(f"Successfully detected microphone: {best_device}") + settings.mic.device = best_device + settings.save() + else: + msgbox( + "Audio was not detected from any microphone.\n" + "If a satellite is currently running, you may need to stop it." + ) + elif choice == "list": + # arecord -L + microphone_device = radiolist( + "Select ALSA Device:", get_microphone_devices(), settings.mic.device + ) + if microphone_device: + settings.mic.device = microphone_device + settings.save() + elif choice == "manual": + microphone_device = inputbox("Enter ALSA Device:", settings.mic.device) + if microphone_device: + settings.mic.device = microphone_device + settings.save() + elif choice == "settings": + configure_audio_settings(settings) + else: + break + + +def microphone_menu(last_choice: Optional[str]) -> Optional[str]: + return menu( + "Main > Microphone", + [ + ("detect", "Autodetect"), + ("list", "Select From List"), + ("manual", "Enter Manually"), + ("settings", "Audio Settings"), + ], + selected_item=last_choice, + menu_args=["--ok-button", "Select", "--cancel-button", "Back"], + ) + + +def get_microphone_devices() -> List[str]: + devices = [] + lines = subprocess.check_output(["arecord", "-L"]).decode("utf-8").splitlines() + for line in lines: + line = line.strip() + + # default = PulseAudio + if (line == "default") or line.startswith("plughw:"): + devices.append(line) + + return devices + + +def _record_proc(device: str) -> Optional[float]: + try: + proc = subprocess.Popen( + [ + "arecord", + "-q", + "-D", + device, + "-r", + "16000", + "-c", + "1", + "-f", + "S16_LE", + "-t", + "raw", + "-d", + str(RECORD_SECONDS), + ], + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + ) + audio, stderr = proc.communicate() + if proc.returncode != 0: + _LOGGER.error( + "Error recording from device %s: %s", device, stderr.decode("utf-8") + ) + return None + + # 16-bit mono + audio_array = array.array("h", audio) + rms = math.sqrt( + (1 / len(audio_array) * sum(x * x for x in audio_array.tolist())) + ) + return rms + except Exception: + _LOGGER.exception("Error recording from device: %s", device) + return None + + return 0 + + +def configure_audio_settings(settings: Settings) -> None: + choice: Optional[str] = None + while True: + choice = audio_settings_menu(choice) + + if choice == "noise": + noise_suppression = radiolist( + "Noise Suppression Level", + [(0, "Off"), (1, "Low"), (2, "Medium"), (3, "High"), (4, "Maximum")], + settings.mic.noise_suppression, + ) + if noise_suppression is not None: + settings.mic.noise_suppression = noise_suppression + settings.save() + elif choice == "gain": + while True: + auto_gain = inputbox("Auto Gain (0-31 dbFS)", settings.mic.auto_gain) + if auto_gain is None: + break + + try: + auto_gain_int = int(auto_gain) + except ValueError: + msgbox("Invalid value") + continue + + if 0 <= auto_gain_int <= 31: + settings.mic.auto_gain = auto_gain_int + settings.save() + break + + msgbox("Must be 0-31") + elif choice == "multiplier": + while True: + volume_multiplier = inputbox( + "Volume Multiplier (1 = default)", settings.mic.volume_multiplier + ) + if volume_multiplier is None: + break + + try: + volume_multiplier_float = float(volume_multiplier) + except ValueError: + msgbox("Invalid value") + continue + + if volume_multiplier_float > 0: + settings.mic.volume_multiplier = volume_multiplier_float + settings.save() + break + + msgbox("Must be > 0") + else: + break + + +def audio_settings_menu(last_choice: Optional[str]) -> Optional[str]: + return menu( + "Main > Microphone > Audio Settings", + [ + ("noise", "Noise Suppression"), + ("gain", "Auto Gain"), + ("multiplier", "Volume Multiplier"), + ], + selected_item=last_choice, + menu_args=["--ok-button", "Select", "--cancel-button", "Back"], + ) diff --git a/installer/packages.py b/installer/packages.py new file mode 100755 index 0000000..1e3bacd --- /dev/null +++ b/installer/packages.py @@ -0,0 +1,87 @@ +"""Install system packages.""" +import logging +import subprocess + +from .const import PROGRAM_DIR +from .whiptail import run_with_gauge + +_LOGGER = logging.getLogger() + + +def packages_installed(*packages) -> bool: + for package in packages: + try: + subprocess.check_call( + ["dpkg", "--status", str(package)], + stdout=subprocess.DEVNULL, + stderr=subprocess.DEVNULL, + ) + except Exception: + return False + + return True + + +def install_packages_nogui(*packages, update: bool = True) -> bool: + assert packages, "No packages" + + commands = [] + if update: + commands.append(["sudo", "apt-get", "update"]) + + commands.append( + ["sudo", "apt-get", "install", "--yes"] + [str(p) for p in packages] + ) + + try: + for command in commands: + subprocess.check_call( + command, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL + ) + except Exception: + _LOGGER.exception("Unexpected error installing packages: %s", packages) + return False + + return True + + +def install_packages( + text: str, sudo_password: str, *packages, update: bool = True +) -> bool: + assert packages, "No packages" + + commands = [] + if update: + commands.append(["sudo", "-S", "apt-get", "update"]) + + commands.append( + ["sudo", "-S", "apt-get", "install", "--yes"] + [str(p) for p in packages] + ) + + return run_with_gauge(text, commands, sudo_password=sudo_password) + + +def can_import(*names) -> bool: + assert names, "No names" + + venv_dir = PROGRAM_DIR / ".venv" + if not venv_dir.exists(): + return False + + try: + import venv + except ImportError: + return False + + context = venv.EnvBuilder().ensure_directories(PROGRAM_DIR / ".venv") + + try: + subprocess.check_call( + [context.env_exe, "-c", "; ".join(f"import {name}" for name in names)], + stdout=subprocess.DEVNULL, + stderr=subprocess.DEVNULL, + ) + except Exception: + return False + + return True diff --git a/installer/satellite.py b/installer/satellite.py new file mode 100755 index 0000000..098c542 --- /dev/null +++ b/installer/satellite.py @@ -0,0 +1,120 @@ +"""Satellite settings.""" +from typing import Optional + +from .const import PROGRAM_DIR, SatelliteType, Settings +from .whiptail import error, inputbox, menu, passwordbox, radiolist, run_with_gauge + + +def configure_satellite(settings: Settings) -> None: + choice: Optional[str] = None + while True: + choice = satellite_menu(choice) + + if choice == "name": + name = inputbox("Satellite Name:", settings.satellite.name) + if name: + settings.satellite.name = name + settings.save() + elif choice == "type": + satellite_type = radiolist( + "Satellite Type:", + [ + (SatelliteType.ALWAYS_STREAMING, "Always streaming"), + (SatelliteType.VAD, "Voice activity detection"), + (SatelliteType.WAKE, "Local wake word detection"), + ], + settings.satellite.type, + ) + + if satellite_type is not None: + settings.satellite.type = SatelliteType(satellite_type) + settings.save() + elif choice == "feedback": + configure_feedback(settings) + elif choice in ("restart", "stop", "start"): + password = passwordbox("sudo password:") + if not password: + continue + + command = ["sudo", "-S", "systemctl", choice, "wyoming-satellite.service"] + text = {"restart": "Restarting", "stop": "Stopping", "start": "Starting"}[ + choice + ] + success = run_with_gauge( + f"{text} satellite...", [command], sudo_password=password + ) + if not success: + error(f"{text.lower()} satellite") + elif choice == "debug": + debug = radiolist( + "Debug Mode:", + [ + ("disabled", "Disabled"), + ("enabled", "Enabled"), + ], + "enabled" if settings.satellite.debug else "disabled", + ) + + if debug is not None: + settings.satellite.debug = debug == "enabled" + settings.save() + else: + break + + +def satellite_menu(last_choice: Optional[str]) -> Optional[str]: + return menu( + "Main > Satellite", + [ + ("name", "Satellite Name"), + ("type", "Satellite Type"), + ("feedback", "Feedback"), + ("restart", "Restart Services"), + ("stop", "Stop Services"), + ("start", "Start Services"), + ("debug", "Set Debug Mode"), + ], + selected_item=last_choice, + menu_args=["--ok-button", "Select", "--cancel-button", "Back"], + ) + + +def configure_feedback(settings: Settings) -> None: + choice: Optional[str] = None + while True: + choice = menu( + "Main > Satellite > Feedback", + [("respeaker", "ReSpeaker")], + menu_args=["--ok-button", "Select", "--cancel-button", "Back"], + ) + if choice == "respeaker": + selected_service: Optional[str] = None + if settings.satellite.event_service_command: + if "2mic" in settings.satellite.event_service_command[0]: + selected_service = "2mic" + elif "4mic" in settings.satellite.event_service_command[0]: + selected_service = "4mic" + + event_service = radiolist( + "Event Service:", + [ + ("none", "None"), + ("2mic", "2mic LEDs"), + ("4mic", "4mic LEDs"), + ], + selected_service, + ) + + if event_service is not None: + if event_service == "none": + settings.satellite.event_service_command = None + else: + settings.satellite.event_service_command = [ + str(PROGRAM_DIR / "script" / f"run_{event_service}"), + "--uri", + "tcp://127.0.0.1:10500", + ] + + settings.save() + else: + break diff --git a/installer/services.py b/installer/services.py new file mode 100755 index 0000000..b801f83 --- /dev/null +++ b/installer/services.py @@ -0,0 +1,262 @@ +"""Systemd service management.""" +import shlex +import subprocess +from pathlib import Path +from typing import List + +from .const import ( + LOCAL_DIR, + PROGRAM_DIR, + SERVICES_DIR, + SatelliteType, + Settings, + WakeWordSystem, +) +from .whiptail import error, msgbox, run_with_gauge + + +def stop_services(password: str) -> None: + stop_commands = [] + for service in ("satellite", "wakeword", "event"): + service_filename = f"wyoming-{service}.service" + service_path = Path("/etc/systemd/system") / service_filename + if not service_path.exists(): + continue + + stop_commands.append(["sudo", "-S", "systemctl", "stop", service_filename]) + stop_commands.append(["sudo", "-S", "systemctl", "disable", service_filename]) + + run_with_gauge("Stopping Services...", stop_commands, sudo_password=password) + + +def generate_services(settings: Settings) -> None: + SERVICES_DIR.mkdir(parents=True, exist_ok=True) + + user_id = subprocess.check_output(["id", "-u"], text=True).strip() + user_name = subprocess.check_output(["id", "--name", "-u"], text=True).strip() + + satellite_command: List[str] = [ + str(PROGRAM_DIR / "script" / "run"), + "--name", + settings.satellite.name, + "--uri", + "tcp://0.0.0.0:10700", + "--mic-command", + f"arecord -D {settings.mic.device} -q -r 16000 -c 1 -f S16_LE -t raw", + ] + satellite_requires: List[str] = [] + + if settings.snd.device is not None: + # Audio output + satellite_command.extend( + [ + "--snd-command", + f"aplay -D {settings.snd.device} -q -r 22050 -c 1 -f S16_LE -t raw", + ] + ) + + if settings.snd.volume_multiplier != 1.0: + satellite_command.extend( + ["--snd-volume-multiplier", str(settings.snd.volume_multiplier)] + ) + + for sound_name in settings.snd.feedback_sounds: + # Try local/sounds first + sound_path = LOCAL_DIR / "sounds" / f"{sound_name}.wav" + if not sound_path.exists(): + sound_path = PROGRAM_DIR / "sounds" / f"{sound_name}.wav" + + satellite_command.extend([f"--{sound_name}-wav", str(sound_path)]) + + if settings.mic.noise_suppression > 0: + satellite_command.extend( + ["--mic-noise-suppression", str(settings.mic.noise_suppression)] + ) + + if settings.mic.auto_gain > 0: + satellite_command.extend(["--mic-auto-gain", str(settings.mic.auto_gain)]) + + if settings.mic.volume_multiplier != 1.0: + satellite_command.extend( + ["--mic-volume-multiplier", str(settings.mic.volume_multiplier)] + ) + + if settings.satellite.type == SatelliteType.VAD: + # Voice activity detect + satellite_command.append("--vad") + elif settings.satellite.type == SatelliteType.WAKE: + # Local wake word detection + assert settings.wake.system is not None, "Wake word system not set" + + wake_word_service = "wyoming-wakeword" + wake_word_dir = LOCAL_DIR / ( + "wyoming-" + WakeWordSystem(settings.wake.system).value.lower() + ) + wake_word_command = [ + str(wake_word_dir / "script" / "run"), + "--uri", + "tcp://127.0.0.1:10400", + ] + + if settings.wake.system == WakeWordSystem.OPENWAKEWORD: + wake_word = settings.wake.openwakeword.wake_word + wake_word_command.extend( + [ + "--threshold", + str(settings.wake.openwakeword.threshold), + "--trigger-level", + str(settings.wake.openwakeword.trigger_level), + "--custom-model-dir", + str(LOCAL_DIR / "custom-wake-words" / "openWakeWord"), + ] + ) + elif settings.wake.system == WakeWordSystem.PORCUPINE1: + wake_word = settings.wake.porcupine1.wake_word + wake_word_command.extend( + ["--sensitivity", str(settings.wake.porcupine1.sensitivity)] + ) + elif settings.wake.system == WakeWordSystem.SNOWBOY: + wake_word = settings.wake.snowboy.wake_word + wake_word_command.extend( + [ + "--sensitivity", + str(settings.wake.snowboy.sensitivity), + "--custom-model-dir", + str(LOCAL_DIR / "custom-wake-words" / "snowboy"), + ] + ) + else: + raise ValueError(settings.wake.system) + + if settings.satellite.debug: + wake_word_command.append("--debug") + + wake_word_command_str = shlex.join(wake_word_command) + + with open( + SERVICES_DIR / f"{wake_word_service}.service", "w", encoding="utf-8" + ) as service_file: + print("[Unit]", file=service_file) + print( + f"Description={WakeWordSystem(settings.wake.system).value}", + file=service_file, + ) + print("", file=service_file) + print("[Service]", file=service_file) + print("Type=simple", file=service_file) + print(f"User={user_name}", file=service_file) + print(f"ExecStart={wake_word_command_str}", file=service_file) + print(f"WorkingDirectory={wake_word_dir}", file=service_file) + print("Restart=always", file=service_file) + print("RestartSec=1", file=service_file) + print("", file=service_file) + print("[Install]", file=service_file) + print("WantedBy=default.target", file=service_file) + + satellite_command.extend( + [ + "--wake-uri", + "tcp://127.0.0.1:10400", + "--wake-word-name", + wake_word, + ] + ) + satellite_requires.append(f"{wake_word_service}.service") + + if settings.satellite.event_service_command: + event_service = "wyoming-event" + event_command_str = shlex.join(settings.satellite.event_service_command) + with open( + SERVICES_DIR / f"{event_service}.service", "w", encoding="utf-8" + ) as service_file: + print("[Unit]", file=service_file) + print("Description=Event service", file=service_file) + print("", file=service_file) + print("[Service]", file=service_file) + print("Type=simple", file=service_file) + print(f"User={user_name}", file=service_file) + print(f"ExecStart={event_command_str}", file=service_file) + print(f"WorkingDirectory={PROGRAM_DIR}", file=service_file) + print("Restart=always", file=service_file) + print("RestartSec=1", file=service_file) + print("", file=service_file) + print("[Install]", file=service_file) + print("WantedBy=default.target", file=service_file) + + satellite_command.extend(["--event-uri", "tcp://127.0.0.1:10500"]) + satellite_requires.append(f"{event_service}.service") + + if settings.satellite.debug: + satellite_command.extend( + ["--debug", "--debug-recording-dir", str(LOCAL_DIR / "debug-recording")] + ) + + satellite_command_str = shlex.join(satellite_command) + + with open( + SERVICES_DIR / "wyoming-satellite.service", "w", encoding="utf-8" + ) as service_file: + print("[Unit]", file=service_file) + print("Description=Wyoming Satellite", file=service_file) + print("Wants=network-online.target", file=service_file) + print("After=network-online.target", file=service_file) + for requires in satellite_requires: + print(f"Requires={requires}", file=service_file) + + print("", file=service_file) + print("[Service]", file=service_file) + print("Type=simple", file=service_file) + print(f"User={user_name}", file=service_file) + + # For PulseAudio + print(f"Environment=XDG_RUNTIME_DIR=/run/user/{user_id}", file=service_file) + + print(f"ExecStart={satellite_command_str}", file=service_file) + print(f"WorkingDirectory={PROGRAM_DIR}", file=service_file) + print("Restart=always", file=service_file) + print("RestartSec=1", file=service_file) + print("", file=service_file) + print("[Install]", file=service_file) + print("WantedBy=default.target", file=service_file) + + +def install_services(settings: Settings, password: str): + # Install and run + installed_services = ["satellite"] + if settings.satellite.type == SatelliteType.WAKE: + assert settings.wake.system is not None, "No wake word system" + installed_services.append("wakeword") + + if settings.satellite.event_service_command: + installed_services.append("event") + + install_commands = [] + for service in installed_services: + service_filename = f"wyoming-{service}.service" + install_commands.append( + [ + "sudo", + "-S", + "cp", + str(SERVICES_DIR / service_filename), + "/etc/systemd/system/", + ] + ) + + install_commands.append(["sudo", "-S", "systemctl", "daemon-reload"]) + + # Copy first, then enable and start + for service in installed_services: + install_commands.append(["sudo", "-S", "systemctl", "enable", service_filename]) + + install_commands.append( + ["sudo", "-S", "systemctl", "enable", "--now", "wyoming-satellite.service"] + ) + + success = run_with_gauge( + "Installing Services...", install_commands, sudo_password=password + ) + if success: + msgbox("Successfully installed services") + else: + error("installing services") diff --git a/installer/speakers.py b/installer/speakers.py new file mode 100755 index 0000000..bffbdbb --- /dev/null +++ b/installer/speakers.py @@ -0,0 +1,150 @@ +"""Speaker settings.""" +import logging +import subprocess +from typing import List, Optional + +from .const import PROGRAM_DIR, Settings +from .whiptail import checklist, inputbox, menu, msgbox, radiolist + +_LOGGER = logging.getLogger() + + +def configure_speakers(settings: Settings) -> None: + choice: Optional[str] = None + while True: + choice = speakers_menu(choice) + + if choice == "play": + if settings.snd.device is None: + msgbox("No speaker device set") + continue + + test_sound_device(settings.snd.device) + elif choice == "test": + sound_device = test_speakers() + if sound_device is not None: + settings.snd.device = sound_device + settings.save() + elif choice == "list": + sound_device = radiolist( + "Select ALSA Device:", + get_sound_devices(), + settings.snd.device, + ) + if sound_device: + settings.snd.device = sound_device + settings.save() + elif choice == "manual": + sound_device = inputbox("Enter ALSA Device:", settings.snd.device) + if sound_device: + settings.snd.device = sound_device + settings.save() + elif choice == "disable": + settings.snd.device = None + settings.save() + msgbox("Sound disabled") + elif choice == "feedback": + feedback_sounds = checklist( + "Enabled Sounds:", + [("awake", "On wake-up"), ("done", "After voice command")], + settings.snd.feedback_sounds, + ) + + if feedback_sounds is not None: + settings.snd.feedback_sounds = feedback_sounds + settings.save() + elif choice == "multiplier": + while True: + volume_multiplier = inputbox( + "Volume Multiplier (1 = default)", settings.snd.volume_multiplier + ) + if volume_multiplier is None: + break + + try: + volume_multiplier_float = float(volume_multiplier) + except ValueError: + msgbox("Invalid value") + continue + + if volume_multiplier_float > 0: + settings.snd.volume_multiplier = volume_multiplier_float + settings.save() + break + + msgbox("Must be > 0") + else: + break + + +def speakers_menu(last_choice: Optional[str]) -> Optional[str]: + return menu( + "Main > Speakers", + [ + ("play", "Play Sound"), + ("test", "Test All Speakers"), + ("list", "Select From List"), + ("manual", "Enter Manually"), + ("disable", "Disable Sound"), + ("multiplier", "Volume Multiplier"), + ("feedback", "Toggle Feedback Sounds"), + ], + selected_item=last_choice, + menu_args=["--ok-button", "Select", "--cancel-button", "Back"], + ) + + +def get_sound_devices() -> List[str]: + devices = [] + lines = subprocess.check_output(["aplay", "-L"]).decode("utf-8").splitlines() + for line in lines: + line = line.strip() + + # default = PulseAudio + if (line == "default") or line.startswith("plughw:"): + devices.append(line) + + return devices + + +def test_speakers() -> Optional[str]: + devices = get_sound_devices() + if not devices: + msgbox("No speakers found") + return None + + device = devices.pop() + + while True: + choice = menu( + f"Device: {device}", + [ + ("play", "Play Sound"), + ("next", "Next Device"), + ("choose", "Choose This Device"), + ], + ) + + if choice == "play": + test_sound_device(device) + elif choice == "next": + if not devices: + msgbox("No more devices") + break + + device = devices.pop() + elif choice == "choose": + return device + else: + break + + return None + + +def test_sound_device(device: str) -> None: + try: + subprocess.check_call( + ["aplay", "-q", "-D", device, str(PROGRAM_DIR / "sounds" / "awake.wav")] + ) + except Exception: + _LOGGER.exception("Error testing device: %s", device) diff --git a/installer/wake_word.py b/installer/wake_word.py new file mode 100755 index 0000000..72c2c03 --- /dev/null +++ b/installer/wake_word.py @@ -0,0 +1,468 @@ +"""Wake word settings.""" +import itertools +import re +import shutil +from pathlib import Path +from typing import Dict, Optional + +from .const import LOCAL_DIR, SatelliteType, Settings, WakeWordSystem +from .packages import install_packages, packages_installed +from .whiptail import ( + error, + inputbox, + menu, + msgbox, + passwordbox, + radiolist, + run_with_gauge, + yesno, +) + + +def configure_wake_word(settings: Settings) -> None: + if settings.satellite.type != SatelliteType.WAKE: + if not yesno("Set satellite type to local wake word?"): + return + + settings.satellite.type = SatelliteType.WAKE + settings.save() + + def star(ww_system: WakeWordSystem) -> str: + return ( + f"{ww_system.value} [*]" + if settings.wake.system == ww_system + else ww_system.value + ) + + choice: Optional[str] = None + while True: + choice = menu( + "Main > Wake Word", + [ + ("system", "Wake Word System"), + ("wake_word", "Choose Wake Word"), + ("openWakeWord", star(WakeWordSystem.OPENWAKEWORD)), + ("porcupine1", star(WakeWordSystem.PORCUPINE1)), + ("snowboy", star(WakeWordSystem.SNOWBOY)), + ], + selected_item=choice, + menu_args=["--ok-button", "Select", "--cancel-button", "Back"], + ) + + if choice == "system": + wake_word_system = radiolist( + "Wake Word System:", + [v.value for v in WakeWordSystem], + settings.wake.system, + ) + if wake_word_system is None: + continue + + wake_word_system = WakeWordSystem(wake_word_system) + install_wake_word(settings, wake_word_system) + elif choice == "wake_word": + select_wake_word(settings) + elif choice == "openWakeWord": + configure_openWakeWord(settings) + elif choice == "porcupine1": + configure_porcupine1(settings) + elif choice == "snowboy": + configure_snowboy(settings) + else: + break + + +def install_wake_word(settings: Settings, wake_word_system: WakeWordSystem) -> None: + if wake_word_system == WakeWordSystem.OPENWAKEWORD: + oww_dir = LOCAL_DIR / "wyoming-openwakeword" + if not oww_dir.exists(): + if not yesno("Install openWakeWord?"): + return + + success = run_with_gauge( + "Installing openWakeWord", + [ + [ + "git", + "clone", + "https://github.com/rhasspy/wyoming-openwakeword.git", + str(oww_dir), + ], + [str(oww_dir / "script" / "setup")], + ], + ) + + if not success: + # Clean up + try: + shutil.rmtree(oww_dir) + except Exception: + pass + + error("installing openWakeWord") + return + + msgbox("openWakeWord installed successfully") + settings.wake.system = wake_word_system + settings.save() + return + + if wake_word_system == WakeWordSystem.PORCUPINE1: + porcupine1_dir = LOCAL_DIR / "wyoming-porcupine1" + if not porcupine1_dir.exists(): + if not yesno("Install porcupine1?"): + return + + success = run_with_gauge( + "Installing porcupine1", + [ + [ + "git", + "clone", + "https://github.com/rhasspy/wyoming-porcupine1.git", + str(porcupine1_dir), + ], + [str(porcupine1_dir / "script" / "setup")], + ], + ) + + if not success: + # Clean up + try: + shutil.rmtree(porcupine1_dir) + except Exception: + pass + + error("installing porcupine1") + return + + msgbox("porcupine1 installed successfully") + settings.wake.system = wake_word_system + settings.save() + return + + if wake_word_system == WakeWordSystem.SNOWBOY: + snowboy_dir = LOCAL_DIR / "wyoming-snowboy" + if not snowboy_dir.exists(): + if not yesno("Install snowboy?"): + return + + snowboy_packages = ["python3-dev", "swig", "libatlas-base-dev"] + if not packages_installed(*snowboy_packages): + password = passwordbox("sudo password:") + if not password: + return + + success = install_packages( + "Installing system packages...", password, *snowboy_packages + ) + if not success: + error("installing " + ", ".join(snowboy_packages)) + return + + success = run_with_gauge( + "Installing snowboy", + [ + [ + "git", + "clone", + "https://github.com/rhasspy/wyoming-snowboy.git", + str(snowboy_dir), + ], + [str(snowboy_dir / "script" / "setup")], + ], + ) + + if not success: + # Clean up + try: + shutil.rmtree(snowboy_dir) + except Exception: + pass + + error("installing snowboy") + return + + msgbox("snowboy installed successfully") + settings.wake.system = wake_word_system + settings.save() + return + + +def select_wake_word(settings: Settings) -> None: + if settings.wake.system == WakeWordSystem.OPENWAKEWORD: + oww_dir = LOCAL_DIR / "wyoming-openwakeword" + if not oww_dir.exists(): + msgbox("openWakeWord is not installed") + return + + custom_wake_word_dir = LOCAL_DIR / "custom-wake-words" / "openWakeWord" + custom_wake_word_dir.mkdir(parents=True, exist_ok=True) + + community_wake_word_dir = LOCAL_DIR / "home-assistant-wakewords-collection" + + while True: + ww_paths: Dict[str, Path] = { + p.stem: p for p in custom_wake_word_dir.glob("*.tflite") + } + + for ww_path in community_wake_word_dir.rglob("*.tflite"): + ww_name = ww_path.stem + if ww_name in ww_paths: + continue + + ww_paths[ww_name] = ww_path + + for ww_path in (oww_dir / "wyoming_openwakeword" / "models").glob( + "*.tflite" + ): + if not re.match("^.+_v[0-9].*$", ww_path.stem): + continue + + ww_name = ww_path.stem.rsplit("_", maxsplit=1)[0] + if ww_name in ww_paths: + continue + + ww_paths[ww_name] = ww_path + + items = sorted(list(ww_paths.keys())) + wake_word = radiolist( + "Wake Word:", items, settings.wake.openwakeword.wake_word + ) + if wake_word is None: + break + + wake_word_path = ww_paths[wake_word] + if wake_word_path.is_relative_to(community_wake_word_dir): + # Copy to custom directory + shutil.copy(wake_word_path, custom_wake_word_dir) + + settings.wake.openwakeword.wake_word = wake_word + settings.save() + break + + return + + if settings.wake.system == WakeWordSystem.PORCUPINE1: + porcupine1_dir = LOCAL_DIR / "wyoming-porcupine1" + if not porcupine1_dir.exists(): + msgbox("porcupine1 is not installed") + return + + ww_names = sorted( + list( + set( + p.stem.rsplit("_", maxsplit=1)[0] + for p in ( + porcupine1_dir / "wyoming_porcupine1" / "data" / "resources" + ).rglob("*.ppn") + ) + ) + ) + + wake_word = radiolist( + "Wake Word:", ww_names, settings.wake.porcupine1.wake_word + ) + if wake_word is not None: + settings.wake.porcupine1.wake_word = wake_word + settings.save() + + return + + if settings.wake.system == WakeWordSystem.SNOWBOY: + snowboy_dir = LOCAL_DIR / "wyoming-snowboy" + if not snowboy_dir.exists(): + msgbox("snowboy is not installed") + return + + custom_wake_word_dir = LOCAL_DIR / "custom-wake-words" / "snowboy" + custom_wake_word_dir.mkdir(parents=True, exist_ok=True) + + builtin_wake_words = (snowboy_dir / "wyoming_snowboy" / "data").glob("*.umdl") + custom_wake_words = itertools.chain( + custom_wake_word_dir.glob("*.pmdl"), custom_wake_word_dir.glob("*.umdl") + ) + ww_names = sorted( + list( + set( + p.stem + for p in itertools.chain(builtin_wake_words, custom_wake_words) + ) + ) + ) + + wake_word = radiolist("Wake Word:", ww_names, settings.wake.snowboy.wake_word) + if wake_word is not None: + settings.wake.snowboy.wake_word = wake_word + settings.save() + + return + + +def configure_openWakeWord(settings: Settings) -> None: + choice: Optional[str] = None + while True: + choice = menu( + "Main > Wake Word > openWakeWord", + [ + ("community", "Download Community Wake Words"), + ("threshold", "Set Threshold"), + ("trigger_level", "Set Trigger Level"), + ], + selected_item=choice, + menu_args=["--ok-button", "Select", "--cancel-button", "Back"], + ) + + if choice == "community": + community_wake_word_dir = LOCAL_DIR / "home-assistant-wakewords-collection" + + if not community_wake_word_dir.exists(): + success = run_with_gauge( + "Downloading community wake words...", + [ + [ + "git", + "clone", + "https://github.com/fwartner/home-assistant-wakewords-collection.git", + str(community_wake_word_dir), + ] + ], + ) + + if not success: + error("downloading community wake words") + else: + success = run_with_gauge( + "Updating community wake words...", + [ + [ + "git", + "-C", + str(community_wake_word_dir), + "pull", + "origin", + "main", + ] + ], + ) + + if not success: + error("updating community wake words") + elif choice == "threshold": + while True: + threshold = inputbox( + "Threshold (0-1, 0.5 = default):", + settings.wake.openwakeword.threshold, + ) + if threshold is None: + break + + try: + threshold_float = float(threshold) + except ValueError: + msgbox("Invalid value") + continue + + if 0 < threshold_float < 1: + settings.wake.openwakeword.threshold = threshold_float + settings.save() + break + + msgbox("Threshold must be in (0, 1)") + elif choice == "trigger_level": + while True: + trigger_level = inputbox( + "Trigger Level (> 0, 1 = default):", + settings.wake.openwakeword.trigger_level, + ) + if trigger_level is None: + break + + try: + trigger_level_int = int(trigger_level) + except ValueError: + msgbox("Invalid value") + continue + + if trigger_level_int > 0: + settings.wake.openwakeword.trigger_level = trigger_level_int + settings.save() + break + + msgbox("Trigger level must be > 0") + else: + break + + +def configure_porcupine1(settings: Settings) -> None: + choice: Optional[str] = None + while True: + choice = menu( + "Main > Wake Word > porcupine1", + [ + ("sensitivity", "Set Sensitivity"), + ], + selected_item=choice, + menu_args=["--ok-button", "Select", "--cancel-button", "Back"], + ) + + if choice == "sensitivity": + while True: + sensitivity = inputbox( + "Sensitivity (0-1, 0.5 = default):", + settings.wake.porcupine1.sensitivity, + ) + if sensitivity is None: + break + + try: + sensitivity_float = float(sensitivity) + except ValueError: + msgbox("Invalid value") + continue + + if 0 < sensitivity_float < 1: + settings.wake.porcupine1.sensitivity = sensitivity_float + settings.save() + break + + msgbox("Sensitivity must be in (0, 1)") + else: + break + + +def configure_snowboy(settings: Settings) -> None: + choice: Optional[str] = None + while True: + choice = menu( + "Main > Wake Word > snowboy", + [ + ("sensitivity", "Set Sensitivity"), + ], + selected_item=choice, + menu_args=["--ok-button", "Select", "--cancel-button", "Back"], + ) + + if choice == "sensitivity": + while True: + sensitivity = inputbox( + "Sensitivity (0-1, 0.5 = default):", + settings.wake.snowboy.sensitivity, + ) + if sensitivity is None: + break + + try: + sensitivity_float = float(sensitivity) + except ValueError: + msgbox("Invalid value") + continue + + if 0 < sensitivity_float < 1: + settings.wake.snowboy.sensitivity = sensitivity_float + settings.save() + break + + msgbox("Sensitivity must be in (0, 1)") + else: + break diff --git a/installer/whiptail.py b/installer/whiptail.py new file mode 100755 index 0000000..4c4d911 --- /dev/null +++ b/installer/whiptail.py @@ -0,0 +1,253 @@ +"""Python interface to whiptail command.""" +import logging +import shlex +import subprocess +import time +from collections.abc import Sequence +from concurrent.futures import ThreadPoolExecutor +from typing import Any, Dict, List, Optional, Tuple, Union + +from .const import HEIGHT, LIST_HEIGHT, TITLE, WIDTH + +ItemType = Union[str, Tuple[Any, str]] + +_LOGGER = logging.getLogger() + + +def whiptail(*args) -> Optional[str]: + proc = subprocess.Popen( + ["whiptail", "--title", TITLE] + list(args), + stderr=subprocess.PIPE, + ) + + _stdout, stderr = proc.communicate() + if proc.returncode != 0: + return None + + return stderr.decode("utf-8") + + +def menu( + text: str, + items: Sequence[ItemType], + selected_item: Optional[str] = None, + menu_args: Optional[Sequence[str]] = None, +) -> Optional[str]: + assert items, "No items" + + item_map: Dict[Optional[str], str] = {} + item_args: List[str] = [] + selected_tag: Optional[str] = None + for i, item in enumerate(items): + item_id = str(i) + item_args.append(item_id) + + if isinstance(item, str): + item_map[item_id] = item + item_args.append(item) + + if selected_item == item: + selected_tag = item_id + else: + item_map[item_id] = item[0] + item_args.append(item[1]) + + if selected_item == item[0]: + selected_tag = item_id + + menu_args = list(menu_args) if menu_args is not None else [] + if selected_tag is not None: + menu_args.extend(["--default-item", selected_tag]) + + result = whiptail( + "--notags", *menu_args, "--menu", text, HEIGHT, WIDTH, LIST_HEIGHT, *item_args + ) + return item_map.get(result) + + +def inputbox(text: str, init: Optional[Any] = None) -> Optional[str]: + return whiptail( + "--inputbox", text, HEIGHT, WIDTH, str(init) if init is not None else "" + ) + + +def passwordbox(text: str) -> Optional[str]: + return whiptail("--passwordbox", text, HEIGHT, WIDTH) + + +def radiolist( + text: str, + items: Sequence[ItemType], + selected_item: Any, + *args, +) -> Optional[Any]: + assert items, "No items" + + item_map: Dict[str, ItemType] = {} + item_args: List[str] = [] + for i, item in enumerate(items): + item_id = str(i) + item_args.append(item_id) + + if isinstance(item, str): + item_map[item_id] = item + item_args.append(item) + + if item == selected_item: + item_args.append("1") + else: + item_args.append("0") + else: + item_map[item_id] = item[0] + item_args.append(item[1]) + + if item[0] == selected_item: + item_args.append("1") + else: + item_args.append("0") + + result = whiptail( + "--notags", *args, "--radiolist", text, HEIGHT, WIDTH, LIST_HEIGHT, *item_args + ) + + if result is None: + return None + + return item_map.get(result, result) + + +def checklist( + text: str, + items: Sequence[ItemType], + selected_items: Sequence[Any], + *args, +) -> Optional[List[Any]]: + assert items, "No items" + + item_map: Dict[str, ItemType] = {} + item_args: List[str] = [] + for i, item in enumerate(items): + item_id = str(i) + item_args.append(item_id) + + if isinstance(item, str): + item_map[item_id] = item + item_args.append(item) + + if item in selected_items: + item_args.append("1") + else: + item_args.append("0") + else: + item_map[item_id] = item[0] + item_args.append(item[1]) + + if item[0] in selected_items: + item_args.append("1") + else: + item_args.append("0") + + result = whiptail( + "--notags", *args, "--checklist", text, HEIGHT, WIDTH, LIST_HEIGHT, *item_args + ) + + if result is None: + return None + + return [ + item_map.get(result_item, result_item) for result_item in shlex.split(result) + ] + + +def yesno(text: str) -> bool: + return whiptail("--yesno", text, HEIGHT, WIDTH) is not None + + +def msgbox(text: str) -> None: + whiptail("--msgbox", text, HEIGHT, WIDTH) + + +def gauge(text: str, seconds: int, parts: int = 20) -> None: + proc = subprocess.Popen( + ["whiptail", "--title", TITLE, "--gauge", text, HEIGHT, WIDTH, "0"], + stdin=subprocess.PIPE, + stderr=subprocess.PIPE, + text=True, + ) + assert proc.stdin is not None + + percent = 0 + while percent <= 100: + time.sleep(seconds / parts) + percent += int(100 / parts) + print(percent, file=proc.stdin, flush=True) + + proc.communicate() + + +def error(reason: str) -> None: + msgbox( + f"An error occurred while {reason}.\n" "See local/installer.log for details." + ) + + +# ----------------------------------------------------------------------------- + + +def run_with_gauge( + text: str, commands: Sequence[Sequence[str]], sudo_password: Optional[str] = None +) -> bool: + proc = subprocess.Popen( + ["whiptail", "--title", TITLE, "--gauge", text, HEIGHT, WIDTH, "0"], + stdin=subprocess.PIPE, + stderr=subprocess.PIPE, + text=True, + ) + assert proc.stdin is not None + percent = 0 + seconds = 5 + parts = 20 + + with ThreadPoolExecutor() as executor: + for command in commands: + future = executor.submit(_run_command, command, sudo_password) + while not future.done(): + time.sleep(seconds / parts) + percent += int(100 / parts) + if percent > 100: + percent = 0 + + print(percent, file=proc.stdin, flush=True) + + if not future.result(): + # Error occurred + return False + + proc.communicate() + return True + + +def _run_command(command: Sequence[str], sudo_password: Optional[str] = None) -> bool: + try: + assert command + proc_input: Optional[str] = None + if (command[0] == "sudo") and (sudo_password is not None): + proc_input = sudo_password + + proc = subprocess.Popen( + command, + stdin=subprocess.PIPE, + stdout=subprocess.DEVNULL, + stderr=subprocess.PIPE, + text=True, + ) + _stdout, stderr = proc.communicate(proc_input) + if proc.returncode != 0: + _LOGGER.error("Error running command: %s", command) + _LOGGER.error(stderr) + return False + except Exception: + _LOGGER.exception("Error running command: %s", command) + return False + + return True diff --git a/integrate.md b/integrate.md new file mode 100755 index 0000000..3c29a48 --- /dev/null +++ b/integrate.md @@ -0,0 +1,62 @@ +## Интеграция VAD и Wakeword: выводы и план + +### 1) Картина текущей архитектуры (Wyoming Satellite) +- **Режимы работы спутника**: + - AlwaysStreaming — всегда стримит аудио, VAD/Wake не участвуют. + - VadStreaming — локальный VAD решает момент старта стриминга; при активации отправляется предречь (pre-roll), опционально действует таймаут на ожидание wakeword. + - WakeStreaming — аудио уходит в локальный wakeword-сервис (Wyoming-протокол); при Detection начинается стриминг на сервер (STT/интенты). +- **VAD по умолчанию**: `SileroVad` с интерфейсом `__call__(audio_bytes|None) -> bool`, поддержка `reset()` через передачу `None`. Предречь хранится в кольцевом буфере, при активации догружается первой. +- **Wakeword**: внешние сервисы по Wyoming (например, openWakeWord, Porcupine, Snowboy), принимают `Audio*` события и отдают `Detection`. + +### 2) Что есть в `myproject` +- **VAD** (`myproject/vad_core.py`): + - Использует `webrtcvad.Vad` + энерго-критерии, адаптивный порог, простое шумоподавление и автоусиление. + - Имеет предбуфер и основной буфер записи сегмента речи; по завершении вызывает callback с целым кусочком аудио. + - Ввод аудио сейчас завязан на PyAudio внутри класса, то есть детектор и источник аудио слиты. +- **Wakeword на Vosk** (`myproject/vosk_local_STT.py` + `commands.py`): + - Собирает грамматику из `commands.yaml` (в т.ч. секцию `Wakewords`) и распознаёт текст. + - Факт wakeword определяется как точное совпадение распознанной фразы с элементами из `Wakewords` (то есть post-utterance wakeword через STT). + +### 3) Сопоставление и ключевые различия +- В Wyoming VAD — быстрый фрейм-по-фрейм решатель с мгновенным флагом активации, а у вас — сегментатор с внутренним циклом и завершением по тишине. +- В Wyoming wakeword — отдельный потоковый сервис (KWS-подобное поведение), а у вас — определение wakeword как часть STT после завершения фразы. + +### 4) Варианты интеграции +1. **Заменить локальный VAD на ваш (рекомендуется этап 2):** + - Выделить из `VADPolling` чистый детектор без PyAudio-ввода (API вида: `process(frame_bytes) -> { started/stopped/speech_detected, prebuffer, ... }`). + - Добавить фабрику VAD в спутник: `settings.vad.system: "silero"|"my_webrtc_vad"`, инициализировать нужную реализацию. + - При активации отдавать предбуфер и стартовать стриминг — совместимо с текущей логикой VadStreaming. +2. **Оформить wakeword на Vosk как Wyoming-сервис (рекомендуется этап 1):** + - Небольшой сервер по Wyoming-протоколу, который: + - подгружает грамматику только из `Wakewords`; + - принимает `AudioStart/AudioChunk/AudioStop` и кормит чанк в `KaldiRecognizer.AcceptWaveform`; + - при совпадении фразы — отправляет `Detection(name=...)` немедленно. + - Подключается как `wake.system: "vosk_wake"`, аналогично `openWakeWord`/`porcupine1`. + +### 5) Минимальные изменения кода +- **Для wakeword (этап 1):** + - Реализовать отдельный модуль `vosk_wake` (сервер Wyoming): запуск по TCP, обработка событий, генерация `Detection` по фразам из `Wakewords`. + - Unit-файл/скрипт запуска по аналогии с `local/services/wyoming-wakeword.service` и запись в конфиг `wake.system`. +- **Для VAD (этап 2):** + - Вынести логику детектора из `VADPolling` в отдельный класс без I/O. + - Добавить флаг `vad.system` и фабрику выбора реализации; адаптер, который преобразует `AudioChunk` → фреймы и использует ваш детектор для решения «старт/стоп/предречь». + +### 6) Пошаговый план внедрения +1) Wakeword на Vosk (быстрый выигрыш): + - Сделать `vosk_wake` сервис: узкая грамматика = только `Wakewords`, немедленный `Detection` при совпадении. + - Прописать сервис в systemd/скрипте, указать URI и `wake.system`. + - Протестировать в режиме `WakeStreamingSatellite`. +2) Замена VAD: + - Рефакторинг `VADPolling`: отделить детектор от аудио-источника. + - Добавить `vad.system` и внедрить адаптер под текущий интерфейс Wyoming. + - Протестировать в `VadStreamingSatellite` с предбуфером и таймаутом wakeword. + +### 7) Риски и примечания +- Vosk как wakeword — это распознавание текста; для «на лету» задержка может быть выше, чем у специализированного KWS. С узкой грамматикой (только wakewords) будет быстрее и устойчивее. +- Ваши улучшения VAD (AGC/NR/адаптивные пороги) полезны; главное — отделить I/O и обеспечить детерминированный фреймовый API, совместимый с Wyoming. + +### 8) Резюме +- Этап 1: добавить `vosk_wake` как Wyoming-сервис wakeword — минимум инвазивности и быстрая интеграция. +- Этап 2: внедрить ваш VAD через фабрику и адаптер — получить продвинутую локальную активацию речи, сохранив предречь и таймауты. + + diff --git a/mypy.ini b/mypy.ini new file mode 100755 index 0000000..261cf49 --- /dev/null +++ b/mypy.ini @@ -0,0 +1,5 @@ +[mypy] +ignore_missing_imports = true + +[mypy-setuptools.*] +ignore_missing_imports = True diff --git a/pylintrc b/pylintrc new file mode 100755 index 0000000..22a70d0 --- /dev/null +++ b/pylintrc @@ -0,0 +1,37 @@ +[MESSAGES CONTROL] +disable= + format, + abstract-method, + cyclic-import, + duplicate-code, + global-statement, + import-outside-toplevel, + inconsistent-return-statements, + locally-disabled, + not-context-manager, + too-few-public-methods, + too-many-arguments, + too-many-branches, + too-many-instance-attributes, + too-many-lines, + too-many-locals, + too-many-public-methods, + too-many-return-statements, + too-many-statements, + too-many-boolean-expressions, + unnecessary-pass, + unused-argument, + broad-except, + too-many-nested-blocks, + invalid-name, + unused-import, + fixme, + useless-super-delegation, + missing-module-docstring, + missing-class-docstring, + missing-function-docstring, + import-error, + consider-using-with + +[FORMAT] +expected-line-ending-format=LF diff --git a/pyproject.toml b/pyproject.toml new file mode 100755 index 0000000..89bdab4 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,61 @@ +[build-system] +requires = ["setuptools>=62.3"] +build-backend = "setuptools.build_meta" + +[project] +name = "wyoming_satellite" +version = "1.4.1" +license = {text = "MIT"} +description = "Wyoming server for remote voice satellite" +readme = "README.md" +authors = [ + {name = "Michael Hansen", email = "mike@rhasspy.org"} +] +keywords = ["rhasspy", "wyoming", "satellite"] +classifiers = [ + "Development Status :: 3 - Alpha", + "Intended Audience :: Developers", + "License :: OSI Approved :: MIT License", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", +] +requires-python = ">=3.9.0" +dependencies = [ + "wyoming==1.5.4", + "zeroconf==0.88.0", + "pyring-buffer>=1,<2", +] + +[project.optional-dependencies] +all = ["pysilero-vad==1.0.0", "webrtc-noise-gain==1.2.3"] +silerovad = ["pysilero-vad==1.0.0"] +webrtc = ["webrtc-noise-gain==1.2.3"] +respeaker = ["gpiozero", "spidev"] +dev = [ + "black==22.12.0", + "flake8==6.0.0", + "isort==5.11.3", + "mypy==0.991", + "pylint==2.15.9", + "pytest==7.4.3", + "pytest-asyncio==0.23.3", + "build==1.2.2" +] + +[project.scripts] +wyoming-satellite = "wyoming_satellite:__main__.run" + +[project.urls] +"Source Code" = "http://github.com/rhasspy/wyoming-satellite" + +[tool.setuptools] +platforms = ["any"] +zip-safe = true +include-package-data = true + +[tool.setuptools.packages.find] +include = ["wyoming_satellite*"] +exclude = ["tests", "tests.*"] diff --git a/script/build_docker b/script/build_docker new file mode 100755 index 0000000..32b18f3 --- /dev/null +++ b/script/build_docker @@ -0,0 +1,3 @@ +#!/usr/bin/env bash +docker build . \ + -t 'rhasspy/wyoming-satellite' "$@" diff --git a/script/format b/script/format new file mode 100755 index 0000000..24d4853 --- /dev/null +++ b/script/format @@ -0,0 +1,18 @@ +#!/usr/bin/env python3 +import subprocess +import venv +from pathlib import Path + +_DIR = Path(__file__).parent +_PROGRAM_DIR = _DIR.parent +_VENV_DIR = _PROGRAM_DIR / ".venv" +_MODULE_DIR = _PROGRAM_DIR / "wyoming_satellite" +_TESTS_DIR = _PROGRAM_DIR / "tests" +_INSTALLER_DIR = _PROGRAM_DIR / "installer" +_EXAMPLES_DIR = _PROGRAM_DIR / "examples" + +_FORMAT_DIRS = [_MODULE_DIR, _TESTS_DIR, _INSTALLER_DIR, _EXAMPLES_DIR] + +context = venv.EnvBuilder().ensure_directories(_VENV_DIR) +subprocess.check_call([context.env_exe, "-m", "black"] + _FORMAT_DIRS) +subprocess.check_call([context.env_exe, "-m", "isort"] + _FORMAT_DIRS) diff --git a/script/lint b/script/lint new file mode 100755 index 0000000..ceabca0 --- /dev/null +++ b/script/lint @@ -0,0 +1,20 @@ +#!/usr/bin/env python3 +import subprocess +import venv +from pathlib import Path + +_DIR = Path(__file__).parent +_PROGRAM_DIR = _DIR.parent +_VENV_DIR = _PROGRAM_DIR / ".venv" +_MODULE_DIR = _PROGRAM_DIR / "wyoming_satellite" +_TESTS_DIR = _PROGRAM_DIR / "tests" +_INSTALLER_DIR = _PROGRAM_DIR / "installer" + +_LINT_DIRS = [_MODULE_DIR, _TESTS_DIR, _INSTALLER_DIR] + +context = venv.EnvBuilder().ensure_directories(_VENV_DIR) +subprocess.check_call([context.env_exe, "-m", "black"] + _LINT_DIRS + ["--check"]) +subprocess.check_call([context.env_exe, "-m", "isort"] + _LINT_DIRS + ["--check"]) +subprocess.check_call([context.env_exe, "-m", "flake8"] + _LINT_DIRS) +subprocess.check_call([context.env_exe, "-m", "pylint"] + _LINT_DIRS) +subprocess.check_call([context.env_exe, "-m", "mypy"] + _LINT_DIRS) diff --git a/script/package b/script/package new file mode 100755 index 0000000..b124a6b --- /dev/null +++ b/script/package @@ -0,0 +1,11 @@ +#!/usr/bin/env python3 +import subprocess +import venv +from pathlib import Path + +_DIR = Path(__file__).parent +_PROGRAM_DIR = _DIR.parent +_VENV_DIR = _PROGRAM_DIR / ".venv" + +context = venv.EnvBuilder().ensure_directories(_VENV_DIR) +subprocess.check_call([context.env_exe, "-m", "build", "--wheel", "--sdist"]) diff --git a/script/run b/script/run new file mode 100755 index 0000000..a648150 --- /dev/null +++ b/script/run @@ -0,0 +1,12 @@ +#!/usr/bin/env python3 +import sys +import subprocess +import venv +from pathlib import Path + +_DIR = Path(__file__).parent +_PROGRAM_DIR = _DIR.parent +_VENV_DIR = _PROGRAM_DIR / ".venv" + +context = venv.EnvBuilder().ensure_directories(_VENV_DIR) +subprocess.check_call([context.env_exe, "-m", "wyoming_satellite"] + sys.argv[1:]) diff --git a/script/run_2mic b/script/run_2mic new file mode 100755 index 0000000..c94f2a2 --- /dev/null +++ b/script/run_2mic @@ -0,0 +1,15 @@ +#!/usr/bin/env python3 +import sys +import subprocess +import venv +from pathlib import Path + +_DIR = Path(__file__).parent +_PROGRAM_DIR = _DIR.parent +_VENV_DIR = _PROGRAM_DIR / ".venv" + +context = venv.EnvBuilder().ensure_directories(_VENV_DIR) +subprocess.check_call( + [context.env_exe, str(_PROGRAM_DIR / "examples" / "2mic_service.py")] + + sys.argv[1:] +) diff --git a/script/run_4mic b/script/run_4mic new file mode 100755 index 0000000..951c8c6 --- /dev/null +++ b/script/run_4mic @@ -0,0 +1,15 @@ +#!/usr/bin/env python3 +import sys +import subprocess +import venv +from pathlib import Path + +_DIR = Path(__file__).parent +_PROGRAM_DIR = _DIR.parent +_VENV_DIR = _PROGRAM_DIR / ".venv" + +context = venv.EnvBuilder().ensure_directories(_VENV_DIR) +subprocess.check_call( + [context.env_exe, str(_PROGRAM_DIR / "examples" / "4mic_service.py")] + + sys.argv[1:] +) diff --git a/script/run_docker b/script/run_docker new file mode 100755 index 0000000..09beb9f --- /dev/null +++ b/script/run_docker @@ -0,0 +1,6 @@ +#!/usr/bin/env bash +docker run \ + -it \ + -p 10700:10700 \ + --device /dev/snd \ + 'rhasspy/wyoming-satellite' "$@" diff --git a/script/run_usbmic b/script/run_usbmic new file mode 100755 index 0000000..665cdbe --- /dev/null +++ b/script/run_usbmic @@ -0,0 +1,15 @@ +#!/usr/bin/env python3 +import sys +import subprocess +import venv +from pathlib import Path + +_DIR = Path(__file__).parent +_PROGRAM_DIR = _DIR.parent +_VENV_DIR = _PROGRAM_DIR / ".venv" + +context = venv.EnvBuilder().ensure_directories(_VENV_DIR) +subprocess.check_call( + [context.env_exe, str(_PROGRAM_DIR / "examples" / "usbmic_service.py")] + + sys.argv[1:] +) diff --git a/script/setup b/script/setup new file mode 100755 index 0000000..e0fe6c4 --- /dev/null +++ b/script/setup @@ -0,0 +1,42 @@ +#!/usr/bin/env python3 +import argparse +import subprocess +import venv +from pathlib import Path + +_DIR = Path(__file__).parent +_PROGRAM_DIR = _DIR.parent +_VENV_DIR = _PROGRAM_DIR / ".venv" + +parser = argparse.ArgumentParser() +parser.add_argument("--dev", action="store_true", help="Install dev requirements") +args = parser.parse_args() + +# Create virtual environment +builder = venv.EnvBuilder(with_pip=True) +context = builder.ensure_directories(_VENV_DIR) +builder.create(_VENV_DIR) + +# Upgrade dependencies +pip = [context.env_exe, "-m", "pip"] +subprocess.check_call(pip + ["install", "--upgrade", "pip"]) + +# Install requirements +subprocess.check_call( + pip + + [ + "install", + "--extra-index-url", + "https://www.piwheels.org/simple", + "-f", + "https://synesthesiam.github.io/prebuilt-apps/", + "-e", + str(_PROGRAM_DIR), + ] +) + +if args.dev: + # Install dev requirements + subprocess.check_call( + pip + ["install", "-e", f"{_PROGRAM_DIR}[dev]"] + ) diff --git a/script/test b/script/test new file mode 100755 index 0000000..5ad78a8 --- /dev/null +++ b/script/test @@ -0,0 +1,13 @@ +#!/usr/bin/env python3 +import subprocess +import sys +import venv +from pathlib import Path + +_DIR = Path(__file__).parent +_PROGRAM_DIR = _DIR.parent +_VENV_DIR = _PROGRAM_DIR / ".venv" +_TEST_DIR = _PROGRAM_DIR / "tests" + +context = venv.EnvBuilder().ensure_directories(_VENV_DIR) +subprocess.check_call([context.env_exe, "-m", "pytest", _TEST_DIR] + sys.argv[1:]) diff --git a/setup.cfg b/setup.cfg new file mode 100755 index 0000000..0076bbf --- /dev/null +++ b/setup.cfg @@ -0,0 +1,22 @@ +[flake8] +# To work with Black +max-line-length = 88 +# E501: line too long +# W503: Line break occurred before a binary operator +# E203: Whitespace before ':' +# D202 No blank lines allowed after function docstring +# W504 line break after binary operator +ignore = + E501, + W503, + E203, + D202, + W504 + +[isort] +multi_line_output = 3 +include_trailing_comma=True +force_grid_wrap=0 +use_parentheses=True +line_length=88 +indent = " " diff --git a/sounds/awake.wav b/sounds/awake.wav new file mode 100755 index 0000000000000000000000000000000000000000..8cb6535ae897dfffd94d6999818f74f69b99f2d3 GIT binary patch literal 17666 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 literal 0 HcmV?d00001 diff --git a/sounds/done.wav b/sounds/done.wav new file mode 100755 index 0000000000000000000000000000000000000000..d76ec5b4780b2420f663aa54e185193ee5d754a9 GIT binary patch literal 49242 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

YPow&Wf`TCnbj; zA}fa%PV=H+7mp>o5{ws|5+8IJ;cQv3K`0WQM8i_C$$5vnq5+v*EY#g62Be+6Cloj&6;E=AcLR2Nim zN9CBS^`+bGP*ILK`xcsHc9+Mwxcdl`V?HBRBAJF@l~}UqSdcnKlics_75jdag^9jn zoXR?vs}*CBQ+RUOjf+4rToviLh#-=79Jz=p*NL9pm@$iVqdG}TCgScF?wzDucH*cP z%X77x)3s<+Y}!RmXXTE5p;oduk&{@OV4~o#<6b1_^6vSBz8VW1^Es zxaxE#cMF}4Cb1@G(?VB_Q?Y!pGKUf|Z*)i|R0;ipfnqt%pPV;~Cp)h}Wc-K^2u(3> za@m92AH$KDkI6BYtvMfczAO~P{6Ww`e#Dm@{i2f?r7^FSV=n%SS36E)8IpLH-0L*r zqM@L=yc0@YM3)hTd%0ie6nk>BxQxfmF4s8O$*6(}a-|zfsFX2fHir@7&9QkzQi3MV z$DKr+jk#+aYPm6E_$9K8-S6k0QIw^@vh8 zhQl+l5}`_t$(@c)hu6_z{xg!imr-J)3J*>u!oS=vKO*Hv*EqV|buryWFNY|XFMUD!mj!v1uNlwO)Yu)|w z-remubx}r+xF09~N78sC4>=#3!;S6cbK|+YWfq}8=yx1ElBUe$jyXPslK=j3T*T&+ zPcds2j^riw{NGZNV=}wU<=#8G+Q)E({fD5F$u-Sk&zzB(n<2aM|5Y! z^Mop~GRM__Tgf9n*dm2R! zNw{`68r4_cN&h3=SGw}V@ZA5jZx}+K(7Dqdt>+i@A$DX|F2~{;$B9L*@GL= zeG+QiJ2!&N<$mN|ITriuxR?3m#~pR=Tq)opJxWGxGj_uXX3;xZL^ZlN&Ln zEqBIoBiFdkZnoH6vHxRN#bo+uZg*$wd~6i?{ODM0ba%wf5WDjKjwDyaBp18O(eS^N z$l2H!kN%fqZWhO@e2)D*(p2nROcMVqsn{Kl{+BV`)o%3InHVqfId&#SsT`9zg~R^` D^5usr literal 0 HcmV?d00001 diff --git a/sounds/listen.wav b/sounds/listen.wav new file mode 100755 index 0000000000000000000000000000000000000000..cb4f29fade2ce45575d0976e090005632a0374fb GIT binary patch literal 304206 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

4h)NOU45hR&onxGibPfCaUjsiWP&+oqcN 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

r@ecs$pO^DRs61Ec0Kq~`uS4&+|rSM;VkGI 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%0DRJBwsiS-sCKGh`)iXEc0= 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 literal 0 HcmV?d00001 diff --git a/sounds/volume.wav b/sounds/volume.wav new file mode 100755 index 0000000000000000000000000000000000000000..40a97bca6c5eafa4e113ebc076d48ded0d9c95a0 GIT binary patch literal 35874 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 literal 0 HcmV?d00001 diff --git a/start-dev.sh b/start-dev.sh new file mode 100755 index 0000000..f6e7615 --- /dev/null +++ b/start-dev.sh @@ -0,0 +1,6 @@ +/home/sirmrak/wyoming-satellite/.venv/bin/python local/vosk-wake-dev/script/run \ + --uri tcp://0.0.0.0:10400 \ + --model-path /home/sirmrak/models/vosk-model-small-ru-0.22 \ + --rate 16000 \ + --wake-word "привет дроид" #\ +# --debug diff --git a/start.sh b/start.sh new file mode 100755 index 0000000..158c425 --- /dev/null +++ b/start.sh @@ -0,0 +1,6 @@ +/home/sirmrak/wyoming-satellite/.venv/bin/python local/vosk-wake/script/run \ + --uri tcp://0.0.0.0:10400 \ + --model-path /home/sirmrak/models/vosk-model-small-ru-0.22 \ + --rate 16000 \ + --wake-word "привет дроид" \ + --debug diff --git a/start_satellite.sh b/start_satellite.sh new file mode 100755 index 0000000..335b9ac --- /dev/null +++ b/start_satellite.sh @@ -0,0 +1,54 @@ +#!/usr/bin/env bash +set -euo pipefail + +# Делаем текущий проект доступным для Python +SCRIPT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) +export PYTHONPATH="${SCRIPT_DIR}" + +# Путь к Python-окружению +PY="/home/sirmrak/wyoming-satellite/.venv/bin/python" + +# Режим запуска: wake|vad (по умолчанию wake) +MODE="${1:-wake}" + +BASE_ARGS=( + --debug + --name 'Wyoming Pi Satellite' + --uri tcp://0.0.0.0:10700 + --mic-command 'arecord -D plughw:CARD=seeed2micvoicec,DEV=0 -q -r 16000 -c 1 -f S16_LE -t raw' + --snd-command 'aplay -D plughw:CARD=0,DEV=0 -q -r 22050 -c 1 -f S16_LE -t raw' + --awake-wav /home/sirmrak/wyoming-satellite/sounds/awake.wav + --mic-noise-suppression 2 + --mic-auto-gain 20 + --event-uri tcp://127.0.0.1:10500 +) + +if [[ "$MODE" == "wake" ]]; then + # Локальный wakeword-сервис (Vosk). VAD в этом режиме не используется спутником. + EXTRA_ARGS=( + --wake-uri tcp://127.0.0.1:10400 + --wake-word-name "привет дроид" \ + #--wake-word-name "привет придурок" \ + #--wake-word-name "привет жопа с ушами" + # Добавьте дополнительные фразы при необходимости: + # --wake-word-name "привет дурик" \ + # --wake-word-name "привет говнюк" + ) +elif [[ "$MODE" == "vad" ]]; then + # Локальный VAD (WebRTC+энергия) без wakeword-сервиса + EXTRA_ARGS=( + --vad + --vad-system webrtc + --vad-trigger-level 5 # ≈100мс при 20мс окне + --vad-energy-threshold 200 + --vad-buffer-seconds 1 + --vad-wake-word-timeout 5 + ) +else + echo "Неизвестный режим: $MODE (ожидается: wake|vad)" >&2 + exit 1 +fi + +exec "$PY" -m wyoming_satellite "${BASE_ARGS[@]}" "${EXTRA_ARGS[@]}" + + diff --git a/test.wav b/test.wav new file mode 100755 index 0000000000000000000000000000000000000000..5ba32cf866068b4599417390c2119e7a0b19ec06 GIT binary patch literal 232044 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

hi*U%w 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

T=1B75XDc67)E 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 literal 0 HcmV?d00001 diff --git a/tests/__init__.py b/tests/__init__.py new file mode 100755 index 0000000..fbab3dc --- /dev/null +++ b/tests/__init__.py @@ -0,0 +1 @@ +"""Wyoming satellite tests.""" diff --git a/tests/shared.py b/tests/shared.py new file mode 100755 index 0000000..2b47c37 --- /dev/null +++ b/tests/shared.py @@ -0,0 +1,64 @@ +"""Shared code for Wyoming satellite tests.""" +import asyncio +import io +from collections.abc import Iterable +from typing import Optional + +from wyoming.audio import AudioChunk, AudioStart, AudioStop +from wyoming.client import AsyncClient +from wyoming.event import Event + +AUDIO_START = AudioStart(rate=16000, width=2, channels=1) +AUDIO_STOP = AudioStop() + +AUDIO_CHUNK = AudioChunk( + rate=16000, width=2, channels=1, audio=bytes([255] * 960) # 30ms +) + + +class FakeStreamReaderWriter: + def __init__(self) -> None: + self._undrained_data = bytes() + self._value = bytes() + self._data_ready = asyncio.Event() + + def write(self, data: bytes) -> None: + self._undrained_data += data + + def writelines(self, data: Iterable[bytes]) -> None: + for line in data: + self.write(line) + + async def drain(self) -> None: + self._value += self._undrained_data + self._undrained_data = bytes() + self._data_ready.set() + self._data_ready.clear() + + async def readline(self) -> bytes: + while b"\n" not in self._value: + await self._data_ready.wait() + + with io.BytesIO(self._value) as value_io: + data = value_io.readline() + self._value = self._value[len(data) :] + return data + + async def readexactly(self, n: int) -> bytes: + while len(self._value) < n: + await self._data_ready.wait() + + data = self._value[:n] + self._value = self._value[n:] + return data + + +class MicClient(AsyncClient): + async def read_event(self) -> Optional[Event]: + # Send 30ms of audio every 30ms + await asyncio.sleep(AUDIO_CHUNK.seconds) + return AUDIO_CHUNK.event() + + async def write_event(self, event: Event) -> None: + # Output only + pass diff --git a/tests/test_satellite.py b/tests/test_satellite.py new file mode 100755 index 0000000..a6686ab --- /dev/null +++ b/tests/test_satellite.py @@ -0,0 +1,222 @@ +import asyncio +import logging +from typing import Final, Optional +from unittest.mock import patch + +import pytest +from wyoming.asr import Transcript +from wyoming.audio import AudioChunk, AudioStart, AudioStop +from wyoming.client import AsyncClient +from wyoming.event import Event, async_read_event +from wyoming.pipeline import PipelineStage, RunPipeline +from wyoming.satellite import RunSatellite, StreamingStarted, StreamingStopped +from wyoming.tts import Synthesize +from wyoming.wake import Detection + +from wyoming_satellite import ( + EventSettings, + MicSettings, + SatelliteSettings, + SndSettings, + WakeSettings, + WakeStreamingSatellite, +) + +from .shared import ( + AUDIO_CHUNK, + AUDIO_START, + AUDIO_STOP, + FakeStreamReaderWriter, + MicClient, +) + +_LOGGER = logging.getLogger() + +TIMEOUT: Final = 1 + + +class WakeClient(AsyncClient): + def __init__(self) -> None: + super().__init__() + self._event_ready = asyncio.Event() + self._event: Optional[Event] = None + self._detected: bool = False + + async def read_event(self) -> Optional[Event]: + await self._event_ready.wait() + self._event_ready.clear() + return self._event + + async def write_event(self, event: Event) -> None: + if AudioChunk.is_type(event.type): + if not self._detected: + self._detected = True + self._event = Detection().event() + self._event_ready.set() + + +class SndClient(AsyncClient): + def __init__(self) -> None: + super().__init__() + self.synthesize = asyncio.Event() + self.audio_start = asyncio.Event() + self.audio_chunk = asyncio.Event() + self.audio_stop = asyncio.Event() + + async def read_event(self) -> Optional[Event]: + # Input only + pass + + async def write_event(self, event: Event) -> None: + if AudioChunk.is_type(event.type): + self.audio_chunk.set() + elif Synthesize.is_type(event.type): + self.synthesize.set() + elif AudioStart.is_type(event.type): + self.audio_start.set() + elif AudioStop.is_type(event.type): + self.audio_stop.set() + + +class EventClient(AsyncClient): + def __init__(self) -> None: + super().__init__() + self.detection = asyncio.Event() + self.streaming_started = asyncio.Event() + self.streaming_stopped = asyncio.Event() + self.transcript = asyncio.Event() + self.synthesize = asyncio.Event() + self.audio_start = asyncio.Event() + self.audio_chunk = asyncio.Event() + self.audio_stop = asyncio.Event() + + async def read_event(self) -> Optional[Event]: + # Input only + return None + + async def write_event(self, event: Event) -> None: + if Detection.is_type(event.type): + self.detection.set() + elif StreamingStarted.is_type(event.type): + self.streaming_started.set() + elif StreamingStopped.is_type(event.type): + self.streaming_stopped.set() + elif Transcript.is_type(event.type): + self.transcript.set() + elif Synthesize.is_type(event.type): + self.synthesize.set() + elif AudioChunk.is_type(event.type): + self.audio_chunk.set() + elif AudioStart.is_type(event.type): + self.audio_start.set() + elif AudioStop.is_type(event.type): + self.audio_stop.set() + + +# ----------------------------------------------------------------------------- + + +@pytest.mark.asyncio +async def test_wake_satellite() -> None: + mic_client = MicClient() + snd_client = SndClient() + wake_client = WakeClient() + event_client = EventClient() + + with patch( + "wyoming_satellite.satellite.SatelliteBase._make_mic_client", + return_value=mic_client, + ), patch( + "wyoming_satellite.satellite.SatelliteBase._make_snd_client", + return_value=snd_client, + ), patch( + "wyoming_satellite.satellite.SatelliteBase._make_wake_client", + return_value=wake_client, + ), patch( + "wyoming_satellite.satellite.SatelliteBase._make_event_client", + return_value=event_client, + ): + satellite = WakeStreamingSatellite( + SatelliteSettings( + mic=MicSettings(uri="test"), + snd=SndSettings(uri="test"), + wake=WakeSettings(uri="test"), + event=EventSettings(uri="test"), + ) + ) + + async def event_from_satellite() -> Optional[Event]: + return await async_read_event(server_io) + + satellite_task = asyncio.create_task(satellite.run(), name="satellite") + + # Fake server connection + server_io = FakeStreamReaderWriter() + await satellite.set_server("test", server_io) # type: ignore + + # Start satellite + await satellite.event_from_server(RunSatellite().event()) + + # Trigger detection + event = await asyncio.wait_for(event_from_satellite(), timeout=TIMEOUT) + assert event is not None + assert Detection.is_type(event.type), event + + # Pipeline should start + event = await asyncio.wait_for(event_from_satellite(), timeout=TIMEOUT) + assert event is not None + assert RunPipeline.is_type(event.type), event + run_pipeline = RunPipeline.from_event(event) + assert run_pipeline.start_stage == PipelineStage.ASR + assert run_pipeline.end_stage == PipelineStage.TTS + + # Event service should have received detection + await asyncio.wait_for(event_client.detection.wait(), timeout=TIMEOUT) + + # Server should be receiving audio now + assert satellite.is_streaming, "Not streaming" + for _ in range(5): + event = await asyncio.wait_for(event_from_satellite(), timeout=TIMEOUT) + assert event is not None + assert AudioChunk.is_type(event.type) + + # Event service should have received streaming start + await asyncio.wait_for(event_client.streaming_started.wait(), timeout=TIMEOUT) + + # Send transcript + await satellite.event_from_server(Transcript(text="test").event()) + + # Event service should have received transcript + await asyncio.wait_for(event_client.transcript.wait(), timeout=TIMEOUT) + + # Wait for streaming to stop + while satellite.is_streaming: + event = await asyncio.wait_for(event_from_satellite(), timeout=TIMEOUT) + assert event is not None + assert AudioChunk.is_type(event.type) + + # Event service should have received streaming stop + await asyncio.wait_for(event_client.streaming_stopped.wait(), timeout=TIMEOUT) + + # Fake a TTS response + await satellite.event_from_server(Synthesize(text="test").event()) + + # Event service should have received synthesize + await asyncio.wait_for(event_client.synthesize.wait(), timeout=TIMEOUT) + + # Audio start, chunk, stop + await satellite.event_from_server(AUDIO_START.event()) + await asyncio.wait_for(snd_client.audio_start.wait(), timeout=TIMEOUT) + await asyncio.wait_for(event_client.audio_start.wait(), timeout=TIMEOUT) + + # Event service does not get audio chunks, just start/stop + await satellite.event_from_server(AUDIO_CHUNK.event()) + await asyncio.wait_for(snd_client.audio_chunk.wait(), timeout=TIMEOUT) + + await satellite.event_from_server(AUDIO_STOP.event()) + await asyncio.wait_for(snd_client.audio_stop.wait(), timeout=TIMEOUT) + await asyncio.wait_for(event_client.audio_stop.wait(), timeout=TIMEOUT) + + # Stop satellite + await satellite.stop() + await satellite_task diff --git a/tests/test_wake_streaming.py b/tests/test_wake_streaming.py new file mode 100755 index 0000000..2550ee5 --- /dev/null +++ b/tests/test_wake_streaming.py @@ -0,0 +1,97 @@ +import asyncio +import logging +from pathlib import Path +from typing import Optional +from unittest.mock import patch + +import pytest +from wyoming.asr import Transcript +from wyoming.audio import AudioChunk +from wyoming.client import AsyncClient +from wyoming.event import Event +from wyoming.satellite import RunSatellite +from wyoming.wake import Detection + +from wyoming_satellite import ( + EventSettings, + MicSettings, + SatelliteSettings, + WakeSettings, + WakeStreamingSatellite, +) + +from .shared import MicClient + +_LOGGER = logging.getLogger() + + +class WakeClient(AsyncClient): + def __init__(self) -> None: + super().__init__() + self._detection_event = asyncio.Event() + + async def read_event(self) -> Optional[Event]: + await self._detection_event.wait() + return Detection().event() + + async def write_event(self, event: Event) -> None: + if AudioChunk.is_type(event.type): + self._detection_event.set() + + +class EventClient(AsyncClient): + def __init__(self) -> None: + super().__init__() + self.wake_event = asyncio.Event() + + async def read_event(self) -> Optional[Event]: + # Input only + return None + + async def write_event(self, event: Event) -> None: + if Detection.is_type(event.type): + self.wake_event.set() + + +@pytest.mark.asyncio +async def test_multiple_wakeups(tmp_path: Path) -> None: + mic_client = MicClient() + wake_client = WakeClient() + event_client = EventClient() + + with patch( + "wyoming_satellite.satellite.SatelliteBase._make_mic_client", + return_value=mic_client, + ), patch( + "wyoming_satellite.satellite.SatelliteBase._make_wake_client", + return_value=wake_client, + ), patch( + "wyoming_satellite.satellite.SatelliteBase._make_event_client", + return_value=event_client, + ): + satellite = WakeStreamingSatellite( + SatelliteSettings( + mic=MicSettings(uri="test"), + wake=WakeSettings(uri="test"), + event=EventSettings(uri="test"), + ) + ) + + # Fake server connection + satellite.server_id = "test" + + satellite_task = asyncio.create_task(satellite.run(), name="satellite") + await satellite.event_from_server(RunSatellite().event()) + + await asyncio.wait_for(event_client.wake_event.wait(), timeout=1) + event_client.wake_event.clear() + + # Stop streaming + await satellite.event_from_server(Transcript("test").event()) + + # Should not trigger again within refractory period (default: 5 sec) + with pytest.raises(asyncio.TimeoutError): + await asyncio.wait_for(event_client.wake_event.wait(), timeout=0.15) + + await satellite.stop() + await satellite_task diff --git a/tox.ini b/tox.ini new file mode 100755 index 0000000..7f338b7 --- /dev/null +++ b/tox.ini @@ -0,0 +1,14 @@ +[tox] +env_list = + py{39,310,311,312,313} +minversion = 4.12.1 + +[testenv] +description = run the tests with pytest +package = wheel +wheel_build_env = .pkg +deps = + pytest>=7,<8 + pytest-asyncio<1 +commands = + pytest {tty:--color=yes} {posargs} diff --git a/wyoming-satellite.service b/wyoming-satellite.service new file mode 100755 index 0000000..630cd81 --- /dev/null +++ b/wyoming-satellite.service @@ -0,0 +1,18 @@ +[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 new file mode 100755 index 0000000000000000000000000000000000000000..4e60663252ed48c95f9ec39dbec45c823a8dd792 GIT binary patch literal 75833 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 None: + """Main entry point.""" + parser = argparse.ArgumentParser() + + # Microphone input + parser.add_argument("--mic-uri", help="URI of Wyoming microphone service") + parser.add_argument("--mic-command", help="Program to run for microphone input") + parser.add_argument( + "--mic-command-rate", + type=int, + default=16000, + help="Sample rate of mic-command (hertz, default: 16000)", + ) + parser.add_argument( + "--mic-command-width", + type=int, + default=2, + help="Sample width of mic-command (bytes, default: 2)", + ) + parser.add_argument( + "--mic-command-channels", + type=int, + default=1, + help="Sample channels of mic-command (default: 1)", + ) + parser.add_argument( + "--mic-command-samples-per-chunk", + type=int, + default=1024, + help="Sample per chunk for mic-command (default: 1024)", + ) + parser.add_argument("--mic-volume-multiplier", type=float, default=1.0) + parser.add_argument( + "--mic-noise-suppression", type=int, default=0, choices=(0, 1, 2, 3, 4) + ) + parser.add_argument("--mic-auto-gain", type=int, default=0, choices=list(range(32))) + parser.add_argument( + "--mic-seconds-to-mute-after-awake-wav", + type=float, + default=0.5, + help="Seconds to mute microphone after awake wav is finished playing (default: 0.5)", + ) + parser.add_argument( + "--mic-no-mute-during-awake-wav", + action="store_true", + help="Don't mute the microphone while awake wav is being played", + ) + parser.add_argument( + "--mic-channel-index", + type=int, + help="Take microphone input from a specific channel (first channel is 0)", + ) + + # Sound output + parser.add_argument("--snd-uri", help="URI of Wyoming sound service") + parser.add_argument("--snd-command", help="Program to run for sound output") + parser.add_argument( + "--snd-command-rate", + type=int, + default=22050, + help="Sample rate of snd-command (hertz, default: 22050)", + ) + parser.add_argument( + "--snd-command-width", + type=int, + default=2, + help="Sample width of snd-command (bytes, default: 2)", + ) + parser.add_argument( + "--snd-command-channels", + type=int, + default=1, + help="Sample channels of snd-command (default: 1)", + ) + parser.add_argument("--snd-volume-multiplier", type=float, default=1.0) + + # Local wake word detection + parser.add_argument("--wake-uri", help="URI of Wyoming wake word detection service") + parser.add_argument( + "--wake-word-name", + action="append", + default=[], + nargs="+", + metavar=("name", "pipeline"), + help="Name of wake word to listen for and optional pipeline name to run (requires --wake-uri)", + ) + parser.add_argument("--wake-command", help="Program to run for wake word detection") + parser.add_argument( + "--wake-command-rate", + type=int, + default=16000, + help="Sample rate of wake-command (hertz, default: 16000)", + ) + parser.add_argument( + "--wake-command-width", + type=int, + default=2, + help="Sample width of wake-command (bytes, default: 2)", + ) + parser.add_argument( + "--wake-command-channels", + type=int, + default=1, + help="Sample channels of wake-command (default: 1)", + ) + parser.add_argument( + "--wake-refractory-seconds", + type=float, + default=5.0, + help="Seconds after a wake word detection before another detection is handled (default: 5)", + ) + + # Voice activity detector + parser.add_argument( + "--vad", action="store_true", help="Wait for speech before streaming audio" + ) + parser.add_argument( + "--vad-system", + dest="vad_system", + choices=("silero", "webrtc"), + default="silero", + help="VAD implementation to use (default: silero)", + ) + parser.add_argument("--vad-threshold", type=float, default=0.5) + parser.add_argument("--vad-trigger-level", type=int, default=1) + parser.add_argument("--vad-buffer-seconds", type=float, default=2) + parser.add_argument( + "--vad-wake-word-timeout", + type=float, + default=5.0, + help="Seconds before going back to waiting for speech when wake word isn't detected", + ) + parser.add_argument( + "--vad-energy-threshold", + type=float, + help="Optional RMS energy threshold for 'webrtc' VAD (int16 scale)", + ) + + # External event handlers + parser.add_argument( + "--event-uri", help="URI of Wyoming service to forward events to" + ) + parser.add_argument( + "--startup-command", help="Command run when the satellite starts" + ) + parser.add_argument( + "--detect-command", help="Command to run when wake word detection starts" + ) + parser.add_argument( + "--detection-command", help="Command to run when wake word is detected" + ) + parser.add_argument( + "--transcript-command", + help="Command to run when speech to text transcript is returned", + ) + parser.add_argument( + "--stt-start-command", + help="Command to run when the user starts speaking", + ) + parser.add_argument( + "--stt-stop-command", + help="Command to run when the user stops speaking", + ) + parser.add_argument( + "--synthesize-command", + help="Command to run when text to speech text is returned", + ) + parser.add_argument( + "--tts-start-command", + help="Command to run when text to speech response starts", + ) + parser.add_argument( + "--tts-stop-command", + help="Command to run when text to speech response stops", + ) + parser.add_argument( + "--tts-played-command", + help="Command to run when text-to-speech audio stopped playing", + ) + parser.add_argument( + "--streaming-start-command", + help="Command to run when audio streaming starts", + ) + parser.add_argument( + "--streaming-stop-command", + help="Command to run when audio streaming stops", + ) + parser.add_argument( + "--error-command", + help="Command to run when an error occurs", + ) + parser.add_argument( + "--connected-command", + help="Command to run when connected to the server", + ) + parser.add_argument( + "--disconnected-command", + help="Command to run when disconnected from the server", + ) + parser.add_argument( + "--timer-started-command", + help="Command to run when a timer starts", + ) + parser.add_argument( + "--timer-updated-command", + help="Command to run when a timer is paused, resumed, or has time added or removed", + ) + parser.add_argument( + "--timer-cancelled-command", + "--timer-canceled-command", + help="Command to run when a timer is cancelled", + ) + parser.add_argument( + "--timer-finished-command", + help="Command to run when a timer finishes", + ) + + # Sounds + parser.add_argument( + "--awake-wav", help="WAV file to play when wake word is detected" + ) + parser.add_argument( + "--done-wav", help="WAV file to play when voice command is done" + ) + parser.add_argument( + "--timer-finished-wav", help="WAV file to play when a timer finishes" + ) + parser.add_argument( + "--timer-finished-wav-repeat", + nargs=2, + metavar=("repeat", "delay"), + type=float, + default=(1, 0), + help="Number of times to play timer finished WAV and delay between repeats in seconds", + ) + + # Satellite details + parser.add_argument("--uri", required=True, help="unix:// or tcp://") + parser.add_argument( + "--name", default="Wyoming Satellite", help="Name of the satellite" + ) + parser.add_argument("--area", help="Area name of the satellite") + + # Zeroconf + parser.add_argument( + "--no-zeroconf", action="store_true", help="Disable discovery over zeroconf" + ) + parser.add_argument( + "--zeroconf-name", + help="Name used for zeroconf discovery (default: MAC from uuid.getnode)", + ) + parser.add_argument( + "--zeroconf-host", + help="Host address for zeroconf discovery (default: detect)", + ) + # + parser.add_argument( + "--debug-recording-dir", help="Directory to store audio for debugging" + ) + parser.add_argument("--debug", action="store_true", help="Log DEBUG messages") + parser.add_argument( + "--log-format", default=logging.BASIC_FORMAT, help="Format for log messages" + ) + parser.add_argument( + "--version", + action="version", + version=__version__, + help="Print version and exit", + ) + args = parser.parse_args() + + # Validate args + if (not args.mic_uri) and (not args.mic_command): + _LOGGER.fatal("Either --mic-uri or --mic-command is required") + sys.exit(1) + + if needs_webrtc(args): + try: + import webrtc_noise_gain # noqa: F401 + except ImportError: + _LOGGER.exception("Extras for webrtc are not installed") + sys.exit(1) + + if needs_silero(args): + try: + import pysilero_vad # noqa: F401 + except ImportError: + _LOGGER.exception("Extras for silerovad are not installed") + sys.exit(1) + + if args.awake_wav and (not Path(args.awake_wav).is_file()): + _LOGGER.fatal("%s does not exist", args.awake_wav) + sys.exit(1) + + if args.done_wav and (not Path(args.done_wav).is_file()): + _LOGGER.fatal("%s does not exist", args.done_wav) + sys.exit(1) + + if args.timer_finished_wav and (not Path(args.timer_finished_wav).is_file()): + _LOGGER.fatal("%s does not exist", args.timer_finished_wav) + sys.exit(1) + + if args.vad and (args.wake_uri or args.wake_command): + _LOGGER.warning("VAD is not used with local wake word detection") + + logging.basicConfig( + level=logging.DEBUG if args.debug else logging.INFO, format=args.log_format + ) + _LOGGER.debug(args) + + if args.debug_recording_dir: + args.debug_recording_dir = Path(args.debug_recording_dir) + _LOGGER.info("Recording audio to %s", args.debug_recording_dir) + + wyoming_info = Info( + satellite=Satellite( + name=args.name, + area=args.area, + description=args.name, + attribution=Attribution(name="", url=""), + installed=True, + version=__version__, + ) + ) + + settings = SatelliteSettings( + mic=MicSettings( + uri=args.mic_uri, + command=split_command(args.mic_command), + rate=args.mic_command_rate, + width=args.mic_command_width, + channels=args.mic_command_channels, + samples_per_chunk=args.mic_command_samples_per_chunk, + volume_multiplier=args.mic_volume_multiplier, + auto_gain=args.mic_auto_gain, + noise_suppression=args.mic_noise_suppression, + seconds_to_mute_after_awake_wav=args.mic_seconds_to_mute_after_awake_wav, + mute_during_awake_wav=(not args.mic_no_mute_during_awake_wav), + channel_index=args.mic_channel_index, + ), + vad=VadSettings( + enabled=args.vad, + system=args.vad_system, + threshold=args.vad_threshold, + trigger_level=args.vad_trigger_level, + buffer_seconds=args.vad_buffer_seconds, + wake_word_timeout=args.vad_wake_word_timeout, + energy_threshold=args.vad_energy_threshold, + ), + wake=WakeSettings( + uri=args.wake_uri, + command=split_command(args.wake_command), + names=[ + WakeWordAndPipeline(*wake_name) for wake_name in args.wake_word_name + ], + refractory_seconds=( + args.wake_refractory_seconds + if args.wake_refractory_seconds > 0 + else None + ), + ), + snd=SndSettings( + uri=args.snd_uri, + command=split_command(args.snd_command), + rate=args.snd_command_rate, + width=args.snd_command_width, + channels=args.snd_command_channels, + volume_multiplier=args.snd_volume_multiplier, + awake_wav=args.awake_wav, + done_wav=args.done_wav, + ), + event=EventSettings( + uri=args.event_uri, + startup=split_command(args.startup_command), + streaming_start=split_command(args.streaming_start_command), + streaming_stop=split_command(args.streaming_stop_command), + detect=split_command(args.detect_command), + detection=split_command(args.detection_command), + played=split_command(args.tts_played_command), + transcript=split_command(args.transcript_command), + stt_start=split_command(args.stt_start_command), + stt_stop=split_command(args.stt_stop_command), + synthesize=split_command(args.synthesize_command), + tts_start=split_command(args.tts_start_command), + tts_stop=split_command(args.tts_stop_command), + error=split_command(args.error_command), + connected=split_command(args.connected_command), + disconnected=split_command(args.disconnected_command), + ), + timer=TimerSettings( + started=split_command(args.timer_started_command), + updated=split_command(args.timer_updated_command), + cancelled=split_command(args.timer_cancelled_command), + finished=split_command(args.timer_finished_command), + finished_wav=args.timer_finished_wav, + finished_wav_plays=int(args.timer_finished_wav_repeat[0]), + finished_wav_delay=args.timer_finished_wav_repeat[1], + ), + debug_recording_dir=args.debug_recording_dir, + ) + + satellite: SatelliteBase + + if settings.wake.enabled: + # Local wake word detection + satellite = WakeStreamingSatellite(settings) + elif settings.vad.enabled: + # Stream after speech + satellite = VadStreamingSatellite(settings) + else: + # Stream all the time + satellite = AlwaysStreamingSatellite(settings) + + if args.startup_command: + await run_event_command(split_command(args.startup_command)) + + _LOGGER.info("Ready") + + # Start server + server = AsyncServer.from_uri(args.uri) + + if (not args.no_zeroconf) and isinstance(server, AsyncTcpServer): + from wyoming.zeroconf import register_server + + if not args.zeroconf_name: + args.zeroconf_name = get_mac_address() + + tcp_server: AsyncTcpServer = server + await register_server( + name=args.zeroconf_name, + port=tcp_server.port, + host=args.zeroconf_host, + ) + _LOGGER.debug( + "Zeroconf discovery enabled (name=%s, host=%s)", + args.zeroconf_name, + args.zeroconf_host, + ) + + satellite_task = asyncio.create_task(satellite.run(), name="satellite run") + + try: + await server.run(partial(SatelliteEventHandler, wyoming_info, satellite, args)) + except KeyboardInterrupt: + pass + finally: + await satellite.stop() + await satellite_task + + +# ----------------------------------------------------------------------------- + + +def run(): + try: + asyncio.run(main()) + except KeyboardInterrupt: + pass + + +if __name__ == "__main__": + run() diff --git a/wyoming_satellite/event_handler.py b/wyoming_satellite/event_handler.py new file mode 100755 index 0000000..58f046b --- /dev/null +++ b/wyoming_satellite/event_handler.py @@ -0,0 +1,57 @@ +"""Wyoming event handler for satellites.""" +import argparse +import logging +import time + +from wyoming.event import Event +from wyoming.info import Describe, Info +from wyoming.server import AsyncEventHandler + +from .satellite import SatelliteBase + +_LOGGER = logging.getLogger() + + +class SatelliteEventHandler(AsyncEventHandler): + """Event handler for clients.""" + + def __init__( + self, + wyoming_info: Info, + satellite: SatelliteBase, + cli_args: argparse.Namespace, + *args, + **kwargs, + ) -> None: + super().__init__(*args, **kwargs) + + self.cli_args = cli_args + self.wyoming_info = wyoming_info + self.client_id = str(time.monotonic_ns()) + self.satellite = satellite + + # ------------------------------------------------------------------------- + + async def handle_event(self, event: Event) -> bool: + """Handle events from the server.""" + if Describe.is_type(event.type): + await self.satellite.update_info(self.wyoming_info) + await self.write_event(self.wyoming_info.event()) + return True + + if self.satellite.server_id is None: + # Take over after a problem occurred + await self.satellite.set_server(self.client_id, self.writer) + elif self.satellite.server_id != self.client_id: + # New connection + _LOGGER.debug("Connection cancelled: %s", self.client_id) + return False + + await self.satellite.event_from_server(event) + + return True + + async def disconnect(self) -> None: + """Server disconnect.""" + if self.satellite.server_id == self.client_id: + await self.satellite.clear_server() diff --git a/wyoming_satellite/example_event_client.py b/wyoming_satellite/example_event_client.py new file mode 100755 index 0000000..606236e --- /dev/null +++ b/wyoming_satellite/example_event_client.py @@ -0,0 +1,67 @@ +#!/usr/bin/env python3 +import argparse +import asyncio +import logging +import time +from functools import partial + +from wyoming.event import Event +from wyoming.server import AsyncEventHandler, AsyncServer + +_LOGGER = logging.getLogger() + + +async def main() -> None: + """Main entry point.""" + parser = argparse.ArgumentParser() + parser.add_argument("--uri", default="stdio://", help="unix:// or tcp://") + # + parser.add_argument("--debug", action="store_true", help="Log DEBUG messages") + args = parser.parse_args() + + logging.basicConfig(level=logging.DEBUG if args.debug else logging.INFO) + _LOGGER.debug(args) + + _LOGGER.info("Ready") + + # Start server + server = AsyncServer.from_uri(args.uri) + + try: + await server.run(partial(ExampleEventHandler, args)) + except KeyboardInterrupt: + pass + + +# ----------------------------------------------------------------------------- + + +class ExampleEventHandler(AsyncEventHandler): + """Event handler for clients.""" + + def __init__( + self, + cli_args: argparse.Namespace, + *args, + **kwargs, + ) -> None: + super().__init__(*args, **kwargs) + + self.cli_args = cli_args + self.client_id = str(time.monotonic_ns()) + + _LOGGER.debug("Client connected: %s", self.client_id) + + async def handle_event(self, event: Event) -> bool: + _LOGGER.info(event) + + return True + + +# ----------------------------------------------------------------------------- + +if __name__ == "__main__": + try: + asyncio.run(main()) + except KeyboardInterrupt: + pass diff --git a/wyoming_satellite/satellite.7z b/wyoming_satellite/satellite.7z new file mode 100755 index 0000000000000000000000000000000000000000..0ebe7bd24e159bc6e37a98cd1a86147a5bff58d2 GIT binary patch literal 9717 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 DJ|CPu literal 0 HcmV?d00001 diff --git a/wyoming_satellite/satellite.py b/wyoming_satellite/satellite.py new file mode 100755 index 0000000..2793679 --- /dev/null +++ b/wyoming_satellite/satellite.py @@ -0,0 +1,1512 @@ +"""Satellite code.""" + +import array +import asyncio +import logging +import math +import time +import wave +import subprocess +import re +import psutil +from dataclasses import dataclass +from enum import Enum, auto +from pathlib import Path +from typing import Callable, Dict, Final, List, Optional, Set, Union + +from pyring_buffer import RingBuffer +from wyoming.asr import Transcript +from wyoming.audio import AudioChunk, AudioFormat, AudioStart, AudioStop +from wyoming.client import AsyncClient +from wyoming.error import Error +from wyoming.event import Event, async_write_event +from wyoming.info import Describe, Info +from wyoming.mic import MicProcessAsyncClient +from wyoming.ping import Ping, Pong +from wyoming.pipeline import PipelineStage, RunPipeline +from wyoming.satellite import ( + PauseSatellite, + RunSatellite, + SatelliteConnected, + SatelliteDisconnected, + StreamingStarted, + StreamingStopped, +) +from wyoming.snd import Played, SndProcessAsyncClient +from wyoming.timer import TimerCancelled, TimerFinished, TimerStarted, TimerUpdated +from wyoming.tts import Synthesize +from wyoming.vad import VoiceStarted, VoiceStopped +from wyoming.wake import Detect, Detection, WakeProcessAsyncClient + +from .settings import SatelliteSettings +from .utils import ( + DebugAudioWriter, + multiply_volume, + normalize_wake_word, + run_event_command, + wav_to_events, +) +from .vad import SileroVad, WebRtcVadEnergy +from .webrtc import WebRtcAudio + +_LOGGER = logging.getLogger() + +_PONG_TIMEOUT: Final = 5 +_PING_SEND_DELAY: Final = 2 +_WAKE_INFO_TIMEOUT: Final = 2 + + +class State(Enum): + NOT_STARTED = auto() + STARTING = auto() + STARTED = auto() + RESTARTING = auto() + STOPPING = auto() + STOPPED = auto() + + +@dataclass +class SoundEvent: + event: Event + is_tts: bool + + +# ----------------------------------------------------------------------------- + + +class SatelliteBase: + """Base class for satellites.""" + + def __init__(self, settings: SatelliteSettings) -> None: + self.settings = settings + self.server_id: Optional[str] = None + self._state = State.NOT_STARTED + self._state_changed = asyncio.Event() + self._writer: Optional[asyncio.StreamWriter] = None + + self._mic_task: Optional[asyncio.Task] = None + self._mic_webrtc: Optional[Callable[[bytes], bytes]] = None + self._snd_task: Optional[asyncio.Task] = None + self._snd_queue: "Optional[asyncio.Queue[SoundEvent]]" = None + self._wake_task: Optional[asyncio.Task] = None + self._wake_queue: "Optional[asyncio.Queue[Event]]" = None + self._event_task: Optional[asyncio.Task] = None + self._event_queue: "Optional[asyncio.Queue[Event]]" = None + + self._ping_server_enabled: bool = False + self._pong_received_event = asyncio.Event() + self._ping_server_task: Optional[asyncio.Task] = None + + self.microphone_muted = False + self._unmute_microphone_task: Optional[asyncio.Task] = None + + # Debug audio recording + self.wake_audio_writer: Optional[DebugAudioWriter] = None + self.stt_audio_writer: Optional[DebugAudioWriter] = None + if settings.debug_recording_dir: + self.wake_audio_writer = DebugAudioWriter( + settings.debug_recording_dir, + "wake", + ring_buffer_size=(2 * 16000 * 2 * 1), # last 2 sec + ) + self.stt_audio_writer = DebugAudioWriter( + settings.debug_recording_dir, "stt" + ) + + @property + def is_running(self) -> bool: + """True if not stopping/stopped.""" + return self._state not in (State.STOPPED,) + + @property + def state(self) -> State: + """Get current state.""" + return self._state + + @state.setter + def state(self, value: State) -> None: + """Set state.""" + self._state = value + self._state_changed.set() + self._state_changed.clear() + + async def run(self) -> None: + """Run main satellite loop.""" + + while self.is_running: + try: + if self.state == State.NOT_STARTED: + await self._start() + elif self.state == State.RESTARTING: + await self._restart() + elif self.state == State.STOPPING: + await self._stop() + elif self.state == State.STOPPED: + await self.stopped() + break + else: + await self._state_changed.wait() + except Exception: + if self.is_running: + # Automatically restart + _LOGGER.exception("Unexpected error running satellite") + self.state = State.RESTARTING + + async def stop(self) -> None: + """Stop the satellite""" + self.state = State.STOPPING + + # Wait for STOPPED + while self.state != State.STOPPED: + await self._state_changed.wait() + + async def set_server(self, server_id: str, writer: asyncio.StreamWriter) -> None: + """Set event writer.""" + self.server_id = server_id + self._writer = writer + _LOGGER.debug("Server set: %s", server_id) + await self.trigger_server_connected() + + async def clear_server(self) -> None: + """Remove writer.""" + self.server_id = None + self._writer = None + self._disable_ping() + + _LOGGER.debug("Server disconnected") + await self.trigger_server_disonnected() + + async def event_to_server(self, event: Event) -> None: + """Send an event to the server.""" + if self._writer is None: + return + + try: + await async_write_event(event, self._writer) + except Exception as err: + await self.clear_server() + + if isinstance(err, ConnectionResetError): + _LOGGER.warning("Server disconnected unexpectedly") + else: + _LOGGER.exception("Unexpected error sending event to server") + + def _enable_ping(self) -> None: + self._ping_server_enabled = True + self._ping_server_task = asyncio.create_task(self._ping_server(), name="ping") + + def _disable_ping(self) -> None: + self._ping_server_enabled = False + if self._ping_server_task is not None: + self._ping_server_task.cancel() + self._ping_server_task = None + + async def _ping_server(self) -> None: + try: + while self.is_running: + await asyncio.sleep(_PING_SEND_DELAY) + if (self.server_id is None) or (not self._ping_server_enabled): + # No server connected + continue + + # Send ping and wait for pong + self._pong_received_event.clear() + await self.event_to_server(Ping().event()) + try: + await asyncio.wait_for( + self._pong_received_event.wait(), timeout=_PONG_TIMEOUT + ) + except asyncio.TimeoutError: + if self.server_id is None: + # No server connected + continue + + _LOGGER.warning("Did not receive ping response within timeout") + await self.clear_server() + except asyncio.CancelledError: + pass + except Exception: + _LOGGER.exception("Unexpected error in ping server task") + + # ------------------------------------------------------------------------- + + async def _start(self) -> None: + """Connect to services.""" + self.state = State.STARTING + await self._connect_to_services() + self.state = State.STARTED + await self.started() + + async def started(self) -> None: + """Called when satellite has started.""" + + async def _stop(self) -> None: + """Disconnect from services.""" + self.server_id = None + self._writer = None + + await self._disconnect_from_services() + self._disable_ping() + self.state = State.STOPPED + + async def stopped(self) -> None: + """Called when satellite has stopped.""" + + async def event_from_server(self, event: Event) -> None: + """Called when an event is received from the server.""" + forward_event = True + + if Ping.is_type(event.type): + # Respond with pong + ping = Ping.from_event(event) + await self.event_to_server(Pong(text=ping.text).event()) + + if not self._ping_server_enabled: + # Enable pinging + self._enable_ping() + _LOGGER.debug("Ping enabled") + + forward_event = False + elif Pong.is_type(event.type): + # Response from our ping + self._pong_received_event.set() + forward_event = False + elif AudioChunk.is_type(event.type): + # TTS audio + await self.event_to_snd(event) + forward_event = False + elif AudioStart.is_type(event.type): + # TTS started + await self.event_to_snd(event) + await self.trigger_tts_start() + elif AudioStop.is_type(event.type): + # TTS stopped + await self.event_to_snd(event) + await self.trigger_tts_stop() + elif Detect.is_type(event.type): + # Wake word detection started + await self.trigger_detect() + elif Detection.is_type(event.type): + # Wake word detected + _LOGGER.debug("Wake word detected") + await self.trigger_detection(Detection.from_event(event)) + elif VoiceStarted.is_type(event.type): + # STT start + await self.trigger_stt_start() + elif VoiceStopped.is_type(event.type): + # STT stop + await self.trigger_stt_stop() + elif Transcript.is_type(event.type): + # STT text + _LOGGER.debug(event) + await self.trigger_transcript(Transcript.from_event(event)) + elif Synthesize.is_type(event.type): + # TTS request + _LOGGER.debug(event) + await self.trigger_synthesize(Synthesize.from_event(event)) + elif Error.is_type(event.type): + _LOGGER.warning(event) + await self.trigger_error(Error.from_event(event)) + elif TimerStarted.is_type(event.type): + _LOGGER.debug(event) + await self.trigger_timer_started(TimerStarted.from_event(event)) + elif TimerUpdated.is_type(event.type): + _LOGGER.debug(event) + await self.trigger_timer_updated(TimerUpdated.from_event(event)) + elif TimerCancelled.is_type(event.type): + _LOGGER.debug(event) + await self.trigger_timer_cancelled(TimerCancelled.from_event(event)) + elif TimerFinished.is_type(event.type): + _LOGGER.debug(event) + await self.trigger_timer_finished(TimerFinished.from_event(event)) + + # Forward everything except audio/ping/pong to event service + if forward_event: + await self.forward_event(event) + + async def _send_run_pipeline(self, pipeline_name: Optional[str] = None) -> None: + """Sends a RunPipeline event with the correct stages.""" + if self.settings.wake.enabled: + # Local wake word detection + start_stage = PipelineStage.ASR + restart_on_end = False + else: + # Remote wake word detection + start_stage = PipelineStage.WAKE + restart_on_end = not self.settings.vad.enabled + + if self.settings.snd.enabled: + # Play TTS response + end_stage = PipelineStage.TTS + else: + # No audio output + end_stage = PipelineStage.HANDLE + + run_pipeline = RunPipeline( + start_stage=start_stage, + end_stage=end_stage, + name=pipeline_name, + restart_on_end=restart_on_end, + snd_format=AudioFormat( + rate=self.settings.snd.rate, + width=self.settings.snd.width, + channels=self.settings.snd.channels, + ), + ).event() + _LOGGER.debug(run_pipeline) + await self.event_to_server(run_pipeline) + await self.forward_event(run_pipeline) + + async def _restart(self) -> None: + """Disconnects from services and restarts loop.""" + self.state = State.RESTARTING + await self._disconnect_from_services() + + _LOGGER.debug("Restarting in %s second(s)", self.settings.restart_timeout) + await asyncio.sleep(self.settings.restart_timeout) + self.state = State.NOT_STARTED + + async def _connect_to_services(self) -> None: + """Connects to configured services.""" + if self.settings.mic.enabled: + _LOGGER.debug( + "Connecting to mic service: %s", + self.settings.mic.uri or self.settings.mic.command, + ) + self._mic_task = asyncio.create_task(self._mic_task_proc(), name="mic") + + if self.settings.snd.enabled: + _LOGGER.debug( + "Connecting to snd service: %s", + self.settings.snd.uri or self.settings.snd.command, + ) + self._snd_task = asyncio.create_task(self._snd_task_proc(), name="snd") + + if self.settings.wake.enabled: + _LOGGER.debug( + "Connecting to wake service: %s", + self.settings.wake.uri or self.settings.wake.command, + ) + self._wake_task = asyncio.create_task(self._wake_task_proc(), name="wake") + + if self.settings.event.enabled: + _LOGGER.debug( + "Connecting to event service: %s", + self.settings.event.uri or self.settings.event.command, + ) + self._event_task = asyncio.create_task( + self._event_task_proc(), name="event" + ) + + _LOGGER.info("Connected to services") + + async def _disconnect_from_services(self) -> None: + """Disconnects from running services.""" + if self._mic_task is not None: + _LOGGER.debug("Stopping microphone service") + self._mic_task.cancel() + self._mic_task = None + + if self._snd_task is not None: + _LOGGER.debug("Stopping sound service") + self._snd_task.cancel() + self._snd_task = None + + if self._wake_task is not None: + _LOGGER.debug("Stopping wake service") + self._wake_task.cancel() + self._wake_task = None + + if self._event_task is not None: + _LOGGER.debug("Stopping event service") + self._event_task.cancel() + self._event_task = None + + _LOGGER.debug("Disconnected from services") + + # ------------------------------------------------------------------------- + # Microphone + # ------------------------------------------------------------------------- + + async def event_from_mic( + self, event: Event, audio_bytes: Optional[bytes] = None + ) -> None: + """Called when an event is received from the mic service. + + For AudioChunk events, the audio_bytes may be set if the audio was + already unpacked for preprocessing. Use this to avoid unpacking the + event again. + """ + + def _make_mic_client(self) -> Optional[AsyncClient]: + """Create client for mic service.""" + if self.settings.mic.command: + program, *program_args = self.settings.mic.command + return MicProcessAsyncClient( + rate=self.settings.mic.rate, + width=self.settings.mic.width, + channels=self.settings.mic.channels, + samples_per_chunk=self.settings.mic.samples_per_chunk, + program=program, + program_args=program_args, + ) + + if self.settings.mic.uri: + return AsyncClient.from_uri(self.settings.mic.uri) + + return None + + async def _mic_task_proc(self) -> None: + """Mic service loop.""" + mic_client: Optional[AsyncClient] = None + audio_bytes: Optional[bytes] = None + + if self.settings.mic.needs_webrtc and (self._mic_webrtc is None): + _LOGGER.debug("Using webrtc audio enhancements") + self._mic_webrtc = WebRtcAudio( + self.settings.mic.auto_gain, self.settings.mic.noise_suppression + ) + + async def _disconnect() -> None: + try: + if mic_client is not None: + await mic_client.disconnect() + except Exception: + pass # ignore disconnect errors + + while self.is_running: + try: + if mic_client is None: + mic_client = self._make_mic_client() + assert mic_client is not None + await mic_client.connect() + _LOGGER.debug("Connected to mic service") + + event = await mic_client.read_event() + if event is None: + _LOGGER.warning("Mic service disconnected") + await _disconnect() + mic_client = None # reconnect + await asyncio.sleep(self.settings.mic.reconnect_seconds) + continue + + # Audio processing + if ( + self.settings.mic.needs_processing + or (self.settings.mic.channel_index is not None) + and AudioChunk.is_type(event.type) + ): + chunk = AudioChunk.from_event(event) + if self.settings.mic.channel_index is not None: + if chunk.width != 2: + raise ValueError( + "Mic channel index selection requires 16-bit samples" + ) + + # Convert to unsigned 16-bit array to make channel extraction easier + audio_array = array.array("H", chunk.audio) + audio_bytes = audio_array[ + self.settings.mic.channel_index :: chunk.channels + ].tobytes() + + if self.settings.mic.needs_processing: + if audio_bytes is None: + audio_bytes = chunk.audio + + audio_bytes = self._process_mic_audio(chunk.audio) + + event = AudioChunk( + rate=chunk.rate, + width=chunk.width, + channels=( + chunk.channels + if (self.settings.mic.channel_index is None) + else 1 + ), + audio=audio_bytes, + ).event() + else: + audio_bytes = None + + await self.event_from_mic(event, audio_bytes) + except asyncio.CancelledError: + break + except Exception: + _LOGGER.exception("Unexpected error in mic read task") + await _disconnect() + mic_client = None # reconnect + await asyncio.sleep(self.settings.mic.reconnect_seconds) + + await _disconnect() + + def _process_mic_audio(self, audio_bytes: bytes) -> bytes: + """Perform audio pre-processing on mic input.""" + if self.settings.mic.volume_multiplier != 1.0: + audio_bytes = multiply_volume( + audio_bytes, self.settings.mic.volume_multiplier + ) + + if self._mic_webrtc is not None: + # Noise suppression and auto gain + audio_bytes = self._mic_webrtc(audio_bytes) + + return audio_bytes + + # ------------------------------------------------------------------------- + # Sound + # ------------------------------------------------------------------------- + + async def event_to_snd(self, event: Event, is_tts: bool = True) -> None: + """Send an event to the sound service.""" + if self._snd_queue is not None: + self._snd_queue.put_nowait(SoundEvent(event, is_tts)) + + def _make_snd_client(self) -> Optional[AsyncClient]: + """Create client for snd service.""" + if self.settings.snd.command: + program, *program_args = self.settings.snd.command + return SndProcessAsyncClient( + rate=self.settings.snd.rate, + width=self.settings.snd.width, + channels=self.settings.snd.channels, + program=program, + program_args=program_args, + ) + + if self.settings.snd.uri: + return AsyncClient.from_uri(self.settings.snd.uri) + + return None + + async def _snd_task_proc(self) -> None: + """Snd service loop.""" + snd_client: Optional[AsyncClient] = None + + async def _disconnect() -> None: + try: + if snd_client is not None: + await snd_client.disconnect() + except Exception: + pass # ignore disconnect errors + + while self.is_running: + try: + if self._snd_queue is None: + self._snd_queue = asyncio.Queue() + + snd_event = await self._snd_queue.get() + event = snd_event.event + + if snd_client is None: + snd_client = self._make_snd_client() + assert snd_client is not None + await snd_client.connect() + _LOGGER.debug("Connected to snd service") + + # Audio processing + if self.settings.snd.needs_processing and AudioChunk.is_type( + event.type + ): + chunk = AudioChunk.from_event(event) + audio_bytes = self._process_snd_audio(chunk.audio) + event = AudioChunk( + rate=chunk.rate, + width=chunk.width, + channels=chunk.channels, + audio=audio_bytes, + ).event() + + await snd_client.write_event(event) + + if self.settings.snd.disconnect_after_stop and AudioStop.is_type( + event.type + ): + await _disconnect() + if snd_event.is_tts: + await self.event_to_server(Played().event()) + await self.trigger_played() + snd_client = None # reconnect on next event + except asyncio.CancelledError: + break + except Exception: + _LOGGER.exception("Unexpected error in snd read task") + await _disconnect() + snd_client = None # reconnect + self._snd_queue = None + await asyncio.sleep(self.settings.snd.reconnect_seconds) + + await _disconnect() + + def _process_snd_audio(self, audio_bytes: bytes) -> bytes: + """Perform audio pre-processing on snd output.""" + if self.settings.snd.volume_multiplier != 1.0: + audio_bytes = multiply_volume( + audio_bytes, self.settings.snd.volume_multiplier + ) + + return audio_bytes + + async def _play_wav( + self, wav_path: Optional[Union[str, Path]], mute_microphone: bool = False + ) -> None: + """Send WAV as events to sound service.""" + if (not wav_path) or (not self.settings.snd.enabled): + return + + try: + if mute_microphone: + with wave.open(str(wav_path), "rb") as wav_file: + seconds_to_mute = wav_file.getnframes() / wav_file.getframerate() + + seconds_to_mute += self.settings.mic.seconds_to_mute_after_awake_wav + _LOGGER.debug("Muting microphone for %s second(s)", seconds_to_mute) + self.microphone_muted = True + self._unmute_microphone_task = asyncio.create_task( + self._unmute_microphone_after(seconds_to_mute) + ) + + for event in wav_to_events( + wav_path, + samples_per_chunk=self.settings.snd.samples_per_chunk, + ): + await self.event_to_snd(event, is_tts=False) + except Exception: + # Unmute in case of an error + self.microphone_muted = False + + raise + + async def _unmute_microphone_after(self, seconds: float) -> None: + await asyncio.sleep(seconds) + self.microphone_muted = False + _LOGGER.debug("Unmuted microphone") + + # ------------------------------------------------------------------------- + # Wake + # ------------------------------------------------------------------------- + + async def event_from_wake(self, event: Event) -> None: + """Called when an event is received from the wake service.""" + + async def event_to_wake(self, event: Event) -> None: + """Send event to the wake service.""" + if self._wake_queue is not None: + self._wake_queue.put_nowait(event) + + def _make_wake_client(self) -> Optional[AsyncClient]: + """Create client for wake service.""" + if self.settings.wake.command: + program, *program_args = self.settings.wake.command + return WakeProcessAsyncClient( + rate=self.settings.wake.rate, + width=self.settings.wake.width, + channels=self.settings.wake.channels, + program=program, + program_args=program_args, + ) + + if self.settings.wake.uri: + return AsyncClient.from_uri(self.settings.wake.uri) + + return None + + async def _wake_task_proc(self) -> None: + """Wake service loop.""" + wake_client: Optional[AsyncClient] = None + to_client_task: Optional[asyncio.Task] = None + from_client_task: Optional[asyncio.Task] = None + pending: Set[asyncio.Task] = set() + + async def _disconnect() -> None: + nonlocal to_client_task, from_client_task + try: + if wake_client is not None: + await wake_client.disconnect() + + # Clean up tasks + if to_client_task is not None: + to_client_task.cancel() + to_client_task = None + + if from_client_task is not None: + from_client_task.cancel() + from_client_task = None + except Exception: + pass # ignore disconnect errors + + while self.is_running: + try: + if self._wake_queue is None: + self._wake_queue = asyncio.Queue() + + if wake_client is None: + wake_client = self._make_wake_client() + assert wake_client is not None + await wake_client.connect() + _LOGGER.debug("Connected to wake service") + + # Reset + from_client_task = None + to_client_task = None + pending = set() + self._wake_queue = asyncio.Queue() + + # Inform wake service of which wake word(s) to detect + await self._send_wake_detect() + + # Read/write in "parallel" + if to_client_task is None: + # From satellite to wake service + to_client_task = asyncio.create_task( + self._wake_queue.get(), name="wake_to_client" + ) + pending.add(to_client_task) + + if from_client_task is None: + # From wake service to satellite + from_client_task = asyncio.create_task( + wake_client.read_event(), name="wake_from_client" + ) + pending.add(from_client_task) + + done, pending = await asyncio.wait( + pending, return_when=asyncio.FIRST_COMPLETED + ) + + if to_client_task in done: + # Event to go to wake service (audio) + assert to_client_task is not None + event = to_client_task.result() + to_client_task = None + await wake_client.write_event(event) + + if from_client_task in done: + # Event from wake service (detection) + assert from_client_task is not None + event = from_client_task.result() + from_client_task = None + + if event is None: + _LOGGER.warning("Wake service disconnected") + await _disconnect() + wake_client = None # reconnect + await asyncio.sleep(self.settings.wake.reconnect_seconds) + continue + + await self.event_from_wake(event) + + except asyncio.CancelledError: + break + except Exception: + _LOGGER.exception("Unexpected error in wake read task") + await _disconnect() + wake_client = None # reconnect + await asyncio.sleep(self.settings.wake.reconnect_seconds) + + await _disconnect() + + async def _send_wake_detect(self) -> None: + """Inform wake word service of which wake words to detect.""" + wake_names: Optional[List[str]] = None + if self.settings.wake.names: + wake_names = [w.name for w in self.settings.wake.names] + + await self.event_to_wake(Detect(names=wake_names).event()) + await self.event_to_wake( + AudioStart( + rate=self.settings.mic.rate, + width=self.settings.mic.width, + channels=self.settings.mic.channels, + ).event() + ) + await self.trigger_detect() + + # ------------------------------------------------------------------------- + # Events + # ------------------------------------------------------------------------- + + async def trigger_server_connected(self) -> None: + """Called when connected to server.""" + _LOGGER.info("Connected to server") + await run_event_command(self.settings.event.connected) + await self.forward_event(SatelliteConnected().event()) + + async def trigger_server_disonnected(self) -> None: + """Called when disconnected from server.""" + _LOGGER.info("Disconnected from server") + await run_event_command(self.settings.event.disconnected) + await self.forward_event(SatelliteDisconnected().event()) + + async def trigger_streaming_start(self) -> None: + """Called when audio streaming starts.""" + await run_event_command(self.settings.event.streaming_start) + await self.forward_event(StreamingStarted().event()) + + async def trigger_streaming_stop(self) -> None: + """Called when audio streaming stops.""" + await run_event_command(self.settings.event.streaming_stop) + await self.forward_event(StreamingStopped().event()) + + async def trigger_detect(self) -> None: + """Called when wake word detection starts.""" + await run_event_command(self.settings.event.detect) + + async def trigger_detection(self, detection: Detection) -> None: + """Called when wake word is detected.""" + await run_event_command(self.settings.event.detection, detection.name) + await self._play_wav( + self.settings.snd.awake_wav, + mute_microphone=self.settings.mic.mute_during_awake_wav, + ) + + async def trigger_played(self) -> None: + """Called when audio stopped playing""" + await run_event_command(self.settings.event.played) + await self.forward_event(Played().event()) + + async def trigger_transcript(self, transcript: Transcript) -> None: + """Called when speech-to-text text is received.""" + await run_event_command(self.settings.event.transcript, transcript.text) + await self._play_wav(self.settings.snd.done_wav) + + async def trigger_stt_start(self) -> None: + """Called when user starts speaking.""" + await run_event_command(self.settings.event.stt_start) + + async def trigger_stt_stop(self) -> None: + """Called when user stops speaking.""" + await run_event_command(self.settings.event.stt_stop) + + async def trigger_synthesize(self, synthesize: Synthesize) -> None: + """Called when text-to-speech text is received.""" + await run_event_command(self.settings.event.synthesize, synthesize.text) + + async def trigger_tts_start(self) -> None: + """Called when text-to-speech audio starts.""" + await run_event_command(self.settings.event.tts_start) + + async def trigger_tts_stop(self) -> None: + """Called when text-to-speech audio stops.""" + await run_event_command(self.settings.event.tts_stop) + + async def trigger_error(self, error: Error) -> None: + """Called when an error occurs on the server.""" + await run_event_command(self.settings.event.error, error.text) + + async def trigger_timer_started(self, timer_started: TimerStarted) -> None: + """Called when timer-started event is received.""" + await run_event_command(self.settings.timer.started, timer_started) + + async def trigger_timer_updated(self, timer_updated: TimerUpdated) -> None: + """Called when timer-updated event is received.""" + await run_event_command(self.settings.timer.updated, timer_updated) + + async def trigger_timer_cancelled(self, timer_cancelled: TimerCancelled) -> None: + """Called when timer-cancelled event is received.""" + await run_event_command(self.settings.timer.cancelled, timer_cancelled.id) + + async def trigger_timer_finished(self, timer_finished: TimerFinished) -> None: + """Called when timer-finished event is received.""" + await run_event_command(self.settings.timer.finished, timer_finished.id) + for _ in range(self.settings.timer.finished_wav_plays): + await self._play_wav( + self.settings.timer.finished_wav, + mute_microphone=self.settings.mic.mute_during_awake_wav, + ) + await asyncio.sleep(self.settings.timer.finished_wav_delay) + + async def forward_event(self, event: Event) -> None: + """Forward an event to the event service.""" + if self._event_queue is not None: + self._event_queue.put_nowait(event) + + def _make_event_client(self) -> Optional[AsyncClient]: + """Create client for event service.""" + if self.settings.event.uri: + return AsyncClient.from_uri(self.settings.event.uri) + + return None + + async def _event_task_proc(self) -> None: + """Event service loop.""" + event_client: Optional[AsyncClient] = None + + async def _disconnect() -> None: + try: + if event_client is not None: + await event_client.disconnect() + except Exception: + pass # ignore disconnect errors + + while self.is_running: + try: + if self._event_queue is None: + self._event_queue = asyncio.Queue() + + event = await self._event_queue.get() + + if event_client is None: + event_client = self._make_event_client() + assert event_client is not None + await event_client.connect() + _LOGGER.debug("Connected to event service") + + await event_client.write_event(event) + except asyncio.CancelledError: + break + except Exception: + _LOGGER.exception("Unexpected error in event read task") + await _disconnect() + event_client = None # reconnect + self._event_queue = None + await asyncio.sleep(self.settings.event.reconnect_seconds) + + await _disconnect() + + # ------------------------------------------------------------------------- + # Info + # ------------------------------------------------------------------------- + + async def update_info(self, info: Info) -> None: + pass + + +# ----------------------------------------------------------------------------- + + +class AlwaysStreamingSatellite(SatelliteBase): + """Satellite that always streams audio.""" + + def __init__(self, settings: SatelliteSettings) -> None: + super().__init__(settings) + self.is_streaming = False + + if settings.vad.enabled: + _LOGGER.warning("VAD is enabled but will not be used") + + if settings.wake.enabled: + _LOGGER.warning("Local wake word detection is enabled but will not be used") + + async def event_from_server(self, event: Event) -> None: + await super().event_from_server(event) + + if RunSatellite.is_type(event.type): + self.is_streaming = True + _LOGGER.info("Streaming audio") + await self._send_run_pipeline() + await self.trigger_streaming_start() + elif PauseSatellite.is_type(event.type): + self.is_streaming = False + _LOGGER.info("Satellite paused") + elif Detection.is_type(event.type): + # Start debug recording + if self.stt_audio_writer is not None: + self.stt_audio_writer.start() + elif Transcript.is_type(event.type) or Error.is_type(event.type): + # Stop debug recording + if self.stt_audio_writer is not None: + self.stt_audio_writer.stop() + + if Transcript.is_type(event.type): + # We're always streaming + _LOGGER.info("Streaming audio") + + # Re-trigger streaming start even though we technically don't stop + # so the event service can reset LEDs, etc. + await self.trigger_streaming_start() + + async def event_from_mic( + self, event: Event, audio_bytes: Optional[bytes] = None + ) -> None: + if (not self.is_streaming) or self.microphone_muted: + return + + if AudioChunk.is_type(event.type): + # Forward to server + await self.event_to_server(event) + + # Debug audio recording + if self.stt_audio_writer is not None: + if audio_bytes is None: + chunk = AudioChunk.from_event(event) + audio_bytes = chunk.audio + + self.stt_audio_writer.write(audio_bytes) + + +# ----------------------------------------------------------------------------- + + +class VadStreamingSatellite(SatelliteBase): + """Satellite that only streams after speech is detected.""" + + def __init__(self, settings: SatelliteSettings) -> None: + if not settings.vad.enabled: + raise ValueError("VAD is not enabled") + + super().__init__(settings) + self.is_streaming = False + if settings.vad.system == "silero": + self.vad = SileroVad( + threshold=settings.vad.threshold, + trigger_level=settings.vad.trigger_level, + ) + elif settings.vad.system == "webrtc": + self.vad = WebRtcVadEnergy( + trigger_level=settings.vad.trigger_level, + energy_threshold=settings.vad.energy_threshold, + ) + else: + raise ValueError(f"Unknown VAD system: {settings.vad.system}") + + # Timestamp in the future when we will have timed out (set with + # time.monotonic()) + self.timeout_seconds: Optional[float] = None + + # Audio from right before speech starts (circular buffer) + self.vad_buffer: Optional[RingBuffer] = None + + if settings.vad.buffer_seconds > 0: + # Assume 16Khz, 16-bit mono samples + vad_buffer_bytes = int(math.ceil(settings.vad.buffer_seconds * 16000 * 2)) + self.vad_buffer = RingBuffer(maxlen=vad_buffer_bytes) + + if settings.wake.enabled: + _LOGGER.warning("Local wake word detection is enabled but will not be used") + + self._is_paused = False + + async def event_from_server(self, event: Event) -> None: + await super().event_from_server(event) + + if RunSatellite.is_type(event.type): + self._is_paused = False + _LOGGER.info("Waiting for speech") + elif Detection.is_type(event.type): + # Start debug recording + if self.stt_audio_writer is not None: + self.stt_audio_writer.start() + elif ( + Transcript.is_type(event.type) + or Error.is_type(event.type) + or PauseSatellite.is_type(event.type) + ): + if PauseSatellite.is_type(event.type): + self._is_paused = True + _LOGGER.debug("Satellite paused") + + self.is_streaming = False + + # Stop debug recording + if self.stt_audio_writer is not None: + self.stt_audio_writer.stop() + + async def event_from_mic( + self, event: Event, audio_bytes: Optional[bytes] = None + ) -> None: + if ( + (not AudioChunk.is_type(event.type)) + or self.microphone_muted + or self._is_paused + ): + return + + # Only unpack chunk once + chunk: Optional[AudioChunk] = None + + # Debug audio recording + if self.stt_audio_writer is not None: + if audio_bytes is None: + # Need to unpack + chunk = AudioChunk.from_event(event) + audio_bytes = chunk.audio + + self.stt_audio_writer.write(audio_bytes) + + if ( + self.is_streaming + and (self.timeout_seconds is not None) + and (time.monotonic() >= self.timeout_seconds) + ): + # Time out during wake word recognition + self.is_streaming = False + self.timeout_seconds = None + + # Stop debug recording + if self.stt_audio_writer is not None: + self.stt_audio_writer.stop() + + # Stop pipeline + await self.event_to_server(AudioStop().event()) + + _LOGGER.info("Waiting for speech") + await self.trigger_streaming_stop() + + if not self.is_streaming: + # Check VAD + if audio_bytes is None: + if chunk is None: + # Need to unpack + chunk = AudioChunk.from_event(event) + + audio_bytes = chunk.audio + + if not self.vad(audio_bytes): + # No speech + if self.vad_buffer is not None: + self.vad_buffer.put(audio_bytes) + + return + + # Speech detected + self.is_streaming = True + _LOGGER.info("Streaming audio") + await self._send_run_pipeline() + await self.trigger_streaming_start() + + if self.settings.vad.wake_word_timeout is not None: + # Set future time when we'll stop streaming if the wake word + # hasn't been detected. + self.timeout_seconds = ( + time.monotonic() + self.settings.vad.wake_word_timeout + ) + else: + # No timeout + self.timeout_seconds = None + + if self.vad_buffer is not None: + # Send contents of VAD buffer first. This is the audio that was + # recorded right before speech was detected. + if chunk is None: + chunk = AudioChunk.from_event(event) + + await self.event_to_server( + AudioChunk( + rate=chunk.rate, + width=chunk.width, + channels=chunk.channels, + audio=self.vad_buffer.getvalue(), + ).event() + ) + + self._reset_vad() + + if self.is_streaming: + # Forward to server + await self.event_to_server(event) + + def _reset_vad(self): + """Reset state of VAD.""" + self.vad(None) + + if self.vad_buffer is not None: + # Clear buffer + self.vad_buffer.put(bytes(self.vad_buffer.maxlen)) + + +# ----------------------------------------------------------------------------- + + +class WakeStreamingSatellite(SatelliteBase): + """Satellite that waits for local wake word detection before streaming.""" + + def __init__(self, settings: SatelliteSettings) -> None: + if not settings.wake.enabled: + raise ValueError("Local wake word detection is not enabled") + + super().__init__(settings) + self.is_streaming = False + + # Timestamp in the future when the refractory period is over (set with + # time.monotonic()). + # wake word id -> seconds + self.refractory_timestamp: Dict[Optional[str], float] = {} + + if settings.vad.enabled: + _LOGGER.warning("VAD is enabled but will not be used") + + # Used for debug audio recording so both wake and stt WAV files have the + # same timestamp. + self._debug_recording_timestamp: Optional[int] = None + + self._is_paused = False + + self._wake_info: Optional[Info] = None + self._wake_info_ready = asyncio.Event() + + def _kill_aplay_processes(self): + """Kill all aplay processes started by snd client.""" + for proc in psutil.process_iter(['pid', 'cmdline']): + try: + if proc.info['cmdline'] and 'aplay' in proc.info['cmdline']: + # Optionally check if it's our aplay (e.g., by args like -f cd -t raw) + if '-t' in proc.info['cmdline'] and 'raw' in proc.info['cmdline']: + proc.terminate() + _LOGGER.debug("Terminated aplay PID %d", proc.info['pid']) + except (psutil.NoSuchProcess, psutil.AccessDenied): + continue + + + async def event_from_server(self, event: Event) -> None: + # Only check event types once + is_run_satellite = False + is_pause_satellite = False + is_transcript = False + is_error = False + + if RunSatellite.is_type(event.type): + is_run_satellite = True + self._is_paused = False + + elif PauseSatellite.is_type(event.type): + is_pause_satellite = True + elif Transcript.is_type(event.type): + is_transcript = True + elif Error.is_type(event.type): + is_error = True + + if is_transcript or is_pause_satellite: + # Stop streaming before event_from_server is called because it will + # play the "done" WAV. + self.is_streaming = False + + # Stop debug recording (stt) + if self.stt_audio_writer is not None: + self.stt_audio_writer.stop() + + await super().event_from_server(event) + + if is_run_satellite or is_transcript or is_error or is_pause_satellite: + # Stop streaming + self.is_streaming = False + + if is_pause_satellite: + self._is_paused = True + _LOGGER.debug("Satellite is paused") + else: + # Go back to wake word detection + await self.trigger_streaming_stop() + + # It's possible to be paused in the middle of streaming + if not self._is_paused: + await self._send_wake_detect() + _LOGGER.info("Waiting for wake word") + + # Start debug recording (wake) + self._debug_recording_timestamp = time.monotonic_ns() + if self.wake_audio_writer is not None: + self.wake_audio_writer.start( + timestamp=self._debug_recording_timestamp + ) + + async def trigger_server_disonnected(self) -> None: + await super().trigger_server_disonnected() + + self.is_streaming = False + + # Stop debug recording (stt) + if self.stt_audio_writer is not None: + self.stt_audio_writer.stop() + + await self.trigger_streaming_stop() + + async def event_from_mic( + self, event: Event, audio_bytes: Optional[bytes] = None + ) -> None: + if ( + (not AudioChunk.is_type(event.type)) + or self.microphone_muted + or self._is_paused + ): + return + + # Debug audio recording + if (self.wake_audio_writer is not None) or (self.stt_audio_writer is not None): + if audio_bytes is None: + chunk = AudioChunk.from_event(event) + audio_bytes = chunk.audio + + if self.wake_audio_writer is not None: + self.wake_audio_writer.write(audio_bytes) + + if self.stt_audio_writer is not None: + self.stt_audio_writer.write(audio_bytes) + + if self.is_streaming: + # Forward to server + await self.event_to_server(event) + else: + # Forward to wake word service + await self.event_to_wake(event) + + + async def _get_current_volume_percent(self) -> int: + """Для seeed-2mic-voicecard — используем 'Headphone'""" + try: + result = subprocess.run( + ["amixer", "-c", "2", "-M", "sget", "Headphone"], + capture_output=True, text=True, check=True + ) + output = result.stdout + + # Ищем [75%] + match = re.search(r"\[(\d+)%\]", output) + if match: + volume = int(match.group(1)) + _LOGGER.info("Громкость динамика: %d%%", volume) + return volume + + # Если [off] + if "[off]" in output: + return 0 + + _LOGGER.warning("Громкость не распознана") + return 50 + + except Exception as e: + _LOGGER.error("Ошибка amixer: %s", e) + return 50 + async def _set_alsa_volume(self, percent: int): + try: + subprocess.run([ + "amixer", "-c", "2", "-M", "sset", "Headphone", f"{percent}%" + ], check=True) + _LOGGER.info("Громкость установлена: %d%%", percent) + await self._play_wav("sounds/volume.wav") + except Exception as e: + _LOGGER.error("Не удалось установить: %s", e) + async def _adjust_volume(self, increase: bool): + """Громче (+10%) или тише (-10%)""" + current = await self._get_current_volume_percent() + step = 10 + new_volume = current + step if increase else current - step + new_volume = max(0, min(100, new_volume)) # 0–100% + + await self._set_alsa_volume(new_volume) + + + + async def _say_volume(self, percent: int): + text = f"Текущая громкость {percent} процентов" + _LOGGER.info("ГОВОРЮ: %s", text) + + # 1. Запускаем пайплайн с TTS + run_pipeline = RunPipeline( + start_stage=PipelineStage.TTS, + end_stage=PipelineStage.TTS + ) + await self.event_to_server(run_pipeline.event()) + _LOGGER.info("Пайплайн TTS запущен") + + # 2. Отправляем текст для TTS + synthesize = Synthesize(text=text) + await self.event_to_server(synthesize.event()) + _LOGGER.info("Текст для TTS отправлен: %s", text) + async def event_from_wake(self, event: Event) -> None: + if Info.is_type(event.type): + self._wake_info = Info.from_event(event) + _LOGGER.debug("Received Info from wake service") + self._wake_info_ready.set() + return + + if self.is_streaming or (self.server_id is None): + return + + if Detection.is_type(event.type): + detection = Detection.from_event(event) + text = detection.name.strip().lower() + + # --- КОМАНДЫ: громкость, остановка --- + # --- КОМАНДА: КАКАЯ ГРОМКОСТЬ? --- + if text == "какая громкость": + _LOGGER.info("Команда 'какая громкость' получена") + current_volume = await self._get_current_volume_percent() + await self._say_volume(current_volume) + return # ← не активируем STT + if text.startswith("дроид громкость "): + level_word = text.split()[-1] + levels = {"ноль":0, "один":10, "два":20, "три":30, "четыре":40, + "пять":50, "шесть":60, "семь":70, "восемь":80, + "девять":90, "десять":100} + if level_word in levels: + await self._set_alsa_volume(levels[level_word]) + _LOGGER.info("УСТАНОВИЛ ГРОМКОСТЬ: %d%%", levels[level_word]) + return + # --- КОМАНДА: ГРОМЧЕ, ТИШЕ --- + if text == "дроид сделай громче": + await self._adjust_volume(increase=True) + return + if text == "дроид сделай тише": + await self._adjust_volume(increase=False) + return + # --- КОМАНДА: ОСТАНОВИ, ХВАТИТ, СТОП, ОТМЕНЯЙ --- + if text in ["дроид останови", "дроид хватит", "дроид стоп", "дроид отмена"]: + _LOGGER.info("ОСТАНОВИЛ ПО КОМАНДЕ: %s", text) + self._kill_aplay_processes() + # Опционально: отправить Played(), чтобы сервер знал, что TTS прерван + await self.event_to_server(Played().event()) + return + + # --- ПРОВЕРКА: это wake word? --- + wake_words = [normalize_wake_word(w.name) for w in (self.settings.wake.names or [])] + if text not in wake_words: + _LOGGER.debug("Игнорируем (не wake word): %s", text) + return + + # --- ЭТО WAKE WORD → оригинальная логика --- + # (всё, что было в оригинале) + + refractory_timestamp = self.refractory_timestamp.get(detection.name) + if (refractory_timestamp is not None) and (refractory_timestamp > time.monotonic()): + _LOGGER.debug("Wake word detection occurred during refractory period") + return + + if self.wake_audio_writer is not None: + self.wake_audio_writer.stop() + if self.stt_audio_writer is not None: + self.stt_audio_writer.start(timestamp=self._debug_recording_timestamp) + + _LOGGER.debug(detection) + self.is_streaming = True + _LOGGER.info("Streaming audio (wake word: %s)", detection.name) + + if self.settings.wake.refractory_seconds is not None: + self.refractory_timestamp[detection.name] = ( + time.monotonic() + self.settings.wake.refractory_seconds + ) + else: + self.refractory_timestamp.pop(detection.name, None) + + await self.event_to_server(event) + + pipeline_name: Optional[str] = None + if self.settings.wake.names: + detection_name = normalize_wake_word(detection.name) + for wake_name in self.settings.wake.names: + if normalize_wake_word(wake_name.name) == detection_name: + pipeline_name = wake_name.pipeline + break + + await self._send_run_pipeline(pipeline_name=pipeline_name) + await self.forward_event(event) + await self.trigger_detection(detection) + await self.trigger_streaming_start() + async def update_info(self, info: Info) -> None: + self._wake_info = None + self._wake_info_ready.clear() + _LOGGER.debug("Sending Describe to wake service") + await self.event_to_wake(Describe().event()) + + try: + await asyncio.wait_for( + self._wake_info_ready.wait(), timeout=_WAKE_INFO_TIMEOUT + ) + + if self._wake_info is not None: + # Update wake info only + info.wake = self._wake_info.wake + _LOGGER.debug("Updated info with wake info") + else: + _LOGGER.warning("Wake info is None after timeout") + except asyncio.TimeoutError: + _LOGGER.warning("Failed to get info from wake service") diff --git a/wyoming_satellite/settings.py b/wyoming_satellite/settings.py new file mode 100755 index 0000000..0e9d42b --- /dev/null +++ b/wyoming_satellite/settings.py @@ -0,0 +1,222 @@ +"""Satellite settings.""" + +from abc import ABC +from dataclasses import dataclass, field +from pathlib import Path +from typing import List, Optional + + +@dataclass(frozen=True) +class ServiceSettings(ABC): + """Base class for service settings.""" + + uri: Optional[str] = None + """tcp://ip-address:port""" + + command: Optional[List[str]] = None + """program + args""" + + reconnect_seconds: float = 3.0 + """Seconds before reconnection attempt is made.""" + + @property + def enabled(self) -> bool: + """True if service is enabled.""" + return bool(self.uri or self.command) + + +@dataclass(frozen=True) +class MicSettings(ServiceSettings): + """Microphone service settings.""" + + volume_multiplier: float = 1.0 + """Multiplier for raw audio data (1.0 = no change)""" + + auto_gain: int = 0 + """Automatic gain control (0-31 dbFS)""" + + noise_suppression: int = 0 + """Level of noise suppression (0-4, 4 is max)""" + + rate: int = 16000 + """Sample rate of mic audio (hertz)""" + + width: int = 2 + """Sample width of mic audio (bytes)""" + + channels: int = 1 + """Sample channels in mic audio""" + + samples_per_chunk: int = 1024 + """Samples to read at a time from mic command""" + + mute_during_awake_wav: bool = True + """True if microphone audio should be muted while the awake WAV is playing.""" + + seconds_to_mute_after_awake_wav: float = 0.5 + """Extra second(s) of microphone audio to mute after awake WAV has finished playing.""" + + channel_index: Optional[int] = None + """Index of microphone channel to use. When not set, all input channels are used as-is.""" + + @property + def needs_webrtc(self) -> bool: + """True if webrtc audio enhancements are needed.""" + return self.enabled and ((self.auto_gain > 0) or (self.noise_suppression > 0)) + + @property + def needs_processing(self) -> bool: + """True if some audio pre-processing is needed for mic audio.""" + return self.enabled and ((self.volume_multiplier != 1.0) or self.needs_webrtc) + + +@dataclass(frozen=True) +class SndSettings(ServiceSettings): + """Sound output service settings.""" + + volume_multiplier: float = 1.0 + """Multiplier for raw audio data (1.0 = no change)""" + + awake_wav: Optional[str] = None + """Path to WAV file played after wake word detection.""" + + done_wav: Optional[str] = None + """Path to WAV file played after voice command is recognized.""" + + rate: int = 22050 + """Sample rate of output audio (hertz)""" + + width: int = 2 + """Sample width of output audio (bytes)""" + + channels: int = 1 + """Sample channels in output audio""" + + samples_per_chunk: int = 1024 + """Samples to write at a time to snd command""" + + disconnect_after_stop: bool = True + """True if snd service should be disconnected after AudioStop.""" + + @property + def needs_processing(self) -> bool: + """True if some pre-processing is needed for output audio.""" + return self.enabled and (self.volume_multiplier != 1.0) + + +@dataclass(frozen=True) +class WakeWordAndPipeline: + """Wake word name + optional pipeline name.""" + + name: str + pipeline: Optional[str] = None + + +@dataclass(frozen=True) +class WakeSettings(ServiceSettings): + """Wake word service settings.""" + + names: Optional[List[WakeWordAndPipeline]] = None + """List of wake word names to listen for.""" + + rate: int = 16000 + """Sample rate of wake word audio (hertz)""" + + width: int = 2 + """Sample width of wake word audio (bytes)""" + + channels: int = 1 + """Sample channels in wake word audio""" + + refractory_seconds: Optional[float] = 5.0 + """Seconds after a wake word detection before another detection is handled.""" + + +@dataclass(frozen=True) +class VadSettings: + """Voice activity detector settings.""" + + enabled: bool = False + """True if VAD should be used.""" + + system: str = "silero" + """VAD implementation to use: 'silero' or 'webrtc'""" + + threshold: float = 0.5 + """Silence threshold (0-1, 1 is speech)""" + + trigger_level: int = 1 + """Number of chunks to cross threshold before activation.""" + + energy_threshold: Optional[float] = None + """Optional RMS energy threshold for 'webrtc' VAD (int16 scale).""" + + buffer_seconds: float = 2.0 + """Seconds of audio before activation to keep/stream""" + + wake_word_timeout: Optional[float] = 5.0 + """Seconds before going back to sleep if wake word is not detected.""" + + +@dataclass(frozen=True) +class EventSettings(ServiceSettings): + """External event service settings.""" + + startup: Optional[List[str]] = None + streaming_start: Optional[List[str]] = None + streaming_stop: Optional[List[str]] = None + detect: Optional[List[str]] = None + detection: Optional[List[str]] = None + played: Optional[List[str]] = None + transcript: Optional[List[str]] = None + stt_start: Optional[List[str]] = None + stt_stop: Optional[List[str]] = None + synthesize: Optional[List[str]] = None + tts_start: Optional[List[str]] = None + tts_stop: Optional[List[str]] = None + error: Optional[List[str]] = None + connected: Optional[List[str]] = None + disconnected: Optional[List[str]] = None + + +@dataclass(frozen=True) +class TimerSettings: + """Voice timer settings.""" + + started: Optional[List[str]] = None + """Command to run when a timer starts.""" + + updated: Optional[List[str]] = None + """Command to run when a timer is paused, resumed, or has time added or removed.""" + + cancelled: Optional[List[str]] = None + """Command to run when a timer is cancelled.""" + + finished: Optional[List[str]] = None + """Command to run when a timer finishes.""" + + finished_wav: Optional[str] = None + """WAV file to play when a timer finishes.""" + + finished_wav_plays: int = 1 + """Number of times to play finished WAV.""" + + finished_wav_delay: float = 0 + """Delay in seconds between repeats of finished WAV.""" + + +@dataclass(frozen=True) +class SatelliteSettings: + """Wyoming satellite settings.""" + + mic: MicSettings + vad: VadSettings = field(default_factory=VadSettings) + wake: WakeSettings = field(default_factory=WakeSettings) + snd: SndSettings = field(default_factory=SndSettings) + event: EventSettings = field(default_factory=EventSettings) + timer: TimerSettings = field(default_factory=TimerSettings) + + restart_timeout: float = 5.0 + + debug_recording_dir: Optional[Path] = None + """Path to directory where debug audio is written.""" diff --git a/wyoming_satellite/utils/__init__.py b/wyoming_satellite/utils/__init__.py new file mode 100755 index 0000000..e47c60b --- /dev/null +++ b/wyoming_satellite/utils/__init__.py @@ -0,0 +1,30 @@ +"""Utility methods.""" +from .audio import ( + AudioBuffer, + DebugAudioWriter, + chunk_samples, + multiply_volume, + wav_to_events, +) +from .misc import ( + get_mac_address, + needs_silero, + needs_webrtc, + normalize_wake_word, + run_event_command, + split_command, +) + +__all__ = [ + "AudioBuffer", + "chunk_samples", + "DebugAudioWriter", + "get_mac_address", + "multiply_volume", + "needs_silero", + "needs_webrtc", + "normalize_wake_word", + "run_event_command", + "split_command", + "wav_to_events", +] diff --git a/wyoming_satellite/utils/audio.py b/wyoming_satellite/utils/audio.py new file mode 100755 index 0000000..fb74300 --- /dev/null +++ b/wyoming_satellite/utils/audio.py @@ -0,0 +1,205 @@ +"""Audio utilities.""" +import array +import logging +import time +import wave +from pathlib import Path +from typing import Iterable, Iterator, Optional, Union + +from pyring_buffer import RingBuffer +from wyoming.audio import AudioChunk, AudioStart, AudioStop +from wyoming.event import Event + +_LOGGER = logging.getLogger() + + +class AudioBuffer: + """Fixed-sized audio buffer with variable internal length.""" + + def __init__(self, maxlen: int) -> None: + """Initialize buffer.""" + self._buffer = bytearray(maxlen) + self._length = 0 + + @property + def length(self) -> int: + """Get number of bytes currently in the buffer.""" + return self._length + + def clear(self) -> None: + """Clear the buffer.""" + self._length = 0 + + def append(self, data: bytes) -> None: + """Append bytes to the buffer, increasing the internal length.""" + data_len = len(data) + if (self._length + data_len) > len(self._buffer): + raise ValueError("Length cannot be greater than buffer size") + + self._buffer[self._length : self._length + data_len] = data + self._length += data_len + + def to_bytes(self) -> bytes: + """Convert written portion of buffer to bytes.""" + return bytes(self._buffer[: self._length]) + + def __len__(self) -> int: + """Get the number of bytes currently in the buffer.""" + return self._length + + def __bool__(self) -> bool: + """Return True if there are bytes in the buffer.""" + return self._length > 0 + + +def multiply_volume(chunk: bytes, volume_multiplier: float) -> bytes: + """Multiplies 16-bit PCM samples by a constant.""" + + def _clamp(val: float) -> float: + """Clamp to signed 16-bit.""" + return max(-32768, min(32767, val)) + + return array.array( + "h", + (int(_clamp(value * volume_multiplier)) for value in array.array("h", chunk)), + ).tobytes() + + +def chunk_samples( + samples: bytes, + bytes_per_chunk: int, + leftover_chunk_buffer: AudioBuffer, +) -> Iterable[bytes]: + """Yield fixed-sized chunks from samples, keeping leftover bytes from previous call(s).""" + + if (len(leftover_chunk_buffer) + len(samples)) < bytes_per_chunk: + # Extend leftover chunk, but not enough samples to complete it + leftover_chunk_buffer.append(samples) + return + + next_chunk_idx = 0 + + if leftover_chunk_buffer: + # Add to leftover chunk from previous call(s). + bytes_to_copy = bytes_per_chunk - len(leftover_chunk_buffer) + leftover_chunk_buffer.append(samples[:bytes_to_copy]) + next_chunk_idx = bytes_to_copy + + # Process full chunk in buffer + yield leftover_chunk_buffer.to_bytes() + leftover_chunk_buffer.clear() + + while next_chunk_idx < len(samples) - bytes_per_chunk + 1: + # Process full chunk + yield samples[next_chunk_idx : next_chunk_idx + bytes_per_chunk] + next_chunk_idx += bytes_per_chunk + + # Capture leftover chunks + if rest_samples := samples[next_chunk_idx:]: + leftover_chunk_buffer.append(rest_samples) + + +def wav_to_events( + wav_path: Union[str, Path], + samples_per_chunk: int = 1024, + volume_multiplier: float = 1.0, +) -> Iterator[Event]: + """Load WAV audio for playback on an event (wake/done).""" + with wave.open(str(wav_path), "rb") as wav_file: + rate = wav_file.getframerate() + width = wav_file.getsampwidth() + channels = wav_file.getnchannels() + + timestamp = 0 + yield AudioStart( + rate=rate, width=width, channels=channels, timestamp=timestamp + ).event() + + audio_bytes = wav_file.readframes(samples_per_chunk) + while audio_bytes: + if volume_multiplier != 1.0: + audio_bytes = multiply_volume(audio_bytes, volume_multiplier) + + chunk = AudioChunk( + rate=rate, + width=width, + channels=channels, + audio=audio_bytes, + timestamp=timestamp, + ) + yield chunk.event() + timestamp += int(chunk.seconds * 1000) + audio_bytes = wav_file.readframes(samples_per_chunk) + + yield AudioStop(timestamp=timestamp).event() + + +class DebugAudioWriter: + def __init__( + self, + dir_path: Union[str, Path], + suffix: str, + rate: int = 16000, + width: int = 2, + channels: int = 1, + ring_buffer_size: Optional[int] = None, + ) -> None: + self.dir_path = Path(dir_path) + self.suffix = suffix + self.rate = rate + self.width = width + self.channels = channels + + self._wav_path: Optional[Path] = None + self._wav_writer: Optional[wave.Wave_write] = None + + # If ring buffer size is set, we will hold audio in a ring buffer + # instead of directly writing it to disk. + # + # This allows only the last few seconds of wake word audio to be stored. + self._ring_buffer: Optional[RingBuffer] = None + if ring_buffer_size is not None: + # Hold audio in a ring buffer before writing + self._ring_buffer = RingBuffer(ring_buffer_size) + + def start(self, timestamp: Optional[int] = None) -> None: + self.stop() + + if timestamp is None: + timestamp = time.monotonic_ns() + + self._wav_path = self.dir_path / f"{timestamp}-{self.suffix}.wav" + self._wav_path.parent.mkdir(parents=True, exist_ok=True) + + self._wav_writer = wave.open(str(self._wav_path), "wb") + self._wav_writer.setframerate(self.rate) + self._wav_writer.setsampwidth(self.width) + self._wav_writer.setnchannels(self.channels) + + _LOGGER.debug("Started recording to %s", self._wav_path) + + def write(self, audio: bytes) -> None: + if self._wav_writer is None: + return + + if self._ring_buffer is not None: + # Hold audio in a ring buffer before writing + self._ring_buffer.put(audio) + else: + # Write directly to disk + self._wav_writer.writeframes(audio) + + def stop(self) -> None: + if self._wav_writer is None: + return + + if self._ring_buffer is not None: + # Write all audio now and reset buffer + self._wav_writer.writeframes(self._ring_buffer.getvalue()) + self._ring_buffer = RingBuffer(self._ring_buffer.maxlen) + + self._wav_writer.close() + self._wav_writer = None + + _LOGGER.debug("Stopped recording to %s", self._wav_path) + self._wav_path = None diff --git a/wyoming_satellite/utils/misc.py b/wyoming_satellite/utils/misc.py new file mode 100755 index 0000000..cd9eaac --- /dev/null +++ b/wyoming_satellite/utils/misc.py @@ -0,0 +1,90 @@ +"""Miscellaneous utilities.""" +import argparse +import asyncio +import json +import logging +import re +import shlex +import unicodedata +import uuid +from functools import lru_cache +from typing import List, Optional, Union + +from wyoming.event import Eventable + +_LOGGER = logging.getLogger() + + +async def run_event_command( + command: Optional[List[str]], command_input: Optional[Union[str, Eventable]] = None +) -> None: + """Run a custom event command with optional input.""" + if not command: + return + + if isinstance(command_input, Eventable): + # Convert event to JSON + event_dict = command_input.event().to_dict() + command_input = json.dumps(event_dict, ensure_ascii=False) + + _LOGGER.debug("Running %s", command) + program, *program_args = command + proc = await asyncio.create_subprocess_exec( + program, *program_args, stdin=asyncio.subprocess.PIPE + ) + assert proc.stdin is not None + + if command_input: + await proc.communicate(input=command_input.encode("utf-8")) + else: + proc.stdin.close() + await proc.wait() + + +def get_mac_address() -> str: + """Return MAC address formatted as hex with no colons.""" + return "".join( + # pylint: disable=consider-using-f-string + ["{:02x}".format((uuid.getnode() >> ele) & 0xFF) for ele in range(0, 8 * 6, 8)][ + ::-1 + ] + ) + + +def needs_webrtc(args: argparse.Namespace) -> bool: + """Return True if webrtc must be used.""" + return (args.mic_noise_suppression > 0) or (args.mic_auto_gain > 0) + + +def needs_silero(args: argparse.Namespace) -> bool: + """Return True if silero-vad must be used.""" + return args.vad and (getattr(args, "vad_system", "silero") == "silero") + + +def split_command(command: Optional[str]) -> Optional[List[str]]: + """Split command line program/args if not empty.""" + if not command: + return None + + return shlex.split(command) + + +@lru_cache +def normalize_wake_word(wake_word: str) -> str: + """Normalizes a wake word name for comparison.""" + + # Lower case + wake_word = wake_word.strip().casefold() + + # Remove version numbers like v1.0 + wake_word = re.sub(r"v[0-9]+(\.[0-9])+", "", wake_word) + + # Replace anything besides letters/numbers with whitespace + wake_word = "".join( + c if unicodedata.category(c) in ("Ll", "Nd") else " " for c in wake_word + ) + + # Normalize whitespace + wake_word = " ".join(wake_word.strip().split()) + + return wake_word diff --git a/wyoming_satellite/vad.py b/wyoming_satellite/vad.py new file mode 100755 index 0000000..9caaf53 --- /dev/null +++ b/wyoming_satellite/vad.py @@ -0,0 +1,88 @@ +"""Voice activity detection.""" +from typing import Optional +import math +import array + + +class SileroVad: + """Voice activity detection with silero VAD.""" + + def __init__(self, threshold: float, trigger_level: int) -> None: + from pysilero_vad import SileroVoiceActivityDetector + + self.detector = SileroVoiceActivityDetector() + self.threshold = threshold + self.trigger_level = trigger_level + self._activation = 0 + + def __call__(self, audio_bytes: Optional[bytes]) -> bool: + if audio_bytes is None: + # Reset + self._activation = 0 + self.detector.reset() + return False + + if self.detector(audio_bytes) >= self.threshold: + # Speech detected + self._activation += 1 + if self._activation >= self.trigger_level: + self._activation = 0 + return True + else: + # Silence detected + self._activation = max(0, self._activation - 1) + + return False + + +class WebRtcVadEnergy: + """Voice activity detection using webrtcvad + RMS energy threshold. + + Expects 16-bit mono PCM at 16Khz. Chunks are internally processed in 20ms windows. + """ + + def __init__(self, trigger_level: int, energy_threshold: Optional[float] = None) -> None: + import webrtcvad # type: ignore + + self.vad = webrtcvad.Vad(3) + self.trigger_level = trigger_level + self.energy_threshold = energy_threshold if energy_threshold is not None else 200.0 + self._activation = 0 + + # 20ms @16kHz, 16-bit mono + self._samples_per_window = 320 + self._bytes_per_window = self._samples_per_window * 2 + + def __call__(self, audio_bytes: Optional[bytes]) -> bool: + if audio_bytes is None: + # Reset + self._activation = 0 + return False + + # Process in 20ms windows as required by webrtcvad + for i in range(0, len(audio_bytes) - (len(audio_bytes) % self._bytes_per_window), self._bytes_per_window): + window = audio_bytes[i : i + self._bytes_per_window] + + # RMS energy + pcm = array.array("h") + pcm.frombytes(window) + if len(pcm) == 0: + continue + rms = math.sqrt(sum(int(s) * int(s) for s in pcm) / len(pcm)) + + is_speech = False + try: + is_speech = self.vad.is_speech(window, 16000) and (rms >= float(self.energy_threshold)) + except Exception: + # If VAD errors on malformed window, skip + is_speech = False + + if is_speech: + self._activation += 1 + if self._activation >= self.trigger_level: + self._activation = 0 + return True + else: + self._activation = max(0, self._activation - 1) + + return False diff --git a/wyoming_satellite/webrtc.py b/wyoming_satellite/webrtc.py new file mode 100755 index 0000000..03185c9 --- /dev/null +++ b/wyoming_satellite/webrtc.py @@ -0,0 +1,28 @@ +"""webrtc audio processing.""" +from typing import Final + +from .utils import AudioBuffer, chunk_samples + + +class WebRtcAudio: + """Audio processing using webrtc.""" + + _sub_chunk_samples: Final = 160 # 10ms @ 16Khz + _sub_chunk_bytes: Final = _sub_chunk_samples * 2 # 16-bit + + def __init__(self, auto_gain: int, noise_suppression: int) -> None: + from webrtc_noise_gain import AudioProcessor + + self.audio_processor = AudioProcessor(auto_gain, noise_suppression) + self.audio_buffer = AudioBuffer(self._sub_chunk_bytes) + + def __call__(self, audio_bytes: bytes) -> bytes: + """Process in 10ms chunks.""" + clean_chunk = bytes() + for sub_chunk in chunk_samples( + audio_bytes, self._sub_chunk_bytes, self.audio_buffer + ): + result = self.audio_processor.Process10ms(sub_chunk) + clean_chunk += result.audio + + return clean_chunk