diff --git a/.vscode/vscode.md b/.vscode/vscode.md index 9b07c4b..60c56df 100644 --- a/.vscode/vscode.md +++ b/.vscode/vscode.md @@ -7,7 +7,8 @@ - [Fonts](#fonts) - [Navigation](#navigation) - [Extensions](#extensions) - - [Continue](#continue) + - [Continue](#continue) + - [Pylance Type Checking](#pylance-type-checking) ## Debugpy Snippet @@ -117,18 +118,10 @@ To install that list of extensions run: cat vscode_extensions.txt | xargs -L 1 code --install-extension ``` -## Continue +### Continue -```json -{ - "models": [ - { - "title": "qwen2.5-coder:32b", - "provider": "ollama", - "apiBase": "https://ollama.example.com", - "apiKey": "...", - "model": "qwen2.5-coder:32b" - } - ], -... -``` +Continue -> Settings -> Help -> Quickstart + +### Pylance Type Checking + +Settings -> `python.analysis.typeChecking` \ No newline at end of file diff --git a/active/device_bambu_p1s/bambu_p1s.md b/active/device_bambu_p1s/bambu_p1s.md index 2f466cb..07c5ebc 100644 --- a/active/device_bambu_p1s/bambu_p1s.md +++ b/active/device_bambu_p1s/bambu_p1s.md @@ -8,6 +8,16 @@ If you want to set up WiFi without logging in follow this: +1. Create a new file on the printer's SD card named `user_wifi.cfg` +2. Add the following contents to `user_wifi.cfg`: + + ```text + ssid:FruitTest08 + password:wikitest12 + ``` + +3. Put the SD card back in the printer. It should connect automatically. + ### Connecting via LAN mode - Make sure you open 1990 and 2021 (tcp + udp) in your firewall application. diff --git a/active/os_fedora/fedora-apps.md b/active/os_fedora/fedora-apps.md index 39f5f51..a2c3d83 100644 --- a/active/os_fedora/fedora-apps.md +++ b/active/os_fedora/fedora-apps.md @@ -46,6 +46,7 @@ - [GHex](#ghex) - [KDiskMark](#kdiskmark) - [Local Send](#local-send) + - [Evolution](#evolution) Flatpak installs are from Flathub unless otherwise noted. @@ -498,4 +499,12 @@ Send anywhere used to be so cool. Unrelated, but I loved that app back in like 2 ```bash flatpak install org.localsend.localsend_app +``` + +## Evolution + +You still use email? I still use email. + +```bash +flatpak install org.gnome.Evolution ``` \ No newline at end of file diff --git a/active/os_fedora/fedora-kinoite.md b/active/os_fedora/fedora-kinoite.md index 055ae92..284edf8 100644 --- a/active/os_fedora/fedora-kinoite.md +++ b/active/os_fedora/fedora-kinoite.md @@ -7,6 +7,8 @@ - [rpm-ostree](#rpm-ostree) - [Git, Vim, etc](#git-vim-etc) - [Libvirt, Qemu, KVM](#libvirt-qemu-kvm) + - [ROCM](#rocm) + - [Ollama](#ollama) - [Network](#network) - [Hostname](#hostname) - [VLAN Setup with nmcli](#vlan-setup-with-nmcli) @@ -133,6 +135,74 @@ rpm-ostree install virt-manager libvirt systemctl enable --now libvirtd ``` +### ROCM + +Credit to: + + +Here are most of the ROCM packages that you'll need. + +Fedora is currently working on a ROCM meta package here: + + +```bash +rpm-ostree install \ +hipblas-devel \ +hipblaslt-devel \ +hipcc \ +hipcc-libomp-devel \ +hipcub-devel \ +hipfft-devel \ +hipfort-devel \ +hiprand-devel \ +hiprt-devel \ +hipsolver-devel \ +hipsparse-devel \ +rocalution-devel \ +rocblas-devel \ +rocfft-devel \ +rocm-clang-devel \ +rocm-clang-tools-extra-devel \ +rocm-cmake \ +rocm-comgr-devel \ +rocm-core-devel \ +rocm-hip-devel \ +rocm-libc++-devel \ +rocm-libc++-static \ +rocm-llvm-devel \ +rocm-omp-devel \ +rocm-runtime-devel \ +rocm-rpp-devel \ +rocm-smi-devel \ +rocminfo \ +rocdecode-devel \ +rocjpeg-devel \ +rocprim-devel \ +rocrand-devel \ +rocsolver-devel \ +rocsparse-devel \ +rocthrust-devel \ +roctracer-devel \ +miopen +``` + +### Ollama + + + +Run the installation script as normal. Make sure you have the [ROCM](#rocm) drivers installed +for GPU acceleration. The script *should* automatically pull the ROCM drivers after installing +the base packages. If not, you should install them manually. + +For starting ollama as a service, follow the link below with one exception. + + + +```bash +# Change the recommended home dir to /var/home/ollama +sudo useradd -r -s /bin/false -U -m -d /var/home/ollama ollama +``` + ## Network ### Hostname @@ -178,7 +248,7 @@ 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.mode.2560x1600@165 \ output.eDP-2.scale.1.25 # Show on Roku TV and Monitor diff --git a/active/os_fedora/fedora.md b/active/os_fedora/fedora.md index 7c1bf00..b65143c 100644 --- a/active/os_fedora/fedora.md +++ b/active/os_fedora/fedora.md @@ -4,12 +4,29 @@ - [Framework 16 Fixes](#framework-16-fixes) - [Wake from Sleep](#wake-from-sleep) - [Wrong keys pressed in the browser](#wrong-keys-pressed-in-the-browser) + - [Fix wifi disconnecting and reconnecting repeatedly on reboot/resume](#fix-wifi-disconnecting-and-reconnecting-repeatedly-on-rebootresume) - [Wifi Powersave](#wifi-powersave) - [Podman](#podman) - [Autostarting services with quadlets](#autostarting-services-with-quadlets) + - [Toolbox](#toolbox) - [Network](#network) - [VLAN Setup with nmcli](#vlan-setup-with-nmcli) - [ZRAM](#zram) + - [Libraries](#libraries) + - [DNF](#dnf) + - [Apps](#apps) + - [DNF](#dnf-1) + - [VSCode](#vscode) + - [Virtualization](#virtualization) + - [NVM](#nvm) + - [Ollama](#ollama) + - [UV](#uv) + - [Pipenv](#pipenv) + - [Backups](#backups) + - [BTRFS Snapshots](#btrfs-snapshots) + - [ROCM](#rocm) + - [Display](#display) + - [Scripted Display Modes](#scripted-display-modes) ## Framework 16 Fixes @@ -39,6 +56,30 @@ sudo udevadm control --reload-rules && sudo udevadm trigger Sometimes keys will stop working when using search bars or do strange things like move the page around. This seems to be caused by some "alt" keypress combination. Pressing "alt" twice fixes it. +### Fix wifi disconnecting and reconnecting repeatedly on reboot/resume + +Create a file in `/etc/systemd/system/reset-iwlwifi.service` with the following content: + +```conf +[Unit] +Description=Reload iwlwifi on wake-up +After=suspend.target +After=multi-user.target + +[Service] +ExecStartPre=rmmod iwlmvm iwlwifi +ExecStart=modprobe iwlwifi + +[Install] +WantedBy=suspend.target +WantedBy=multi-user.target +``` + +```bash +systemctl daemon-reload +systemctl enable reset-iwlwifi.service +``` + ### Wifi Powersave **NOTE: THIS DOESN'T WORK. IT CAUSES WIFI DISCONNECT AND RECONNECT ISSUES.** @@ -102,6 +143,13 @@ systemctl --user daemon-reload systemctl --user start ollama ``` +## Toolbox + +```bash +toolbox create +toolbox enter +``` + ## Network ### VLAN Setup with nmcli @@ -128,3 +176,218 @@ zramctl -r /dev/zram0 # Set a new size zramctl --size 4G /dev/zram0 ``` + +## Libraries + +### DNF + +```bash +sudo dnf install -y \ +make \ +gcc \ +zlib-devel \ +bzip2 \ +bzip2-devel \ +readline-devel \ +sqlite \ +sqlite-devel \ +openssl-devel \ +tk-devel \ +libffi-devel \ +xz-devel \ +libgle-devel +``` + +## Apps + +### DNF + +```bash +sudo dnf install \ + # Advanced text editor for code editing and other tasks. + vim \ + # Network bandwidth measuring tool. + iperf3 \ + # Command-line interface for managing Kubernetes clusters. + kubectl \ + # Package manager and deployment tool for Kubernetes. + helm \ + # Utility to monitor real-time network usage of processes. + nethogs \ + # DevOps configuration management tool. + ansible \ + # Terminal multiplexer. + tmux \ + # Multimedia player with support for a wide range of codecs and file formats. + ffmpeg \ + # Microsoft Windows compatibility layer. + wine \ + # Archive utility similar to GNU tar, used to package files into single archive files. + unzip \ + # A terminal activity monitor (top clone). + btop \ + # Command-line JSON processor. + jq \ + # YAML-based configuration-as-code tool for command-line interfaces written in Go, Rust, Python, and more. + yq \ + # An image manipulation software suite based on ImageMagick. + ImageMagick \ + # The Go programming language environment including a toolchain (gc) and libraries. + go \ + # Rust package manager and compiler installation utility. + rust rustup \ + # Distributed version control system, Git extension that adds support for large files like multimedia assets. + git git-lfs \ + # Provides traditional network tools such as ifconfig, netstat, hostname, etc., in a single package. + net-tools \ + # Document conversion tool and markup language converter. + pandoc \ + # Comprehensive LaTeX distribution for high-quality typesetting of documents. + texlive-latex \ + # Generate strong passwords. + pwgen \ + # Reattach to running processes + reptyr \ + # Netcat, for basic tcp/udp operations + netcat \ + # 7zip support + p7zip +``` + +### VSCode + + + +### Virtualization + +```bash +# Virtualization +sudo dnf group install --with-optional virtualization +``` + +### NVM + + + +### Ollama + + + +Run the installation script as normal. Make sure you have the [ROCM](#rocm) drivers installed +for GPU acceleration. The script *should* automatically pull the ROCM drivers after installing +the base packages. If not, you should install them manually. + +For starting ollama as a service, follow the link below: + + + +### UV + + + +### Pipenv + + + +## Backups + +### BTRFS Snapshots + + + + + +We'll be using snapper, a tool for automating and controlling snapshot behavior. + +```bash +dnf install snapper dnf-plugin-snapper + +# Allow selinux management +semanage permissive -a snapperd_t + +# Note, if you mess something up you can run snapper -c root delete-config to delete +# System configs are stored in /etc/sysconfig/snapper as well as /etc/snapper +snapper -c root create-config / +snapper -c data create-config /path/to/other/data + +# Enable automatic snapshots +systemctl enable --now snapper-timeline.timer +# Enable automatic cleanup +systemctl enable --now snapper-cleanup.timer +# Enable snapshots on boot +systemctl enable --now snapper-boot.timer + +# List snapshots +snapper -c root list +# Create snapshot manually +snapper -c root create --description "test snapshot" +# Delete first snapshot +snapper -c root delete 1 +``` + +Note - you probably don't want to keep yearly snapshots. +Edit `/etc/snapper/configs/root` and change `TIMELINE_LIMIT_YEARLY=` to `0`. + +## ROCM + +```bash +sudo dnf install \ +hipblas-develhipblaslt-devel \ +hipcc \ +hipcc-libomp-devel \ +hipcub-devel \ +hipfft-devel \ +hipfort-devel \ +hiprand-devel \ +hiprt-devel \ +hipsolver-devel \ +hipsparse-devel \ +rocalution-devel \ +rocblas-devel \ +rocfft-devel \ +rocm-clang-devel \ +rocm-clang-tools-extra-devel \ +rocm-cmake \ +rocm-comgr-devel \ +rocm-core-devel \ +rocm-hip-devel \ +rocm-libc++-devel \ +rocm-libc++-static \ +rocm-llvm-devel \ +rocm-omp-devel \ +rocm-runtime-devel \ +rocm-rpp-devel \ +rocm-smi-devel \ +rocminfo \ +rocdecode-devel \ +rocjpeg-devel \ +rocprim-devel \ +rocrand-devel \ +rocsolver-devel \ +rocsparse-devel \ +rocthrust-devel \ +roctracer-devel \ +miopen +``` + +## Display + +### Scripted Display Modes + +Put something like these in `~/.bashrc.d/screen.sh` + +```bash +alias screen-reset='kscreen-doctor \ +output.eDP-2.enable \ +output.eDP-2.position.0,0 \ +output.eDP-2.primary \ +output.eDP-2.mode.2560x1600@165 \ +output.eDP-2.scale.1.25' + +alias screen-1080='kscreen-doctor \ +output.eDP-2.enable \ +output.eDP-2.position.0,0 \ +output.eDP-2.primary \ +output.eDP-2.mode.1920x1080@165 \ +output.eDP-2.scale.1' +``` \ No newline at end of file diff --git a/active/os_fedora/screen-scripts/screen-1080 b/active/os_fedora/screen-scripts/screen-1080 new file mode 100644 index 0000000..3b34695 --- /dev/null +++ b/active/os_fedora/screen-scripts/screen-1080 @@ -0,0 +1,8 @@ +#!/bin/bash + +kscreen-doctor \ +output.eDP-2.enable \ +output.eDP-2.position.0,0 \ +output.eDP-2.primary \ +output.eDP-2.mode.1920x1080@60 \ +output.eDP-2.scale.1 \ No newline at end of file diff --git a/active/os_fedora/screen-scripts/screen-reset b/active/os_fedora/screen-scripts/screen-reset new file mode 100644 index 0000000..0e5144b --- /dev/null +++ b/active/os_fedora/screen-scripts/screen-reset @@ -0,0 +1,8 @@ +#!/bin/bash + +kscreen-doctor \ +output.eDP-2.enable \ +output.eDP-2.position.0,0 \ +output.eDP-2.primary \ +output.eDP-2.mode.2560x1600@165 \ +output.eDP-2.scale.1.25 \ No newline at end of file diff --git a/active/os_truenas/truenas.md b/active/os_truenas/truenas.md index 168de3e..7f5590f 100644 --- a/active/os_truenas/truenas.md +++ b/active/os_truenas/truenas.md @@ -202,7 +202,7 @@ If you want to delete every snapshot: tmux # This pool you want to clean up -export POOL=enc0 +export POOL=backup0 # This can be anything, set it to something memorable export SNAPSHOTS_FILE=enc0_mar2025_snapshots.txt diff --git a/active/software_bash/bash.md b/active/software_bash/bash.md new file mode 100644 index 0000000..da61e94 --- /dev/null +++ b/active/software_bash/bash.md @@ -0,0 +1,101 @@ +# Bash Tips + +- [Bash Tips](#bash-tips) + - [bashrc](#bashrc) + - [Eternal History](#eternal-history) + - [Global bashrc](#global-bashrc) + - [User Environment](#user-environment) + - [User Aliases](#user-aliases) + - [Check if executable exists](#check-if-executable-exists) + - [Check if file exists](#check-if-file-exists) + - [Check if last command exit code was zero](#check-if-last-command-exit-code-was-zero) + +## bashrc + +### Eternal History + +```bash +# Eternal bash history. +# --------------------- +# Undocumented feature which sets the size to "unlimited". +# http://stackoverflow.com/questions/9457233/unlimited-bash-history +export HISTFILESIZE=-1 +export HISTSIZE=-1 +export HISTTIMEFORMAT="[%F %T] " +# Change the file location because certain bash sessions truncate .bash_history file upon close. +# http://superuser.com/questions/575479/bash-history-truncated-to-500-lines-on-each-login +export HISTFILE=~/.bash_eternal_history +# Force prompt to write history after every command. +# http://superuser.com/questions/20900/bash-history-loss +PROMPT_COMMAND="history -a; $PROMPT_COMMAND" +``` + +### Global bashrc + +```bash +# Source global definitions +if [ -f /etc/bashrc ]; then + . /etc/bashrc +fi +``` + +### User Environment + +```bash +# User specific environment +if ! [[ "$PATH" =~ "$HOME/.local/bin:$HOME/bin:" ]]; then + PATH="$HOME/.local/bin:$HOME/bin:$PATH" +fi +export PATH +``` + +### User Aliases + +Allows custom aliases in ~/.bashrc.d + +```bash +# User specific aliases and functions +if [ -d ~/.bashrc.d ]; then + for rc in ~/.bashrc.d/*; do + if [ -f "$rc" ]; then + . "$rc" + fi + done +fi +unset rc +``` + +## Check if executable exists + +```bash +if command -v aws 2>&1 >/dev/null +then + echo "aws command found" +else + echo "aws could not be found" +fi +``` + +## Check if file exists + +```bash +FILE=/etc/resolv.conf +if [ -f "$FILE" ]; then + echo "$FILE exists." +else + echo "$FILE does not exist." +fi +``` + +## Check if last command exit code was zero + +```bash +cat /i/do/not/exit + +if [ $? -eq 0 ] +then + echo "Success." +else + echo "Failure." >&2 +fi +``` \ No newline at end of file diff --git a/active/systemd_borg/borg.md b/active/systemd_borg/borg.md index 97ba516..57064b2 100644 --- a/active/systemd_borg/borg.md +++ b/active/systemd_borg/borg.md @@ -5,6 +5,7 @@ - [Adding a Client](#adding-a-client) - [Installing the Backup Service](#installing-the-backup-service) - [Adding Nextcloud](#adding-nextcloud) + - [Manual Client Use](#manual-client-use) ## Server Setup @@ -111,4 +112,48 @@ Rather than creating a client, just set the borg backup location to: backup@borg.reeselink.com:nextcloud ``` -Then run the backup. It will generate a pubkey. Copy this into the authorized_keys file. \ No newline at end of file +Then run the backup. It will generate a pubkey. Copy this into the authorized_keys file. + +## Manual Client Use + +```bash +borg list borg.reeselink.com:home + +# Do not include the first / in the path +export PATH_TO_BACKUP=var/home/ducoterra +export BORG_REPO=borg.reeselink.com:home + +# If not initialized, do that now +borg init --encryption none $BORG_REPO + +# Run backup and timestamp it +borg create \ +--verbose \ +--filter AME \ +--list \ +--stats \ +--progress \ +--show-rc \ +--compression lz4 \ +--exclude-caches \ +-e "pp:/${PATH_TO_BACKUP}/.cache" \ +-e "re:^${PATH_TO_BACKUP}/\.var/app/[^/]+/cache/" \ +-e "CACHEDIR.TAG" \ +-e "pp:/${PATH_TO_BACKUP}/.local/share/gnome-boxes" \ +-e "pp:/${PATH_TO_BACKUP}/.var/app/org.gnome.Boxes" \ +-e "pp:/${PATH_TO_BACKUP}/.var/app/org.gnome.BoxesDevel" \ +-e "pp:/${PATH_TO_BACKUP}/.local/share/bottles" \ +-e "pp:/${PATH_TO_BACKUP}/.var/app/com.usebottles.bottles" \ +-e "pp:/${PATH_TO_BACKUP}/.local/share/libvirt" \ +-e "pp:/${PATH_TO_BACKUP}/.config/libvirt" \ +-e "pp:/${PATH_TO_BACKUP}/.local/share/containers" \ +-e "pp:/${PATH_TO_BACKUP}/.local/share/docker" \ +${BORG_REPO}::$(date +"%F-%H-%M-%S") \ +/${PATH_TO_BACKUP} + +# Mount a borg archive +borg mount $BORG_REPO::2025-05-14-00-44-05 /mnt/ + +# Restore a borg archive to a location (dry run) +borg extract --dry-run --list --strip-components 1 $BORG_REPO::my-files home/USERNAME +``` \ No newline at end of file diff --git a/active/systemd_stablediffusion/stablediffusion.md b/active/systemd_stablediffusion/stablediffusion.md index 1c896f0..06123ba 100644 --- a/active/systemd_stablediffusion/stablediffusion.md +++ b/active/systemd_stablediffusion/stablediffusion.md @@ -4,6 +4,8 @@ +### Arch Linux + ```bash sudo pacman -S python-pytorch-rocm @@ -21,8 +23,33 @@ pip install -r requirements.txt # Check https://download.pytorch.org/whl/nightly/torch/ for versions # Specifically you want the "rocm" versions for AMD # Just copy the "torch-2.6.0.dev20241205+rocm6.2.4" part -pip install torch==2.6.0.dev20241205+rocm6.2.4 --index-url https://download.pytorch.org/whl/nightly -pip install torchvision==0.20.0.dev20241207+rocm6.2.4 --index-url https://download.pytorch.org/whl/nightly +pip install torch==2.8.0.dev20250520+rocm6.4 --index-url https://download.pytorch.org/whl/nightly +pip install torchvision==0.22.0.dev20250520+rocm6.4--index-url https://download.pytorch.org/whl/nightly + +./webui.sh +``` + +### Fedora + +```bash +toolbox create +toolbox enter +``` + +```bash +sudo dnf install -y \ +libgle-devel + +uv venv venv --seed +source venv/bin/activate + +# We need to replace the torch/pytorch versions with amd compatible ones. +# Check https://download.pytorch.org/whl/nightly/torch/ for torch +# Check https://download.pytorch.org/whl/torchvision/ for torchvision +# Specifically you want the "rocm" versions for AMD +# Just copy the "torch-2.6.0.dev20241205+rocm6.2.4" part +pip install torch==2.8.0.dev20250520+rocm6.4 --index-url https://download.pytorch.org/whl/nightly +pip install torchvision==0.22.0.dev20250520+rocm6.4 --index-url https://download.pytorch.org/whl/nightly ./webui.sh ``` @@ -38,6 +65,10 @@ pip install torchvision==0.20.0.dev20241207+rocm6.2.4 --index-url https://downlo +### SD3.5 + + + ### Flux AI - You must use Stable Diffusion WebUI Forge @@ -46,6 +77,16 @@ pip install torchvision==0.20.0.dev20241207+rocm6.2.4 --index-url https://downlo +This is working as of 5/12/25: + + + +#### Low VRAM + + + +Generate 512x512 images. + ## Nginx ```bash diff --git a/active/systemd_wyoming/install_wyoming.yaml b/active/systemd_wyoming/install_wyoming.yaml index 093c343..1f6b989 100644 --- a/active/systemd_wyoming/install_wyoming.yaml +++ b/active/systemd_wyoming/install_wyoming.yaml @@ -1,4 +1,4 @@ -- name: Create Backup Service +- name: Install or Update the Wyoming Service hosts: wyoming vars_files: - secrets/vars.yaml diff --git a/active/systemd_wyoming/vars.yaml b/active/systemd_wyoming/vars.yaml index 9b516f6..c844629 100644 --- a/active/systemd_wyoming/vars.yaml +++ b/active/systemd_wyoming/vars.yaml @@ -4,9 +4,8 @@ wyoming: repo: https://github.com/rhasspy/wyoming-satellite.git listen_ip: 0.0.0.0 listen_port: 10700 - mic_auto_gain: 5 + mic_auto_gain: 31 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 diff --git a/active/systemd_wyoming/wyoming.md b/active/systemd_wyoming/wyoming.md index d5a3150..17d534a 100644 --- a/active/systemd_wyoming/wyoming.md +++ b/active/systemd_wyoming/wyoming.md @@ -1,7 +1,11 @@ # Wyoming Satellite - [Wyoming Satellite](#wyoming-satellite) + - [Data Flow](#data-flow) - [Install Wyoming](#install-wyoming) + - [Hardware](#hardware) + - [Bluetooth keepalive](#bluetooth-keepalive) + - [Bluetooth autoconnect](#bluetooth-autoconnect) - [On-device wake word](#on-device-wake-word) - [Systemd](#systemd) - [Debugging](#debugging) @@ -11,26 +15,47 @@ - [Default](#default) - [Starship House](#starship-house) +## Data Flow + +```mermaid +sequenceDiagram + actor us as User + participant mic as Listening Device + participant ww as Wake Word Model + participant ha as Home Assistant + participant stt as Speech to Text + participant tts as Text to Speech + participant ai as LLM Tool Caller + us ->> mic: Say wakeword + mic ->> ww: Are you > x% confident the wake word was detected? + break When mic didn't detect wake word + ww ->> mic: No + mic ->> mic: keep listening + end + ww ->> mic: Yes + mic ->> us: "listening sound" + us ->> mic: Say request + mic ->> ha: Send audio to Home Assistant + ha ->> stt: Convert this speech to text + stt ->> ha: Here's the text + ha ->> mic: The user is done talking, here's what was said + mic ->> us: "done listening sound" + ha ->> ha: Did the text match any known intent? + alt Yes + ha ->> ha: Do the thing the intent is supposed to do + ha ->> tts: Turn the reply text into speech + tts ->> ha: here's the audio clip + ha ->> mic: play this audio clip + mic ->> user: audio clip + else No + ha ->> ai: Send entities exposed by Home Assistant, TTS, and "Can you figure this out?" + end +``` + ## Install Wyoming -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 @@ -53,6 +78,121 @@ script/run \ --threshold 0.9 ``` +## Hardware + +Finding available speakers/microphones + +```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 + +# Change audio levels +alsamixer + +# Save audio levels +sudo alsactl store +``` + +Bluetooth + +```bash +bluetoothctl +discoverable on +pairable on +agent on +default-agent +scan on +``` + +Then wait for `[NEW] Device 12:23:34:45:56:67 devicename` + +```bash +pair 12:23:34:45:56:67 +``` + +The bluetooth speaker should now work with `aplay`. + +### Bluetooth keepalive + +Bluetooth speakers have a tendency to sleep and then take a bit to wake up. We can force +them to stay alive permanently by constantly playing an inaudible sound onloop. + +```bash +# generate our 48000kHz sample rate synth 1 second sin 10hz wave file at -20dB so it's quiet +# This takes some tweaking depending on the speaker. A 1hz wave didn't work on my bluetooth speaker, +# but 10hz did. +sudo sox -V -r 48000 -n -b 16 -c 2 /usr/share/sounds/silence.wav synth 1 sin 10 vol -20dB + +# Copy that to /usr/share/sounds +sudo cp silence.wav /usr/share/sounds +``` + +Create a script at `/usr/local/bin/speakeralive.sh` + +```bash +#!/bin/bash +while true; do aplay /usr/share/sounds/silence.wav; done +``` + +Then create a systemd service at `~/.config/systemd/user/speakeralive.service` + +```conf +[Unit] +Description=Plays an inaudible noise continuously to keep a speaker alive +After=network.target +Wants=network-online.target + +[Service] +Restart=always +Type=simple +ExecStart=/usr/local/bin/speakeralive.sh + +[Install] +WantedBy=bluetooth.target +``` + +And enable the service + +```bash +systemctl --user enable --now speakeralive +``` + +### Bluetooth autoconnect + +In order to automatically connect a bluetooth speaker at boot you'll need a oneshot service + +Create `~/.config/systemd/user/speakerconnect.service` + +```conf +[Unit] +Description=Connects a bluetooth speaker on boot +After=bluetooth.target + +[Service] +Restart=on-failure +Type=oneshot +RestartSec=5 +ExecStart=bluetoothctl connect A1:B2:C3:D4... + +[Install] +WantedBy=bluetooth.target +``` + +Enable it + +```bash +systemctl --user enable --now speakerconnect.service +``` + ## On-device wake word diff --git a/active/systemd_wyoming/wyoming.service b/active/systemd_wyoming/wyoming.service index 694f744..98f3dc2 100644 --- a/active/systemd_wyoming/wyoming.service +++ b/active/systemd_wyoming/wyoming.service @@ -8,8 +8,8 @@ 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' \ +--mic-command 'arecord -r 16000 -c 1 -f S16_LE -t raw {% if hostvars[inventory_hostname].mic_device %}-D {{hostvars[inventory_hostname].mic_device}}{% endif %}' \ +--snd-command 'aplay -r 22050 -c 1 -f S16_LE -t raw {% if hostvars[inventory_hostname].speaker_device %}-D {{hostvars[inventory_hostname].speaker_device}}{% endif %}' \ --awake-wav sounds/listening.wav \ --done-wav sounds/finished.wav \ --timer-finished-wav sounds/timer_finished.wav \ diff --git a/ansible/inventory.yaml b/ansible/inventory.yaml index e7dfa57..2bfd18c 100644 --- a/ansible/inventory.yaml +++ b/ansible/inventory.yaml @@ -18,8 +18,10 @@ caddy: wyoming: hosts: pink-rpi.reeselink.com: - mic_volume_multiplier: 2 + mic_volume_multiplier: 1 + mic_device: plughw:CARD=ArrayUAC10,DEV=0 + speaker_device: "" red-rpi.reeselink.com: - mic_volume_multiplier: 2 - rpi5.reeselink.com: - mic_volume_multiplier: 8 \ No newline at end of file + mic_volume_multiplier: 1 + mic_device: plughw:CARD=ArrayUAC10,DEV=0 + speaker_device: plughw:CARD=Speaker,DEV=0 \ No newline at end of file