独自のウェイクワードでお部屋をチェックする
第1回: ウェイクワードで操作できるスマートホーム・デバイスを作り始める
こんにちは、ヨシケンです!
ラズパイでスマートホーム化の第2回です。前回はSnowboyというウェイクワードの仕組みを導入して、「スノーボーイ!」と呼び掛けると、ラズパイからLEDを光らせるようにしました。
今回はそのウェイクワードを自分の声でカスタマイズし、独自の掛け声で部屋の状況(温湿度など)をチェックする仕組みを作ります。
今回の記事で必要な物一覧
ラズパイケース
(何でも構いませんが、今回はこちらを使っています)
・小型USBマイク
(USBで使える小型のこちらを使いました。)
小型スピーカー
(イヤフォン・ジャックで使えるアンプ付きのこちらを使っています。)
・温湿度センサ(今回はBME280というセンサを使っています)
・ミニブレッドボード
・LED、抵抗やケーブル類
今回の記事の流れ
1.独自ウェイクワードの設定
2.温湿度センサの設定
3.ラズパイから温湿度をしゃべらせる
4.ウェイクワードとセンサ、LEDを連動させる
5.まとめ
1.独自ウェイクワードの設定
前回Snowboyというソフトウェアをラズパイにインストールして、音声から起動させる仕組みを作りました。このSnowboyは自分の声を吹き込んで、好きな言葉でウェイクワードを作る機能もあるので、自分のワードを登録してみましょう。
まずSnowboyのサイトからアカウントを取得します。そのアカウントでログオンして、Profile settingsというメニューを選ぶと、以下のように自分のAPI Tokenを取得する事ができます。
ここに表示されるトークンをコピーしておきます。
以下のモデル作成用サンプル・スクリプトtraining.pyをresourcesフォルダ下に作ります。
このスクリプト中の黄色くハイライトした部分を、今回の設定に合わせて変更します。
まずtokenの部分に上記でコピーしたトークンを貼りつけます。またhotword_name部分は、 “oheya”(お部屋) にしておきます。言語、年齢、性別などは適宜変えて、保存して下さい。
[training.py]
# -*- coding: utf-8 -*- | |
import sys | |
import base64 | |
import requests | |
def get_wave(fname): | |
with open(fname) as infile: | |
return base64.b64encode(infile.read()) | |
endpoint = "https://snowboy.kitt.ai/api/v1/train/" | |
############# MODIFY THE FOLLOWING ############# | |
token = "" # アカウントに設定されたAPI Tokenをここにペースト | |
hotword_name = "???" # ウェイクワードの名前、ここではoheya など | |
language = "en" # 適宜jpなどに変更 | |
age_group = "20_29" # 適宜変更 | |
gender = "M" # 適宜変更 | |
microphone = "macbook microphone" # 適宜変更 | |
############### END OF MODIFY ################## | |
if __name__ == "__main__": | |
try: | |
[_, wav1, wav2, wav3, out] = sys.argv | |
except ValueError: | |
print "Usage: %s wave_file1 wave_file2 wave_file3 out_model_name" % sys.argv[0] | |
sys.exit() | |
data = { | |
"name": hotword_name, | |
"language": language, | |
"age_group": age_group, | |
"gender": gender, | |
"microphone": microphone, | |
"token": token, | |
"voice_samples": [ | |
{"wave": get_wave(wav1)}, | |
{"wave": get_wave(wav2)}, | |
{"wave": get_wave(wav3)} | |
] | |
} | |
response = requests.post(endpoint, json=data) | |
if response.ok: | |
with open(out, "w") as outfile: | |
outfile.write(response.content) | |
print "Saved model to '%s'." % out | |
else: | |
print "Request failed." | |
print response.text |
次に以下のコマンドから自分のワードを録音します。一つのウェイクワード・モデルを作るのに、同じ言葉を吹き込んだ3つのファイルが必要になリます。
マイクの近くで「ねぇ、お部屋!」と言って録音してください。(この言葉はもちろん他の言葉でも構いません。お好きな呼びかけ易い言葉を選んで下さい。)
これを1.wav, 2.wav, 3.wavといったファイル名を付けて、三回繰り返します。
さて三つのファイルができたら、training.pyと同じresources下に置き、モデルを作成します。モデル名はoheya.pmdlとしました。(.pmdlはpersonal modelという意味だそうです。)
程なくするとoheya.pmdlファイルが出来上がります。
それではこのウェイクワード・モデルを使って、デモプログラムや、前回作ったLEDを光らせるプログラムを流してみます。
前回のSnowboyを起動させるプログラムの際、エラーが出た場合は以下のlibatlas-base-devというライブラリが足りないかもしれないので、インストールしておいて下さい。
また元々用意されているdemo2.pyというサンプルプログラムを改変して、2つのウェイクワードを使えるようなwake2_led.pyも作って試してみます。
$ python demo.py resources/oheya.pmdl$ cp ~/smart/snowboy/demo2.py ~/smart/snowboy/wake2_led.py
前回同様に赤色LEDもつないでおきます。
以下の黄色の部分を追加、変更する事により、snowboyという呼びかけと、今回作ったoheyaを同時に使う事ができます。
[wake2_led.py]
# -*- coding: utf-8 -*- | |
import RPi.GPIO as GPIO | |
from light import Light | |
interrupted = False | |
LED=17 | |
GPIO.setwarnings(False) | |
import snowboydecoder | |
….. | |
sensitivity = [0.5]*len(models) | |
detector = snowboydecoder.HotwordDetector(models, sensitivity=sensitivity) | |
led = Light(LED) | |
callbacks = [lambda: snowboydecoder.play_audio_file(snowboydecoder.DETECT_DING), | |
lambda: led.blink()] #snowboydecoder.play_audio_file(snowboydecoder.DETECT_DONG)] | |
print("ウェイクワードを発話して下さい。Ctrl+Cで終了します。") | |
それでは2つのウェイクワードに対応したwake2_led.pyを流してみます。
自分の声で「ねぇ、お部屋!」と言うと、前回作ったLEDが点灯してくれたでしょうか?
実際に動かしている動画はこちらです。
2.温湿度センサの設定
次に、ラズパイに温湿度センサをつないで、部屋の温度を測ってもらいましょう。
今回の温湿度センサは、温度、湿度だけでなく気圧も測ることができ、I2Cという通信方式を使っています。
以下コマンドから、ラズパイのI2Cを使用可能にしていきます。
“Interfacing Options”を選び。その中から”Enable I2C”を選びます。
この後、再起動が必要となる場合がありますので、再起動して続けていきます。
実際の接続としては、写真のようにセンサのピンヘッダを半田付けして、小さいブレッドボードに挿してラズパイと使っています。
後続の赤、緑LEDも合わせた接続図は以下のようになっています。接続の際の参考にして下さいね。
センサとラズパイをつないだら、このセンサを操る為の幾つかのI2Cのライブラリをインストールします。その後、コマンドから接続したセンサが使用可能になっているか見てみましょう。
$ sudo apt-get install i2c-tools
$ sudo apt-get install python-smbus
$ sudo i2cdetect -y 1
この I2C Detectコマンドを流すと、以下のようにBME280のデフォルトアドレス0x76での通信が確認できます。何の表示もされない場合は、I2Cの設定がされていないか、接続が正しくない可能性があるので、チェックしてみて下さい。
接続が確認できたら、このセンサを販売しているスイッチサイエンスから便利なサンプルスクリプトが出ているので、ダウンロードして使ってみましょう。
今回使うプログラムを格納するsmartフォルダを作って、そこに置きます。
$ sudo mkdir smart
$ cd smart
$ sudo git clone https://github.com/SWITCHSCIENCE/BME280.git
$ sudo pip install smbus2
$ python BME280/Python27/bme280_sample.py
このサンプル・プログラムを流すと、以下のように簡単に温度、湿度、気圧が取れました!
3.お部屋の状況をしゃべって、光ってお知らせ
では、取得した室温をラズパイからしゃべらせる為に、日本語読み上げで定番のAquesTalkをインストールしておきます。公式ページからラズパイ版AquesTalkを、以下のようにダウンロード、ラズパイ内に設置しておいてください。pi@raspi.localの部分はご自分のラズパイ名に合わせて転送して下さい。
(ダウンロードしたPCから) scp aquestalkpi-20130827.tgz pi@raspi.local:smart
(ラズパイにログオンして) $ tar zxvf ~/smart/aquestalkpi-20130827.tgz
温湿度センサにプラスして、赤と緑のLEDをつなぎます。少し配線が多くなってしまいましたが、赤色LEDをGPIO17に、緑色LEDをGPIO18につないでいます。
それでは、元のサンプル・プログラムをコピーして、室温などに応じてしゃべる内容を変えたり、LEDを光らせたりするプログラムを作ります。
$ sudo cp BME280/Python27/bme280_sample.py snowboy/bme.py$ sudo vi snowboy/bme.py
それでは、以下の黄色の部分の追加、修正を行います。室温や湿度の区切り、しゃべらせるメッセージなどはお好きに設定して下さい。
[bme.py]
# -*- coding: utf-8 -*- | |
import RPi.GPIO as GPIO | |
from light import Light | |
interrupted = False | |
GPIO.setwarnings(False) | |
aquest_dir = "/home/pi/smart/aquestalkpi/" | |
from smbus2 import SMBus | |
import time | |
….. | |
setup() | |
get_calib_param() | |
def led_blink(color, count): | |
if color == "red": | |
led = Light(17) | |
elif color == "green": | |
led = Light(18) | |
else: | |
led = Light(17) | |
for i in range(count): | |
led.blink() | |
time.sleep(1) | |
def temp_led(): | |
try: | |
temp, press, hum = readData() | |
except KeyboardInterrupt: | |
pass | |
if temp: | |
msg = "今の室温は、" + str(round(temp,1)) + "度、湿度は、" + str(round(hum,1)) + "パーセントです!" | |
print msg | |
os.system(aquest_dir + "AquesTalkPi " + msg + " | aplay") | |
if temp > 30: | |
room = "暑くないですか?" | |
led_blink("red", 5) | |
elif temp < 15: | |
room = "寒いですね!" | |
led_blink("red", 4) | |
elif hum > 70: | |
room = "蒸し蒸ししますね" | |
led_blink("red", 3) | |
elif hum < 40: | |
room = "スーパードライ!" | |
led_blink("red", 2) | |
elif press < 1000: | |
room = "低気圧ですね" | |
led_blink("red", 1) | |
else: | |
room = "快適です!" | |
led_blink("green", 3) | |
print room | |
os.system(aquest_dir + "AquesTalkPi " + room + " | aplay") | |
if __name__ == '__main__': | |
temp_led() |
4.ウェイクワードとセンサ、LEDの連動
それでは最後に、bme.pyとSnowboyの仕組みを連動させます。先ほどのwake2_led.pyを改造して、wake_temp.pyを作ります。
$ cp ~/smart/snowboy/wake2_led.py ~/smart/snowboy/wake_temp.py$ sudo vi ~/smart/snowboy/wake_temp.py
複数の呼びかけに対応しますので、元々の「スノーボーイ!」という掛け声は残して、「ねぇ、お部屋!」と言うと、室温などを測って読み上げてくれるものにします。以下の黄色の部分をwake2_led.pyに追加、修正します。
[wake_temp.py]
# -*- coding: utf-8 -*- | |
Import bme | |
….. | |
sensitivity = [0.5]*len(models) | |
detector = snowboydecoder.HotwordDetector(models, sensitivity=sensitivity) | |
callbacks = [lambda: snowboydecoder.play_audio_file(snowboydecoder.DETECT_DING), | |
lambda: bme.temp_led()] #snowboydecoder.play_audio_file(snowboydecoder.DETECT_DONG)] | |
print("ウェイクワードを発話して下さい。Ctrl+Cで終了します。") | |
# main loop | |
….. | |
それでは部屋の好きなところに置いて、プログラムを流して、「ねぇ、お部屋!」と呼びかけてみましょう。
いかがでしょうか?プログラムは特定のウェイクワードを待ち続け、「ねぇ、お部屋!」と言うと、すかさず室温、湿度、気圧を読み上げてくれたのではないでしょうか。
最初は部屋が乾燥し過ぎていて、「スーパードライ!」と赤いLEDで警告した後、室温、湿度が戻ると「快適ですね!」と緑LEDが点滅したかと思います。
こちらは動いているところの動画です。参考にしてみて下さい。
5.まとめ
今回はラズパイでスマートホームの第二回、自分の声でウェイクワードを登録しました。
その声から部屋の温湿度などを測って、しゃべってもらう事ができるようになりました。
それに合わせてLEDを光らせて視覚的にも分かるようにもなりました。今回は簡単のため赤と緑のLEDを使いましたが、Wi-fi対応の電球Hueなどを持っていましたら、IFTTTを使って簡単に部屋の電気の色を変える事もできます。
部屋の状況を声だけでチェックできる、スマートホームに近づいて来たのではないかと思います。
次回は、リモコンなどと連動させて、更に便利なおうちにする機能を追加していきます。お楽しみに!
(ヨシケン)
今回の連載の流れ
第1回: ウェイクワードで操作できるスマートホーム・デバイスを作り始める
第2回: 独自のウェイクワードでお部屋をチェックする(今回)
第3回: 声でリモコンを操作して便利に使う
第4回:カメラをつけて、お部屋のチェックなど便利に使おう!