Amazon Web Services ブログ

AWSでプールの水温監視ソリューションを構築してみましょう!

(この記事は『Build your pool water temperature monitoring solution with AWS』を翻訳したものです)

私は南フランスのトゥールーズに住んでおり、気候は温暖湿潤気候に分類されています(ケッペンの気候区分によるとCfa に分類されています)。 これが、ここでプールがとても一般的なものである理由です! 私の家族も例外ではありません。 しかし、ギークとして、自分のプールの温度の監視、リアルタイムの指標の確認、履歴の表示、というのが実現したかったです。

一緒に deep dive(ダジャレのつもりです)してみましょう!このブログでは、AWSサービスを組み合わせて、コスト効率の高い方法で水温監視ソリューションを構築する方法を説明していきます。 このデモに従うことで、独自の水温監視ソリューションを構築するだけでなく、他のクリエイティブな監視ソリューションを構築するための便利なツールも学ぶことができます。

前提条件

私は NCIR hat を備えた M5StickC と、AWS IoT Core、Amazon Timestream、Amazon Managed Service for Grafana を備えた AWS アカウントを持っていました。これは、始めるために必要なものをすべてをカバーしています!

コンポーネントの概要

M5StickC は、ESP32 を搭載した Mini M5Stack であり、ポータブルで使いやすいオープンソースの IoT 開発ボードです。 M5StickC は M5Stack 製品シリーズのメインデバイスの一つであり、継続的に成長しているハードウェアとソフトウェアのエコシステムに組み込まれています。開発プロセスのすべてのステップに役に立つ多くの互換性のあるモジュールとユニット、およびオープンソースとエンジニアリングのコミュニティもあります。

NCIR hat は M5StickC 互換の赤外線センサーです。この HAT モジュールは、人体またはその他の物体の表面温度を測定するために使用できる MLX90614 を統合しています。このセンサーは、物体から跳ね返る赤外線を測定することで、物理的に接触せずに温度を感知することができます。

AWS IoT Core を使用すると、サーバーのプロビジョニングや管理が必要なく、IoT デバイスを AWS に接続できます。 AWS IoT Core は、数十億のデバイスと数兆のメッセージに対応できて、それらのメッセージを処理して AWS エンドポイントや他のデバイスに確実かつ安全にルーティングできます。 AWS IoT Core を使用すると、デバイスが接続されていない場合でも、アプリケーションが常にすべてのデバイスに対して追跡し通信することが可能になります。

Amazon Timestream は、IoT および運用アプリケーション向けの高速でスケーラブルなサーバーレス時系列データベースサービスです。リレーショナルデータベースの 1/10 のコストと最大1,000倍の高速で、1日あたり数兆のイベントを保存および分析することができます。

Amazon Managed Service for Grafana(AMG)はオープンソースの Grafana のもとで Grafana Labs と共同で開発されたフルマネージドサービスです。エンタープライズ機能で強化された AMG を使用すると、運用データを大規模に視覚化および分析することが容易になります。 Grafana は人気のあるオープンソース分析プラットフォームであり、メトリックが保存されている場所に関係なく、メトリックのクエリ、視覚化、アラート、および分析を可能にします。

大まかなアーキテクチャ

以下の図は M5StickC から AWS IoT Core を経由、Timestream を経て、AMG でダッシュボードを見ているエンドユーザーまでのデータの流れを示しています。

image.png

AWS IoT Core のセットアップ

次の手順から始めます:

  • ポリシー作成
  • 以下のものを含む、Thing(モノ)の作成
    • 証明書作成
    • ポリシーのアタッチ

ポリシー作成

AWS IoT Core ポリシーを使用すると、AWS IoT Core メッセージバスに接続したり、MQTT メッセージを送受信したりできるAWS IoT Core オペレーションへのアクセスを制御できます。

  1. AWS マネジメントコンソールを開きます。
  2. AWS IoT Core サービスに移動し、「Secure」 → 「Policy」セクションを開きます。
  3. 「Create」を選択します。
  4. 次の値を入力します。
    • Name:TempCheckerPolicy
    • Statements → Advanced
      {
        "Version": "2012-10-17",
        "Statement": [
          {
            "Effect": "Allow",
            "Action": "iot:Publish",
            "Resource": "arn:aws:iot:<region>:<account-id>:topic/TempCheckerTopic"
          },
          {
            "Effect": "Allow",
            "Action": "iot:Subscribe",
            "Resource": "arn:aws:iot:<region>:<account-id>:topicfilter/TempCheckerTopic"
          },
          {
            "Effect": "Allow",
            "Action": "iot:Connect",
            "Resource": "*"
          }
        ]
      }
  5. 「Create」をクリックします。

モノの作成

  1. AWS マネジメントコンソールで AWS IoT Core を開きます。
  2. 「Manage」→「Things」セクションで、「Create」を選択します。
  3. 「Create a single thing」を選択します。
  4. 以下の情報で、モノのタイプを作成します。
    • Name: M5Stick
    • Description: An M5StickC with NCIR hat.
  5. 「Create thing type」を選択します。
  6. 次のページで、以下の情報でモノ作成のフォームに入力します。
    • Name: TempChecker
    • Thing type: M5Stick を選択します
  7. 「Next」を選択します。

モノに証明書を追加し、ポリシーをアタッチ

  1. 「One-click certificate creation (recommended)」のパネルで「Create certificate」をクリックします。

    そうすると、証明書が迅速に作成されます。
  2. 証明書、パブリックキー、プライベートキー、全てをダウンロードします。
  3. 「Attach a policy」を選択します。
    image.png
  4. 「TempCheckerPolicy」というポリシーを選択し、「Register Thing」をクリックします。

M5Stick のセットアップ

AWS IoT Core が IoT(MQTT)メッセージを受信する準備ができたので、次に進みましょう。

M5Stick は、UIFlowArduinoFreeRTOS などの複数の開発プラットフォームをサポートしています。このユースケースでは、UIFlow ビジュアルプログラミング機能(Blockly + Python を使用)と AWS IoT 組み込みライブラリを使用して、ビジネスロジックを簡単に構築およびデプロイすることができます。

注:UIFlow IDE をインストールする方法、および M5StickC に UIFlow ファームウェアを「書き込む」方法の詳細については、こちらを参照してください。

M5Stick で継続的に実行されるプログラムをビルドしてデプロイする必要があります。温度センサーデータを取得して AWS IoT Core に送信するために必要なすべての手順が含まれています。アルゴリズムは以下のようにシンプルです:

  • AWS IoT Core との通信を開始します。
  • M5StickC 内部クロックを NTP で初期化します。
  • 次のように毎秒繰り返すループを開始します。
    • NCIR hat から温度を取得します。
    • 温度と現在のタイムスタンプを含む JSON 形式のメッセージをパブリッシュします。

MQTT メッセージを使って、LCD 画面及び LED 信号に温度の視覚的表示を追加しました。

AWS CTO の Werner Vogels が言ったように、「すべてが常に失敗する」ので、エラーを減らすために、エラーから回復するための try-catchコンポーネントをデバッグに追加しました。

AWS IoT ブロックでは、ダウンロードした秘密鍵と証明書ファイルを使用して、keyFile と certFile の値を設定します。

image.png

UIFlow がブロックから micropython に変換します。

from m5stack import *
from m5ui import *
from uiflow import *
from IoTcloud.AWS import AWS
import ntptime
import hat
import json
import time
import hat

setScreenColor(0x111111)
hat_ncir5 = hat.get(hat.NCIR)
iterator = None
temperature = None
label0 = M5TextBox(5, 72, "1", lcd.FONT_Default, 0xFFFFFF, rotate=0)

from numbers import Number

try :
  aws = AWS(things_name='TempChecker', host='<endpoint>.iot.eu-west-1.amazonaws.com', port=8883, keepalive=300, cert_file_path="/flash/res/c47c10a25d-certificate.pem", private_key_path='')
  aws.start()
  try :
    ntp = ntptime.client(host='pool.ntp.org', timezone=2)
    iterator = 1
    while True:
      temperature = hat_ncir5.temperature
      M5Led.on()
      try :
        aws.publish(str('TempCheckerTopic'),str((json.dumps(({'Temperature':temperature,'Iterator':iterator,'Timestamp':(ntp.getTimestamp())})))))
        iterator = (iterator if isinstance(iterator, Number) else 0) + 1
        label0.setText(str(temperature))
        pass
      except:
        label0.setColor(0xff0000)
        label0.setText('IoT error')
      M5Led.off()
      wait(1)
    pass
  except:
    label0.setColor(0xff0000)
    label0.setText('NTP error')
  pass
except:
  label0.setColor(0xff0000)
  label0.setText('AWS error')

Amazon Timestream のセットアップ

次に、温度データ用のストレージを構成します。 Amazon はさまざまなユースケースをサポートするために、専用のデータベースを幅広く提供しています。 この場合、適切なジョブに適切なツールは Timestream です。

私たちのユースケースは、明らかに時系列データに関連しています。 Timestream は SQL を使用して、このタイプのデータを操作するための専用サービスであり、平滑化、近似、および補間のための組み込みの時系列関数を備えています。 Amazon Timestream は高度な集計、ウィンドウ関数、および配列や行などの複雑なデータ型もサポートしています。 また、Amazon Timestream はサーバーレスです。管理するサーバーも、プロビジョニングする容量もありません。 詳細については、ドキュメントをご覧ください。

Timestream でデータベースを作成

  1. AWS マネジメントコンソールで Timestream を開きます。
  2. 「Create database」を選択します。
  3. 以下の情報を入力します:
    • Configuration: Standard database
    • Name: TempCheckerDatabase
    • Encryption: aws/timestream
  4. 「Create database」をクリックします。

テーブルを作成

次のページで、テーブルを作成します。

  1. 新しく作成されたデータベースを選択し、「Tables」タブを開き、「Create table」を選択します。
  2. 以下の値で設定します:
    • Table name: Temperature
    • Data retention:
      • Memory: 1 day
      • Magnetic: 1 year
        image.png

AWS IoT Core 送信先のセットアップ

ストレージ側は AWS IoT Core からデータを受信する準備ができました。

では、M5StickC がデータを送信するときにトリガーされる IoT ルールを構成しましょう。 これにより、タイムストリームにデータを挿入するアクションが実行されます。

  1. AWS マネジメントコンソールで AWS IoT Core を開きます。
  2. 「Act」→「Rules」セクションで、「Create」を選択し、以下の情報を入力します:
    • Name: TempCheckerRule
    • Description: Rule to handle temperature messages
    • Rule query statement: SELECT Temperature FROM ‘TempCheckerTopic’image.png
  3. 「Set one or more actions」パネルで、「Add action」を選択します。「Write a message into a Timestream table」を選択し、「Configure action」をクリックします。
    image.png
  4. Timestream データベースおよび作成されたテーブルを選択します。次元として以下を設定します:
    • Dimension Name: Device
    • Dimension Value: M5stick
  5. 次に、サービスがデータベースをアクセスできるように、AWS IAM ロールを作成する必要があります。「Create role」を選択し、以下の情報を入力します:
    • Name: TempCheckerDatabaseRole
  6. 設定されたものをレビューし、「Add action」をクリックすることでアクションの作成を完了します。
    image.png
  7. 「Error action」パネルで、「Add action」を選択します。「Send message data to CloudWatch logs」を選び、「Configure action」をクリックします。
    image.png
  8. 「Create a new resource」を選択し、Cloudwatch に移動します。
  9. 「TempCheckerRuleErrors」というロググループを作成します。
  10. 「Action configuration wizard」で、リソースリストをリフレッシュし、新しく作成されたロググループを選択します。
  11. サービスが Cloudwatch にアクセスできるように、AWS IAM ロールを作成する必要があります。「Create role」を選択し、以下の名前を入力します:
    • Name: TempCheckerCloudwatchRole
      image.png
  12. 「Add action」をクリックします。
    image.png
  13. 「Create rule」をクリックすることで、ルールの作成を完了します。
    image.png
これで、M5StickC によって送信された温度データを Timestream データベースに送信する有効なルールができました。

Amazon Managed Service for Grafana のセットアップ

次に、データを可視化しましょう。

注:このブログが執筆された2021年8月12日時点では、AMG はまだプレビューの段階でしたが、2021年8月31日から AMG の一般向け提供が発表されました。

  1. AMG コンソールを開き、「Create workspace」を選択し、以下のように入力します:
    • Workspace name: TempCheckerWorkspace
  2. 「Next」を選択します。
    image.png

    管理を開始する前に、AWS シングルサインオン(SSO)を有効にするように求められます。 AWS アカウントでこれらのアクションをすでに実行している場合は、このステップをスキップできます。

    image.png

    AMG は AWS SSO と統合されているため、Grafana ワークスペース内の Active Directory、LDAP、Okta などの既存のユーザーディレクトリからユーザーとグループを簡単に割り当て、既存のユーザーID とパスワードを使用してシングルサインオンできます。 詳細については、このブログ投稿をご覧ください。

  3. 「Create user」を選択します。
  4. メールアドレス及びファーストネーム、ラストネームを入力し、「Create user」をクリックします。

    AWS Organization と AWS SSO は数秒で有効になります。 いくつかのメールが並行して届きます。1つは AWS Organization のセットアップの検証用で、もう1つは AWS SSO セットアップの検証用です。 それらを確認し、検証手順を完了することを忘れないでください。
  5. パーミッションタイプのところでデフォルトのマネージドサービスパーミッションを使用することで、AWS が IAM ロールを管理できるようにします。 その結果、AMG の進化によって IAM の更新が必要になった場合にも自動的に反映され、サービスが中断されることはありません。 「Next」をクリックします。
  6. これは個人プロジェクト用に作成したため、「Current account」を使用して、この AWS アカウントの承認を管理できます。 複雑な組織の場合は、AWS Organizations Units を活用した方が適切です。
  7. ワークスペースが Timestream のデータソースにアクセスできるように、「Amazon TimeStream」を選び、「Next」を選択します。

    「you must assign user(s) or user group(s) before they can access Grafana console (Grafana コンソールにアクセスする前に、ユーザーまたはユーザーグループを割り当てる必要があります)」という警告パネルが表示されます。 ユーザーを割り当てるには、次の手順を使用します:
  8. 「Assign user」を選択します。
  9. 新しく作成されたユーザーを選択し、「Assign user」をクリックします。
Grafana ワークスペースが作成されたら、このページでリンクが提供されます。

Grafana ダッシュボードを設定

  1. AWS SSO でログインします。
  2. Welcome page で Create → Dashboard に移動します。
image.png

Grafana では、各ダッシュボードに1つ以上のパネルが含まれています。 パネルは、基本的な視覚化の構成要素です。 いくつかの特別な目的のパネルを除いて、パネルは時間の経過に伴うデータの視覚的表現です。 これは、温度変動から現在のサーバーステータス、ログまたはアラートのリストまで扱うことが可能です。 各パネルには、さまざまなスタイルとフォーマットのオプションがあります。 パネルは、移動、再配置、およびサイズを変更できます。

まず、リアルタイムの温度表示用のパネルを追加します。 そのために、「Gauge」で素早くカラフルな可視化が実現できます。

温度計パネルを構成

  1. データソースとして Amazon Timestream を選択し、新しいパネルを追加します。
  2. データベースから最新の温度の値を取得するため、以下のクエリを入力します:
    SELECT measure_value::double AS temperature 
    FROM "TempCheckerDatabase".Temperature 
    ORDER BY time DESC 
    LIMIT 1

  3. 右側のパネルの設定で、パネルの名前を「Real time monitoring」に設定し、「Gauge visualization」を選択します。
  4. フィールドの設定で、「Min」と「Max」オプション及び関連する閾値を設定します。気温が上がるはずなので、青から赤へと進む虹を選びました。

  5. 「Save」を選択し、我々の温度計を見ることができます。

    温度ヒストリーパネルの設定

    二つ目のパネルは、Grafana でユーザーが選択した期間でフィルタリングされた履歴データを取得する温度履歴パネルです。

    1. データソースとして Amazon Timestream を選択し、新しいパネルを追加します。
    2. データベースに関連のあるフィルターでクエリするため、以下のクエリを入力します:
      SELECT ROUND(AVG(measure_value::double), 2) AS avg_temperature, BIN(time, $__interval_ms) AS binned_timestamp 
      FROM "TempCheckerDatabase".Temperature 
      WHERE $__timeFilter 
      AND measure_value::double < 100 
      AND measure_value::double > 20 
      GROUP BY BIN(time, $__interval_ms) 
      ORDER BY BIN(time, $__interval_ms)

      image.png

    3. 右側のパネルの設定で、パネルのタイトルを「Trend」に設定し、「Graph visualization」を選択します。
    4. 「Apply」をクリックすることで、二つ目のパネルを完了します。
    image.png

    これで、Grafana ダッシュボードに2つのパネルが作成されました。1つはゲージに現在の温度を表示し、もう1つはグラフに過去の温度を表示します。

    コスト

    AWS の従量課金制サービスを使用したこのプロジェクトのコストを見積もるために、以下の前提を設けます。

    • M5StickC が常時接続され、1秒あたり1つのメッセージを送信します。
    • すべての IoT メッセージは、それぞれ約40バイトで時系列データベースに書き込まれます。
    • 私は私のパーソナルダッシュボードの唯一のユーザーであるため、一つの Grafana エディターライセンスが有効になります。

    コストの内訳

    (注:現在の価格を確認するには、次の価格ページを確認してください)

    • AWS IoT Core の接続、メッセージング、およびルールエンジンのコストは月額3.42ドルです。
    • Amazon Timestream は、1年間のデータが保存された後、ストレージとクエリに月額1.64ドルの費用がかかります。
    • Amazon Managed Service for Grafana には、エディターライセンスごとに月額9.00ドルが請求されます。

    総費用

    総合的に、月額総費用は3.42ドル+1.64ドル+9.00ドル=月14.06ドルです。

    片付け

    このソリューションを実行した場合は、AWS アカウントに不要な料金が発生しないように、次の手順を実行してください。

    AWS IoT Core

    • 「Manage」セクションでモノとモノのタイプを削除します。
    • 「Secure」セクションでポリシーと証明書を削除します。
    • 「Act」セクションでルールを削除します。

    Amazon Timestream

    • データベースを削除します(これにより、テーブルも自動的に削除されます)

    Amazon Managed Service for Grafana

    • ワークスペースを全部削除します。

    AWS IAM

    • 作成されたロールを削除します。

    Amazon CloudWatch

    • 関連するロググループを削除します。

    まとめ

    このブログでは、スイミングプールの温度を監視するためのシンプルなエンドツーエンドソリューションを構築する方法を示しました。 このソリューションでは、多くのコーディングは不要:Grafana に対して2つのみの SQL クエリが求められました。試してみたい場合は、次のコードを使用して AWS アカウントに AWS Lambda 関数を作成することで、M5StickC をシミュレートできます。 AWS IoT Core へのアクセス権を持つ IAM ロールも付与してください。

    注:Cloud9 以外の環境で試す場合、iot_client を定義する際に endpoint_url と region_name で IoT エンドポイントと使うリージョンを指定する必要があります。(例:iot_client=boto3.client(‘iot-data’, endpoint_url=‘https://xxxxxxxx-ats.iot.ap-northeast-1.amazonaws.com’, region_name=’ap-northeast-1‘))

    import boto3
     import datetime
     import time
     import math
     import json
     
     iot_client=boto3.client('iot-data')
     topic = "TempCheckerTopic"
     
     def lambda_handler(event, context):
        i = 0
        while i < 800:
            i += 1
        
            # Calculating seconds from midnight
            now = datetime.datetime.now()
            midnight = now.replace(hour=0, minute=0, second=0, microsecond=0)
            seconds = (now - midnight).seconds
            
            # Calculating fake temperature value
            temperature = round(math.sin(seconds/600) * 5 + 25, 2)
            
            # Preparing payload
            payload = json.dumps({"Iterator": i,"Temperature": temperature,"Timestamp": now.timestamp()})
            
            # Publishing to IoT Core
            iot_client.publish(topic=topic, payload=payload)
            
            # Waiting for 1 second before next value
            time.sleep(1)
            
        return {
            'statusCode': 200
        }

    AWS IoT Core、Timestream、AMG を用いたプール用のスマート水温監視ソリューションを構築する方法を示したこのブログを読んでいただきありがとうございます。デモと学んだことが、革新的なアイデアを実現するきっかけになることを願っています。AWS IoT を使用したコネクテッドホームソリューションの詳細も是非ご覧ください。

    著者について

    image.png

    ジェローム・グラスは AWS のソリューションアーキテクトです。 彼は、インダストリーの顧客がビジネス目標を達成するために、スケーラブルで安全で費用効果の高いアプリケーションを構築できるよう支援することに情熱を注いでいます。 仕事以外では、ジェロームは家族と一緒に DIY やビデオゲーム、ボードゲームを楽しんでいます。

    翻訳は Solutions Architect の Fikko が担当しました。原文はこちらです。