AWS IoT Device SDK for Pythonを使ってRaspberryPiとAWS IoTをつないでみる

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

どうも!大阪オフィスの西村祐二です。

今頃感はありますが、AWS IoTのマネージメントコンソールのUIが変わっていたりするので、
AWS IoTとデバイス(RaspberryPi)の接続方法について記載していきたいと思います。

今回、AWS IoT Device SDK for Pythonを使って接続してみます。
そして、サンプルコードにあるPubSubやThingShadowの更新など動かしてみたいと思います。

※RaspberryPiにSSH接続できる前提で進めていますのでご了承ください。

環境

  • RaspberryPi 3 Model B
  • Linux raspberrypi 4.14.18-v7+ #1093 SMP Fri Feb 9 15:33:07 GMT 2018 armv7l GNU/Linux
  • aws-iot-device-sdk-python:v1.3.1
  • python2.7

AWS IoTでの作業

▼AWS IoTのマネージメントコンソールにアクセスします。

▼「モノの登録」をクリックし、デバイスを登録していきます。

▼「単一のモノを作成する」をクリックします。

▼Thing Registryにデバイスを追加します。
名前は今回「office-raspberry」としました。
モノのタイプ、グループは適時設定してください。

▼AWS IoTとデバイスを接続するたの証明書を作成します。
「証明書の作成」クリックすると自動的に証明書一式を作成してくれます。

▼証明書の作成が完了したら、それぞれローカルにダウンロードしておきます。
また、ルートCAは「rootCA.pem」として今回は保存しています。
さらに、「有効化」のボタンを押して「完了」をクリックします。
ポリシーのアタッチは後で行ないます。(この時点でまだポリシー未作成なのでアタッチするポリシーがない)

▼ポリシーを作成します。

▼名前を「RaspberryPiPolicy」、アクションを「iot:*」、リソース「*」として今回は作成します。

▼先程作成した証明書にポリシーをアタッチします。

これでAWS IoT側の作業は完了です。

RaspberryPiでの作業

▼RaspberryPiにSSHでログインし、aws-iot-device-sdk-pythonをインストールします。

$ sudo pip install AWSIoTPythonSDK
$ git clone https://github.com/aws/aws-iot-device-sdk-python.git
$ cd aws-iot-device-sdk-python

▼作成した証明書をRaspberryPiに配置します。
動作確認でサンプルコードを動かすため、「samples」の中に「cert」ディレクトリを作成し、証明書を配置していきます。

$ cd samples
$ mkdir cert
FTPなどで証明書を配置する
$ ls cert
xxxxxxxxxx-certificate.pem.crt  xxxxxxxx-private.pem.key  rootCA.pem

これでRaspberryPi側の準備は完了です。

動作確認

RaspberryPiにダウンロードしたaws-iot-device-sdk-pythonの中にサンプルプログラムがあるので、
それを使って、AWS IoTと接続できているか確認してみます。

その前に、エンドポイントを確認しておきます。

MQTTのpublish/subscribeをしてみる

▼「basicPubSub」の中にいくつかサンプルがありますが一番シンプルなbasicPubSub.pyを実行します。

$ cd samples/basicPubSub
$ python basicPubSub.py \
--endpoint xxxxxxxxxxxx.iot.ap-northeast-1.amazonaws.com \
--rootCA ../cert/rootCA.pem \
--cert ../cert/xxxxxxx-certificate.pem.crt \
--key ../cert/xxxxxxx-private.pem.key


2018-03-05 23:29:52,908 - AWSIoTPythonSDK.core.protocol.internal.clients - DEBUG - Initializing MQTT layer...
2018-03-05 23:29:52,910 - AWSIoTPythonSDK.core.protocol.internal.clients - DEBUG - Registering internal event callbacks to MQTT layer...
2018-03-05 23:29:52,910 - AWSIoTPythonSDK.core.protocol.mqtt_core - INFO - MqttCore initialized
2018-03-05 23:29:52,910 - AWSIoTPythonSDK.core.protocol.mqtt_core - INFO - Client id: basicPubSub
2018-03-05 23:29:52,911 - AWSIoTPythonSDK.core.protocol.mqtt_core - INFO - Protocol version: MQTTv3.1.1
2018-03-05 23:29:52,911 - AWSIoTPythonSDK.core.protocol.mqtt_core - INFO - Authentication type: TLSv1.2 certificate based Mutual Auth.
2018-03-05 23:29:52,911 - AWSIoTPythonSDK.core.protocol.mqtt_core - INFO - Configuring endpoint...
2018-03-05 23:29:52,911 - AWSIoTPythonSDK.core.protocol.mqtt_core - INFO - Configuring certificates...
2018-03-05 23:29:52,912 - AWSIoTPythonSDK.core.protocol.mqtt_core - INFO - Configuring reconnect back off timing...
2018-03-05 23:29:52,912 - AWSIoTPythonSDK.core.protocol.mqtt_core - INFO - Base quiet time: 1.000000 sec
2018-03-05 23:29:52,912 - AWSIoTPythonSDK.core.protocol.mqtt_core - INFO - Max quiet time: 32.000000 sec
2018-03-05 23:29:52,913 - AWSIoTPythonSDK.core.protocol.mqtt_core - INFO - Stable connection time: 20.000000 sec
2018-03-05 23:29:52,913 - AWSIoTPythonSDK.core.protocol.mqtt_core - INFO - Configuring offline requests queueing: max queue size: -1
.
.
.
2018-03-05 23:25:39,015 - AWSIoTPythonSDK.core.protocol.internal.clients - DEBUG - Invoking custom event callback...
2018-03-05 23:25:40,011 - AWSIoTPythonSDK.core.protocol.mqtt_core - INFO - Performing sync publish...
2018-03-05 23:25:40,013 - AWSIoTPythonSDK.core.protocol.internal.clients - DEBUG - Filling in custom puback (QoS>0) event callback...
2018-03-05 23:25:40,048 - AWSIoTPythonSDK.core.protocol.internal.workers - DEBUG - Produced [puback] event
2018-03-05 23:25:40,049 - AWSIoTPythonSDK.core.protocol.internal.workers - DEBUG - Dispatching [puback] event
2018-03-05 23:25:40,051 - AWSIoTPythonSDK.core.protocol.internal.clients - DEBUG - Invoking custom event callback...
2018-03-05 23:25:40,052 - AWSIoTPythonSDK.core.protocol.internal.clients - DEBUG - This custom event callback is for pub/sub/unsub, removing it after invocation...
2018-03-05 23:25:40,079 - AWSIoTPythonSDK.core.protocol.internal.workers - DEBUG - Produced [message] event
2018-03-05 23:25:40,081 - AWSIoTPythonSDK.core.protocol.internal.workers - DEBUG - Dispatching [message] event
Received a new message:
{"message": "Hello World!", "sequence": 4}
from topic:
sdk/test/Python
--------------


2018-03-05 23:25:40,082 - AWSIoTPythonSDK.core.protocol.internal.clients - DEBUG - Invoking custom event callback...
2018-03-05 23:25:41,081 - AWSIoTPythonSDK.core.protocol.mqtt_core - INFO - Performing sync publish...
2018-03-05 23:25:41,082 - AWSIoTPythonSDK.core.protocol.internal.clients - DEBUG - Filling in custom puback (QoS>0) event callback...
2018-03-05 23:25:41,133 - AWSIoTPythonSDK.core.protocol.internal.workers - DEBUG - Produced [puback] event
2018-03-05 23:25:41,134 - AWSIoTPythonSDK.core.protocol.internal.workers - DEBUG - Dispatching [puback] event
2018-03-05 23:25:41,136 - AWSIoTPythonSDK.core.protocol.internal.clients - DEBUG - Invoking custom event callback...
2018-03-05 23:25:41,137 - AWSIoTPythonSDK.core.protocol.internal.clients - DEBUG - This custom event callback is for pub/sub/unsub, removing it after invocation...
2018-03-05 23:25:41,152 - AWSIoTPythonSDK.core.protocol.internal.workers - DEBUG - Produced [message] event
2018-03-05 23:25:41,155 - AWSIoTPythonSDK.core.protocol.internal.workers - DEBUG - Dispatching [message] event
Received a new message:
{"message": "Hello World!", "sequence": 5}
from topic:
sdk/test/Python
--------------

DEBUGログよりMQTTv3.1.1を利用していることや、きちんとconnectionされていることを確認することができます。
また「sdk/test/Python」というトピックをサブスクライブし、同じトピックに対してパブリッシュするのを繰り返していることがわかります。

ThingShadowを更新してみる

▼「basicShadow」の中のbasicShadowUpdater.pyはシャドウステータスのdesired(あるべき状態)を1秒毎に更新してくれるサンプルコードとなります。
basicShadowUpdater.pyを実行してます。

$ cd ../basicShadow/
$ python basicShadowUpdater.py \
--endpoint xxxxxxxxxxxx.iot.ap-northeast-1.amazonaws.com \
--rootCA ../cert/rootCA.pem \
--cert ../cert/xxxxxxx-certificate.pem.crt \
--key ../cert/xxxxxxx-private.pem.key
--thingName office-raspberry

.
.
.
.
2018-03-06 00:17:07,751 - AWSIoTPythonSDK.core.protocol.mqtt_core - INFO - Performing sync publish...
2018-03-06 00:17:07,753 - AWSIoTPythonSDK.core.protocol.internal.workers - DEBUG - Produced [puback] event
2018-03-06 00:17:07,756 - AWSIoTPythonSDK.core.protocol.internal.workers - DEBUG - Dispatching [puback] event
2018-03-06 00:17:07,804 - AWSIoTPythonSDK.core.protocol.internal.workers - DEBUG - Produced [message] event
2018-03-06 00:17:07,805 - AWSIoTPythonSDK.core.protocol.internal.workers - DEBUG - Dispatching [message] event
2018-03-06 00:17:07,807 - AWSIoTPythonSDK.core.shadow.deviceShadow - DEBUG - shadow message clientToken: 
2018-03-06 00:17:07,808 - AWSIoTPythonSDK.core.shadow.deviceShadow - DEBUG - Token is in the pool. Type: accepted
~~~~~~~~~~~~~~~~~~~~~~~
2018-03-06 00:17:07,810 - AWSIoTPythonSDK.core.protocol.internal.clients - DEBUG - Invoking custom event callback...
Update request with token: accepted!
property: 14
~~~~~~~~~~~~~~~~~~~~~~~
.
.

ログよりAWS IoTがもつシャドウを更新されたことがわかります。

AWS IoTのコンソールを確認するとこちらも同時に値が更新されていくことが確認できるかと思います。

▼「basicShadow」の中のbasicShadowDeltaListener.pyはシャドウステータスのdesired(あるべき状態)とDelta(デバイスの状態)に差分があるとDeltaを更新して同じ値に更新してくれるサンプルコードとなります。
basicShadowDeltaListener.pyを実行してます。
これを利用することで遠隔でデバイスを操作することができます。

$ python basicShadowDeltaListener.py \
--endpoint xxxxxxxxxxxx.iot.ap-northeast-1.amazonaws.com \
--rootCA ../cert/rootCA.pem \
--cert ../cert/xxxxxxx-certificate.pem.crt \
--key ../cert/xxxxxxx-private.pem.key
--thingName office-raspberry

basicShadowDeltaListener.pyを実行した状態でAWS IoTのコンソールからシャドウのdesiredを更新してみます。

basicShadowDeltaListener.pyで差分を読み取って自動的にDeltaが更新されます。

RaspberryPiのほうでは下記ログが出力されています。

.
.
.

++++++++DELTA++++++++++
property: 10
version: 10
+++++++++++++++++++++++


2018-03-06 00:37:53,517 - AWSIoTPythonSDK.core.protocol.connection.cores - DEBUG - stableConnection: Resetting the backoff time to: 1 sec.
2018-03-06 00:38:16,388 - AWSIoTPythonSDK.core.protocol.internal.workers - DEBUG - Produced [message] event
2018-03-06 00:38:16,390 - AWSIoTPythonSDK.core.protocol.internal.workers - DEBUG - Dispatching [message] event
delta/office-raspberry
2018-03-06 00:38:16,392 - AWSIoTPythonSDK.core.protocol.internal.clients - DEBUG - Invoking custom event callback...
++++++++DELTA++++++++++
property: 11
version: 11
+++++++++++++++++++++++

さいごに

いかがだったでしょうか。

AWS IoT Device SDK for Pythonを使ってRaspberryPiとAWS IoTをつないでみました。
また、サンプルコードより、MQTTのpublish/subscribe、ThingShadowの更新をおこなってみました。

誰かの参考になれば幸いです。