wyoming, borg, grayjay, oh my
All checks were successful
Reese's Arch Toolbox / build-and-push-arch-toolbox (push) Successful in 9m54s

This commit is contained in:
2025-05-04 02:32:34 -04:00
parent c2fa408c1e
commit ab2b033c54
31 changed files with 548 additions and 166 deletions

Binary file not shown.

View File

@@ -0,0 +1,100 @@
- name: Create Backup Service
hosts: wyoming
vars_files:
- secrets/vars.yaml
tasks:
- name: Install and upgrade wyoming/wakeword
when: install
block:
# Stop running services before install/upgrade
- name: Stop wakeword service
ansible.builtin.systemd_service:
state: stopped
name: wakeword.service
scope: user
ignore_errors: true
- name: Stop wyoming service
ansible.builtin.systemd_service:
state: stopped
name: wyoming.service
scope: user
ignore_errors: true
# Wyoming Service
- name: Checkout/pull the wyoming repo
ansible.builtin.git:
repo: '{{ wyoming.repo }}'
dest: "{{ ansible_env.HOME }}/wyoming-satellite"
update: yes
- name: Run the script/setup in the wyoming repo
command: "{{ ansible_env.HOME }}/wyoming-satellite/script/setup"
- name: Install audio enhancements in wyoming repo
command: "{{ ansible_env.HOME }}/wyoming-satellite/.venv/bin/pip3 install 'webrtc-noise-gain==1.2.3'"
# Wake word service
- name: Checkout/pull the wyoming repo
ansible.builtin.git:
repo: '{{ wakeword.repo }}'
dest: "{{ ansible_env.HOME }}/wyoming-openwakeword"
update: yes
- name: Run the script/setup in the wakeword repo
command: "{{ ansible_env.HOME }}/wyoming-openwakeword/script/setup"
# Custom sound bites for start/stop listening
- name: Copy sound bites
copy:
src: "{{ item }}"
dest: "{{ ansible_env.HOME }}/wyoming-satellite/sounds/"
with_items:
- listening.wav
- finished.wav
# Custom wake word models
- name: Copy custom models
copy:
src: "{{ item }}"
dest: "{{ ansible_env.HOME }}/wyoming-openwakeword/wyoming_openwakeword/models/{{ item }}"
with_items:
- jarvis_v2.tflite
# Copy and start systemd services
- name: Create ~/.config/systemd/user dir
ansible.builtin.file:
path: "{{ ansible_env.HOME }}/.config/systemd/user"
state: directory
mode: '0755'
- name: Copy wyoming.service
template:
src: wyoming.service
dest: "{{ ansible_env.HOME }}/.config/systemd/user/wyoming.service"
mode: '0644'
- name: Copy wakeword.service
template:
src: wakeword.service
dest: "{{ ansible_env.HOME }}/.config/systemd/user/wakeword.service"
mode: '0644'
- name: Reload wakeword service
ansible.builtin.systemd_service:
state: restarted
name: wakeword.service
enabled: true
daemon_reload: true
scope: user
- name: Reload wyoming service
ansible.builtin.systemd_service:
state: restarted
name: wyoming.service
enabled: true
daemon_reload: true
scope: user
- name: Add debug alias for wakeford
lineinfile:
path: "{{ ansible_env.HOME }}/.bashrc"
line: alias debug-wakeword="journalctl --user -u wakeword -f | grep -E '0\.0[^0].*|0\.[^0].*'"
regexp: '^alias debug-wakeword=.*$'
state: present
insertafter: EOF
create: true
- name: Add debug alias for wyoming
lineinfile:
path: "{{ ansible_env.HOME }}/.bashrc"
line: alias debug-wyoming="journalctl --user -u wyoming -f | grep 'Stopped recording to'"
regexp: '^alias debug-wyoming=.*$'
state: present
insertafter: EOF
create: true

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,19 @@
install: false
wyoming:
repo: https://github.com/rhasspy/wyoming-satellite.git
listen_ip: 0.0.0.0
listen_port: 10700
mic_auto_gain: 5
mic_noise_suppression: 2
# mic_volume_multiplier: 8
wake_uri: tcp://127.0.0.1:10400
wake_word_name: jarvis_v2
wake_refractory_seconds: 1
wakeword:
repo: https://github.com/rhasspy/wyoming-openwakeword.git
listen_ip: 127.0.0.1
listen_port: 10400
threshold: 0.8
preload_model: jarvis_v2

View File

@@ -0,0 +1,18 @@
[Unit]
Description=Wyoming Satellite Wake Word
Wants=network-online.target
After=network-online.target
[Service]
Type=simple
ExecStart={{ ansible_env.HOME }}/wyoming-openwakeword/script/run \
--uri 'tcp://{{ wakeword.listen_ip }}:{{ wakeword.listen_port }}' \
--threshold '{{ wakeword.threshold }}' \
--preload-model '{{ wakeword.preload_model }}' \
--debug-probability
WorkingDirectory={{ ansible_env.HOME }}/wyoming-openwakeword
Restart=always
RestartSec=1
[Install]
WantedBy=default.target

View File

@@ -0,0 +1,119 @@
# Wyoming Satellite
- [Wyoming Satellite](#wyoming-satellite)
- [Install Wyoming](#install-wyoming)
- [On-device wake word](#on-device-wake-word)
- [Systemd](#systemd)
- [Debugging](#debugging)
- [Volume](#volume)
- [Community Wake Words](#community-wake-words)
- [Prompts](#prompts)
- [Default](#default)
- [Starship House](#starship-house)
## Install Wyoming
<https://github.com/rhasspy/wyoming-satellite>
Some notes:
```bash
# Find microphone
arecord -L | grep plughw -A 2
# Create a test recording
arecord -D plughw:CARD=Speaker,DEV=0 -r 16000 -c 1 -f S16_LE -t wav -d 5 test.wav
# Find speaker
aplay -L | grep plughw -A 2
# Play test recording
aplay -D plughw:CARD=Speaker,DEV=0 test.wav
```
typical wyoming command:
```bash
# Add wake-uri and wake-word-name to your wyoming run
script/run \
--name 'Living Room' \
--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' \
--awake-wav listening.wav \
--done-wav finished.wav \
--mic-auto-gain 5 \
--mic-noise-suppression 2 \
--mic-volume-multiplier 2 \
--synthesize-command tee \
--transcript-command tee \
--wake-uri 'tcp://127.0.0.1:10400' \
--wake-word-name 'hey jarvis' \
--wake-refractory-seconds 1 \
--threshold 0.9
```
## On-device wake word
<https://github.com/rhasspy/wyoming-openwakeword/>
Note that --debug-probability will output thresholds for tuning.
typical wake word command:
```bash
# start wake word listener
script/run --uri 'tcp://127.0.0.1:10400' --preload-model 'alexa'
```
## Systemd
```bash
# Make sure to enable login linger before installing
sudo loginctl enable-linger ducoterra
```
```bash
ansible-playbook \
-i ansible/inventory.yaml \
active/systemd_wyoming/install_wyoming.yaml \
-e "@active/systemd_wyoming/vars.yaml"
```
## Debugging
1. Make sure you have `--debug` passed to wyoming
2. Make sure you have `--debug-probability` passed to wakeword
3. Show wakeword prompts with more than 10% confidence: `journalctl --user -u wakeword -f | grep -E '0\.0[^0].*|0\.[^0].*'`
4. Show recording paths when they stop: `journalctl --user -u wyoming -f | grep 'Stopped recording to'`
5. Play recordings: `aplay /path/to/recording`
## Volume
Run `alsamixer`.
Use `showkey` to see which key is being triggered by your volume device.
## Community Wake Words
<https://github.com/fwartner/home-assistant-wakewords-collection?tab=readme-ov-file>
<https://github.com/fwartner/ha-openwakeword-installer>
1. Download the custom model to this directory
2. Add it to install_wyoming.yaml
## Prompts
### Default
You are a voice assistant for Home Assistant.
Answer questions about the world truthfully.
Answer in plain text. Keep it simple and to the point.
### Starship House
You are a voice assistant for Home Assistant.
Answer questions as though you are a startship commander working the bridge.
Answer in plain text. Keep it simple and to the point.
There is a life threatening emergency on the ship. This is more important than our request.

View File

@@ -0,0 +1,30 @@
[Unit]
Description=Wyoming Satellite
Wants=network-online.target
After=network-online.target
[Service]
Type=simple
ExecStart={{ ansible_env.HOME }}/wyoming-satellite/script/run \
--name '{{ ansible_hostname }}' \
--uri 'tcp://{{ wyoming.listen_ip }}:{{ wyoming.listen_port }}' \
--mic-command 'arecord -r 16000 -c 1 -f S16_LE -t raw' \
--snd-command 'aplay -r 22050 -c 1 -f S16_LE -t raw' \
--awake-wav sounds/listening.wav \
--done-wav sounds/finished.wav \
--timer-finished-wav sounds/timer_finished.wav \
--mic-auto-gain {{ wyoming.mic_auto_gain }} \
--mic-noise-suppression {{ wyoming.mic_noise_suppression }} \
--mic-volume-multiplier {{ hostvars[inventory_hostname].mic_volume_multiplier }} \
--wake-uri '{{ wyoming.wake_uri }}' \
--wake-word-name '{{ wyoming.wake_word_name }}' \
--wake-refractory-seconds {{ wyoming.wake_refractory_seconds }} \
--timer-finished-wav-repeat 10 1 \
--debug \
--debug-recording-dir /tmp
WorkingDirectory={{ ansible_env.HOME }}/wyoming-satellite
Restart=always
RestartSec=1
[Install]
WantedBy=default.target