死活監視はIoTの制御でよく実施される機能だと思いますが、AWS IoTではいくつかのアプローチがあるようです。
今回はconnectionトピックへ送信されるメッセージを使用した死活監視の一例を書き留めておきます。
環境
IoT機器:ラズパイ
ラズパイはAWSIoTPythonSDKのインストールと証明書ファイルの配置を行い、MQTT接続できる状態のものを想定。
通信状態の検知
まず、以下のようにAWSIoTPythonSDKのAWSIoTMQTTShadowClientを使用し、ラズパイとAWSIoTの間でコネクションを張ります。
from AWSIoTPythonSDK.MQTTLib import AWSIoTMQTTShadowClient
...
# Connect to AWS IoT
myAWSIoTMQTTShadowClient.connect()
すると、AWSIoT側は接続を検知し、以下のトピックにメッセージを送信する仕様となっています。
# 対象のclientIdのIoT機器が接続、切断を実施した際にパブリッシュされるトピック
$aws/events/presence/connected/clientId
$aws/events/presence/disconnected/clientId
ここにパブリッシュされたメッセージは以下の構造で入ってきます。
{
"clientId": "a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6",
"timestamp": 1460065214626,
"eventType": "connected",
"sessionIdentifier": "00000000-0000-0000-0000-000000000000",
"principalIdentifier": "000000000000/ABCDEFGHIJKLMNOPQRSTU:some-user/ABCDEFGHIJKLMNOPQRSTU:some-user"
}
このメッセージを死活監視情報とすることで監視を行います。
IoT Roleを使用した他サービスとの連携
死活情報の取得場所が分かったので、AWSの他のサービスと連携して保存していきます。
AWS IoTではトピックに入ったメッセージをトリガーとして他のサービスを呼び出すことが可能です。
今回はLambdaを使用してラズパイのShadowに死活情報を保存していきます。
Lambda関数を予め作成した後IoT Roleから呼び出すことで保存します。
- AWSIoTのコンソールからACT画面へ移動し、ルールの作成を開始。
- ルールクエリステートメントを以下のように記述
3.アクションの項目でアクションの追加
を選択
4. 実行したいAWSサービスを選択、今回はLambdaを選択
ここでShadowへの書き込みを行うLambda関数を選択します。指定するLambda関数は下記に記載します。
Shadowを書き換えるLambda関数の作成
Lambdaのコンソールへ移動します。
今回はPythonでboto3を使用し、Shadowに状態をレポートする処理を記述します。
import boto3
import json
def lambda_handler(event, context):
client = boto3.client('iot-data')
connected_bool = 0
if event['eventType'] == "connected":
connected_bool = 1
shadow = {"state":{'reported': {'connected': connected_bool}}}
print(event)
response = client.update_thing_shadow(
thingName = event['clientId'],
payload = json.dumps(shadow, ensure_ascii=False)
)
return
この関数を連携することでShadowに常にヘルスチェック情報を反映させることが可能になります。
ヘルスチェックの情報とShadowの状態は分けずにまとめた方が管理がしやすいと思いこのような構成にしました。
データベースへの保存などはこのShadowの内容をそのままDynamoDBへ保存すると良いと思います。