はじめに
本記事は、2021年4月19日〜5月31日 | ソラコム主催 ラズパイコンテスト参加のための記事です。
この企画を簡単に説明すると
・Raspberry Piと、SORACOM IoT SIMまたはSORACOMサービスを利用し**「普段の生活を豊かにした」「業務の改善を実現した」IoT作品を作る。
・SORACOMサービスとラズパイの使用が必須
・アイデアのみではなく、きちんと実際に動く物**を作る
です。
ということで、今回は「普段の生活を豊かにした」に焦点を絞って、作品を作りました。
背 景
プライベートな話ですが、妻が妊娠しました。
まだ安定期に入っておらず、つわりがひどい時期で、食欲がありません。
何にも食べないのは身体に良くないので、食べられるものを食べさせたいのですが、
食べたいものがその時によって変わるらしいです。
しかも、帰り道に立ち寄るスーパーが某R社の電波圏外で、電波が入りません(泣)
スーパーを出た後に妻から追加の買い物リストが来ると、見なかったことにしてます。
よって、スーパーの中で妻と通信するためにはR社以外の回線が必要です。
解決方針
家にいる妻が、食べたい物を言うと夫(私)に通知する、VUIシステムの構築を目指しました。
これによってスマホアプリを開いてテキストを入力するなどの手間なく、食べたい物をすぐに通知できます。
また、「OK Google」みたいなウェイクワードを使わないことで、煩わしさを軽減します。
また、電波が入らない場所でも通知を可能とするために、R社以外の回線を用意しました。
わざわざ携帯回線を購入するのはもったいないのでSORACOMさんのSIMカードで接続しました。
システム構成図と処理の流れ
以下の簡単なVUIシステムを作りました。
名付けて**「家にいる妻が、食べたい物を言うと夫が買ってくるVUIシステム」**です。
①テキスト抽出
ラズパイでマイク集音し、音声情報を文字起こし。「〇〇食べたい」のみを抽出
②webhook
「〇〇食べたい」をwebhookでラズパイからIFTTに送信
③端末へ通知
「〇〇食べたい」をIFTTがアンドロイド端末に送信
④端末で確認
「〇〇食べたい」がプッシュ通知される。
(夫が〇〇を買ってくる)
使用機器等は以下のとおりです。
・SIMカード
SORACOM IoT SIM スターターガイド(SIM付きパッケージ)
・ラズパイ
[RaspberryPi 4B 4GB](https://www.amazon.co.jp/-/en/gp/product/B081YD3VL5
/ref=ppx_yo_dt_b_asin_title_o02_s00?ie=UTF8&psc=1)
OSはRaspbian GNU/Linux 10 (buster)
・マイク
ECM-PCV80U
・アンドロイド端末
Qua phone QZ(KYV44)
R社に乗り換えた際に不要になったスマホです。
作り方
ラズパイの構築
システム構成図の①と②の構築です。
音声認識用のライブラリのインストールとwebhook用のpythonスクリプトを作成します。
音声認識についてはJuliusを使用しました。
Juliusはオープンソースソフトウェアの汎用大語彙連続音声認識エンジンです。
大学の研究室が開発しているおかげか、ドキュメントが豊富です。
インストール方法はgit-hubの手順どおりです。
https://github.com/julius-speech/julius
$ sudo apt-get update
$ sudo apt-get install build-essential zlib1g-dev libsdl2-dev libasound2-dev
$ git clone https://github.com/julius-speech/julius.git
$ cd julius
$ ./configure --enable-words-int
$ make -j4
$ ls -l julius/julius
-rwxr-xr-x 1 ri lab 746056 May 26 13:01 julius/julius #←のように、実行ファイルが作成できていることを確認
ライブラリのインストールに加えて、 日本語のディクテーションファイルが必要です。
下記のgit-hubサイトからcloneしておきます。
注意書きにも記載されていますが、ファイル容量が大きいので、git-lfsを事前にインストールしておきます。
$ sudo apt-get install git-lfs
$ git clone https://github.com/julius-speech/dictation-kit
上記の作業が終わったら、マイクをラズパイに接続します。
マイクの設定が終わったら下記コマンドを入力し、音声認識の結果を確認します。
$ julius -C /home/pi/dictation-kit/am-gmm.jconf -C /home/pi/dictation-kit/main.jconf
マイクで音声入力し、下記のように標準出力に認識結果が帰ってくればOKです。
### read waveform input
Stat: capture audio at 16000Hz
Stat: adin_alsa: latency set to 32 msec (chunk = 512 bytes)
Error: adin_alsa: unable to get pcm info from card control
Warning: adin_alsa: skip output of detailed audio device info
STAT: AD-in thread created
pass1_best: こんにちは 。
pass1_best_wordseq: <s> こんにちは+感動詞 </s>
pass1_best_phonemeseq: silB | k o N n i ch i w a | silE
pass1_best_score: -2375.406006
### Recognition: 2nd pass (RL heuristic best-first)
STAT: 00 _default: 21186 generated, 1539 pushed, 279 nodes popped in 97
sentence1: こんにちは 。
wseq1: <s> こんにちは+感動詞 </s>
phseq1: silB | k o N n i ch i w a | silE
cmscore1: 0.679 0.680 1.000
score1: -2392.535889
マイクについて(ご参考)
最初は安価なワイヤレスヘッドフォンマイクで試したのですが、認識精度が全然良くありませんでした。
そこで、今回はたまたま家にあった、配信用によく使われているマイク、ECM-PCV80Uを使用しました。
次に、認識した情報をIFTTTサーバにwebhookするpythonスクリプト「order.py」を作成します。
import subprocess
import requests
import json
if __name__ == "__main__":
#pi2roidの部分はEvent nameなので、後に説明するIFTTT設定時の情報を入力する。
url = "https://maker.ifttt.com/trigger/pi2roid/with/key/fR51N65yFxnR0tY2FvUFfXkA56YVBiVHxMiujkU-qw4"
#subprocessでjuliusの標準出力を取得する。
#ディレクトリは各々の環境に合わせる。
proc = subprocess.Popen(['julius','-C','/home/pi/dictation-kit/am-gmm.jconf','-C','/home/pi/dictation-kit/main.jconf','-quiet'], stdout=subprocess.PIPE)
for line in proc.stdout:#標準出力を行ごと抽出
text = line.decode('utf-8'):#bytes型からstr型に変換
if("食べ たい" in text and "sentence" in text):#送信したい行「〇〇食べたい」を抽出
text = text.replace("sentence1: ","")#余計な部分を削除
json_data ={"value1":text}#送信データを整形
res = requests.post(url, data=json_data)
if(res.status_code==200):#エラーチェック
print("Post ok : "+json_data['value1'])
else:
print("Post error")
ちなみに、Juliusは解析結果を
・標準出力
・ソケット通信
・ログファイル
から取得できます。
今回は、一通り試しましたが、最も実装が早そうな、「標準出力」を選択しました。
これでラズパイの構築は終わりです。
IFTTサービスの登録
システム構成図の②と③の構築です。
ここからはのノーコードで実装します。
まずはシステムの中心となる、IFTTTから設定を行っていきます。
下記図のようにトリガー(if)をwebhook、アクション(Then)をnotificationに設定したアプレットを作成します。
webhookの設定画面です。
Event NameはURLの一部となります。
今回は「pi2roid」に設定しました。
次に、notificationの設定画面です。
Add ingredientを押して、MessageにValue1を入れます。
Value1にはラズパイが送信した「〇〇食べたい」が入ります。
これでIFTTTの設定は終わりです。(簡単!!)
Android端末の設定
システム構成図の④の構築です。
使用したいスマートフォンにSORACOMのSIMカードを挿入し、APN設定を行います。
こちらの公式ページの手順どおりに実施すればOKです。
さすがSORACOMさん、何にも困ることはありませんでした。
加えてIFTTTのAndroidアプリをインストールし、ログインします。
これでシステムの構築は終了です。
実際の様子
Twitterに上げました。
あとは、夫が買い物して帰ってくればOKです。#soracom#RaspberryPi#Qiita
— zakuzaku-3 (@zakuzaku_3) May 31, 2021
音声認識ライブラリJuliusとIFTTTを組み合わせて、食べたいものをAndroid端末に通知するVUIシステムを構築。
動画には映っていませんが、SORACOM Airとラズパイ4Bを使用しています。
詳細はQiitaの記事へ。https://t.co/TKXZ04t3S1 pic.twitter.com/t4r0XaudVp
おわりに
今回は、2021年4月19日〜5月31日 | ソラコム主催 ラズパイコンテストのための記事を作成しました。
「家にいる妻が、食べたい物を言うと夫が買ってくるVUIシステム」を構築し、実際に動作することを確認しました。
SORACOMさんの一瞬でインターネットにつながるSIMカードと、ラズパイのなんでもこなせる感のいいとこどりが出来て良かったです。
半日もかからず、システムを構築することができました。
これからも家族のためにIoTでライフハックに勤しみます!