LoginSignup
0
2

More than 5 years have passed since last update.

Raspberry Pi+PythonでLoRaWAN Deviceにチャレンジしてみる(3)

Last updated at Posted at 2017-11-20

今回の内容

前回からの続きで、3回目となります。(長くなってスミマセン・・・)
これまでの2回でプラットフォームへデータが送信できることを確認できましたので、今回と次回の2回に渡ってデバイスに取り付けたセンサーで取得したデータを、Amazon S3に保存するところまでやってみたいと思います。

トポロジ

アプリケーションサーバ側は下図のように、API GatewayKinessis Firehose(以下、Firehose)、S3を使って構築します。

Topology.png

AWS側の準備

クラスメソッドさんが解りやすい情報を公開していましたので、その情報にある「AWSサービスプロキシ」方式に倣って設定してみます。
尚、クラスメソッドさんが情報を公開した時点では、東京リージョンでのFirehose利用はできませんでしたが、現在は利用できますので、AWS側は全て東京リージョンで構成することにしました。

Firehose

  1. AWSマネジメントコンソールからKinesisを開き、次にFirehoseコンソールに移動をクリック
    firehose_002.png

  2. Create Delivery Streamをクリック
    firehose_003.png

  3. Delivery stream nameに任意のストリーム名を入力、SourceDirect PUT or other sourcesが選択されていることを確認し、ページ下部のNextをクリック
    firehose_004.png

  4. Record transformationDisabledが選択されていることを確認し、Nextをクリック
    firehose_005.png

  5. DestinationAmazon S3を選択、S3 bucketは任意のバケット(既存、またはCreate newをクリックして新しいバケットを作成)を選択し、Nextをクリック
    firehose_006.png

  6. Buffer interval60に変更し、IAM roleにあるCreate new, or Chooseボタンをクリック
    firehose_007.png

  7. 別ページが新たに開くので、IAMロール新しいIAMロールの作成のまま、ロール名に任意の名称を入力し、許可をクリック
    firehose_008.png

  8. IAMロールページが閉じて元のページに戻るので、IAM roleに上記で作成したロール名が表示されていることを確認し、Nextをクリック
    firehose_009.png

  9. ここまでの操作で設定した内容が表示されるので、内容を確認してCreate delivery streamをクリック
    firehose_010.png

  10. S3 Delivery Streams一覧に、作成したストリームが表示される
    firehose_011.png

以上の手順で、FirehoseがS3を操作するためのIAM Roleと、Firehoseストリーム、S3バケット(新規作成した場合)が作成されます。

またFirehoseストリームに対して、次のようなIAM Role(lorawan_delivery_role)が作成されています。

信頼関係(Trust Relationships)

Firehose に対し、AssumeRoleすることを許可するポリシードキュメント

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "",
      "Effect": "Allow",
      "Principal": {
        "Service": "firehose.amazonaws.com"
      },
      "Action": "sts:AssumeRole",
      "Condition": {
        "StringEquals": {
          "sts:ExternalId": "<アカウントID>"
        }
      }
    }
  ]
}

アクセス権限(Permissions)

S3やAmazon Lambda、Logs、Kinesisに対して、操作を許可するインラインポリシー

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "",
            "Effect": "Allow",
            "Action": [
                "s3:AbortMultipartUpload",
                "s3:GetBucketLocation",
                "s3:GetObject",
                "s3:ListBucket",
                "s3:ListBucketMultipartUploads",
                "s3:PutObject"
            ],
            "Resource": [
                "arn:aws:s3:::<バケット名>",
                "arn:aws:s3:::<バケット名>/*",
                "arn:aws:s3:::%FIREHOSE_BUCKET_NAME%",
                "arn:aws:s3:::%FIREHOSE_BUCKET_NAME%/*"
            ]
        },
        {
            "Sid": "",
            "Effect": "Allow",
            "Action": [
                "lambda:InvokeFunction",
                "lambda:GetFunctionConfiguration"
            ],
            "Resource": "arn:aws:lambda:ap-northeast-1:<アカウントID>:function:%FIREHOSE_DEFAULT_FUNCTION%:%FIREHOSE_DEFAULT_VERSION%"
        },
        {
            "Sid": "",
            "Effect": "Allow",
            "Action": [
                "logs:PutLogEvents"
            ],
            "Resource": [
                "arn:aws:logs:ap-northeast-1:<アカウントID>:log-group:/aws/kinesisfirehose/lorawan:log-stream:*"
            ]
        },
        {
            "Sid": "",
            "Effect": "Allow",
            "Action": [
                "kinesis:DescribeStream",
                "kinesis:GetShardIterator",
                "kinesis:GetRecords"
            ],
            "Resource": "arn:aws:kinesis:ap-northeast-1:<アカウントID>:stream/%FIREHOSE_STREAM_NAME%"
        },
        {
            "Effect": "Allow",
            "Action": [
                "kms:Decrypt"
            ],
            "Resource": [
                "arn:aws:kms:region:accountid:key/%SSE_KEY_ARN%"
            ],
            "Condition": {
                "StringEquals": {
                    "kms:ViaService": "kinesis.%REGION_NAME%.amazonaws.com"
                },
                "StringLike": {
                    "kms:EncryptionContext:aws:kinesis:arn": "arn:aws:kinesis:%REGION_NAME%:<アカウントID>:stream/%FIREHOSE_STREAM_NAME%"
                }
            }
        }
    ]
}

API Gateway向けIAMロール作成

API Gatewayのメソッド作成時に指定するIAMロールを、新たに作成します。
今回はfirehose_for_lorawanという名前で作成しました。

信頼関係(Trust Relationships)

API GatewayがAssumeRoleすることを許可するポリシードキュメント

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "",
      "Effect": "Allow",
      "Principal": {
        "Service": "apigateway.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}

アクセス権限(Permissions)

Firehoseにデータレコードを書き込むAPI(PutRecordPutRecordBatch)を許可するインラインポリシー

PutRecord
単一のデータレコードをストリームに書き込む
PutRecordBatch
1回の呼出しで複数のデータレコードをストリームに書き込む
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "Stmt",
            "Effect": "Allow",
            "Action": [
                "firehose:PutRecord",
                "firehose:PutRecordBatch"
            ],
            "Resource": [
                "*"
            ]
        }
    ]
}

API Gateway作成

  1. AWSマネジメントコンソールからAPI Gatewayを開き、APIの作成をクリック、更に新しいAPIを選択し、API名に任意の名称を入力してAPIの作成をクリック
    apigw_001.png

  2. アクションをクリックし、リソースの作成をクリック
    apigw_002.png

  3. リソース名にapiを入力し、リソースの作成をクリック(リソースパスは、デフォルトでリソース名と同一文字が自動入力される)
    apigw_003.png

  4. 上記2~3と同様に、リソースapiの下にリソースv1を作成
    apigw_004.png

  5. アクションをクリックし、メソッドの作成をクリック
    apigw_005.png

  6. ドロップダウンからPOSTを選択し、確定アイコンをクリック
    apigw_006.png

  7. 下図に従って必要な値を入力し、保存をクリック
    apigw_007.png

    項目 設定値
    統合タイプ AWSサービス
    AWSリージョン Firehoseを作成したリージョン ※今回は東京リージョンなのでap-northeast-1
    AWSサービス Firehose
    HTTPメソッド POST
    アクション PutRecord
    実行ロール API Gateway向けIAMロール(firehose_for_lorawan
  8. メソッドの実行ページに遷移するので、統合リクエストをクリック
    apigw_008.png

  9. 本文マッピングテンプレートをクリックして展開し、リクエストが定義されていない場合を選択、更にマッピングテンプレートの追加をクリックし、Content-Typeapplication/jsonと入力して確定アイコンをクリック
    apigw_009.png

  10. テンプレートの生成欄が表示されるので、以下のコードを入力し、保存ボタンをクリック

    {
      "DeliveryStreamName": "lorawan_stream",
      "Record": {
        "Data": "$util.base64Encode($input.json('$.DevEUI_uplink'))"
      }
    }
    

    apigw_010.png

    [補足] マッピングテンプレートについて
    公式ドキュメントを確認すると、Firehoseに単一のデータレコードを書き込むPutRecord APIは、次のフォーマットになります。

    {
       "DeliveryStreamName": "string",
       "Record": { 
          "Data": blob
       }
    }
    

    また、LoRaWANプラットフォーム(ThingPark)からAPI GatewayにPOST送信されるJSONオブジェクトは、次のようなフォーマットです。

    {
        "DevEUI_uplink": {
            "Time": "2017-11-02T08:48:47.595+01:00",
            "DevEUI": "47XXXXXXXXXXXXXX",
            "FPort": "8",
            "FCntUp": "35",
            "ADRbit": "1",
            "MType": "4",
            "FCntDn": "40",
            "payload_hex": "1b1083202fd06b8c5410350c16b5",
            "mic_hex": "41293adb",
            "Lrcid": "01234567",
            "LrrRSSI": "-116.000000",
            "LrrSNR": "-5.000000",
            "SpFact": "9",
            "SubBand": "G0",
            "Channel": "LC4",
            "DevLrrCnt": "1",
            "Lrrid": "65XXXXXX",
            "Late": "0",
            "LrrLAT": "33.588463",
            "LrrLON": "130.397446",
                "Lrrs": {
                "Lrr": [
                    {
                        "Lrrid": "65XXXXXX",
                        "Chain": "0",
                        "LrrRSSI": "-116.000000",
                        "LrrSNR": "-5.000000",
                        "LrrESP": "-122.193314"
                    }
                ]
            },
            "CustomerID": "100008500",
            "CustomerData": {
                "alr": {
                    "pro": "LORA/Generic",
                    "ver": "1"
                }
            },
            "ModelCfg": "0",
            "DevAddr": "01XXXXXX"
        }
    }
    

    つまり、プラットフォームから送られてくるJSONオブジェクトの最上位メンバー DevEUI_uplinkを、PutRecord APIのDataメンバーにマッピングするすることで、DevEUI_uplinkメンバー内のデータを、Firehoseストリームに書き込む仕組みとなっています。
    更に、PutRecord APIのDataメンバーの値(上記APIフォーマットのblob)は、Base64でエンコードする必要があるため、組み込み関数base64Encode()を利用しています。
    マッピングテンプレートのその他組み込み関数については、こちらに詳しく説明があります。

ここまでの手順で、AWS側の設定作業は完了です。

API Gatewayテスト

以下の手順で、API Gatewayのテストを行ってみます。
(背後でFirehoseストリームと連動していますので、実質AWS側の統合テストになります)

  1. ページ上部にスクロールし、メソッドの実行をクリック
    apigw_011.png

  2. テストをクリック
    apigw_012.png

  3. リクエスト本文に以下のJSONコードを入力し、テストをクリック

    {
        "DevEUI_uplink" : "Fukuoka City LoRaWAN"
    }
    

    apigw_013.png

  4. (レスポンスの)ステータス200になっているか確認
    ※ステータスが200でない場合、表示されているログからエラー内容を確認できます。
    apigw_014.png

  5. S3バケットを確認し、データを確認
    apigw_015.png
    バケットに保存されたデータの中身

    "Fukuoka City LoRaWAN"
    

API Gatewayデプロイ

以下の手順で、作成したAPIをユーザーが呼び出せるようにデプロイします。

  1. アクションをクリックし、APIのデプロイをクリック
    apigw_016.png

  2. デプロイされるステージ新しいステージを選択、ステージ名に任意の名称を入力(今回はprod)してデプロイをクリック
    apigw_017.png

  3. ステージエディタが表示されればデプロイ完了
    尚、URLの呼び出しに記載されたURLに続けてリソースパスを指定したアドレス(今回の場合、https://xxxxxxxxxx.execute-api.ap-northeast-1.amazonaws.com/prod/api/vi)が、プラットフォーム側で設定するアプリケーションサーバのアドレスになります。(=>前回のアプリケーションサーバの登録を参照)
    apigw_018.png

次回

LoRaWANデバイスにセンサーを取り付け、送信してみます。

0
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
2