Amazon Web Services ブログ
AWS IoT Eventsと Amazon SageMaker を利用して遠隔地の設備検査を実現する
多数の設備を持つ組織は、物理的および運用上の問題を検出し対処するために、設備の状況を検査する必要があります。この記事では、バルブ、石油/ガスパイプライン、送電線などのインフラストラクチャのようにアクセス困難なエリアにある設備を定期的に検査する架空の企業であるAcmedroneのドローンデバイスを使用した事例について説明します。これら設備の検査では、ドローンデバイスが設備の画像を撮影し、物理的な損傷や適切な設備の動作に影響を与える可能性のある物理的な障害など、設備の変更(シーンの変化)を検出する機械学習モデルに対して検証します。
この記事では、前述の設備検査ソリューションの運用概要を説明し、該当する AWS IoT サービスの設定方法について説明します。
- AWS IoT Eventsを利用し、設備の検査ルートを管理
- Amazon SageMaker を利用してシーンの変化を検出
- 設備画像のアップロードや検出で利用するAmazon S3 と AWS Lambda function
- シーンの変化の通知で利用するAmazon Simple Notification Service (SNS)
- デバイスとAWSサービスとの連携にAWS IoT Core
ソリューション概要
大規模な産業施設内のさまざまな設備を検査するために、ドローンデバイスが特定のルートをたどらなければならないシナリオを考えてみましょう。検査中、ドローンデバイスは、設備のシーン画像をキャプチャするために、ルート上の各場所で停止します。これらの画像は AWS に送信され、シーンの変化を検出するために使用されます。大幅な変更が検出された場合、このソリューションは設備オペレータに通知します。
ドローンデバイスは、AWS IoT Device SDK for Python を利用したアプリケーションでAWS IoT Coreと接続します。また、認証プロバイダの機能を使いAWSのサービスを利用します。
この設備検査ソリューションでは、以下の一連のデータとメッセージングが含まれています。
- ドローンデバイスは、検査ルートの開始のために、MQTT トピックを介して AWS IoT Core にメッセージをパブリッシュします
- AWS IoT Core ルールエンジンは、MQTT トピックからメッセージを取得します
- AWS IoT Core ルールエンジンのアクションでAWS IoT Eventsにメッセージを送ります
- メッセージを受け取ったAWS IoT Eventsでは探知器モデルを利用し、検査ルートの開始を検出(ドローンデバイスからの通知)し、AWS IoT Core MQTT トピックに指示用のメッセージ(撮影エリアへの移動)をパブリッシュします
- デバイスは、MQTTトピックから指示を受け取ります
- デバイスは撮影エリアに移動し、設備のシーンを撮影します
- デバイスは撮影したシーン画像をAmazon S3のバケットにアップロードします
- バケット内にシーン画像がアップロードされると、AWS Lambda 関数が実行されます
- AWS Lambda 関数は、アップロードされた画像のシーンの変化を検出するように Amazon SageMaker (事前にAmazon SageMaker で作成したモデルがデプロイされた)エンドポイントにリクエストを投げます
- もし、シーンに変化が検出された場合、AWS Lambda関数はSNSのトピックに対してメッセージを送信します
- SNSトピックにサブスクライブしたユーザーは、シーンに変化があった通知を受け取ります
前提条件
設備検査ソリューションに従って設定するには、次のものを用意してください。
- AWSのアカウント
- PythonおよびAWS IoT Device SDK for Pythonがインストールされた、デバイスまたはPC
ドローンデバイスのルートを管理するAWS IoT Eventsの設定
AWS IoT Events では、ドローンデバイスのルートを開始するための次のコンポーネントを作成します。
- ドローンデバイスから AWS クラウドに送信されるメッセージを表す 1 つの入力
- 2 つの状態 (および 2 つの遷移) を持つ検出器モデル。メッセージを受信すると、デバイスの状態は「Area1」に変更されます。この状態はドローンが撮影エリアに移動するトリガーに使用されます
以下のセクションでは、上記のコンポーネントの実装方法と、デバイスからのメッセージを AWS IoT Eventsに転送するように AWS IoT Core を設定する方法について説明します。
AWS IoT Eventsで入力の作り方
AWS IoT Eventsで入力を作成するには、ガイドに従って入力を作成します。この例では、次の情報で入力を作成します。
- 入力名が「deviceNotifInput」に設定されています
- 以下の内容を含む JSON ペイロード/イベントの例
{
  "deviceID": "1",
  "notifType": "StartRoute",
  "dateTm": "05/26/2021  08:03:20.200"
}AWS IoT Eventsで探知器の作り方と公開方法
この例では、次の情報を持つ検出器モデルを作成します。
- 2 つの状態 (Stoppedと Area1)
- デバイスをあるステートから別のステートに移行する2 つのトランジション(StartTransition と stopTransition)
- デバイスからのメッセージを受信すると、開始トランジション(startTransition)は、 AWS IoT Core の MQTT トピック(詳細については、前のセクションの手順 1 ~ 4 を参照)へのメッセージ送信を実行し、デバイスの状態を Stopped から Area1 に変更
探知機モデルを作成するには、次の手順に従って、このサンプルをダウンロードし、AWS IoT Events にインポートします。
- 探知機モデルの IAM ロールを作成します。詳細については、AWS IoT Eventsのアクセス権限の設定に関するドキュメントを参照してください
- GitHubのリポジトリからサンプル探知機モデルファイルをダウンロードします
- 探知機モデルの IAM ロールの ARN でファイルを更新します (“#detectorModelRoleArn#”の部分を、次の形式のARNに置き換えます”arn:aws: iam። account:role/Service-role/detectorRoleName“)
- AWSのマネージメントコンソールを開き、AWS IoT Eventsのコンソールに移動します
- 探知機モデルの作成を選択し、- 探知機モデルのインポートを選択します
- インポートを選択し、ダウンロードしたファイルを選択し、- 開くを選択します。これにより、探知機モデルが作成されます
- 探知機モデルを作成したら、探知機モデルの作成ガイドに従って公開できます。この例では、探知機の生成モデルは、deviceId にキーが設定された一意のキー値ごとに探知器を作成するに設定されています。ディテクターの評価方法は、以下のスクリーンショットに示すようにバッチ評価に設定されています
AWS IoT Coreのルールを設定するには
AWS IoT Core (MQTT トピック) から AWS IoT Eventsにデバイスからのメッセージを転送するように AWS IoT Coreのルールを以下の手順で設定します。
- AWSのマネージメントコンソールを開き、AWS IoT Coreのコンソールに移動
- 左のメニューからACT、ルール、作成と選択します
- ルールの名称を指定し、ルールクエリステートメントにSELECT * FROM ‘deviceInboundTopic’と入力します
- アクションの追加を選択します
- 以下のスクリーンショットのようにIoT Events入力にメッセージを送信するを選択し、アクションの設定を選択します
- AWS IoT Eventsで作成した入力を選択します
- ロールではロールの作成を選択し、ロール名を入力します
- アクションの追加を選択します
- ルールの作成を選択します
シーンの変化を検出するようにAmazon SageMakerを設定する
Amazon SageMaker は、設備(設備のシーン画像)が変更されたかどうかを評価するモデルを構築します。
Amazon SageMaker でモデルを作成するには、このノートブックをダウンロードして、以下の手順に従います。
- Amazon SageMaker のノートブックインスタンスの作成の手順を参考に、Amazon SageMaker ノートブックインスタンスを作成します
- ノートブックインスタンスが起動したら、JupyterLab を開くを選択してノートブックインスタンスを開きます
- 以下のスクリーンショットにあるように、ファイルアップロードのアイコンを選択します
- 先ほどダウンロードしたノートブックを選択します
- ファイルがアップロードされたら、次のスクリーンショットの様に、新しいフォルダを作成アイコンを選択し、フォルダ名を「images」に設定します
- images フォルダーに移動し、こちらにある画像をアップロードします
- ノートブックを開き、すべてのセルを実行します。完了したら、モデルエンドポイントが Amazon SageMaker コンソールに表示されるはずです
- Amazon SageMakerのコンソールに戻ります
- 左側のメニューから 推論>エンドポイントと開き作成されているのを確認します
Amazon S3 に設備画像をアップロードし、AWS Lambda で検査する
デバイスがシーン画像を撮影すると、Amazon S3 バケットにアップロードされます。次に、Amazon SageMaker モデルに対してイメージを評価するために AWS Lambda 関数がトリガーされます。変更が検出された場合、Lambda 関数は SNS トピックに通知を発行します。
このソリューションを設定するには、次の手順を実行します。
Amazon Simple Notification Service の設定
- SNS トピックを作成します。詳細については、SNSの開発者ガイドを参照してください。具体的には、Amazon SNS の API リファレンスの CreateTopic オペレーションのドキュメントを参照してください
- Amazon SNS トピックへのサブスクライブをサブスクライブするには」に従って、SNS トピックをサブスクライブします
AWS Lambdaの設定
- 以下の JSON ポリシードキュメントを使用して IAM ポリシーを作成します。手順の詳細については、IAM ユーザーガイドの手順を参照してください
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "sagemaker:InvokeEndpoint"
      ],
      "Resource": [
        "arn:aws:sagemaker:region:account_number:endpoint/#endpoint_name#"
      ]
    },
    {
      "Effect": "Allow",
      "Action": [
        "sns:Publish*"
      ],
      "Resource": [
        "sns_topic_arn"
      ]
    }
  ]
}- 注:上記のポリシーでは、次の太字で書かれているregion、account number、Amazon SageMaker endpoint name (例:linear-learner-2021-01-01-22-39-49-363)、SNS トピックの ARN (arn:aws:sns:region:account:snsTopicName)を正しい値に置き換えます
- このユーザーガイドの説明に従って、AWS Lambda 関数の IAM ロールを作成します 
         - 権限の選択を求めるメッセージが表示されたら、以前に作成したポリシーを選択します
- Amazons3ReadOnlyAccessを選択します
 
- コンソールで Lambda 関数を作成するの説明に従って AWS Lambda 関数を作成します 
         - ランタイムではPythonを指定します(例: Python3.8)
- ロールには先ほど作成したロールを指定します
 
- AWS Lambda関数が作成されたら、以下の設定を行います 
         - 設定のタブを選択し、- 一般設定で- 編集を選択し、メモリに- 256を入力、タイムアウトを1分に変更して保存します
- コードタブを選択し、レイヤーセクションでレイヤーの追加を選択します
- AWSレイヤーで、AWS-Lambda-Python38-SciPi1xを選択します
- バージョンでは、最新のバージョンを選択し、追加を選択します
 
- 作業しているPCにディレクトリを作成し、こちらからAWS Lambda ソースコードをダウンロードし、作成したディレクトリに保存します 
         - このディレクトリで、lambda_function.pyを開き、作成したAmazon SageMakerのエンドポイントを#SAGEMAKER_ENDPOINT_NAME#に指定し、SNSトピックのARNを#SNS_TOPIC_ARN#に指定したら保存します
- pip3 install –upgrade -r requirements.txt -t . --no-dependenciesを実行して必要なPythonのライブラリをインストールします
- ディレクトリ内の全てのファイルを含めたzipファイルを作成します
- 注意:pipでインストールする際には、AWS Lambda関数で指定したPythonのバージョンと合わせる必要があります (例: Python 3.8を選択したならばPip 3.8を利用)
 
- AWS Lambdaのコンソールで、コードのタブを選択し、アップロード元のドロップダウンで.zipファイルを選択して、作成したzipファイルを選択し、保存でアップロードします
Amazon S3の設定
- こちらの手順を参考に、Amazon S3のバケットを作成します
- Amazon S3 バケットに新しい画像がアップロードされたときに AWS Lambda 関数をトリガーするために、Amazon S3 イベント通知を作成します。イベント通知を有効にするには、ドキュメントを参照してください。 
         - イベントの種類ではすべてのオブジェクト作成イベント(s3:ObjectCreated:*)を指定します
- 送信先では、Lambda関数を選択し、Lambda関数ARNを入力を選び、ARNを入力します
 
- イベントの種類では
デバイス接続のためにAWS IoT Coreを設定
デバイスのクレデンシャルを作成
デバイスクレデンシャルを作成するには、以下のガイドに従ってください。完了すると、証明書、秘密鍵、公開鍵、ルート CA 証明書が取得できます。
- AWS IoT Core Policyの作成
- 証明書を作成し、証明書にIoT Core Policyを紐付け
- IoT Core Policyに以下のポリシーを指定
注意:以下のAWS IoT Core Policy例では、太字のregion, accountを実際の値に置き換えます
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": "iot:Connect",
      "Resource": "arn:aws:iot:region:account:client/clientid"
    },
    {
      "Effect": "Allow",
      "Action": ["iot:Publish", "iot:Receive"],
      "Resource": "arn:aws:iot:region:account:topic/deviceInboundTopic"
    },
    {
      "Effect": "Allow",
      "Action": ["iot:Publish", "iot:Receive"],
      "Resource": "arn:aws:iot:region:account:topic/deviceOutboundTopic"
    },
    {
      "Effect": "Allow",
      "Action": ["iot:Subscribe"],
      "Resource": "arn:aws:iot:region:account:topicfilter/*"
    }
  ]
}AWS IoT Coreに接続
デバイスのクレデンシャルが作成されたら、IoT デバイスを AWS IoT Core に接続し、以下の手順に従ってデバイスからメッセージをパブリッシュできます
注意: 最初にAWS Python SDKとAWS IoT Device SDKをインストールしておく必要があります。取得したクレデンシャルはプログラムを実行するデバイスに配置し、以下のサンプルのmyMQTTClient.configureCredentialsの引数に正しいパスを指定します。myMQTTClient.configureEndpointにはAWS IoT Coreのエンドポイントを指定します。
import boto3
import json
import logging
import time
from AWSIoTPythonSDK.MQTTLib import AWSIoTMQTTClient
logging.basicConfig(filename='pythonIotDevice.log', filemode='w', format='%(name)s - %(levelname)s - %(message)s',level=logging.DEBUG)
logger = logging.getLogger('pythonIotDevice')
logger.info("pythonIotDevice")
#Connection to the AWS IoT Core with Root CA certificate and unique device credentials (keys and certificate) previously retrieved
# For certificate based connection
myMQTTClient = AWSIoTMQTTClient("clientid")
# For TLS mutual authentication
myMQTTClient.configureEndpoint("your.iot.endpoint", 8883) #Provide your AWS IoT Core endpoint (Example: "abcdef12345-ats.iot.us-east-1.amazonaws.com")
myMQTTClient.configureCredentials("/root/ca/path", "/private/key/path", "/certificate/path") #Set paths for Root CA, for private key and private certificate
myMQTTClient.configureOfflinePublishQueueing(-1)
myMQTTClient.configureDrainingFrequency(2)
myMQTTClient.configureConnectDisconnectTimeout(10)
myMQTTClient.configureMQTTOperationTimeout(5)
logger.info("Connecting...")
myMQTTClient.connect()
#Publish device notification to AWS IoT Core
deviceId = 1
timestamp = time.time()
logger.info("Publishing...")
myMQTTClient.publish("deviceInboundTopic", "{\"deviceID\":\"" + str(deviceId) + "\",\"notifType\":\"StartRoute\",\"dateTm\":\""+ str(timestamp) +"\"}", 0)
def handleResponse(client, userdata, message):
    jsonMessage = json.loads(message.payload)
    logger.info('jsonMessage=%s', jsonMessage)
    logger.info("Subscribing...")
myMQTTClient.subscribe("deviceOutboundTopic", 1, handleResponse)
#Wait until reception of subscription confirmation (wait 60 seconds)
time.sleep(60)
logger.info("Disconnecting...")
myMQTTClient.disconnect()Amazon S3に接続
デバイスが Amazon S3 にイメージを直接アップロードする際には、AWS IoT Core には認証情報プロバイダーという仕組みがあり、組み込みのデバイスに発行した X.509 証明書をユニークなIDとしてAWS リクエストを認証できます。これにより、アクセスキー ID とシークレットアクセスキーをデバイスに保存する必要がなくなります。
設定の手順の詳細については、ドキュメントを参照してください。認証情報プロバイダーが引き受ける IAM ロールに次の IAM ポリシーをアタッチします。
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": "s3:PutObject",
      "Resource": "arn:aws:s3:::#bucket_name#/*"
    }
  ]
}注意:太字の部分は実際のバケット名を指定します
次のコードスニペットは、Amazon S3 にイメージをアップロードする方法のみを示しています。コードスニペットを実行するには、この場所からイメージの 1 つをダウンロードします。次に、以下太字の部分には、正しい名前やパスを指定します。
import boto3
import json
import logging
import time
import requests
logging.basicConfig(filename='pythonS3IotDevice.log', filemode='w', format='%(name)s - %(levelname)s - %(message)s',level=logging.DEBUG)
logger = logging.getLogger('pythonS3IotDevice')
logger.info("pythonS3IotDevice")
iot_credentials_endpoint='https://#iot_credentials_provider_endpoint#/role-aliases/#role_alias#/credentials' #Provide your AWS IoT Credentials endpoint (Example: "acbcdef12345.credentials.iot.us-east-1.amazonaws.com") and the IAM role alias previously created.
response = requests.get(iot_credentials_endpoint, cert=("/certificate/path", "/private/key/path")) #Set paths for private certificate and private key
if response:
    tmp_credentials = response.json()
    access_key_id = tmp_credentials['credentials']['accessKeyId']
    secrete_access_key = tmp_credentials['credentials']['secretAccessKey']
    session_token = tmp_credentials['credentials']['sessionToken']
    s3client = boto3.client(
      's3',
      aws_access_key_id=access_key_id,
      aws_secret_access_key=secrete_access_key,
      aws_session_token=session_token,
    )
    s3client.upload_file('/jpegimage/path', "#bucket_name#", '#image_name#.jpg') #Set path for jpeg image to upload. Then specify the bucket name (name of the bucket previously created) and the image name.メモ:より詳細なサンプルを参照するには、AWS IoT SDK(for Python)のサンプルやAWSのサービスの直接呼び出しの認証を参照してください。
後片付け
全ての動作確認が終わり、追加のコストが発生しないようにしたい場合は、作成したリソースをアカウントから削除してください。削除が必要なリソースは以下になります。
- 以下のCLIコマンドで、AWS Lambda関数を削除します
aws lambda delete-function --function-name #lambda_function_name# --region #region#- こちらのガイドを参考に、Amazon S3のバケットを削除します
- こちらのガイドを参考に、Amazon SageMakerのリソースを削除(モデル、エンドポイント、ノートブック)
- 以下ののCLIコマンドで、AWS IoT Eventsの探知機モデルを削除します
aws iotevents delete-detector-model --detector-model-name #detector_model_name# --region #region#メモ:上記のCLIコマンドの太字部分について
- #lambda_function_name#は、作成したAWS Lambda関数の名称です
- #region#は、実際にリソースを作成したリージョンを指定します(例:us-east-1)
- #detector_model_name#は、作成したAWS IoT Eventsの探知機の名称です
まとめ
この記事では、ドローンが設備(例:ガス管)の画像を撮影し、機械学習のモデルを使って検証し、正常な動作に影響を与える可能性のある設備の変更を検出するユースケースについてみてきました。
このソリューションをまとめると
- まずは、ドローンのルートを管理するAWS IoT Eventsの探知機を作成しました
- 次に、ドローンからの画像を検証する機械学習のモデルを作成し、検証する画像をアップロード先のAmazon S3のバケットを作成しました
- Amazon S3にアップロードされた画像を処理するためのAWS Lambda関数を作成し、受け取った画像をAmazon SageMakerのモデルを使って検証して、変化を検出したらAmazon SNSを利用して通知を送るようにしました
- 最後に、AWS IoT Coreとデバイスを接続する設定や、デバイスからAmazon S3へアクセスできるようなPythonのサンプルコードも確認しました
今回利用したサービス( AWS IoT Core、AWS IoT Event、Amazon SageMaker)をさらに詳しく知りたい場合は、それぞれのサービスのページを参照してください。
また、AWS IoTのサービスに関しては公開ハンズオンを数多く用意していますので、そちらも参考にしてください。
原文はこちら
翻訳はソリューションアーキテクト 市川が担当しました。





