以前にもArduinoとさくらのIoTを使ってWatson IoTにデータを送るというようなことはやっていましたが、久しぶりにGrovePiを使ってIoTを扱ってみようと思います。今回はAWS IoTに気温等のデータを送ります。
Raspberry Pi + GrovePi
冒頭の写真のようにRaspberry PiとGrovePiを使った簡単なIoTセンサーを作ります。接続されているセンサーは、明度、気温、音量の3つです。
Raspberry PiなどでIoTセンサーを簡単に試すには、ブレッドボードを使うのが一般的ですが、GrovePi(もともとはArduino向けに提供されているGroveですが、それをRaspberry Piで使うのがGrovePiです)を使うと、より簡単に試すことができます。少し値段は張りますが、楽なのが一番です。
Raspberry PiにGrovePiを接続した後で、DEXTER社のGrovePiのガイドにあるようにセットアップを進めます。
sudo curl -kL dexterindustries.com/update_grovepi | bash
このセットアップには少し時間がかかります。完了したら、Raspberry Piを再起動します。
AWS IoT
AWS IoTのセットアップは、下記の手順で進めます。
- モノの登録
- 証明書を発行しダウンロード
- ポリシーの作成
- 証明書にポリシーをアタッチ
- 証明書にモノをアタッチ
この手順はAWSのガイドのとおりに進めると良いでしょう。もしくはDevelopers.IOのこちらの記事も参考になります。
当ブログのこちらの記事も参考になります。
Raspberry PiにAWS IoTのPython SDKをインストールします。
pip install AWSIoTPythonSDK
GrovePiのセンサーデータをAWS IoTに送信
Raspberry Piでこのようなプログラムを動かします。
import time
import grovepi
from AWSIoTPythonSDK.MQTTLib import AWSIoTMQTTClient
import json
from datetime import datetime
from pytz import timezone
temperature_sensor = 0
light_sensor = 1
sourd_sensor = 2
grovepi.pinMode(light_sensor, 'INPUT')
grovepi.pinMode(sourd_sensor, 'INPUT')
awsClient = AWSIoTMQTTClient('<モノの名前>')
awsClient.configureEndpoint('<ホスト名>.iot.ap-northeast-1.amazonaws.com', 8883)
awsClient.configureCredentials('<rootCA.pemのパス>', '<private.pem.keyのパス>', '<certificate.pem.crtのパス>')
awsClient.connect()
while True:
try:
# temperature_sensor
temp_value = grovepi.temp(temperature_sensor, '1.1')
# light_sensor
light_value = grovepi.analogRead(light_sensor)
light_resistance = (float)(1023 - light_value) * 10 / light_value
# sound_sensor
sound_value = grovepi.analogRead(sourd_sensor)
# AWS IoT Publish
topic = 'raspi-office/status'
message = {
'serial_no': 1001,
'temp': temp_value,
'light': light_resistance,
'sound': sound_value,
'timestamp': datetime.now(timezone('UTC')).isoformat()
}
json_message = json.dumps(message)
awsClient.publish(topic, json_message, 1)
print(topic, json_message)
time.sleep(10)
except IOError:
print('Error')
気温センサーをA0、明度センサーをA1、音量センサーをA2に接続しています。awsClient = AWSIoTMQTTClient()
の引数はクライアントIDと説明されていますが、AWS IoTにモノの追加をした際に指定したモノの名前を指定すれば問題ありません。
AWS IoTにはMQTTでセンサーデータを送ります(パブリッシュ)。WebSocketやHTTPSでも送信可能なようです。MQTTのパブリッシュはトピックにメッセージを投げつけるように行いますが、トピックはraspi-office/status
のように、モノを識別する名前(ここではモノの名前と同じにしました)とstatusのようにどんなデータかを示す情報を組み合わせてみました。
MQTTでは、raspi-office/+
や+/status
のようなワイルドカードを使ったフィルタリングができるので、このようなトピックにするのが良いかと思います。一応、メッセージの中にserial_no
を入れてデバイスを識別できるようにしましたがトピックで分かるので不要かもしれません。(でも、後でDynamoDBに保存する際に使えそうなので入れておきます。)
あと、メッセージにはtimestamp
をセットしています。タイムゾーンはUTC、文字列の形式はISO8601に準拠しました。
送信状況を確認
AWS IoTの画面でテストをクリックし、トピックを+/status
と指定してサブスクリプションします。
このように送信されたメッセージを確認できました。
次回はAWS IoTのルールを使って、送信されたメッセージを保存できるようにしたいと思います。