Edited at

Alexaに部屋の温度と湿度を教えてもらう


はじめに

Amazon Echoに温度計の搭載が噂されていますが、一足お先にAlexaと温度計の組み合わせを体験してみます。温度計と湿度計が一体化されたセンサーを使って、Alexaに部屋の温度と湿度の両方をも教えてもらいます。センサーの呼び出しと、Alexaスキルのエンドポイントはラズパイで実装します。


使用環境


  • Amazon Echo

  • Raspberry PI 3B

  • 温湿度センサーモジュールキット(SHT31-DIS使用)

温湿度センサーは秋月電子通商で購入しました。(通販コード: K-12125)


おおまかな作業のながれ


  1. センサーキットの組み立てとラズパイの配線

  2. I2Cインターフェースの有効化

  3. Pythonコードの実装

  4. Webサーバーの外部公開

  5. Alexaスキルの作成

ではやっていきます。


センサーキットの組み立て

組み立てと言ってもセンサー基盤にピンヘッダを取り付けるだけです。基盤にピンヘッダを通して、基盤の裏面に半田付けします。


結線方法

センサーとラズパイのピンヘッダの対応です。

SHT31
ピン番号
ラズパイ
ピン番号
メモ

1 (VDD)
1 (3.3V)

2 (SDA)
3 (SDA)

3 (SCL)
5 (SCL)

4 (ADR)
-
未使用。開放時はアドレスが0x45になる。

5 (GND)
6 (GND)

配線例


動作確認

I2Cライブラリをインストールします。


Raspbian

$ sudo apt-get install i2c-tools


ラズパイのデフォルトではI2Cが無効化されているので、I2Cインターフェースを有効化します。


Raspbian

$ sudo raspi-config


「5 Interfacing Options」を選択

「P5 I2C」を選択。表示された画面で「はい」を選択。「Finish」でツールを終了します。

i2cdetectで信号が取れているか確認します。


Raspbian

$ sudo i2cdetect -r -y 1

0 1 2 3 4 5 6 7 8 9 a b c d e f
00: -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- 45 -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --

アドレス0x45が検出されていれば、機材の準備はこれでOKです。


Alexaスキルのエンドポイントの実装

ここからは、Alexaスキルと対話するためのエンドポイントを実装します。今回はAWSのLambdaは使用せずに、ラズパイ上にWebサーバを立てて、ngrokを使って外部に公開する方法を取ります。温湿度センサーはPythonコードでアクセスするため、ついでにWebサーバもPythonの簡易HTTPサーバーで手軽に実装しました。


Python3の簡易HTTPサーバーを使う

ラズベリ側の~/app/sht31ディレクトリにWebサーバーを配置します。


~/app/sht31/server.py

import http.server

server_address = ("", 8000)
handler_class = http.server.CGIHTTPRequestHandler #ハンドラを設定
simple_server = http.server.HTTPServer(server_address, handler_class)
simple_server.serve_forever()


いちおうindex.htmlを作成しておきます。


~/app/sht31/index.html

<html>

<body>
Hello HTTPServer.
</body>
</html>


Alexaスキルの応答コード

PythonのCGIでセンサーの読み取りとAlexaスキルの応答を実装します。コードの前半は温湿度センサーSHT31から値を読みコードです。I2Cのクロックストレッチで1回の転送で6バイトの温湿度データを受信します(ラズパイマガジン2018年2月号のP111を参考にしました)。後半は読み取った値をAlexaスキルに返すためのJSONを生成しています。


~/app/sht31/cgi-bin/sht31.py

#!/usr/bin/env python3


import datetime
import pigpio
import json

pi = pigpio.pi()
pi.bb_i2c_open(2, 3, 100000)

result = pi.bb_i2c_zip(2, [4, 0x45, 2, 7, 2, 0x2c, 0x10, 2, 6, 6, 3, 0])

if result[0] == 6:
temp = -45 + 175 * int.from_bytes(result[1][0:2], 'big') / 65535
humi = 100 * int.from_bytes(result[1][3:5], 'big') / 65535

pi.bb_i2c_close(2)

speak = "この部屋の温度は{0}度。湿度は{1}パーセントです。".format(int(temp), int(humi))

resp = {
"version": "1.0",
"response": {
"outputSpeech": {
"ssml": "<speak>" + speak + "</speak>",
"type": "SSML"
},
"speechletResponse": {
"outputSpeech": {
"ssml": "<speak>" + speak + "</speak>"
},
"shouldEndSession": True
}
},
"sessionAttributes": {}
}

print("Content-type: application/json\n")
print(json.dumps(resp))



Webサーバーの起動

pigpioデーモンを立ち上げてから、PythonでWebサーバーを起動します。


Raspbian

$ sudo pigpiod

$ cd /home/pi/app/sht31
$ python3 server.py

ngrokで外部に公開します。ngrokのセットアップ方法は「LINEからGoogle Homeを喋らせる」を参考にしてください。


Raspbian

$ ngrok 8000



Alexaスキルの作成

いよいよ、Alexaスキルを作成していきます。Alexa Skills Kit Developer Consoleでポチポチとやっていきます。コードを書いたりする必要はありません。


新しいスキルの作成


呼び出し名

「アレクサ、室温」でAlexaが反応するように設定します。

 


インテント

今回はカスタムインテントは使用しないのですが、対話モデルに最低1つ要求されるようですので、適当にダミーを作成しておきます。(自信なし)


エンドポイント

「HTTPS」を選択し、ngrockのURLに/cgi-bin/sht31.pyを付けたものを指定します。証明書の種類は「開発用のエンドポイントは、証明期間が発行したワイルドカード証明書をもつドメインのサブドメインです」を選択します。


テストしてみる

alexa developer consoleの「テスト」タブで試してみます。入力欄に「室温」と入力すると、温度と湿度が返ってくるはずです。


完成

これで完成です。自分のアカウントに紐づいたEcho実機に「アレクサ、室温」と呼びかけると、アレクサたんが応答してくれるはずです。温度といっしょに湿度もわかるのは意外と便利です。お試しあれ。