AWSIoTCore検証メモ②：IoT rule 編

公式ドキュメント
https://docs.aws.amazon.com/ja_jp/iot/latest/developerguide/iot-rules.html

##　IoT ruleとは

AWS IoT Core->ACT->RuleにIoT ruleを追加することでTopicへ送られてくるメッセージに対してアクションを行う事ができます。
IoT ruleを使うことで、デバイスから送られてくるメッセージをもとに他のAWSサービスと連携することができます。

例）

- デバイスから受け取ったデータの加工またはフィルタ処理を行う。
- デバイスから受け取ったデータを Amazon DynamoDB データベースに書き込む。
- Lambda 関数を呼び出してデータを抽出する。
- MQTT メッセージから Amazon Machine Learning にデータを送信して、Amazon ML モデルに基づいて予測を行う。
- ウェブアプリケーションまたはサービスにメッセージデータを送信する。


## IoT ruleの設定
IoT ruleの作成は[AWS IoT Core]->[ルール]->[作成]で新規ルールを作成できます。
クエリステートメントにルールクエリを記載することで送られてきたメッセージに対して加工を行うことができます。
![IoTRule_01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/678268/865ca543-b566-63c6-446c-eb3e5db8820f.png)


~~~sql
#topicに送られてくる全てのメッセージをトリガー
SELECT * FROM "<topic>"
~~~

ルールクエリには以下の組み込み関数が利用可能  
https://docs.aws.amazon.com/ja_jp/iot/latest/developerguide/iot-sql-functions.html#iot-func-abs

使用頻度の高そうな組み込み関数

- clientid() : メッセージを送信している MQTT クライアントのID
 - clientid() AS client_id
- timestamp()：ミリ秒単位で現在のタイムスタンプ
 - timestamp() AS timestam
- traceid() : MQTT メッセージのトレース ID (UUID)
 - traceid() AS trace_id

例）Topic:test/testingに送られてくるすべてのメッセージ内にデバイスのclientIDとtimestanpを追加するルールクエリ

~~~sql
SELECT clientid() AS client_id, timestamp() AS timestamp, * FROM "test/testing"
~~~
デバイスから以下のデータをTopic:test/testingに送信すると

~~~JSON
"data": {
    //元のデバイスからのメッセージ
    "message": "SendSensorData",
    "SensorData": 2
}
~~~
ルールクエリ内でclient_idとtimestampが送られてきたメッセージに追加される

~~~JSON
"data": {
    //元のデバイスからのメッセージ
    "message": "SendSensorData",
    "SensorData": 2,
    //ルールクエリで追加されたclientIDとtimestamp
    "clientID": "10PC202010012",
    "timestamp": 1617598518923
}
~~~
## DynamoDBに保存された静的データとの連携
ルール内でDynamoDBからのテーブルの抽出も可能

DynamoDBからルールクエリ内でデータを抽出する際の書式

~~~
get_dynamoDB (tableName、partitionKeyName、partitionKeyValue、sortKeyName、sortKeyValue, roleArn)
~~~

get_dynamoDB() の使用方法の例として、AWS IoT に接続されているすべてのデバイスのデバイス ID と位置情報を含む DynamoDB テーブルがあるとします。次の SELECT 文は、 get_dynamoDB() 関数を使用して、指定したデバイス ID の場所を取得することができます。
以下のような内容でDynamoDBにテーブルを用意し、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/678268/9ed57878-3016-989f-1b42-4cee4bd44d65.png)

ルールクエリに以下のクエリを指定します。
クエリの内容は、timestampの追加と、DynamoDBのIoTCoreTestテーブルからclientIDが一致するデータをDBdataとして追加するといった内容になっています。

~~~sql
SELECT *, timestamp() AS timestamp,get_dynamoDB("IoTCoreTest", "clientID" , clientID ,"arn:aws:iam::941279141676:role/DynamoDBTest").* AS DBdata FROM 'Test/IoTDevice01'
~~~
ルールクエリを動かしてみると以下のようなデータが取得できます。

~~~JSON
"data": {
  //元のデバイスからのメッセージ
  "message": "SendSensorData",
  "SensorData": 2,
  //ルールクエリで追加されたclientIDとtimestamp
  "clientID": "10PC202010012",
  "timestamp": 1617598518923,
  //ルールクエリ内でDynamoDBから抽出したデータ
  "DBdata": {
    "address": "東京都墨田区押上１丁目１−２",
    "clientID": "10PC202010012",
    "Tell": "yyy-yyyy-yyyy",
    "GeoJSON": {
      "coordinates": [
        139.764658,
        35.688752
      ],
      "type": "POINT"
    },
    "InstallationDate": "2021/04/05",
    "Admin": "Tom_zono",
    "LastCommunication": "",
    "DeviceName": "LIFEBOOK_U939"
  }
}      
~~~

ルールクエリを設定することにより、デバイスから送られてきたメッセージに対して、DBに保存してある静的データの追加等の処理が行えるようになりました。
初回のユースケースの構成では今回の内容は赤枠内のトピックからルールまでの設定部分になります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/678268/4c739f74-1395-1799-3975-374f5c9b0ffb.png)

## IoT ruleの使いどころ
AWSのサービスとデバイスからのメッセージを連携させて処理させるときにはIoT ruleのRuleActionを使えば簡単に連携させることができる。

デバイスからのデータにclientIDを追加することによって、AWS以外のサービスを使うときにもどのデバイスからデータが送信されてきてるのかの判別が容易になる。
このデータに、DynamoDBに保存されているデバイスの静的データ(設置場所の情報、設置時期、デバイスの管理者etc...)が加わってくれば付加価値の高いデータとしてリアルタイム処理を行うことができそう。
センサー等の動きのあるデータはデバイス上のプログラムから送信して、変更される頻度が少ないデータはDynamoDBに保存して、その都度呼び出してあげたほうがよさそうですね。
後はWHERE句を使うことでセンサー値n以上の場合処理を行うなど取った設定もできるので、閾値の設定などlambda等を使う必要がない簡単な処理はルールクエリを活用するといいと思います。


次回は届いたメッセージの内容に応じて何らかのアクションを起こす[ IoT action ]について検証を行っていきます。
[AWS IoT CoreCore検証メモ③：IoT action について](https://qiita.com/tomzono/private/e5eb603d7f84348cc95c)

---
[AWS IoT CoreCore検証内容一覧へ](https://qiita.com/tomzono/private/eaa786b6a1889351c752)