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

View File

@@ -37,4 +37,4 @@ jobs:
target: amdgpu target: amdgpu
push: true push: true
tags: "gitea.reeseapps.com/services/arch-toolbox-amdgpu:latest,gitea.reeseapps.com/services/arch-toolbox-amdgpu:${{gitea.sha}}" tags: "gitea.reeseapps.com/services/arch-toolbox-amdgpu:latest,gitea.reeseapps.com/services/arch-toolbox-amdgpu:${{gitea.sha}}"
no-cache: true no-cache: false

1
.gitignore vendored
View File

@@ -6,3 +6,4 @@ volumes/
__pycache__/ __pycache__/
.pytest_cache/ .pytest_cache/
.venv/ .venv/
.mypy_cache

View File

@@ -45,6 +45,8 @@ Host ${KEYGEN_HOST}
EOF EOF
``` ```
In vim: `esc + o` will take you to the end of a file and insert a new line.
## Important Dates and Times ## Important Dates and Times
- Machine updates happen at 4am on on Saturday - Machine updates happen at 4am on on Saturday

View File

@@ -1,16 +0,0 @@
fedora:
hosts:
3dserver:
podman:
kubernetes:
docker:
yellow:
borg:
ubuntu:
hosts:
unifi-external:
caddy:
hosts:
3dserver:

View File

@@ -18,7 +18,7 @@ On the operator:
```bash ```bash
export SSH_HOST=kube export SSH_HOST=kube
ssh-keygen -t rsa -b 4096 -C ducoterra@${SSH_HOST}.reeselink.com -f ~/.ssh/id_${SSH_HOST}_rsa ssh-keygen -t rsa -b 4096 -C ${USER}@${HOSTNAME} -f ~/.ssh/id_${SSH_HOST}_rsa
# Note: If you get "too many authentication failures" it's likely because you have too many private # Note: If you get "too many authentication failures" it's likely because you have too many private
# keys in your ~/.ssh directory. Use `-o PubkeyAuthentication` to fix it. # keys in your ~/.ssh directory. Use `-o PubkeyAuthentication` to fix it.

View File

@@ -11,6 +11,7 @@
- [Hostname](#hostname) - [Hostname](#hostname)
- [VLAN Setup with nmcli](#vlan-setup-with-nmcli) - [VLAN Setup with nmcli](#vlan-setup-with-nmcli)
- [GPU Support in Distrobox](#gpu-support-in-distrobox) - [GPU Support in Distrobox](#gpu-support-in-distrobox)
- [Automatic Display Switching](#automatic-display-switching)
## TPM2 Luks Decryption ## TPM2 Luks Decryption
@@ -162,3 +163,56 @@ sudo usermod -aG render $USER
``` ```
Logout and log back in to adopt new groups. Logout and log back in to adopt new groups.
## Automatic Display Switching
```bash
# List displays
# Builtin: eDP-2
# Roku: DP-13
# Lenovo: DP-11
kscreen-doctor -o
# Put the builtin display back to normal
kscreen-doctor \
output.eDP-2.enable \
output.eDP-2.position.0,0 \
output.eDP-2.primary \
output.eDP-2.mode.2560x1600@60 \
output.eDP-2.scale.1.25
# Show on Roku TV and Monitor
kscreen-doctor \
output.DP-11.enable \
output.DP-11.position.0,0 \
output.DP-11.mode.2560x1440@60 \
output.DP-11.scale.1 \
output.DP-13.enable \
output.DP-13.position.0,0 \
output.DP-13.mode.2560x1440@100 \
output.DP-13.scale.1 \
output.DP-13.primary \
output.eDP-2.disable
# Show only on the roku TV
kscreen-doctor \
output.DP-11.enable \
output.DP-11.position.0,0 \
output.DP-11.primary \
output.DP-11.mode.3840x2160@60 \
output.DP-11.scale.2 \
output.DP-13.disable \
output.eDP-2.disable
# Mirror the builtin display to the roku tv
kscreen-doctor \
output.DP-11.enable \
output.DP-11.position.0,0 \
output.DP-11.primary \
output.DP-11.mode.3840x2160@60 \
output.DP-11.scale.2 \
output.eDP-2.enable \
output.eDP-2.mode.1920x1080@60 \
output.eDP-2.scale.1 \
output.eDP-2.position.0,0
```

View File

@@ -79,7 +79,7 @@ On the operator:
```bash ```bash
export SSH_HOST=kube export SSH_HOST=kube
ssh-keygen -C ducoterra@${SSH_HOST}.reeselink.com -f ~/.ssh/id_${SSH_HOST}_rsa ssh-keygen -C ${USER}@${HOSTNAME} -f ~/.ssh/id_${SSH_HOST}_rsa
# Note: If you get "too many authentication failures" it's likely because you have too many private # Note: If you get "too many authentication failures" it's likely because you have too many private
# keys in your ~/.ssh directory. Use `-o PubkeyAuthentication` to fix it. # keys in your ~/.ssh directory. Use `-o PubkeyAuthentication` to fix it.

View File

@@ -28,6 +28,8 @@ services:
- postgres - postgres
security_opt: security_opt:
- label=disable - label=disable
labels:
- "io.containers.autoupdate=registry"
postgres: postgres:
image: docker.io/library/postgres:15 image: docker.io/library/postgres:15

View File

@@ -5,6 +5,7 @@
- [Create the gitea user](#create-the-gitea-user) - [Create the gitea user](#create-the-gitea-user)
- [Convert Compose to Quadlet](#convert-compose-to-quadlet) - [Convert Compose to Quadlet](#convert-compose-to-quadlet)
- [Install Quadlets](#install-quadlets) - [Install Quadlets](#install-quadlets)
- [Upgrade Quadlets](#upgrade-quadlets)
- [Editing Configs within Container](#editing-configs-within-container) - [Editing Configs within Container](#editing-configs-within-container)
- [Gitea Runners](#gitea-runners) - [Gitea Runners](#gitea-runners)
- [Firewall Rules](#firewall-rules) - [Firewall Rules](#firewall-rules)
@@ -63,9 +64,18 @@ scp -r quadlets/. gitea:~/.config/containers/systemd/
The first user you register will be the admin The first user you register will be the admin
```bash ```bash
ssh gitea ssh gitea systemctl --user daemon-reload
systemctl --user daemon-reload ssh gitea systemctl --user restart gitea postgres
systemctl --user start gitea postgres # Enables auto-update service which will pull new container images automatically every day
ssh gitea systemctl --user enable --now podman-auto-update.timer
```
### Upgrade Quadlets
```bash
scp -r quadlets/. gitea:~/.config/containers/systemd/
ssh gitea systemctl --user daemon-reload
ssh gitea systemctl --user restart gitea postgres
``` ```
### Editing Configs within Container ### Editing Configs within Container
@@ -141,10 +151,11 @@ You should run something like this on a schedule:
docker builder prune -a docker builder prune -a
``` ```
To run it every day at midnight: `crontab -e` To run it every day at noon: `crontab -e`
```bash ```bash
0 0 * * * yes | docker builder prune -a 0 12 * * * yes | docker builder prune -a
0 12 * * * docker image prune -a -f
``` ```
## Email Notifications ## Email Notifications

View File

@@ -2,6 +2,7 @@
Requires=postgres.service Requires=postgres.service
[Container] [Container]
AutoUpdate=registry
ContainerName=gitea ContainerName=gitea
Environment=USER_UID=1000 USER_GID=1000 GITEA__database__DB_TYPE=postgres GITEA__database__HOST=postgres:5432 GITEA__database__NAME=gitea GITEA__database__USER=gitea GITEA__database__PASSWD=gitea Environment=USER_UID=1000 USER_GID=1000 GITEA__database__DB_TYPE=postgres GITEA__database__HOST=postgres:5432 GITEA__database__NAME=gitea GITEA__database__USER=gitea GITEA__database__PASSWD=gitea
Image=docker.gitea.com/gitea:1.23.7 Image=docker.gitea.com/gitea:1.23.7
@@ -9,7 +10,7 @@ Network=gitea.network
PublishPort=3000:3000 PublishPort=3000:3000
PublishPort=2222:22 PublishPort=2222:22
SecurityLabelDisable=true SecurityLabelDisable=true
Volume=/home/gitea/gitea:/data Volume=/home/gitea/gitea_data:/data
Volume=/etc/localtime:/etc/localtime:ro Volume=/etc/localtime:/etc/localtime:ro
[Service] [Service]

View File

@@ -4,7 +4,7 @@ Environment=POSTGRES_USER=gitea POSTGRES_PASSWORD=gitea POSTGRES_DB=gitea
Image=docker.io/library/postgres:15 Image=docker.io/library/postgres:15
Network=gitea.network Network=gitea.network
SecurityLabelDisable=true SecurityLabelDisable=true
Volume=/home/gitea/postgres:/var/lib/postgresql/data Volume=/home/gitea/gitea_postgres:/var/lib/postgresql/data
[Service] [Service]
Restart=always Restart=always

View File

@@ -0,0 +1,7 @@
#!/bin/bash
# wget -O /tmp/GrayJay.zip https://updater.grayjay.app/Apps/Grayjay.Desktop/Grayjay.Desktop-linux-x64.zip
unzip /tmp/GrayJay.zip -d /tmp/GrayJay
mkdir -p ~/Applications/GrayJay
rsync /tmp/GrayJay/*/* ~/Applications/GrayJay
desktop-file-install --dir ~/.local/share/applications ./active/software_grayjay/grayjay.desktop

View File

@@ -0,0 +1,7 @@
[Desktop Entry]
Name=GrayJay
Exec=/home/ducoterra/Applications/GrayJay/Grayjay
Icon=/home/ducoterra/Applications/GrayJay/grayjay
Type=Application
Path=/home/ducoterra/Applications/GrayJay
Terminal=false

View File

@@ -0,0 +1,11 @@
# GrayJay
<https://grayjay.app/>
A youtube/spotify/media source agregator and player alternative.
## Desktop Install
```bash
./active/software_grayjay/desktop-install.sh
```

View File

@@ -1,10 +1,18 @@
#!/bin/sh #!/bin/sh
export BACKUP_HOST=driveripper.reeselink.com {% for service in stop_services %}
sshfs ${BACKUP_HOST}:backup /backup systemctl stop {{ service }}
{% endfor %}
{% for service in stop_user_services %}
systemctl --user --machine={{ systemd_user }}@.host stop {{ service }}
{% endfor %}
# Setting this, so the repo does not need to be given on the commandline: # Setting this, so the repo does not need to be given on the commandline:
export BORG_REPO='/backup' export BORG_REPO={{ borg_user }}@{{ borg_host }}:{{ repo_name }}
# See the section "Passphrase notes" for more infos.
export BORG_PASSPHRASE={{ borg_passphrase }}
# some helpers and error handling: # some helpers and error handling:
info() { printf "\n%s %s\n\n" "$( date )" "$*" >&2; } info() { printf "\n%s %s\n\n" "$( date )" "$*" >&2; }
@@ -21,19 +29,29 @@ borg create \
--list \ --list \
--stats \ --stats \
--show-rc \ --show-rc \
--compression none \ --compression lz4 \
--exclude-caches \ --exclude-caches \
--exclude 'home/*/.cache/*' \ --exclude 'home/*/.cache/*' \
--exclude 'var/tmp/*' \ --exclude 'var/tmp/*' \
{% for dir in exclude_dirs %}
--exclude '{{ dir }}' \
{% endfor %}
\ \
::'{hostname}-{now}' \ ::'{hostname}-{now}' \
/etc \ {% for dir in backup_dirs %}
/home \ {{ dir }} \
/root \ {% endfor %}
/var
backup_exit=$? backup_exit=$?
{% for service in stop_services %}
systemctl start {{ service }}
{% endfor %}
{% for service in stop_user_services %}
systemctl --user --machine={{ systemd_user }}@.host start {{ service }}
{% endfor %}
info "Pruning repository" info "Pruning repository"
# Use the `prune` subcommand to maintain 7 daily, 4 weekly and 6 monthly # Use the `prune` subcommand to maintain 7 daily, 4 weekly and 6 monthly
@@ -45,9 +63,9 @@ borg prune \
--list \ --list \
--glob-archives '{hostname}-*' \ --glob-archives '{hostname}-*' \
--show-rc \ --show-rc \
--keep-daily 7 \ --keep-daily {{ keep_daily }} \
--keep-weekly 2 \ --keep-weekly {{ keep_weekly }} \
--keep-monthly 1 --keep-monthly {{ keep_monthly }} \
prune_exit=$? prune_exit=$?
@@ -71,5 +89,4 @@ else
info "Backup, Prune, and/or Compact finished with errors" info "Backup, Prune, and/or Compact finished with errors"
fi fi
fusermount -u /backup
exit ${global_exit} exit ${global_exit}

View File

@@ -0,0 +1,11 @@
[Unit]
Description=Run Backup backup_{{ repo_name }}.service every hour
[Timer]
OnCalendar=hourly
AccuracySec=10min
Persistent=true
Unit=ddns.{{ item.record }}.service
[Install]
WantedBy=timers.target

View File

@@ -1,5 +1,11 @@
# Borg Backup # Borg Backup
- [Borg Backup](#borg-backup)
- [Server Setup](#server-setup)
- [Adding a Client](#adding-a-client)
- [Installing the Backup Service](#installing-the-backup-service)
- [Adding Nextcloud](#adding-nextcloud)
## Server Setup ## Server Setup
<https://borgbackup.readthedocs.io/en/stable/deployment/central-backup-server.html#user-and-group> <https://borgbackup.readthedocs.io/en/stable/deployment/central-backup-server.html#user-and-group>
@@ -28,7 +34,7 @@ Note: See [adding nextcloud](#adding-nextcloud) for nextcloud instructions here.
```bash ```bash
export BACKUP_HOST="" export BACKUP_HOST=""
ssh-keygen -C backup@${BACKUP_HOST} -f ~/.ssh/id_${BACKUP_HOST} ssh-keygen -C ${USER}@${HOSTNAME} -f ~/.ssh/id_${BACKUP_HOST}
cat <<EOF >> ~/.ssh/config cat <<EOF >> ~/.ssh/config
Host ${BACKUP_HOST} Host ${BACKUP_HOST}
@@ -58,7 +64,43 @@ Then back on the client:
```bash ```bash
ssh borg.reeselink.com ssh borg.reeselink.com
# root
borg init --encryption none backup@${BACKUP_HOST}:root borg init --encryption none backup@${BACKUP_HOST}:root
# home
borg init --encryption none backup@${BACKUP_HOST}:home
# app
borg init --encryption none backup@${BACKUP_HOST}:gitea
# another app
borg init --encryption none backup@${BACKUP_HOST}:nextcloud
```
### Installing the Backup Service
Create your vars file in `secrets/host_vars.yaml`
```yaml
repo_name: my_repo
borg_user: backup
borg_host: borg.reeselink.com
borg_passphrase: ""
backup_dirs:
- /home
exclude_dirs: []
keep_daily: 7
keep_weekly: 4
keep_monthly: 1
stop_services: []
stop_user_services:
- gitea
- postgres
```
```bash
ansible-playbook \
-i active/ansible/inventory.yaml \
-l podman \
active/systemd_borg/install_backup.yaml \
-e "@active/systemd_borg/secrets/gitea_vars.yaml"
``` ```
#### Adding Nextcloud #### Adding Nextcloud

View File

@@ -0,0 +1,43 @@
- name: Create Backup Service
hosts: all
vars_files:
- secrets/vars.yaml
tasks:
- name: Create /usr/local/script dir
ansible.builtin.file:
path: /usr/local/script
state: directory
mode: '0755'
- name: Copy backup.service
template:
src: backup.service
dest: /etc/systemd/system/backup-{{ repo_name }}.service
owner: root
group: root
mode: '0644'
- name: Copy backup.timer
template:
src: backup.timer
dest: /etc/systemd/system/backup-{{ repo_name }}.timer
owner: root
group: root
mode: '0644'
- name: Template backup.sh
template:
src: backup.sh.j2
dest: /usr/local/script/backup-{{ repo_name }}.sh
owner: root
group: root
mode: '0744'
# - name: Reload ddns timer
# ansible.builtin.systemd_service:
# state: restarted
# name: ddns.{{ item.record }}.timer
# enabled: true
# daemon_reload: true
# loop: "{{ records }}"
# - name: Run ddns service
# ansible.builtin.systemd_service:
# state: restarted
# name: ddns.{{ item.record }}.service
# loop: "{{ records }}"

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

25
ansible/inventory.yaml Normal file
View File

@@ -0,0 +1,25 @@
fedora:
hosts:
3dserver:
podman:
kubernetes:
docker:
yellow:
borg:
ubuntu:
hosts:
unifi-external:
caddy:
hosts:
3dserver:
wyoming:
hosts:
pink-rpi.reeselink.com:
mic_volume_multiplier: 2
red-rpi.reeselink.com:
mic_volume_multiplier: 2
rpi5.reeselink.com:
mic_volume_multiplier: 8

View File

@@ -1,122 +0,0 @@
# Wyoming Satellite
## Install
<https://github.com/rhasspy/wyoming-satellite/blob/master/docs/tutorial_2mic.md>
```bash
sudo apt update && sudo apt upgrade -y
sudo apt install --no-install-recommends \
git \
python3-venv \
vim \
tmux
sudo reboot
git clone https://github.com/rhasspy/wyoming-satellite.git
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/' \
-r requirements.txt \
-r requirements_audio_enhancement.txt \
-r requirements_vad.txt
# Find microphone
arecord -L | grep plughw -A 2
# Create a test recording
arecord -D plughw:CARD=JV801,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=JV801,DEV=0 test.wav
# Bedroom
script/run \
--debug \
--name 'Bedroom Satellite' \
--uri 'tcp://0.0.0.0:10700' \
--mic-command 'arecord -D plughw:CARD=Speaker,DEV=0 -r 16000 -c 1 -f S16_LE -t raw' \
--snd-command 'aplay -D plughw:CARD=Speaker,DEV=0 -r 22050 -c 1 -f S16_LE -t raw'
# Living Room
script/run \
--debug \
--name 'Living Room Satellite' \
--uri 'tcp://0.0.0.0:10700' \
--mic-command 'arecord -D plughw:CARD=Speaker,DEV=0 -r 16000 -c 1 -f S16_LE -t raw' \
--snd-command 'aplay -D plughw:CARD=Speaker,DEV=0 -r 22050 -c 1 -f S16_LE -t raw'
```
## Systemd
### Create and Edit
```bash
sudo systemctl edit --force --full wyoming-satellite.service
sudo systemctl enable --now wyoming-satellite.service
sudo journalctl -u wyoming-satellite.service -f
```
### Bedroom
```conf
[Unit]
Description=Wyoming Satellite
Wants=network-online.target
After=network-online.target
[Service]
Type=simple
ExecStart=/home/ducoterra/wyoming-satellite/script/run \
--name 'Bedroom Satellite' \
--uri 'tcp://0.0.0.0:10700' \
--mic-command 'arecord -D plughw:CARD=Speaker,DEV=0 -r 16000 -c 1 -f S16_LE -t raw' \
--snd-command 'aplay -D plughw:CARD=Speaker,DEV=0 -r 22050 -c 1 -f S16_LE -t raw'
WorkingDirectory=/home/ducoterra/wyoming-satellite
Restart=always
RestartSec=1
[Install]
WantedBy=default.target
```
### Living Room
```conf
[Unit]
Description=Wyoming Satellite
Wants=network-online.target
After=network-online.target
[Service]
Type=simple
ExecStart=/home/ducoterra/wyoming-satellite/script/run \
--name 'Living Room Satellite' \
--uri 'tcp://0.0.0.0:10700' \
--mic-command 'arecord -D plughw:CARD=Speaker,DEV=0 -r 16000 -c 1 -f S16_LE -t raw' \
--snd-command 'aplay -D plughw:CARD=Speaker,DEV=0 -r 22050 -c 1 -f S16_LE -t raw'
WorkingDirectory=/home/ducoterra/wyoming-satellite
Restart=always
RestartSec=1
[Install]
WantedBy=default.target
```
## Volume
Run `alsamixer`.
## Community Wake Words
<https://github.com/fwartner/home-assistant-wakewords-collection?tab=readme-ov-file>
<https://github.com/fwartner/ha-openwakeword-installer>