Raspberry Pi + GrovePiのIoTデータをAWS IoTに送信する

以前にも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のセットアップは、下記の手順で進めます。

  1. モノの登録
  2. 証明書を発行しダウンロード
  3. ポリシーの作成
  4. 証明書にポリシーをアタッチ
  5. 証明書にモノをアタッチ

この手順は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のルールを使って、送信されたメッセージを保存できるようにしたいと思います。

この記事を書いた人

井上 研一

株式会社ビビンコ代表取締役、ITエンジニア/経済産業省推進資格ITコーディネータ。AI・IoTに強いITコーディネータとして活動。画像認識モデルを活用したアプリや、生成AIを業務に組み込むためのサービス「Gen2Go」の開発などを行っている。近著に「使ってわかった AWSのAI」、「ワトソンで体感する人工知能」。日本全国でセミナー・研修講師としての登壇も多数。