[[AWSメモ]] >
* AWS IotでPub/Subしてみる [#n9a088b0]
#setlinebreak(on);

#contents
-- 参考
--- https://docs.aws.amazon.com/ja_jp/iot/latest/developerguide/what-is-aws-iot.html
--- https://docs.aws.amazon.com/ja_jp/iot/index.html#lang/ja_jp
--- https://github.com/aws/aws-iot-device-sdk-python

** 概要 [#wc6ff721]
#html(<div style="padding-left: 10px;">)
[[AWS IoT SDK>https://docs.aws.amazon.com/iot/latest/developerguide/iot-sdks.html]] を使用してMQTT接続するクライアントを書く。
#html(</div>)


** AWSサービス側の設定 [#z7306981]
#html(<div style="padding-left: 10px;">)

参考
AWS IoT への Raspberry Pi の接続 - https://docs.aws.amazon.com/ja_jp/iot/latest/developerguide/iot-sdk-setup.html

*** ポリシーの作成 [#e2daf2bb]
#html(<div style="padding-left: 10px;">)

[[マネージメントコンソール>https://ap-northeast-1.console.aws.amazon.com/iot/home?region=ap-northeast-1#/policyhub]] から、以下の通りポリシーを作成する。

| 名前 | sample-iot-policy |
| アクション | iot:* |
| リソース ARN | * |
| 効果 | 許可 |

#html(</div>)

*** 証明書の作成 [#z018d450]
#html(<div style="padding-left: 10px;">)

- [[マネージメントコンソール>https://ap-northeast-1.console.aws.amazon.com/iot/home?region=ap-northeast-1#/certificatehub]] から証明書を作成する。
- 作成したモノの証明書、パブリックキー、プライベートキー、及び ルートCA証明書をダウンロードしておく。
-「有効化」しておく。
-「ポリシーをアタッチ」で作成しておいたポリシーをアタッチする。

※ルートCA証明のダウンロード先
https://docs.aws.amazon.com/ja_jp/iot/latest/developerguide/managing-device-certs.html#server-authentication

#html(</div>)

*** モノの登録 [#q456980c]
#html(<div style="padding-left: 10px;">)
[[マネージメントコンソール>https://ap-northeast-1.console.aws.amazon.com/iot/home?region=ap-northeast-1#/thinghub]]  の「単一のモノを作成する」からモノを登録する。
#html(</div>)

*** 証明書にモノにアタッチ [#wfea3c81]
#html(<div style="padding-left: 10px;">)

[[マネージメントコンソール>https://ap-northeast-1.console.aws.amazon.com/iot/home?region=ap-northeast-1#/certificatehub]] から対象の証明書に「モノをアタッチ」する。
※ポリシーをアタッチ済みの場合は不要?

#html(</div>)

*** エンドポイントの確認 [#h72c0a96]
#html(<div style="padding-left: 10px;">)
[[マネージメントコンソールの設定>https://ap-northeast-1.console.aws.amazon.com/iot/home?region=ap-northeast-1#/settings]] からエンドポイントを確認しておく。
※エンドポイントはAWSアカウント毎に1つだけ存在する。
#html(</div>)

#html(</div>)


** デバイス側の環境構築 [#z104781d]
#html(<div style="padding-left: 10px;">)

いくつか方法はあるが、ここでは AWSIoTPythonSDK を使用した。
尚、Publish は [[マネージメントコンソール>https://ap-northeast-1.console.aws.amazon.com/iot/home?region=ap-northeast-1#/test]] から簡単に行う事ができるが、一応 boto3 から Publish する処理を作る為、ここでは boto3 もインストールしておく。
尚、テスト用の Publish は [[マネージメントコンソール>https://ap-northeast-1.console.aws.amazon.com/iot/home?region=ap-northeast-1#/test]] から簡単に行う事ができるが、一応 boto3 から Publish する処理を作る為、ここでは boto3 もインストールしておく。
※aws configure は事前にしておく事。

GitHub
https://github.com/aws/aws-iot-device-sdk-python

#myterm2(){{
mkdir test_iot && test_iot
python3 -m venv venv
source venv/bin/activate
pip install boto3
pip install AWSIoTPythonSDK
}}
#html(</div>)

** デバイス側の処理作成 [#c5c6dcad]
#html(<div style="padding-left: 10px;">)

https://github.com/aws/aws-iot-device-sdk-python/blob/master/samples/basicPubSub/basicPubSub.py を参考に任意のトピックをサブスクライブするクライアントを作成する。

client.py
#mycode2(){{
# coding: utf-8

from AWSIoTPythonSDK.MQTTLib import AWSIoTMQTTClient
import logging
import time
import argparse
import json

# MQTTの設定情報
host = 設定画面で確認したエンドポイント
port = 8883
rootCAPath = ルートCA証明書ファイルPATH
certificatePath = モノの証明書ファイルPATH
privateKeyPath = プライベートキーのファイルPATH
clientId = 'sample-thing1'  # Thing Name と同じである事が推奨されている
topic = 'topic/SampleTopic1'  # サブスクライブするTopic
# topic = 'topic/#'  # トピックの前方一致でサブスクライブする事も可能

# メッセージ受信時のコールバック
def customCallback(client, userdata, message):
    print("Received a new message: ")
    print(message.payload)
    print("from topic: ")
    print(message.topic)
    print("--------------\n\n")

# ログ設定
logger = logging.getLogger("AWSIoTPythonSDK.core")
logger.setLevel(logging.DEBUG)
streamHandler = logging.StreamHandler()
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
streamHandler.setFormatter(formatter)
logger.addHandler(streamHandler)

# MQTTクライアントの初期化/設定
myAWSIoTMQTTClient = AWSIoTMQTTClient(clientId)
myAWSIoTMQTTClient.configureEndpoint(host, port)
myAWSIoTMQTTClient.configureCredentials(rootCAPath, privateKeyPath, certificatePath)
myAWSIoTMQTTClient.configureAutoReconnectBackoffTime(1, 32, 20) 
myAWSIoTMQTTClient.configureOfflinePublishQueueing(-1)  # Infinite offline Publish queueing
myAWSIoTMQTTClient.configureDrainingFrequency(2)  # Draining: 2 Hz
myAWSIoTMQTTClient.configureConnectDisconnectTimeout(10)  # 10 sec
myAWSIoTMQTTClient.configureMQTTOperationTimeout(5)  # 5 sec

# 接続
myAWSIoTMQTTClient.connect()

# サブスクライブ
myAWSIoTMQTTClient.subscribe(topic, 1, customCallback)

while True:
    time.sleep(1)
}}

#html(</div>)

** テスト用のPublish処理を作成 [#ucfbd5c2]
#html(<div style="padding-left: 10px;">)

test_publish.py
#mycode2(){{
# coding: utf-8

import boto3
import json
from datetime import datetime

def main():
    client = boto3.client('iot-data')
    now = datetime.now()
    payload = json.dumps({
        'message': f'Hello AWS Iot! {now}'
    }).encode()
    response = client.publish(
        topic='topic/SampleTopic1',
        qos=0,
        payload=payload
    )   
    print(response)


if __name__ == '__main__':
    main()
}}
※ https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/iot-data.html#IoTDataPlane.Client.publish

#html(</div>)

** 実行 [#tc583bce]
#html(<div style="padding-left: 10px;">)

デバイス側のクライアントを起動
#myterm2(){{
python client.py
}}

テストメッセージをPublish
#myterm2(){{
python test_publish.py
}}

結果(デバイス側のクライアント)
#myterm2(){{
2018-01-01 14:26:39,574 - AWSIoTPythonSDK.core.protocol.internal.workers - DEBUG - Dispatching [message] event
Received a new message: 
b'{"message": "Hello AWS Iot! 2018-01-01 14:26:39.287980"}'
from topic: 
topic/SampleTopic1
--------------
}}

#html(</div>)

** 補足 [#x1332ab0]
#html(<div style="padding-left: 10px;">)

*** ワイルドカードを使用したトピックのサブスクライブ [#p734f8bd]
#html(<div style="padding-left: 10px;">)
ワイルドカードを使用してトピックの前方一致や部分一致でサブスクライブする事が可能。

参考
https://docs.aws.amazon.com/ja_jp/iot/latest/developerguide/topics.html
#html(</div>)


#html(</div>)

トップ   差分 バックアップ リロード   一覧 単語検索 最終更新   ヘルプ   最終更新のRSS