ローコードツール「FileMaker」開発者に贈る｜AWS IoT Core 初級ハンズオン

#この記事を読んで欲しい方
- **全FileMaker開発者**
 - クラウド触ったことない
 - AWS難しい
 - 新しいいこと好き
 - etc...

# この記事を読むとどうなるか？
AWSIoTCoreの概要とFileMakerとAWSの連携方法を理解できる
⇨日々楽しく改善できるようになる！

# どうやるか
AWS IoT Core 初級ハンズオン(https://aws-iot-core-for-beginners.workshop.aws/ )
に沿ってIoT実装の基本を理解し、その後FileMakerとの連携方法を学ぶ。


# 実践開始
この記事は
AWS IoT Core 初級ハンズオン(https://aws-iot-core-for-beginners.workshop.aws/ )
をみながら進めていきます。別タブで[こちら](https://aws-iot-core-for-beginners.workshop.aws/)を開いておくことをオススメします。

## AWS IoT Coreのサービス説明
まずはこちら(https://aws-iot-core-for-beginners.workshop.aws/phase1/step1.html )から
AWS IoT Coreのサービス説明動画をご覧ください。

まとめると。AWS IoT Coreとは「ラズパイやマイコンとの通信や管理を効率的に実現できるしくみ」です。

## ハンズオン構成
本ハンズオンで使用するAWSサービスの概要説明をこちら（https://aws-iot-core-for-beginners.workshop.aws/phase1/step2.html ）からご覧ください。

- Cloud9
    - ブラウザ上でコード記述可能
    - リアルタイムで共同編集可能
    - 今回はダミークライアントとして利用（センサー信号を送っているふりをさせる）
- Amazon Kinesis Data Streams
    - 管理が容易
    - 他サービスとのデータ連携を実現
    - 複数データまとめて処理が可能
- AWS Lambda
    - コードを書けばすぐに動く仕組み
    - サーバーの準備や管理が不要
    - 使用した分だけ課金
    - 「センサーデータが来たとき」などイベントで起動可能
- Amazon DynamoDB
    - Amazonが提供するNoSQLデータベース
    - 低遅延
    - 大規模データに向いている

## AWSアカウント作成
まずはこちら（https://aws.amazon.com/jp/register-flow/ ）に従ってAWSアカウントの作成をお願いします。
アカウント作成後にAWSマネジメントコンソールにログインすると下記のような画面が表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184509/bdf05514-9b2a-bb1e-7c58-e1b5fe1281c9.png)

## デバイスのセットアップ
- Raspberry Piとセンサーを使用される方はこちら（https://aws-iot-core-for-beginners.workshop.aws/phase2/step2.html ）
- その他の方はこちら（https://aws-iot-core-for-beginners.workshop.aws/phase2/step1.html　　) からセンサー情報をAWSに送信する仕組みを準備してください。
※Raspberry Piでセットアップを行う場合はファイルの場所にご注意ください。
SSHの設定はこちら（https://qiita.com/tomokin966/items/bc22d09f97ebeb3955d2 )の記事などを参考に設定してください。

## IoT Coreのセットアップ
こちら（https://aws-iot-core-for-beginners.workshop.aws/phase3.html　　 ) からAWS IoT Coreの設定をお願いします。
※Raspberry Piの場合はcertフォルダの作成場所にご注意ください。

## アプリケーション向けDB作成
こちら（https://aws-iot-core-for-beginners.workshop.aws/phase4.html　 　）よりFileMakerと連携するためのDBを作成します。
「(OPTIONAL)API用Lambdaの設定」まで実施してください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184509/3f40c8dc-ac3e-829d-1290-1a82c7567bf8.png)

## API用Lambdaのコード「lambda_function.py」を修正　｜↓ここからFileMakerとの接続のため本記事独自構成
取得するデータに湿度も追加します。また、クエリストリングを使用した検索を実装します。
下記のコードを「lambda_function.py」に貼り付けてください。


```python
from __future__ import print_function
import boto3
from boto3.dynamodb.conditions import Key
import datetime
import json
import traceback
import os

#-----Dynamo Info change here------
TABLE_NAME = os.environ.get('TABLE_NAME', "default")
DDB_PRIMARY_KEY = "deviceid"
DDB_SORT_KEY = "timestamp"
#-----Dynamo Info change here------

dynamodb = boto3.resource('dynamodb')
table  = dynamodb.Table(TABLE_NAME)

#------------------------------------------------------------------------


def dynamoQuery(deviceid, requestTime):
    print("dynamoQuery start")
    # データを取得
    valList = []
    res = table.query(
        KeyConditionExpression=
            Key(DDB_PRIMARY_KEY).eq(deviceid) &
            Key(DDB_SORT_KEY).lt(requestTime),
            ScanIndexForward = False,
            Limit = 5
        )

    # 取得したデータをリストに格納
    for row in res['Items']:
        temper = row['TEMPERATURE']
        humid = row['HUMIDITY']
        itemDict = {
            "timestamp":row['timestamp'],
            "temper":int(temper),
            "humid":int(humid)
            
        }
        valList.append(itemDict)

    return valList
    
def lambda_handler(event, context):
    HttpRes ={
        'isBase64Encoded': False,
        'statusCode': 200,
        'headers': {},
        'body': '{"message": "Hello from AWS Lambda"}'
    }
    
    
    try:
        print("lambda_handler start")
        print(json.dumps(event))

        # get Parameters
        pathParameters =  event['queryStringParameters']
        deviceid = pathParameters["deviceid"]
        requestTime = datetime.datetime.now().strftime('%Y-%m-%dT%H:%M:%S')

        resItemDict = { deviceid : ""}
        resItemDict[deviceid] = dynamoQuery(deviceid, requestTime)
        HttpRes['body'] = json.dumps(resItemDict)

    except Exception as e:
        print(traceback.format_exc())
        HttpRes["statusCode"] = 500
        HttpRes["body"] = "Lambda error. check lambda log"

    print("response:{}".format(json.dumps(HttpRes)))
    return HttpRes
```
コードの修正を反映させるために「Deploy」ボタンをクリックしてください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184509/97aa9945-cbbf-c23d-978d-c3dee681730b.png)

## API Gatewayの設定
外部から上記で作成したLambda関数をAPIで使用するための設定を行います。
### API Gatewayの画面を開く
こちら（　https://console.aws.amazon.com/apigateway ）からAPI Gatewayの画面を開いてください。
右上にある「APIを作成」をクリックしてください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184509/ee311fd7-1e76-e20f-78e1-c990a6973cf9.png)

REST APIの「構築」をクリックしてください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184509/c446e5b6-6604-5c9a-c2d0-adbd5e736ab0.png)

好きなAPI名をつけて右下にある「APIの作成」をクリックしてください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184509/303dcc8b-faee-12aa-091f-00391bfc68d2.png)

「アクション」→「リソースの作成」をクリックしてください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184509/53d5b0c6-c798-e422-52f2-347c14823e3b.png)

リソース名に「data」と入力し、「リソースの作成」をクリックしてください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184509/498bfb0e-a027-08ae-f1d8-41792933c0a3.png)

上記で作成した「data」をクリックした状態で「アクション」→「メソッドの作成」をクリックしてください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184509/b3d09d4c-f976-66ae-6a13-8b35a462c733.png)

「GET」を選択し、チェックをクリックてください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184509/8cd300ee-54c9-9d00-6f31-a80ac8391337.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184509/e35d9bff-8544-89a9-73ca-8bbda10d53d5.png)

統合タイプ「Lambda 関数」を選択、Lambda プロキシ統合の使用にチェック、Lambda 関数に「(OPTIONAL) API 用 LAMBDA の設定」で作成したlambda関数名を設定し、「保存」をクリックしてください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184509/721704d1-1b23-6990-ea64-48c5b2e129e7.png)

下記のようのようなダイアログが表示されるので「OK」をクリックしてください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184509/2bf5fad3-a2bd-d7ac-8644-f0882f06f922.png)


作成されたAPIとlambda関数のテストを行います。「テスト」をクリックしてください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184509/041b6808-0134-f90b-0ee1-6f225d17a7b5.png)

クエリ文字列に「deviceid={作成したモノのID}」を設定し、「テスト」をクリックしてください。
下記のようなレスポンスが返ってきます。
ここでうまく動かない場合は、センサー→IoTCore→kinesis→dynamoDBまでデータが来ているか、lambdaでエラーは発生していないか、などのご確認をお願いします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184509/1b56bcbd-cfbb-adea-3154-ca428cda9d44.png)

作成したAPIをデプロイし、どこからでも使用できるようにします。
※本番運用の際はセキュリティを強化してからご使用ください。
「アクション」→「APIのデプロイ」をクリックしてください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184509/71b46204-d980-5952-b5f5-279e14276074.png)

下記ダイアログが出るので、デプロイされるステージに「新しいステージ」を選択、ステージ名に「handson」と設定し、「デプロイ」をクリックしてください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184509/db22d4e9-1dbf-32e1-f2d3-465a1d0ee817.png)

APIをテストします。URL呼び出しのURLをコピーしてください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184509/947a4b0c-2d4b-1a66-fec1-097f03c934e8.png)

下記のように「/data/?deviceid={モノのID}」と修正し、ブラウザのURL欄に入れてアクセスしてください。

```
https://****.execute-api.ap-northeast-1.amazonaws.com/handson/data/?deviceid=rasp_ppi_20211005
```

下記のようにデータが表示されればAPIの設定は完了です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184509/c0e4c22c-f1cb-f4e4-11f1-1a73103ec76f.png)

## FileMakerの開発
上記で作成したAPIよりデータを取得するサンプルファイルをこちら （https://drive.google.com/uc?export=download&id=1cHPmAOIz6zfTeDiHmhDKTpCoZmP1f0KT ）からダウンロードしてください。

## 動きの確認
ダウンロードしたファイルを開き、g_base_urlに作成したAPIのURLを、g_deviceidに作成したモノのIDを下記のように設定してください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184509/591d68a8-19a2-fcba-8d93-29748d257300.png)

「データ取得」をクリックし、g_resultに結果が出力されることを確認してください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184509/00cf4d10-e2db-f956-b46d-2c6c4882b5ef.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184509/cd937a72-1057-7e4f-ab48-2e1fdacef11d.png)


「テーブル表示」をクリックし、ポータルにデータが表示されていることを確認してください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184509/a4954bb9-3ac1-2e51-3029-da69ea726d22.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184509/b3521197-aec3-6370-b6cf-0be8358eb5bd.png)

## スクリプトの解説
### 「データ取得」スクリプトについて
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184509/ba030722-73c5-7080-d403-9bcac3dd082c.png)
「URLから挿入」にてAWS　API Gatewayで作成したAPIに対してリクエストを送り、返ってきた値を$resultに挿入します。
「フィールド設定」にて取得した結果を見やすい形に整形し、g_resultに設定します。
```JSONFormatElements ( $result )```

### 「テーブル表示」スクリプトについて
取得したデータをポータルに表示します。
JSONGetElementを使用して取得したデータの中から各フィールドのデータを取り出します。
データをループさせて「環境情報」テーブルに書き込みます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184509/68c98aac-4000-a632-b45a-6f8f45271224.png)

# まとめ
以上でセンサー→AWS IoT Core→kinesis→dynamoDBにデータを貯めて
FileMaker→API Gateway→Lambda→dynamoDB からデータを取得する流れを実装しました。

# 注意
本記事の実装はあくまでハンズオンの構成となっています。実運用の際はセキュリティ周りを最適なものに置き換えてください。
AWS１年間無料枠での実装を行いましたが１年以上放置すると料金が発生する可能性があります。

こちら（https://aws-iot-core-for-beginners.workshop.aws/phase7.html ）　に沿って使用したサービスを削除してください。

# つむぎや株式会社について
私が所属するつむぎや株式会社ではFileMakerやIoTや機械学習を使用して業務を楽しく改善するお手伝いを行っています。
IoTについてやFileMakerについてお問い合わせお待ちしております^^
https://tsumugiya-it.com/