Amazon Web Services ブログ

新しい AWS IoT Core Device Location 機能の使い方

この記事は How to get started with the new AWS IoT Core Device Location service の日本語訳です。

はじめに

新しい AWS IoT Core Device Location 機能 により、Internet of Things (IoT) デバイスは、全地球測位システム (GPS) ハードウェアに依存せずに、現在地を取得出来る様になりました。 GPS 座標や位置の特定に AWS IoT Core Device Location 機能を使用することで、AWS IoT Core に接続されたデバイスとクライアントは、クラウドアシストな全地球測位衛星システム (GNSS) や Wi-Fi スキャン、携帯基地局を利用した測位、IP アドレスに基づく位置推定といった方法を利用出来るようになります。

多くの Internet of Things (IoT) アプリケーションで、ジオロケーション情報とロケーショントラッキングは必須要件とされています。物流や自動車などの領域では、これらのデータなしに大きな成果を上げることは出来ません。歴史的にジオロケーションのモニタリングには、全地球測位システム (GPS) モジュールのような特定のハードウェアに依存してきました。デバイスに GPS ハードウェアが搭載されていない場合、デバイスへの機能追加やアップグレードには大幅なコストがかかったり、実装不可能である可能性があります。また GPS ハードウェアを内蔵していたとしても、そのデバイスが座標を取得するための GPS 衛星を常に捕捉し続けられるとは限りません。

この記事では、AWS IoT Core Device Location 機能の使い方をご紹介します。まず利用手順を確認し、その後に IP アドレスのみを使ってデバイス位置の取得をデモしてみます。

前提条件

このブログ記事の内容を実施するには、AWS アカウントAWS IoT Core が利用可能なリージョン、また AWS IoT ルールAWS Lambda 関数AWS Identity and Access Management (IAM) ロールとポリシーの作成権限、そして AWS CloudShell へのアクセス権限が必要です。また基本的な Linux bash コマンドの知識がある事を前提としています。

デモ

本記事のデモではデバイスの位置を取得するために、初めに MQTT メッセージで IP アドレスを AWS IoT Core にパブリッシュします。次に AWS IoT ルールがメッセージを Lambda 関数に転送します。続けて Lambda 関数で GetPositionEstimate API を使って AWS IoT Core Device Location 機能を呼び出します。最後に Lambda 関数で、デバイスまたは MQTT クライアントがサブスクライブしている位置情報応答トピックに、デバイスの位置情報を MQTT メッセージとしてパブリッシュします。以下の図は、このデモの実装内容を示しています。

ステップ 1: AWS Lambda 実行ロールとポリシーを作成

AWS CloudShell 環境から以下のコマンドを実行:

  1. 以降のステップで利用する環境変数の設定
    export ACCOUNT_ID=< アカウント ID に置き換え >
    export REGION=< リージョンコードに置き換え >
    
  2. create-role コマンドで Lambda 関数を実行するための IAM ロールを作成
    aws iam create-role --role-name "lambda-ex-ipAddressToDeviceLocationService" \
    --assume-role-policy-document '{
        "Version": "2012-10-17",
        "Statement": [
            {
                "Effect": "Allow",
                "Principal": {
                    "Service": "lambda.amazonaws.com"
                },
                "Action": "sts:AssumeRole"
            }
        ]
    }'
    
  3. ロールへ付与するポリシードキュメントを作成するために、下記コマンドを実行
    ( jq -n \
                --arg region "$REGION" \
                --arg account_id "$ACCOUNT_ID" \
                '{
                "Version": "2012-10-17",
                "Statement": [
                    {
                        "Effect": "Allow",
                        "Action": "iotwireless:GetPositionEstimate",
                        "Resource": "*"
                    },
                    {
                        "Effect": "Allow",
                        "Action": [
                            "logs:CreateLogGroup",
                            "iot:Publish"
                        ],
                        "Resource": [
                            "arn:aws:logs:\($region):\($account_id):*",
                            "arn:aws:iot:\($region):\($account_id):topic/device/test-1/location/ipbased/response"
                        ]
                    },
                    {
                        "Effect": "Allow",
                        "Action": [
                            "logs:CreateLogStream",
                            "logs:PutLogEvents"
                        ],
                        "Resource": "arn:aws:logs:\($region):\($account_id):log-group:/aws/lambda/ipAddressToDeviceLocationService:*"
                    }
                ]
            }' ) > lambda_policy.json
    
  4. put-role-policy コマンドでポリシーをロールにアタッチ
    aws iam put-role-policy \
    --role-name "lambda-ex-ipAddressToDeviceLocationService" \
    --policy-name lambda-ex-ipAddressToDeviceLocationService-policy \
    --policy-document file://lambda_policy.json
    

    get-role-policy コマンドでポリシーが正しくアタッチされたかを確認出来ます。

    aws iam get-role-policy \
    --role-name "lambda-ex-ipAddressToDeviceLocationService" \
    --policy-name lambda-ex-ipAddressToDeviceLocationService-policy

ステップ 2: Lambda 関数の作成

AWS CloudShell 環境から以下のコマンドを実行:

この Lambda 関数は、GetPositionEstimate API が新たにサポートされている AWS SDK for Python (Boto3) バージョン 1.26.45 以降が必要です。最新バージョンの Boto3 を Lambda 関数 で利用するために、 Lambda レイヤーを作成します。

  1. 次のコマンドで Lambda レイヤーを作成
    LIB_DIR=boto3-mylayer/python
     
    mkdir -p $LIB_DIR
    
    #(You may need to run this command 2 or 3 times so it can be resolved automatically)
    pip3 install boto3 -t $LIB_DIR
    
    cd boto3-mylayer 
    
    zip -r /tmp/boto3-mylayer.zip .
    
    LAYER=$(aws lambda publish-layer-version --layer-name boto3-mylayer --zip-file fileb:///tmp/boto3-mylayer.zip)
     
    LAYER_ARN=$(jq -r '.LayerVersionArn' <<< "$LAYER")
    
  2. 次のコマンドで Lambda デプロイパッケージを作成
    cd /home/cloudshell-user
    touch lambda_function.py
    
    cat > lambda_function.py <<EOF
    import json, boto3
    from datetime import datetime
    iot_wireless_client = boto3.client('iotwireless')
    iot_data_client = boto3.client('iot-data')
    
    def lambda_handler(event, context):
    
        iot_wireless_response = iot_wireless_client.get_position_estimate(Ip={ 'IpAddress': event['ipAddress']}, Timestamp=datetime.now())
    
        print(f"IoT Wireless Response: {iot_wireless_response}")
        
        iot_data_response = iot_data_client.publish(
            topic='device/test-1/location/ipbased/response',
            qos=0,
            payload=json.dumps({'location':json.loads(iot_wireless_response['GeoJsonPayload'].read())})
            )
       
        print(f"IoT Data Response: {iot_data_response}")
    EOF
    
    zip -r lambda_function.zip lambda_function.py
    
  3. 次のコマンドで Lambda 関数を作成し、Boto3 Lambda レイヤーを追加
    LAMBDA_FUNCTION=$(aws lambda create-function --function-name ipAddressToDeviceLocationServiceFunction \
    --zip-file fileb://lambda_function.zip --handler lambda_function.lambda_handler --runtime python3.9 \
    --role arn:aws:iam::$ACCOUNT_ID:role/lambda-ex-ipAddressToDeviceLocationService)
    
    LAMBDA_ARN=$(jq -r '.FunctionArn' <<< "$LAMBDA_FUNCTION")
    
    
    aws lambda update-function-configuration \
    --function-name ipAddressToDeviceLocationServiceFunction \
    --layers $LAYER_ARN
    

    add-permission コマンドで、作成した Lambda 関数の実行権限を AWS IoT Core に付与

    aws lambda add-permission --function-name ipAddressToDeviceLocationServiceFunction \
    --statement-id iot-events --action "lambda:InvokeFunction" --principal iot.amazonaws.com
    

ステップ 3: AWS IoT ルールの作成

AWS CloudShell 環境から以下のコマンドで IoT ルールを作成:

  1. create-topic-rule コマンドで IoT ルールを作成
    ( jq -n \
        --arg lambda_arn "$LAMBDA_ARN" \
        '{
            "sql": "SELECT * FROM \"device/+/location/ipbased\"",
            "ruleDisabled": false,
            "awsIotSqlVersion": "2016-03-23",
            "actions": [{
                "lambda": {
                    "functionArn": "\($lambda_arn)"
                }
            }]
        }' ) > iot_rule_document.json
        
    aws iot create-topic-rule \
    --rule-name "ip_address_to_device_location_service" \
    --topic-rule-payload file://iot_rule_document.json
    

ステップ 4: AWS IoT MQTT クライアントでデバイス位置の確認

MQTT メッセージを確認するために下記を実施:

  1. AWS IoT console 左側メニューの、テストセクションにある MQTT テストクライアントを選択
  2. トピックをサブスクライブする タブ内で、トピックのフィルターに device/test-1/location/ipbased/response を入力してサブスクライブを選択

    図 1 - MQTT テストクライアントでトピックのサブスクライブ

    図 1 – MQTT テストクライアントでトピックのサブスクライブ

MQTT メッセージをトピックへをパブリッシュする:

  1. トピックに公開する タブ内で、トピック名 device/test-1/location/ipbased を入力し、メッセージペイロードとして下記の JSON を入力
    • { "ipAddress": "< パブリック IP アドレスに置き換え >" }
  2. 発行 を選択し、メッセージをパブリッシュする

    図 2 – MQTT テストクライアントでトピックにパブリッシュ

    図 2 – MQTT テストクライアントでトピックにパブリッシュ

次の様な出力内容:

{
  "location": {
    "coordinates": [
      **Longitude**,
      **Latitude**
    ],
    "type": "Point",
    "properties": {
      "country": "United States",
      "city": "New York",
      "postalCode": "*****",
      "horizontalAccuracy": 20,
      "horizontalConfidenceLevel": 0.67,
      "state": "New York",
      "timestamp": "2023-01-04T20:59:13.024Z"
    }
  }
}

リソースの削除

課金を避けるために、この記事内で作成されたリソースを確実に削除します。リソースを削除するために、次のコマンドを実行してして下さい。

  1. aws iot delete-topic-rule --rule-name "ip_address_to_device_location_service"
  2. aws lambda delete-function --function-name "ipAddressToDeviceLocationServiceFunction"
  3. aws iam delete-role-policy --role-name "lambda-ex-ipAddressToDeviceLocationService"  --policy-name "lambda-ex-ipAddressToDeviceLocationService-policy"
  4. aws iam delete-role --role-name "lambda-ex-ipAddressToDeviceLocationService"

まとめ

この投稿では、新しい AWS IoT Core Device Location 機能の使い方や、利用する際の主な手順、および IP アドレスのみを使ったデバイス位置の取得について学習しました。この機能を使用してデバイスの位置を取得するだけでなく、Amazon Location Service を利用してデバイス位置を地図上で追跡することもできます。AWS IoT Core Device Location 機能を使った開発の詳細については、開発者ガイドSend Geo Coordinates from IoT Devices to Amazon Location Service with the AWS IoT Rules Engine をご確認下さい。AWS IoT Core for LoRaWAN を使用するアプリケーションの場合は、こちらの “アセットトラッキングソリューションをサポートする AWS IoT Core Device Location のご紹介” をご参照下さい。

著者

Yuri Chamarelli は、米国を拠点とする Amazon Web Services (AWS) のソリューションアーキテクトです。IoT スペシャリストとして、AWS IoT を使ったお客様のビジネス達成を支援することに注力しています。Yuri は、IT/OT システムで 10 年以上の経験を持つ制御エンジニアであり、多くの業界における産業変革や産業オートメーションプロジェクトで複数のお客様を支援してきました。

Nicholas Switzer は、Amazon Web Services の IoT スペシャリストソリューションアーキテクトです。2022 年に AWS に入社し、IoT とエッジコンピューティングを専門とし、コネクテッドプロダクト領域のお客様と協働しています。米国を拠点とし、日常生活を向上させるスマートプロダクトの構築を楽しんでいます。

この記事はソリューションアーキテクトの 山岡 卓紀夫 が翻訳しました。