M5StackGRAYのセンサの値を3G拡張ボードを使ってDynamoDBに送ってみた


以前、
[M5StackGRAYのジャイロセンサの値を3G拡張ボードを使ってSORACOM Harvestに送ってみた](https://qiita.com/tatsuya1970/items/b25881ddf11ae8cd6409)
というのをやったのですが、ゲームのように頻繁にリクエストが生じる場合、Harvestだとすぐリクエスト制限にかかってしまい、悩んでたところ、[SORACOMのMAXさん](https://qiita.com/ma2shita)からアドバイスを受け、DynamoDBに保存することにしました。

こんな感じです。
![アーキテクチャ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/291592/55461a60-5adf-b517-1c21-a43b8fba64e5.png)


M5Stackに3G拡張ボード（SORACOMのSIM）を使ってSORACOMプラットフォームに飛ばすまでは、手順、コードとも冒頭で紹介しました[私が以前書いた記事]
(
https://qiita.com/tatsuya1970/items/b25881ddf11ae8cd6409)のとおりです。




以下、DynamoDBに保存するまでの手順を示します。


##DynamoDBのテーブル作成

AWSのコンソールから DynamoDBへ

DynamoDBの[ダッシュボード]から[テーブルの作成]で
[テーブルの作成]をクリックします。
[![Image from Gyazo](https://i.gyazo.com/dca69fdee0ba49f5cdb5dbe130525c68.png)](https://gyazo.com/dca69fdee0ba49f5cdb5dbe130525c68)

[![Image from Gyazo](https://i.gyazo.com/ebe7676922f82e4ee84056bd66b36f1a.png)](https://gyazo.com/ebe7676922f82e4ee84056bd66b36f1a)
テーブル名、プライマリキーのパーティションキーを入力します。
私は複数のM5Stackからデータを集めようと思ってるので、テーブル名を「M5Stack」、パーティションキーをM5Stackごとに識別するために[id]という名前にしました。


##SORACOM Funkの設定
※このコーナーはほとんど[SORACOMのサイト](https://dev.soracom.io/jp/start/funk_aws_lambda/)のとおりです。

###事前準備（AWS)
SORACOM Funk から AWS Lambda を呼び出す為に、設定した AWS Lambda の ARN をメモします。

[![Image from Gyazo](https://i.gyazo.com/70652043c426bcc7461dfa3c2e475755.png)](https://gyazo.com/70652043c426bcc7461dfa3c2e475755)

以下の JSON を参考に Lambda 実行用の AWS IAM ユーザーを作成します。

```
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "AllowAuroraToExampleFunction",
            "Effect": "Allow",
            "Action": "lambda:InvokeFunction",
            "Resource": "先ほどコピーしたARN"
        }
    ]
}
```

AWS IAM ユーザーの作成方法は私が書いたこちらの記事を参考にしてください。
・[AWS IAM ユーザーの作成方法](https://qiita.com/tatsuya1970/items/51aceb688241d2460597)

AWS IAM　ユーザーを作成したとき生成される　「アクセスキーID」 と「シークレットアクセスキー」 をコピーします。

###SORACOMコンソールでの設定
SORACOM コンソールで AWS IAM ユーザーの認証情報を登録します。
SORACOM ユーザーコンソールの右上のユーザー名をクリックし、"セキュリティ“ を選択。
[![Image from Gyazo](https://i.gyazo.com/4190a258d46f96e0d00ec0d9d2378eed.png)](https://gyazo.com/4190a258d46f96e0d00ec0d9d2378eed)

[認証情報ストア] > [認証情報を登録]

認証情報 ID： 任意
種別　： [AWS 認証情報]を選択
AWS Access Key ID：　先ほどコピーした AWS ユーザーのアクセスキー ID
AWS Secret Access Key：　先ほどコピーした AWS ユーザーのシークレットアクセスキー

[![Image from Gyazo](https://i.gyazo.com/6b3f0a4a0a9f7804fd2bbcf2c4799822.png)](https://gyazo.com/6b3f0a4a0a9f7804fd2bbcf2c4799822)

利用する SIM の[SIM グループ] > [SORACOM Funk 設定]
[![Image from Gyazo](https://i.gyazo.com/2ee0e1a3ee4f42b9fdbeb803bfb9cd65.png)](https://gyazo.com/2ee0e1a3ee4f42b9fdbeb803bfb9cd65)

以下のように入力
[![Image from Gyazo](https://i.gyazo.com/831ca4b52ecdcf55f2c1ef7f376710fa.png)](https://gyazo.com/831ca4b52ecdcf55f2c1ef7f376710fa)


##AWS Lambdaの設定
###関数の作成
AWSのコンソールから
Lambda > 関数　＞　関数の作成
[![Image from Gyazo](https://i.gyazo.com/d76b7dbbadd14afec50e867a73bbb219.png)](https://gyazo.com/d76b7dbbadd14afec50e867a73bbb219)
[一から作成]
関数名　：　適当に
ランタイム：　Python3.8
[関数の作成]をクリックします。

関数ができたら、
以下のコードを入力します。
なお、このコードはこちらのサイトのコードを参考にしました。ありがとうございました。
・[LambdaでDynamoDBのデータを操作する(Node&Python)](https://qiita.com/is_ryo/items/74f3fc70b7602888a2ac)




```lambda_function.py
import boto3

def lambda_handler(event, context):
  
  gyroX = str(event["gyroX"])
  gyroY = str(event["gyroY"])
  gyroZ = str(event["gyroZ"])
 
  try:
    dynamoDB = boto3.resource("dynamodb")
    table = dynamoDB.Table("M5Stack") # DynamoDBのテーブル名

    # DynamoDBへのPut処理実行
    table.put_item(
      Item = {
        "id": "1",   # Partition Keyのデータ(複数のM5Stackから情報をとることにしてる)
        "payloads": {
            "gyroX":  gyroX,
            "gyroY":  gyroY,
            "gyroZ":  gyroZ
        }
      }
    )
    
    
  except Exception as e:
        print (e)


```

なお、上記のコードは、[冒頭でご紹介した私の記事（M5StackからHarvestに送る）](https://qiita.com/tatsuya1970/items/b25881ddf11ae8cd6409)から飛んでくる以下のようなJSONを想定しています。

```
{"gyroX": -13.2,"gyroY": -20.2,"gyroZ": -16.8}
```
<br>

###ポリシーの設定
このままでは、DynamoDBにデータが送れませんでした。
Lambdaのログを見るとこんなエラーでした。

```
arn:aws:sts::XXXXXXXXXXXXXXXXX is not authorized to perform: dynamodb:DeleteItem on resource: arn:aws:dynamodb:XXXXXXXXXXXXXXXX",
```

こちらのQiitaの記事を読んで解決できました。ありがとうございました。
・ [AWS lambdaからdynamodbに接続: "AccessDeniedException"で怒られたのでポリシーを設定した](https://qiita.com/hiroga/items/a672344efcf940e66485)

余談ですが、このQiitaの記事は約3年前に[Startup Weekend深セン](http://tatsuya1970.com/?p=11575)で同じチームだった方が書かれてました。凄い偶然にびっくり！　

エラーの原因は
LambdaにDynamoDBへアクセスできるポリシーを持たせてなかったからでした。

ポリシーを持たすには、以下の手順です。

アクセス権限　＞　実行ロール　[編集]をクリックします。
[![Image from Gyazo](https://i.gyazo.com/a35e622db0093cffc423e3d9a2cabf40.png)](https://gyazo.com/a35e622db0093cffc423e3d9a2cabf40)

[Lambda-Dynamo-role-XXXXXXXXロールを表示] をクリックします。
[![Image from Gyazo](https://i.gyazo.com/d73ed328a0bea0e4291359cac1af504a.png)](https://gyazo.com/d73ed328a0bea0e4291359cac1af504a)

こんな画面に遷移
[ポリシーをアタッチします] をクリックします。
[![Image from Gyazo](https://i.gyazo.com/c75eb37725d73f8f0583901112e16774.png)](https://gyazo.com/c75eb37725d73f8f0583901112e16774)

「dynamo」で検索し、
AmazonDynamoDBFullAccess にチェックを入れて、[ポリシーのアタッチ]をクリック
[![Image from Gyazo](https://i.gyazo.com/1bbc77e8a617d7970d597d3dfae3b758.png)](https://gyazo.com/1bbc77e8a617d7970d597d3dfae3b758)



##M5Stack起動

成功！！

無事、M5Stackのセンサーデータが、DynamoDBに送られました。

[![Image from Gyazo](https://i.gyazo.com/c944d3bcbe02461a2d478ae8c8d93413.png)](https://gyazo.com/c944d3bcbe02461a2d478ae8c8d93413)

DynamoDB JSON （普通のJSONとは違う）に直すと

```
{
  "id": {
    "S": "1"
  },
  "payloads": {
    "M": {
      "gyroX": {
        "S": "-10.7"
      },
      "gyroY": {
        "S": "-22.3"
      },
      "gyroZ": {
        "S": "-17.6"
      }
    }
  }
}
```

以上です。