Raspbarry Piで取得した気温・湿度情報をAWSに送ってみた

こんにちは。
Raspberry PiとAWSをつなげて何かできないかと思い、今回はRaspberry Piに気温/気圧/湿度センサーを接続して、取得した情報をAWS IoT Coreに送り、S3バケットに情報を保存するところまでやってみようと思います。

構成イメージ

今回AWS上で構築するリソースとデータの流れは以下のイメージです。
センサー ⇒ Raspberry Pi ⇒ AWS IoT Core ⇒ S3バケットの順でデータが流れる想定です。
Raspberry Pi上でPythonスクリプトを動かして取得データをMQTTでAWS IoT Coreに送り、AWS IoT CoreでメッセージをS3バケットに保存するようにルール設定をしてみようと思います。

 

用意するもの

今回使うものは以下の通りです。

・Raspberry Pi 5
・温湿度・気圧センサーモジュールキット (BME280使用)
・ジャンパーケーブル×5
・ブレッドボード×1
(・AWSコンソール接続用PC)

 

Raspberry Pi 事前設定

今回やりたいことを実施するために、いくつかRaspberry Pi上で設定しておく必要があります。
・I2C通信の有効化
・必要なライブラリのインストール
・温湿度・気圧センサーモジュールキットとRasberry Piの接続
以上の設定方法を順を追って説明します。
※今回は取得したデータをRaspberry Piから送り、AWS上へ保存することがメインのため簡単に説明します。

Raspberry Pi設定:I2C有効化

Raspberry Piとセンサーの通信を行うために、Raspberry Pi側でI2C通信を有効化します。
コンソールで以下のコマンドを実行します。

sudo raspi-config
GUIが立ち上がったら以下の手順でI2C通信を有効化します。
①「3.Interface Options」を選択して[ENTER]キーを押下
②「I5 I2C」を選択し、[ENTER]キーを押下
③ 確認画面が表示されたら<はい>を選択し、[ENTER]キーを押下
④ I2Cが有効化されたメッセージが表示されたら[ENTER]キーを押下
⑤ Raspberry Piを再起動する

Raspberry Pi設定:ライブラリのインストール

BME280センサーからデータを取得するために、以下のコマンドを実行して必要なライブラリを追加します。

sudo pip3 install smbus2 –break-system-packages
sudo pip3 install bme280 –break-system-packages
sudo pip3 install paho-mqtt –break-system-packages

※インストールオプションに「–break-system-packages」をつけないと、インストール時にエラーになります。

温湿度・気圧センサーモジュールキットとRasberry Piの接続

センサーをRaspbarry Piにつなぐため、まずはブレッドボードに温湿度・気圧センサーモジュールキットを接続します。
次に回路とRaspbarry Piを接続します。

センサー側 Raspberry Pi側
BME280 VDD 3.3V:1ピン
BME280 GND GND:9ピン
BME280 SDI GPIO2(SDA):3ピン
BME280 SDO GND:6ピン
BME280 SCK GPIO3(SDL):5ピン

ちょっと見づらいですが、実物はこんな感じ↓です。
 

接続が終わったら、以下のコマンドを実行します。

sudo i2cdetedt -y 1

実行結果に「76」という表記があれば、正常に接続できています。

 

AWS設定

さて、Rasberry Piの下準備が完了したところで、次にAWSの設定を実施していきます。
今回AWS上で設定が必要なのは以下の通りです。

・S3バケットの作成
・AWS IoT Coreのポリシー作成
・Raspberry Piの登録と接続用証明書発行
・AWS IoT Coreのエンドポイント作成
・AWS IoT Coreのルール設定

こちらも順を追って説明していきます。

S3バケットの作成

まずは、最終的にデータが保存されるS3バケットを作成します。
※下図の赤枠部分

AWSコンソールにログインして、Amazon S3を開きます。
[汎用バケット]>[バケットを作成]からバケットを作成します。
※今回は特別な設定は実施せず、すべてデフォルトのまま作成します。

AWS IoT Core:ポリシー設定

ここからはAWS IoT Coreの設定を実施します。
※下図の赤枠部分

まずは、Raspberry PiがIoT Core向けに実施できる操作を制御する「ポリシー」を設定していきます。
※このあと発行する証明書にポリシーをアタッチすることで、実施できる操作が制御されます。

AWSコンソールでIoT Coreを開いて、[管理]>[セキュリティ]>[ポリシー]を開いてください。
ポリシーが表示されたら、画面右上の[ポリシーを作成]からポリシーを作成していきます。

作成画面が表示されたら、ポリシー名と許可するアクションを設定します。
今回は一通りのMQTTアクションを許可するため、以下の許可設定とします。
すべて設定し終えたら、画面右下の[作成]でポリシーを作成します。

ポリシー効果 ポリシーアクション ポリシーリソース
Allow iot:Connect *
Allow iot:Publish *
Allow iot:Receive *
Allow iot:Subscribe *

以上でポリシーの作成は完了です。

AWS IoT Core:Raspberry Piの登録と接続用証明書発行

ポリシーの作成が完了したら、Raspberry PiをIoT Coreへ接続するための証明書を発行します。
[管理]>[すべてのデバイス]>[モノ]を開き、画面右上の[モノを作成]からデバイスを登録していきます。

作成するものの数は1つを選択し、次へ進みます。

モノのプロパティはデフォルト設定のまま、次へ進みます。
今回は、デバイスシャドウも「シャドウがありません」のままで問題ないです。

デバイス証明書の設定は「新しい証明書を自動生成 (推奨)」を選択したまま、次へ進みます。

ポリシーの選択では、先ほど作成したポリシーにチェックを入れ、「モノの作成」を押下してください。

「モノの作成」を押下すると、証明書ファイルのダウンロード画面が表示されますので、必要な証明書をダウンロードします。
今回利用するのは、以下の3ファイルです。
・デバイス証明書ファイル (.crt)
・プライベートキーファイル (*****-private.pem.key)
・「Amazon ルートCA 1」のルートCA証明書ファイル

以上で証明書の発行は完了です。

AWS IoT Core:エンドポイント作成

続いて、Raspberry PiがMQTT接続する際の接続先になるエンドポイントを作成していきます。
IoT Coreコンソールの[接続]>[ドメイン設定]を開き、[ドメイン設定を作成]からエンドポイントを作成します。

作成画面が開いたら、以下の通り設定します。
※記述の無い箇所はデフォルトのままで結構です。

・ドメイン設定名:任意の名前
・ドメインタイプ:AWSマネージドドメイン (カスタムドメインも利用できるようですが、今回はマネージドを利用します。)

・アプリケーションプロトコル:セキュアな Websocket 経由の MQTT

・ドメイン設定のステータス:有効にする

設定し終えたら、[ドメイン設定を作成]を押下します。
ドメイン設定が作成出来たら、作成したドメイン設定の「ドメイン名」を控えておいてください。
(後ほど作成するPythonスクリプトの中に記述します。)

以上でエンドポイントの作成は完了です。

AWS IoT Core:ルール設定

最後に、Raspberry Piから送信されてきたときのルール設定をします。
ルール設定では、ルールの対象とするメッセージをSQL形式で指定出来たり、
そのメッセージに対するアクションを設定することができます。

IoT Coreコンソールの[管理]>[メッセージのルーティング]>[ルール]を開き、[ルールを作成]からルールを作成します。
ルールのプロパティ設定画面が表示されたら、任意のルール名を入力して次へ進みます。

次に、SQLステートメントを設定します。ここで設定したSQLに従って、対象とするメッセージを抽出します。
今回は、「topic/」から始まるすべてのメッセージを対象としたいため、以下の通りSQLステートメントを入力し、次へ進みます。

SELECT * FROM ‘topic/#’
続いて、ルールアクションを設定します。
ルールアクションでは、SQLに従って抽出したメッセージに対して、どのようなアクションを実行するかを設定できます。
今回は冒頭に説明した通り、受け取ったメッセージをS3バケットに出力したいため、以下の通りアクションを追加し、次へ進みます。
・アクション:S3 bucket
・S3 URI:先ほど作成したS3バケット
・キー:iot/${topic()}/${timestamp()}.json
・IAMロール:アクションに必要なアクセス許可が付与されたロール
キーの設定では、メッセージがS3バケットに保存される際のパスとファイル名を指定します。
今回は「iot/トピック名」の下に、「タイムスタンプ.json」というファイル名で、メッセージが保存されるように指定しています。
また、IAMロールについては、今回は「AmazonS3FullAccess」を付与したロールを指定しています。
※作成されていない場合は、このタイミングで作成してください。
最後に設定確認画面が表示されますので、[作成]を押してルールを作成してください。
以上で、すべてのAWS設定が完了しました。
 

Pythonスクリプトの作成

ここまで来たら、残すはPythonスクリプトを作成して、Raspberry Pi上で動かすだけです。
Pythonスクリプトのコードを以下に記述します。
こちらのスクリプトでは、AWS IoT CoreのエンドポイントへMQTTクライアント接続し、
センサーで取得した情報を5秒おきにエンドポイント向けにパブリッシュします。
トピック名は「topic/raspi1」としているため、パブリッシュされたメッセージは先ほどのルール設定に引っかかって、
S3バケットに保存されるという算段です。         

※事前にRaspbarry Piにダウンロードした証明書ファイルを保存しておいてください。
※以下はご自身の設定に合わせて置き換えてください。
・IoT Coreのエンドポイントドメイン名
・各種証明書ファイルのパス/ファイル名

import time
import json
import socket
from datetime import datetime

import ssl
import paho.mqtt.client as mqtt

from smbus2 import SMBus
import bme280

#AWSエンドポイント情報
aws_endpoint = "********.amazonaws.com" #作成したエンドポイントのドメイン名
aws_port = 8883

#MQTTトピック設定
mqtt_topic = "topic/raspi1"

#AWS証明書
ca_path   = "*************.pem"             #「Amazon ルートCA 1」のルートCA証明書ファイル
crt_path  = "*************.pem.crt"         #デバイス証明書ファイル (.crt)
key_path  = "*************-private.pem.key" #プライベートキーファイル (*****-private.pem.key)

# BME280のI2C定義(I2Cポート1、アドレスはSDOをGNDなら0x76)
i2c_port = 1
i2c_address = 0x76

# I2Cバス・BME280初期化
bus = SMBus(i2c_port)
bme280.load_calibration_params(bus, i2c_address)  # キャリブレーション

#MQTTクライアント接続
client = mqtt.Client()
client.tls_set(ca_certs=ca_path,
               certfile=crt_path,
               keyfile=key_path,
               tls_version=ssl.PROTOCOL_TLSv1_2)
client.connect(aws_endpoint, aws_port, keepalive=60)

client.loop_start()
time.sleep(1) 

hostname = socket.gethostname()

try:
    while True:
        # BME280データ取得
        data = bme280.sample(bus, i2c_address)
        temperature = data.temperature
        humidity    = data.humidity
        pressure    = data.pressure

        now = datetime.utcnow().isoformat() + "Z"
        payload = {
            "datetime": now,
            "hostname": hostname,
            "temperature": round(temperature, 2),
            "humidity": round(humidity, 2),
            "pressure": round(pressure, 2)
        }

        client.publish(mqtt_topic, json.dumps(payload), qos=1)
        print("published:", payload)

        time.sleep(5)

except KeyboardInterrupt:
    print("終了します。")
finally:
    client.disconnect()
    bus.close()

 

Pythonスクリプトの実行/動作確認

ここまでですべての準備が整いましたので、実際にRaspberry Pi上でPythonスクリプトを動かして動作を確認してみましょう。
Raspbarry Piでコンソールを開いて、以下のコマンドを実行してください。
今回はPythonスクリプトのファイル名を「sensor.py」としています。

python3 sensor.py
スクリプトを実行すると、コンソール上で5秒おきにメッセージをパブリッシュした旨の出力がされます。
パブリッシュされたメッセージはIoT Coreで設定したルールの通り、指定のS3バケットへjson形式で保存されます。
ダウンロードしたファイルをメモ帳で開いてみると、気温/気圧/湿度が記述されたメッセージがそのまま保存されていることが
分かります。
         

以上で、Raspberry PiとAWS IoT Coreを連携し、センサーで取得したデータをS3バケットに保存することができました。
 

最後に

今回はRaspberry Piに気温/気圧/湿度センサーを接続して、取得した情報をAWS IoT Coreに送り、S3バケットに情報を保存するところまでやってみました。
個人的にはRaspbarry PiもAWS IoT Coreも初めて触る代物だったため、構成はかなり簡単めかな?と思っております。
皆様もぜひとも触ってみてはいかがでしょうか。

また、続きとして、今回S3バケットに保存したデータをQuickSightで可視化してみる記事もございますので、
ぜひともご覧ください。
https://blog.usize-tech.com/visualize-iot-data-raspberrypi-aws/

もっと詳しく調べたら色々できそうだと思ったので、まだまだたくさん触ってみたいと思います。
最後まで読んでいただきありがとうございました。

タイトルとURLをコピーしました