ProtoBoksi ohje

Raspberry Pi 3 äänisatelliitiksi Home Assistantiin

Tässä ohjeessa rakennetaan Raspberry Pi 3 A+ -kortista Home Assistantin äänisatelliitti. Tavoitteena on korvata kaupallinen älykaiutin omalla, paikallisemmalla ratkaisulla.

Raspberry Pi toimii mikrofonina ja kaiuttimena. Home Assistant hoitaa puheohjauksen. Pelikoneella pyörivä paikallinen tekoälymalli voi halutessa toimia älykkäämpänä keskusteluagenttina.

Tämä ohje syntyi vähän nurinkurin. Ensin tehtiin toimiva prototyyppi, ja video tulee joskus myöhemmin.

  • Raspberry Pi käynnistyy automaattisesti.
  • Herätesana toimii.
  • Home Assistant vastaa.
  • Valot saa päälle puheella.
  • Alexa saa lähteä eläkkeelle.

Lähtötilanne

Minulla oli ennestään Raspberry Pi 3 Model A+. ESP32-pohjaisten äänisatelliittien kanssa oli tullut säädettyä jo sen verran, että päätin kokeilla väliin Raspberry Pi -ratkaisua.

Raspberryllä äänen kanssa säätäminen on helpompaa, koska käytössä on normaali Linux-audio.

Käytössä tässä testissä

  • Raspberry Pi 3 Model A+
  • Raspberry Pi OS Lite 64-bit
  • HyperX Quadcast USB-mikrofoni
  • Home Assistant
  • Wyoming Satellite
  • wyoming-openwakeword
  • Herätesana: Alexa
  • Paikallinen LLM-agentti testissä pelikoneella

Lopputulos: komento Alexa, turn on living room lights toimii, ja olohuoneen valot menevät päälle.

Raspberry Pi OS

Raspberry Pi:lle asennettiin Raspberry Pi OS Lite 64-bit.

Raspberry Pi Imagerissa kannattaa laittaa heti valmiiksi SSH, Wi-Fi, käyttäjätunnus, hostname ja timezone.

SSH-yhteys
ssh protoboksi@voice-satellite.local
Päivitykset
sudo apt update && sudo apt upgrade -y
Tarkista Raspberryn malli
cat /proc/device-tree/model

Minulla tulos oli:

Raspberry Pi 3 Model A Plus Rev 1.0

Äänilaitteiden tarkistus

USB-mikrofoni kiinni Raspberry Pi:hin.

Nauhoituslaitteet
arecord -l
Toistolaitteet
aplay -l

Minulla HyperX Quadcast näkyi esimerkiksi näin:

card 2: Quadcast [HyperX Quadcast], device 0: USB Audio [USB Audio]

Korttinumeroon ei kannata luottaa. plughw:2,0 voi muuttua uudelleenkäynnistyksen jälkeen. Käytä pysyvämpää laitenimeä.

Pysyvämpi laitenimi
arecord -L

Minulla oikea laitenimi oli:

plughw:CARD=Quadcast,DEV=0

Äänitesti

Pysäytä satelliittipalvelu, jos se on jo päällä:

sudo systemctl stop wyoming-satellite.service

Tallenna testipätkä:

arecord -D plughw:CARD=Quadcast,DEV=0 -f S16_LE -r 16000 -c 1 -d 5 test.wav

Toista se Raspberryn kuulokeliitännästä:

aplay -D plughw:0,0 test.wav

Tarvittavat paketit

sudo apt install -y python3-venv python3-pip git alsa-utils

Wyoming Satellite

Asennus
cd ~
git clone https://github.com/rhasspy/wyoming-satellite.git
cd wyoming-satellite
script/setup
Käsin testi
script/run \
  --name "ProtoBoksi Satellite" \
  --uri tcp://0.0.0.0:10700 \
  --mic-command "arecord -D plughw:CARD=Quadcast,DEV=0 -r 16000 -c 1 -f S16_LE -t raw" \
  --snd-command "aplay -D plughw:0,0 -r 22050 -c 1 -f S16_LE -t raw"

Jos kaikki toimii, lokissa näkyy suunnilleen:

INFO:root:Ready
INFO:root:Connected to services
Recording raw data 'stdin' : Signed 16 bit Little Endian, Rate 16000 Hz, Mono

Home Assistant

Home Assistantissa lisätään integraatio:

Settings → Devices & services → Add integration → Wyoming Protocol

Osoite ja portti:

voice-satellite.local
10700

Wyoming Satellite palveluksi

sudo nano /etc/systemd/system/wyoming-satellite.service
[Unit]
Description=Wyoming Satellite
After=network-online.target wyoming-openwakeword.service
Wants=network-online.target wyoming-openwakeword.service
Requires=wyoming-openwakeword.service

[Service]
Type=simple
User=protoboksi
WorkingDirectory=/home/protoboksi/wyoming-satellite
ExecStartPre=/bin/sleep 10
ExecStart=/home/protoboksi/wyoming-satellite/script/run --name "ProtoBoksi Satellite" --uri tcp://0.0.0.0:10700 --mic-command "arecord -D plughw:CARD=Quadcast,DEV=0 -r 16000 -c 1 -f S16_LE -t raw" --snd-command "aplay -D plughw:0,0 -r 22050 -c 1 -f S16_LE -t raw" --wake-uri tcp://127.0.0.1:10400 --wake-word-name alexa
Restart=always
RestartSec=5

[Install]
WantedBy=multi-user.target

Muuta User=protoboksi ja polut, jos Raspberryllä on eri käyttäjätunnus.

openWakeWord

Asennus
cd ~
git clone https://github.com/rhasspy/wyoming-openwakeword.git
cd wyoming-openwakeword
script/setup
Käsin testi
script/run --uri tcp://0.0.0.0:10400 --preload-model alexa

Jos lokiin tulee INFO:root:Ready, malli toimii.

Pysäytä testi komennolla Ctrl + C.

openWakeWord palveluksi

sudo nano /etc/systemd/system/wyoming-openwakeword.service
[Unit]
Description=Wyoming openWakeWord
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
User=protoboksi
WorkingDirectory=/home/protoboksi/wyoming-openwakeword
ExecStart=/home/protoboksi/wyoming-openwakeword/script/run --uri tcp://127.0.0.1:10400 --preload-model alexa
Restart=always
RestartSec=5

[Install]
WantedBy=multi-user.target

Miksi 0.0.0.0 ja 127.0.0.1?

Tämä oli yksi kohta, jossa tuli itsekin sotkettua hetki.

Palvelu Osoite Miksi?
Wyoming Satellite HA:lle 0.0.0.0:10700 Home Assistantin pitää päästä Raspberryyn verkon yli.
openWakeWord 127.0.0.1:10400 Wake word -palvelua tarvitaan vain samalla Raspberryllä.
Satellite → wake service 127.0.0.1:10400 Satelliitti kysyy herätesanan tunnistuksen paikalliselta palvelulta.

Älä käytä osoitetta 127.0.0.0. Oikea paikallinen osoite on 127.0.0.1.

Palveluiden käynnistys

sudo systemctl daemon-reload
sudo systemctl enable wyoming-openwakeword.service
sudo systemctl enable wyoming-satellite.service

Käynnistä järjestyksessä:

sudo systemctl start wyoming-openwakeword.service
sleep 10
sudo systemctl start wyoming-satellite.service

Tarkista tila:

sudo systemctl status wyoming-openwakeword.service
sudo systemctl status wyoming-satellite.service

Tarkista satelliitin loki:

journalctl -u wyoming-satellite.service -n 50 --no-pager

Hyvässä tilanteessa näkyy:

INFO:root:Ready
INFO:root:Connected to services
INFO:root:Connected to server
INFO:root:Waiting for wake word

Testi

Sano:

Alexa

Sitten:

What time is it?

Jos Home Assistant vastaa, perusketju toimii.

Seuraavaksi kannattaa testata laiteohjausta:

Alexa, turn on living room lights.

Vikatilanteet

Failed to get info from wake service

Jos lokissa näkyy:

Failed to get info from wake service

tai:

ConnectionRefusedError: Connect call failed ('127.0.0.1', 10400)

satelliitti ei saa yhteyttä openWakeWord-palveluun.

Tarkista kuunteleeko portti:

ss -ltnp | grep 10400

Hyvä tulos on esimerkiksi:

LISTEN 0 100 127.0.0.1:10400

Mikki on varattu

Jos arecord antaa virheen:

audio open error: Device or resource busy

Wyoming Satellite käyttää mikkiä jo. Pysäytä satelliitti ennen äänitestiä:

sudo systemctl stop wyoming-satellite.service

Käynnistä takaisin:

sudo systemctl start wyoming-satellite.service

Portti on jo käytössä

Jos käsin käynnistäessä tulee:

address already in use 0.0.0.0:10700

satelliitti pyörii jo taustalla servicenä.

sudo systemctl stop wyoming-satellite.service

Tarvittaessa tapa porttia käyttävä prosessi:

sudo fuser -k 10700/tcp
sudo fuser -k 10400/tcp

Alexa herätesanana

Herätesanaksi valittiin alexa, koska sitä on jo totuttu käyttämään.

openWakeWord-palvelussa:

--preload-model alexa

satelliittipalvelussa:

--wake-word-name alexa

Nämä pitää olla samat.

Yleisiä vaihtoehtoja ovat esimerkiksi:

ok_nabu
hey_jarvis
hey_mycroft
hey_rhasspy
alexa

Home Assistantin puoli

Kun satelliitti näkyy Home Assistantissa, sille valitaan Assist-pipeline. Minulla käyttö alkoi toimia paljon paremmin englanniksi.

Suomenkielinen Assist kyllä toimii teknisesti, mutta komennot pitää sanoa välillä liian tarkasti.

Esimerkki ongelmasta:

Okei Nabu, laita kattovalo päälle

saattoi tulkita entiteetiksi:

laita kattovalo

Englanniksi sama asia toimii luonnollisemmin:

Alexa, turn on living room lights.

Paikallinen tekoäly pelikoneella

Tässä testissä ideana oli käyttää pelikoneella pyörivää paikallista LLM-mallia Home Assistantin conversation agenttina. Raspberry Pi ei siis aja tekoälymallia.

Raspberry Pi
korva, suu, herätesana ja Wyoming-satelliitti

Pelikone + RTX 5080
paikallinen tekoäly ja tulkinta

Tämä on hyvä testitapa ennen kuin rakentaa erillistä tekoälyserveriä.

Home Assistantin siivous on tärkeää

Tämä projekti paljasti nopeasti, että Home Assistantin nimet ja alueet pitää siivota. Tekoäly toimii paljon paremmin, jos laitteet on nimetty järkevästi.

Hyviä nimiä

Living Room
Living room ceiling light
Living room side lights
Bedroom curtains
Bedroom lights

Huonoja nimiä

switch.sonoff_100156aa41_2
Sonoff 4
Katto ledi vanha
valo ehkä

Jos Assistia käytetään englanniksi, alueet kannattaa ehkä nimetä myös englanniksi:

Living Room
Bedroom
Kitchen
Garage
Hallway

Device, Area ja Entity

Käsite Mitä tarkoittaa?
Device Fyysinen laite, esimerkiksi yksi Sonoff-laite.
Entity Laitteen yksittäinen toiminto, esimerkiksi valo, lämpötila tai rele.
Area Huone tai alue, esimerkiksi Living Room.

Yksi Sonoff-laite voi sisältää monta entityä:

Living room ceiling light
Living room side lights
Living room temperature
Outdoor temperature

Tällöin laitteen nimeksi kannattaa antaa neutraali nimi, esimerkiksi:

Living room Sonoff

Voice assistantille näkyvät laitteet

Kaikkea ei kannata antaa voice assistantille näkyviin. Aluksi kannattaa exposea vain turvalliset ja tarpeelliset asiat.

Living room lights
Bedroom lights
Bedroom curtains
Good night
Good morning

Ei kannata heti exposea koko taloa, lämminvesivaraajaa, sähköauton latausta ja kaikkia testientiteettejä. Mitä siistimpi lista, sitä paremmin tekoäly osaa valita oikean laitteen.

Skriptit ovat järkeviä

Tekoälylle kannattaa antaa valmiita skriptejä.

Good night
Good morning
Open bedroom curtains
Close bedroom curtains
Start car charging
Stop car charging

Tällöin tekoälyn ei tarvitse päättää kaikkia yksityiskohtia itse. Se vain ymmärtää mitä käyttäjä tarkoittaa ja kutsuu valmista toimintoa.

Nykyinen lopputulos

Tällä hetkellä toimiva ketju on:

Alexa-herätesana
→ Raspberry Pi 3 A+
→ wyoming-openwakeword
→ Wyoming Satellite
→ Home Assistant
→ valittu Assist pipeline
→ valot päälle

Esimerkiksi:

Alexa, turn on living room lights.

ja olohuoneen valot menevät päälle.

Mitä seuraavaksi?

Seuraavaksi pitää tehdä tästä siistimpi fyysinen laite.

  • pienempi mikrofoni
  • pieni kaiutin
  • 3D-tulostettu kotelo
  • parempi sijoitus huoneessa
  • Home Assistantin alueiden ja entityjen siivous
  • makuuhuoneen verhojen ohjaus
  • Good night / Good morning -rutiinit

Tavoite on yksinkertainen: Alexa saa lähteä eläkkeelle. Oma Home Assistant -satelliitti hoitaa kodin puheohjauksen paikallisemmin.

Lopputiivistelmä

Tämä ei ollut aluksi valmis tuote. Tämä oli säätöprojekti. Mutta lopputulos toimii.

  • Käytä mikrofonille pysyvää nimeä, ei korttinumeroa.
  • Käytä wake word -palvelulle 127.0.0.1.
  • Käytä satelliitin HA-portille 0.0.0.0.
  • Käynnistä openWakeWord ennen satelliittia.
  • Anna satelliitille pieni käynnistysviive.
  • Pidä Home Assistantin entityt ja alueet siistinä.
  • Käytä englannin kieltä, jos suomi alkaa käydä hermoille.
  • Exposea voice assistantille vain tarvittavat laitteet.
  • Skriptit tekevät tekoälyohjauksesta luotettavampaa.

Tämä oli ensimmäinen kerta, kun oma Home Assistant -äänisatelliitti alkoi tuntua oikeasti käyttökelpoiselta.