見出し画像

Raspberry Pi + AWS IoT Core + Grafana で室内環境を可視化してみた

はじめに

こんにちは、最近すっかり暖かくなってきましたね。
部屋で仕事をしていると「暑い!」とさえ感じるようになってきました。

今回は Raspberry Pi と SCD40 センサを使って室内環境データを取得 し、
AWS IoT Core 経由でクラウドに送信して、Grafana で可視化 してみました。

最終的には、このセンサデータを AI Agent に活用 することを考えていて、
可視化だけでなく、後続の AI システムで扱いやすいデータ基盤 を作ることを目的としています。




作ったもの

この記事で紹介する構成は以下となります。

  • SCD40 センサーで CO2 / 温度 / 湿度 を測定

  • Raspberry Pi から AWS IoT Core に MQTT publish

  • IoT Core トピックルールによる Lambda 起動

  • Lambda で DynamoDB に時系列データを保存

  • Athena 経由の Grafana ダッシュボード

最終的に、Grafana ダッシュボード上で、室内環境データをリアルタイムに可視化できるようになりました。

ダッシュボード完成形

全体構成

室内環境データ可視化のアーキテクチャは以下となります。


AWS IoT Core を使う理由

今回の目的ですと、センサー値を API Gateway に直接 POST する構成も考えられましたが、
ここでは AWS IoT Core を使うことにしました。

理由は以下となります。

  • デバイス証明書ベースで安全に接続できる

  • MQTT publish / subscribe と相性が良い

  • 小さなセンサーデータを軽量に送信できる

  • IoT Core トピックルールにより後続処理へ柔軟にルーティングできる

  • 将来的にデバイス制御にも拡張しやすい (AWS 側からデバイス操作ができる!)

特にトピックルールを使うことで、
受信した MQTT メッセージを Lambda や DynamoDB などの AWS サービスに流しやすくなる点 が魅力でした。


センサーから AWS にデータを送る

SCD40 と Raspberry Pi の接続

SCD40 は CO2、温度、湿度を取得できるセンサーモジュールで、
Raspberry Pi とは I2C で接続しています。

配線表

ピンを刺すだけで簡単に接続できました。もう少し電子工作したかった…

SCD40 と Raspberry Pi

センサーデータ取得のポイント

配線は楽でしたが、SCD40 から返ってくる値はそのまま使える形式ではなく、生データを変換する 必要があります。

実装上で注意したポイントは以下となります。

  • I2C 経由で SCD40 から測定値を取得する

  • CRC チェックで通信データの破損を検知する

  • CO2 / 温度 / 湿度を扱いやすい形式に変換する

  • MQTT payload として JSON 形式で送信する

最終的に payload は以下のような形式で、Raspberry Pi から IoT Core に送信しています。

{
  "device_id": "raspi-home-1",
  "timestamp_ms": 1711958400000,
  "temperature": 25.0,
  "humidity": 40.0,
  "co2_ppm": 500
}

MQTT publish 処理

以下は、Raspberry Pi からセンサデータを MQTT で送信するスクリプトの一部となります。
※ MQTT は軽量な publish/subscribe 型の通信プロトコルで、IoTデバイスとの連携に適しています

ENDPOINT = "<IoT Core Endpoint>.iot.ap-northeast-1.amazonaws.com"
PORT = 8883
TOPIC = "wellness/device/raspi-home-1/telemetry"

# センサデータの読み取り、変換、CRC チェック、etc...
def read_measurement():
  ...
  return co2, temp, hum

client.connect(ENDPOINT, PORT, keepalive=60)
client.loop_start()
start_periodic_measurement()

while True:
    co2, temp, hum = read_measurement()

    payload = {
        "device_id": "raspi-home-1",
        "timestamp_ms": int(time.time() * 1000),
        "temperature": round(temp, 2),
        "humidity": round(hum, 2),
        "co2_ppm": int(co2),
    }

    # MQTT publish
    result = client.publish(
      TOPIC,
      json.dumps(payload),
      qos=1
    )

    time.sleep(5)

スクリプトを Raspberry Pi 上で実行すると、センサデータのログが流れてきます。
センサに息を吹きかけると、CO2 が上昇していることが分かりますね!

Raspberry Pi 実行ログ


AWS 側で受信する

先ほどのスクリプトで、Raspberry Pi から送信した MQTT メッセージは、
IoT Core の以下のトピックに publish しています。

wellness/device/raspi-home-1/telemetry

AWS 側では、IoT Core のトピックルールにより、上記トピックに publish された場合は、
Lambda を起動し、受信した payload を DynamoDB に保存する ような仕組みになっています。

IoT Core トピックルール

ここまでで確認するポイントは以下となります。

  • CloudWatch Logs に Lambda の受信ログが出ること

  • DynamoDB の room_metrics テーブルにデータが保存されること

  • device_id と timestamp_ms を使って時系列データとして扱えること

まず、CloudWatch Logs から、AWS 側でセンサデータを受信できていることが確認できます。

CloudWatch Logs

DynamoDB にもセンサデータが登録されていますね!

DynamoDB

ここまでで、SCD40 → Raspberry Pi → IoT Core → DynamoDB までの、
センサデータを AWS 上に送信・保存 することができました。


Grafana でデータを可視化する

ここからは AWS 上のデータを可視化する 領域になりますが、
いくつかポイントを説明しながら進めていきます。

なぜ Athena を挟むのか?

DynamoDB に保存したデータを Grafana で時系列グラフとして扱うため、
今回は Athena DynamoDB Connector を利用しました。

Athena を挟むことで、DynamoDB のデータを SQL で扱える ようになる点がポイントです。

SELECT *
FROM "dynamodb_datasource"."room_metrics"
LIMIT 10;

クエリを Athena で実行すると、DynamoDB からデータを取得できました。

Athenaクエリ実行結果

Grafana ダッシュボード作成

Grafana 側では、Athena をデータソースとして追加して、
CO2 / 温度 / 湿度 を時系列グラフとして表示 できるようにします。

実際には以下のような流れで設定しています。

  • Amazon Managed Grafana Workspace 作成

  • Athena データソース追加

  • Time series グラフ作成

  • Athena SQL を使ったデータ可視化

例えば、CO2 の時系列グラフでは、以下のようなクエリを利用しています。

SELECT
  from_unixtime(timestamp_ms / 1000) as time,
  CAST(co2_ppm AS DOUBLE) as co2_ppm
FROM "dynamodb_datasource"."room_metrics"
WHERE
  device_id = 'raspi-home-1'
ORDER BY time

Grafana では Data source に Athena を選択して、
上記クエリを入力し、Visualizations に Time series を設定しています。

Grafana Datasource

クエリ結果から CO2 グラフを表示することができました!

CO2グラフ

CO2 / 温度 / 湿度 でダッシュボードを作成すると以下のようになります。
測定中にセンサに息を吹きかけた後、手で握ったので、
最初に CO2 が上昇した後、温度 / 湿度が上昇している ことがわかります。

Grafana Dashboard (3min)

苦労した点

実は、Grafana 側の権限設定にはかなりハマりました。

Athena Connector の Lambda Invoke 権限や、
Grafana Workspace IAM Role の S3 権限不足など、
複数サービスを跨ぐため原因の切り分けが難しかったです。

今回の構成では「動かない原因が IAM にある」ケースがかなり多く、
AWS の権限設計の重要さを実感しました。


可視化して分かったこと

実際にデータを可視化してみると、室内の状況をかなり把握することができました。

  • 換気しなかった夜間に CO2 の濃度が上昇している

  • 換気すると CO2 は一気に下がる

  • 日中は PC 作業や外気温の影響で室温が上がる

  • 湿度も温度や換気に連動して変化する

Grafana Dashboard (24h)

AI Agent へつなげるための設計

今回データを可視化してみて、Agent に渡すべき情報は「最新値」だけでは足りないということも分かりました。

例えば CO2 が高い場合でも、以下のパターンが考えられます。

  • 瞬間的に高いのか / 1時間ずっと高いのか

  • 上昇傾向なのか / ピークから下降傾向なのか

そのため、後続の AI Agent では情報を正しく判断できるように、
以下の情報を使うような設計にしました。

  • 最新値

  • 1時間平均

  • 最大値 / 最小値

  • トレンド

今回はセンサデータを AWS 上に集計・可視化までのお話ですが、
次の記事では、センサーデータ基盤を活用した AI Agent システム を紹介したいと思います。


まとめ

この記事では、SCD40 + Raspberry Pi + AWS IoT Core + Grafana を使って、室内環境を可視化するデータ基盤を構築しました。

できたことは以下となります。

  • Raspberry Pi から CO2 / 温度 / 湿度 を測定

  • AWS IoT Core に MQTT publish

  • Lambda で DynamoDB に保存

  • Athena 経由で Grafana 可視化

  • グラフから AI Agent に必要なデータ設計を検討

次の記事では、このデータを活用した、
室内環境・天気・スケジュールを統合的に判断する AI Wellness Agent
テーマにする予定です。


参考リンク



いいなと思ったら応援しよう!