Last active
January 1, 2022 21:24
-
-
Save ChrisB85/3e3fd98493ceb2398be63e9d63271361 to your computer and use it in GitHub Desktop.
Sterowanie urządzeniami głosem w języku polskim przy użyciu Raspberry Pi, asystenta Snips i Home Assistant
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Co będzie potrzebne? | |
- Raspberry Pi (zalecane 3B lub 3B+, ale myślę, że 2 również da radę) z zainstalowanym Raspbianem | |
- Głośnik i mikrofon. Można użyć zwykłego "dongla" typu https://pupilsys.com/image/cache/catalog/Product_images/PS139/USB_soundCard-600x600.jpg z wejściem na mikrofon i wyjściem na głośniki lub przystawki typu HAT. Ja użyłem Sound Blaster SBX8, czyli głośnik i mikrofon USB w jednym (http://www.benchmark.pl/mini-recenzje/creative-sound-blaster-axx-sbx8-test.html). Jedyny problem jaki napotkałem i którego nie udało mi się przeskoczyć, to "rwanie" dźwięku (zarówno nagrywanie jak odtwarzanie) w sytuacji, kiedy system jest również na nośniku podłączonym pod USB (u mnie dysk SSD). W przypadku systemu na karcie SD wszystko jest OK. Należy również zwrócić uwagę na fakt, że głośnik ten pobiera maksymalnie 1A z portu USB. | |
1. Instalacja | |
Wykonujemy instalację zgodnie z instrukcją: https://docs.snips.ai/getting-started/quick-start-raspberry-pi (kroki 1-4). Nie opisuję tutaj tego dokładniej, bo dokumentacja ulega modyfikacjom. Podczas moich zabaw kilka rzeczy się zmieniło w "międzyczasie" (konkretnie to zostało opisane dokładniej). | |
2. Tworzenie asystenta | |
Rejestrujemy się na https://console.snips.ai, tworzymy nowy model asystenta jako język wybierając angielski. Sam proces tworzenia modelu asystenta jest dokładnie opisany na stronie https://docs.snips.ai/getting-started/quick-start-console | |
3. Obsługa języka polskiego | |
Rozpoznawanie języka polskiego (ASR): | |
Odinstalowujemy pakiet snips-asr, a następnie instalujemy snips-asr-google | |
sudo apt-get remove snips-asr | |
sudo apt-get install snips-asr-google | |
sudo systemctl restart snips-* | |
Rejestrujemy się na https://console.cloud.google.com | |
Tworzymy nowy projekt, z menu bocznego wybieramy Interfejsy API i usługi. Wyszukujemy i włączamy Cloud Speech API. Przechodzimy do zakładki Dane logowania i klikamy Utwórz dane logowania -> Klucz konta usługi, jako typ wybieramy JSON. Po kliknięciu przycisku Utwórz powinniśmy otrzymać plik JSON, który zapisujemy pod nazwą googlecredentials.json i umieszczamy w katalogu /usr/share/snips | |
UWAGA! Do korzystania z tej usługi Google wymaga podania danych karty płatniczej. W pakiecie darmowym Cloud Speech API otrzymujemy 60 minut/miesiąc przy naliczaniu 15-sekundowym. Wszystko powyżej naliczane jest wg cennika https://cloud.google.com/speech-to-text/pricing?hl=pl | |
Aktualne informacje o stanie konta można znaleźć pod adresem https://console.cloud.google.com/billing | |
Mowa w języku polskim (TTS): | |
Klonujemy repozytorium https://github.com/ChrisB85/snips_custom_tts do dowolnego katalogu na naszym RPI. Nadajemy plikowi snipsGoogle.sh uprawnienia do wykonywania (755, właściciel pi). W pliku config.sh wskazujemy katalog dla plików cache pamiętając o uprawnieniach (u mnie akurat 777). | |
W pliku /etc/snips.toml dodajemy na końcu | |
provider = "customtts" | |
customtts = { command = ["pełna_ścieżka_do_pliku_snipsGoogle.sh", "%%OUTPUT_FILE%%", "pl", "%%TEXT%%"] } | |
3. Integracja z protokołem MQTT: Wyszukujemy i dodajemy w konsoli Snips do naszego modelu asystenta aplikację o nazwie UniDeviceControl, której zadaniem jest przekształcić nasze polecenia na publikacje MQTT. Aby ją dostosować do własnych potrzeb, najlepiej ją "sforkować" - będziemy mogli wtedy dodać własne polecenia i urządzenia. | |
Aplikacja UniDeviceControl obsługuje "na dzień dobry" następujące intencje (można to rozumieć jako rozpoznane przez asystenta polecenia, które wydajemy): | |
TurnOff - wyłączanie urządzenia (Hej Snips, wyłącz [urządzenie]) | |
TurnOn - włączanie urządzenia (Hej Snips, włącz [urządzenie]) | |
Unmute - przywracanie dźwięku (Hej Snips, przywróć dźwięk [urządzenie]) | |
Mute - wyciszanie (Hej Snips, wycisz [urządzenie]) | |
Pause - pauza w odtwarzaniu (Hej Snips, wstrzymaj [urządzenie]) | |
Stop - zatrzymanie odtwarzania (Hej Snips, zatrzymaj [urządzenie]) | |
Play - rozpoczęcie odtwarzania (Hej Snips, odtwarzaj [urządzenie]) | |
Dodatkowo jest jeszcze intencja pomocnicza o nazwie DeviceControlAnswer używana w momencie, gdy asystent nie do końca nas zrozumie. Przykładowo powiemy: | |
- Hej Snips, włącz komputer. | |
Jeśli Snips nie zrozumie słowa komputer, zada pytanie: | |
- Co chcesz włączyć? | |
Odpowiadając "komputer" intencja zamiast TurnOn przyjmie nazwę DeviceControlAnswer. | |
4. Wdrażanie asystenta z konsoli na RPI: | |
Model asystenta instalujemy na RPI zgodnie z krokiem 5 z instrukcji z punktu 1. Podczas wdrażania asystenta na Raspberry Pi powinno zostać pobrane repozytorium https://github.com/ChrisB85/snips_mqtt | |
Możliwe, że pojawi się również komunikat o konieczności nadania plikowi /var/lib/snips/skills/snips_mqttaction-snips-mqtt.py uprawnień do wykonywania. U mnie jest to 755. | |
Na końcu instalacji kreator zapyta nas o dane dostępowe do MQTT (można je ustawić w pliku /etc/snips.toml) - domyślnie nie ma żadnego loginu i hasła, więc wystarczy wciskać ENTER. | |
WAŻNE! Po każdym wdrożeniu asystenta na RPI, należy w pliku /usr/share/snips/assistant/assistant.json zmienić kod języka ("language") z "en" na "pl" i zrestartować usługi Snipsa poleceniem sudo systemctl restart 'snips-*' | |
UWAGA! Podczas wdrażania asystenta skrypt instalacyjny "przetwarza" plik configuration.yaml m.in. wyrzucając komentarze i (przynajmniej w moim przypadku) nadpisuje linię z "intent_scripts:". Co prawda przed całą operacją robi również kopię tego pliku, ale jeśli nie chcemy aby cokolwiek w nim "mieszał", najlepiej zmienić właściciela na root, odebrać prawa do zapisu i umożliwić jedynie odczyt. | |
4. Integracja z Home Assistant: | |
Dokumentacja komponentu Snips dla HA znajduje się pod adresem https://www.home-assistant.io/components/snips/ | |
W pliku konfiguracyjnym HA (configuration.yaml) dopisujemy "snips:" i restartujemy HA. | |
Domyślnie Snips integruje się z HA poprzez tzw intent scripts, natomiast aplikacja UniDeviceControl umożliwia przekształcenie intencji na publikacje MQTT o strukturze: | |
[satelita]/[temat]/[wartość] | |
gdzie: | |
[satelita] - inaczej site_id; domyślnie default. Snips umożliwia obsługę wielu stacji "nasłuchowych" (dla wielu pomieszczeń). Dokładniej jest to opisane na stronie https://docs.snips.ai/articles/raspberrypi/satellites | |
[temat] - intencja/wydane polecenie np. TurnOn | |
[wartość] - nazwa urządzenia wg. aplikacji UniDeviceControl. | |
Przykładowo wydając polecenie "Hej Snips, włącz komputer", wystawiona publikacja będzie miała postać: | |
default/TurnOn/computer | |
zatem w Home Assistant możemy ustawić następujący wyzwalacz: | |
Typ wyzwalacza: | |
MQTT | |
Temat: | |
default/TurnOn | |
Payload: | |
computer | |
Komunikaty zwrotne (czyli to co Snips odpowie), można wywołać poprzez usługę snips.say z poziomu HA. Przykładowo możemy wywołać usługę z danymi: | |
{ | |
"site_id": "default", | |
"text": "Włączam komputer" | |
} | |
Dzięki temu z satelity "default" usłyszymy to, co podaliśmy jako argument "text". | |
Pomocne polecenia: | |
sam watch - podgląd zdarzeń Snips (rozpoznawanie mowy, intencji itp.) | |
sam status - status usług Snips; oczywiście po deinstalacji pakietu snips-asr normalnym będzie, że usługa o tej samej nazwie nie będzie działać. | |
sam setup audio - konfiguracja dźwięku (mikrofonu i głośników) | |
sam update-assistant - aktualizacja modelu asystenta (pobieranie modelu z konsoli Snips na RPI) | |
sudo journalctl -u snips-skill-server - podgląd dziennika akcji |
Dziękuję za tutorial.
Możesz mi powiedzieć czy dobrze rozumiem. Google zaokrągla każdy request do 15 sekund? Czyli mówimy 3-4 sekundy a on zaokrągla do 15sekund? Czy dopiero po osiągnięciu 15 sekund razem pobiera opłatę?
Tak wynika z dokumentacji https://cloud.google.com/speech-to-text/pricing
PS. Niestety obecnie komponent Snips Google ASR nie działa wcale. Google wprowadziło zmiany w API.
W dniu wczorajszym udało mi się wykonać własną implementację komponentu ASR w oparciu o Google Cloud. Działa z najnowszą wersją Snips. Można ją znaleźć pod tym adresem https://github.com/ChrisB85/snips_google_asr
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Po aktualizacji komponentów do wersji 0.61.1 występują problemy z Google ASR. Problem można usunąć poprzez przywrócenie poprzedniej wersji komponentu snips-asr-google:
sudo apt-get install snips-asr-google=0.60.12