AWS IoT デバイス死活監視

# はじめに
[前回の記事](http://qiita.com/yokobonbon/items/be0da968bba40b396187)で簡単にPythonでIoTデバイスのエミュレーションが可能になったことを説明させていただきました。

今回はAWS IoTのPub/Subの仕組みを利用してデバイスの死活監視を簡単に行ってみたいと思います。

# 前準備
[前回の記事](http://qiita.com/yokobonbon/items/be0da968bba40b396187)で作成したthingを利用しますので、内容を実施しておいてください。

# デバイス側(Python)の実装
デバイス側は、クライアント証明書や、デバイスのUUIDを指定して実行することを想定しています。死活監視用のtopicをデバイス側で登録して、そこにメッセージが入れば、返信するという単純な実装になっています。

以下、Pythonのサンプルコードです

```python
class AWSIoTClient:
    def __init__(self, endpoint, rootCA, key, cert, uuid):
        self.myMQTTClient = AWSIoTMQTTClient("python-thing")
        self.myMQTTClient.configureEndpoint(endpoint, 8883)
        self.myMQTTClient.configureCredentials(rootCA, key, cert)
        self.myMQTTClient.configureOfflinePublishQueueing(-1)  # Infinite offline Publish queueing
        self.myMQTTClient.configureDrainingFrequency(2)  # Draining: 2 Hz
        self.myMQTTClient.configureConnectDisconnectTimeout(10)  # 10 sec
        self.myMQTTClient.configureMQTTOperationTimeout(5)

        self.notificationTopic = uuid + "/notification"
        self.eventTopic = uuid + "/event"

    def start(self):
        self.myMQTTClient.connect()
        print "Wating for : " + self.notificationTopic
        self.myMQTTClient.subscribe(self.notificationTopic, 1, self.customCallback)

    def customCallback(self, client, userdata, message):
        print message.payload
        callbackMessage = "{\n    I'm healthy\n}"
        client.publish(self.eventTopic, callbackMessage, 1)

def main():
    args = Args()
    client = AWSIoTClient(args.getEndpoint(), args.getRootCA(), args.getKey(), args.getCert(),
                          args.getUUID())
    client.start()
    while True:
        time.sleep(1)
```
MQTTClientのsubscribeメソッドで"UUID/notification"トピックを監視しています。トピックにメッセージが書き込まれると、customCallbackメソッドが呼び出され、"UUID/event"トピックにメッセージを記述します。これにより死活監視が単純に実現されています。

subscribeメソッドの第二引数の1という値は、MQTTのQOSを表しています。

* 0: At most once 最高1回。到達を保証しない
* 1: At least once 少なくとも1回の到達を保証。重複の可能性あり
* 2: Exactly once 確実に一度の転送

[MQTClientのAPIリファレンス](https://s3.amazonaws.com/aws-iot-device-sdk-python-docs/sphinx/html/generated/AWSIoTPythonSDK.MQTTLib.html#AWSIoTPythonSDK.MQTTLib.AWSIoTMQTTClient)

pythonアプリの実装は、以下のような形で動作させる

```bash
python python-thing.py -e XXXX.iot.ap-northeast-1.amazonaws.com -r root-CA.crt -c test_thing.cert.pem -k test_thing.private.key -u 1234
```

# AWS IoT コンソールを使った動作確認
デバイス側の準備が整ったので、後はAWS IoTコンソールからメッセージをトピックに送信すれば良い。AWS IoTコンソールでは"Test"を選択すればトピックにメッセージを送信"Publish"もしくはメッセージの読み取り"Subscribe"が可能。

まずは、1234/eventトピックにデバイスからのヘルスチェックで返信されるので、以下のようにSubscribeする。

<img width="869" alt="スクリーンショット 2017-01-15 18.33.17.png" src="https://qiita-image-store.s3.amazonaws.com/0/85182/a02a066c-d17c-f23e-d3a6-a88280bd5881.png">

そして以下のようにデバイスが待ち受けている1234/notificationトピックにメッセージを送信。

<img width="995" alt="スクリーンショット 2017-01-15 18.32.50.png" src="https://qiita-image-store.s3.amazonaws.com/0/85182/f92df881-9512-84d1-0e36-d9f90415bf87.png">

デバイス側がトピックのメッセージを受信して、1234/eventに以下のように返信する。

<img width="824" alt="スクリーンショット 2017-01-15 18.38.19.png" src="https://qiita-image-store.s3.amazonaws.com/0/85182/fd35a0ba-7ce3-7b19-fa85-0ad29feb21a9.png">

# おわりに

特定のトピックにメッセージが来た場合に別のトピックにメッセージを返すことで簡単に死活監視が実現できる。これが一人で数時間で実現できるAWS IoT素晴らしいです。