今回はRaspberry PiをAWS IoTに接続してみたいと思います。AWS IoTとは簡単に言うと、IoTデバイスをAWS上のプラットフォームに登録しておき、デバイスの状態を記録するとともに、複数のデバイス間やデバイスとAWSサービス間の通信のハンドリングを行うことができるサービスです。
デバイスとAWS IoTプラットフォーム間のプロトコルとしては MQTT, HTTP, WebSocket に対応していて、AWSサービスとの連携としては Lambda や DynamoDB、Kinesis、SNSなどに対応しています。
今のところまだどういった連携をしていくか決めていませんが、ひとまずは Raspberry Pi を AWS IoT に登録して、接続ができるところまでを行ってみたいと思います。
AWS側の環境構築
AWS IoT コンソールからデバイスの登録等を行うにはAWS IoT関連の権限が付与されている必要があります。今回はテストということで、 AWSIoTFullAccess
ポリシーをアタッチして、AWS IoTに関する全ての権限を付与しました。実際のサービス提供時は最低限の権限に絞って付与した方が良いかと思います。
権限が付与されたら該当のユーザでAWSマネジメントコンソールにログインし、サービスのリストから AWS IoT を選択して AWS IoT のコンソールへ移動します。
今すぐ始める
をクリックします。
AWS IoT コンソールが表示されますので、 「AWS IoT に接続する」の 接続オプションの表示
をクリックします。
今回は Raspberry Pi を接続するので、「デバイスの設定」の 今すぐ始める
をクリックします。
ステップの案内ページが表示されますので、 今すぐ始める
をクリックします。
プラットフォームとSDKの選択画面が表示されますので、今回は Linux と Python を選択して、画面右下の 次へ
をクリックします。
モノ(IoTデバイス)の登録画面になりますので、名前を決めて入力し、 次のステップ
をクリックします。
作成されるモノの情報と接続キットの情報が表示されますので、 Linux/OSX
をクリックして接続キットをダウンロードします。ダウンロードすると画面右下の 次のステップ
ボタンが活性化しますので、クリックして次へ進みます。
デバイス上でのテスト手順が表示されます。
Raspberry Pi 側からの接続操作
ダウンロードした接続キットをscp等で Raspberry Pi 上に転送し、上記手順を実行します。
pi@raspberrypi:~/aws_iot $ ls connect_device_package.zip pi@raspberrypi:~/aws_iot $ pi@raspberrypi:~/aws_iot $ unzip connect_device_package.zip Archive: connect_device_package.zip inflating: raspberry_pi.private.key inflating: raspberry_pi.public.key inflating: raspberry_pi.cert.pem inflating: start.sh pi@raspberrypi:~/aws_iot $ pi@raspberrypi:~/aws_iot $ ls connect_device_package.zip raspberry_pi.cert.pem raspberry_pi.private.key raspberry_pi.public.key start.sh pi@raspberrypi:~/aws_iot $ pi@raspberrypi:~/aws_iot $ chmod +x start.sh pi@raspberrypi:~/aws_iot $ pi@raspberrypi:~/aws_iot $ ls -l total 20 -rw-r--r-- 1 pi pi 3620 Jul 1 02:05 connect_device_package.zip -rw-r--r-- 1 pi pi 1224 Jul 1 02:01 raspberry_pi.cert.pem -rw-r--r-- 1 pi pi 1679 Jul 1 02:01 raspberry_pi.private.key -rw-r--r-- 1 pi pi 451 Jul 1 02:01 raspberry_pi.public.key -rwxr-xr-x 1 pi pi 928 Jul 1 02:01 start.sh pi@raspberrypi:~/aws_iot $ pi@raspberrypi:~/aws_iot $ ./start.sh Downloading AWS IoT Root CA certificate from Symantec... % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 1758 100 1758 0 0 12381 0 --:--:-- --:--:-- --:--:-- 12468 Installing AWS SDK... Cloning into 'aws-iot-device-sdk-python'... remote: Counting objects: 116, done. remote: Compressing objects: 100% (19/19), done. remote: Total 116 (delta 3), reused 15 (delta 3), pack-reused 92 Receiving objects: 100% (116/116), 117.74 KiB | 0 bytes/s, done. Resolving deltas: 100% (35/35), done. Checking connectivity... done. ~/aws_iot/aws-iot-device-sdk-python ~/aws_iot running install running build running build_py creating build creating build/lib.linux-armv7l-2.7 creating build/lib.linux-armv7l-2.7/AWSIoTPythonSDK copying AWSIoTPythonSDK/MQTTLib.py -> build/lib.linux-armv7l-2.7/AWSIoTPythonSDK copying AWSIoTPythonSDK/__init__.py -> build/lib.linux-armv7l-2.7/AWSIoTPythonSDK creating build/lib.linux-armv7l-2.7/AWSIoTPythonSDK/core copying AWSIoTPythonSDK/core/__init__.py -> build/lib.linux-armv7l-2.7/AWSIoTPythonSDK/core creating build/lib.linux-armv7l-2.7/AWSIoTPythonSDK/exception copying AWSIoTPythonSDK/exception/operationTimeoutException.py -> build/lib.linux-armv7l-2.7/AWSIoTPythonSDK/exception copying AWSIoTPythonSDK/exception/AWSIoTExceptions.py -> build/lib.linux-armv7l-2.7/AWSIoTPythonSDK/exception copying AWSIoTPythonSDK/exception/operationError.py -> build/lib.linux-armv7l-2.7/AWSIoTPythonSDK/exception copying AWSIoTPythonSDK/exception/__init__.py -> build/lib.linux-armv7l-2.7/AWSIoTPythonSDK/exception creating build/lib.linux-armv7l-2.7/AWSIoTPythonSDK/core/shadow copying AWSIoTPythonSDK/core/shadow/shadowManager.py -> build/lib.linux-armv7l-2.7/AWSIoTPythonSDK/core/shadow copying AWSIoTPythonSDK/core/shadow/deviceShadow.py -> build/lib.linux-armv7l-2.7/AWSIoTPythonSDK/core/shadow copying AWSIoTPythonSDK/core/shadow/__init__.py -> build/lib.linux-armv7l-2.7/AWSIoTPythonSDK/core/shadow creating build/lib.linux-armv7l-2.7/AWSIoTPythonSDK/core/util copying AWSIoTPythonSDK/core/util/sigV4Core.py -> build/lib.linux-armv7l-2.7/AWSIoTPythonSDK/core/util copying AWSIoTPythonSDK/core/util/offlinePublishQueue.py -> build/lib.linux-armv7l-2.7/AWSIoTPythonSDK/core/util copying AWSIoTPythonSDK/core/util/__init__.py -> build/lib.linux-armv7l-2.7/AWSIoTPythonSDK/core/util copying AWSIoTPythonSDK/core/util/progressiveBackoffCore.py -> build/lib.linux-armv7l-2.7/AWSIoTPythonSDK/core/util creating build/lib.linux-armv7l-2.7/AWSIoTPythonSDK/core/protocol copying AWSIoTPythonSDK/core/protocol/__init__.py -> build/lib.linux-armv7l-2.7/AWSIoTPythonSDK/core/protocol copying AWSIoTPythonSDK/core/protocol/mqttCore.py -> build/lib.linux-armv7l-2.7/AWSIoTPythonSDK/core/protocol creating build/lib.linux-armv7l-2.7/AWSIoTPythonSDK/core/protocol/paho copying AWSIoTPythonSDK/core/protocol/paho/client.py -> build/lib.linux-armv7l-2.7/AWSIoTPythonSDK/core/protocol/paho copying AWSIoTPythonSDK/core/protocol/paho/__init__.py -> build/lib.linux-armv7l-2.7/AWSIoTPythonSDK/core/protocol/paho creating build/lib.linux-armv7l-2.7/AWSIoTPythonSDK/core/protocol/paho/securedWebsocket copying AWSIoTPythonSDK/core/protocol/paho/securedWebsocket/securedWebsocketCore.py -> build/lib.linux-armv7l-2.7/AWSIoTPythonSDK/core/protocol/paho/securedWebsocket copying AWSIoTPythonSDK/core/protocol/paho/securedWebsocket/__init__.py -> build/lib.linux-armv7l-2.7/AWSIoTPythonSDK/core/protocol/paho/securedWebsocket running install_lib creating /usr/local/lib/python2.7/dist-packages/AWSIoTPythonSDK error: could not create '/usr/local/lib/python2.7/dist-packages/AWSIoTPythonSDK': Permission denied pi@raspberrypi:~/aws_iot $ pi@raspberrypi:~/aws_iot $ sudo ./start.sh Running pub/sub sample application... Traceback (most recent call last): File "aws-iot-device-sdk-python/samples/basicPubSub/basicPubSub.py", line 18, in <module> from AWSIoTPythonSDK.MQTTLib import AWSIoTMQTTClient ImportError: No module named AWSIoTPythonSDK.MQTTLib pi@raspberrypi:~/aws_iot $
AWSIoTPythonSDK
がみつからないということなので、インストールします。
pi@raspberrypi:~/aws_iot $ sudo pip install AWSIoTPythonSDK Downloading/unpacking AWSIoTPythonSDK Downloading AWSIoTPythonSDK-1.1.2.tar.gz (55kB): 55kB downloaded Running setup.py (path:/tmp/pip-build-06EpCW/AWSIoTPythonSDK/setup.py) egg_info for package AWSIoTPythonSDK Installing collected packages: AWSIoTPythonSDK Running setup.py install for AWSIoTPythonSDK Successfully installed AWSIoTPythonSDK Cleaning up... pi@raspberrypi:~/aws_iot $
再度テスト用スクリプトを実行します。
pi@raspberrypi:~/aws_iot $ sudo ./start.sh Running pub/sub sample application... 2017-07-01 02:14:37,153 - AWSIoTPythonSDK.core.protocol.mqttCore - DEBUG - Paho MQTT Client init. 2017-07-01 02:14:37,153 - AWSIoTPythonSDK.core.protocol.mqttCore - INFO - ClientID: basicPubSub 2017-07-01 02:14:37,153 - AWSIoTPythonSDK.core.protocol.mqttCore - INFO - Protocol: MQTTv3.1.1 2017-07-01 02:14:37,154 - AWSIoTPythonSDK.core.protocol.mqttCore - DEBUG - Register Paho MQTT Client callbacks. 2017-07-01 02:14:37,154 - AWSIoTPythonSDK.core.protocol.mqttCore - DEBUG - mqttCore init. 2017-07-01 02:14:37,154 - AWSIoTPythonSDK.core.protocol.mqttCore - DEBUG - Load CAFile from: root-CA.crt 2017-07-01 02:14:37,154 - AWSIoTPythonSDK.core.protocol.mqttCore - DEBUG - Load Key from: raspberry_pi.private.key 2017-07-01 02:14:37,155 - AWSIoTPythonSDK.core.protocol.mqttCore - DEBUG - Load Cert from: raspberry_pi.cert.pem 2017-07-01 02:14:37,155 - AWSIoTPythonSDK.core.protocol.mqttCore - DEBUG - Custom setting for backoff timing: baseReconnectTime = 1 sec 2017-07-01 02:14:37,155 - AWSIoTPythonSDK.core.protocol.mqttCore - DEBUG - Custom setting for backoff timing: maximumReconnectTime = 32 sec 2017-07-01 02:14:37,155 - AWSIoTPythonSDK.core.protocol.mqttCore - DEBUG - Custom setting for backoff timing: minimumConnectTime = 20 sec 2017-07-01 02:14:37,155 - AWSIoTPythonSDK.core.protocol.mqttCore - DEBUG - Custom setting for publish queueing: queueSize = -1 2017-07-01 02:14:37,156 - AWSIoTPythonSDK.core.protocol.mqttCore - DEBUG - Custom setting for publish queueing: dropBehavior = Drop Newest 2017-07-01 02:14:37,156 - AWSIoTPythonSDK.core.protocol.mqttCore - DEBUG - Custom setting for draining interval: 0.5 sec 2017-07-01 02:14:37,156 - AWSIoTPythonSDK.core.protocol.mqttCore - DEBUG - Set maximum connect/disconnect timeout to be 10 second. 2017-07-01 02:14:37,156 - AWSIoTPythonSDK.core.protocol.mqttCore - DEBUG - Set maximum MQTT operation timeout to be 5 second 2017-07-01 02:14:37,157 - AWSIoTPythonSDK.core.protocol.mqttCore - INFO - Connection type: TLSv1.2 Mutual Authentication 2017-07-01 02:14:37,507 - AWSIoTPythonSDK.core.protocol.mqttCore - DEBUG - Connect result code 0 2017-07-01 02:14:37,510 - AWSIoTPythonSDK.core.protocol.mqttCore - INFO - Connected to AWS IoT. 2017-07-01 02:14:37,510 - AWSIoTPythonSDK.core.protocol.mqttCore - DEBUG - Connect time consumption: 70.0ms. 2017-07-01 02:14:37,511 - AWSIoTPythonSDK.core.protocol.mqttCore - DEBUG - Started a subscribe request 1 2017-07-01 02:14:37,559 - AWSIoTPythonSDK.core.protocol.mqttCore - DEBUG - _resubscribeCount: -1 2017-07-01 02:14:37,560 - AWSIoTPythonSDK.core.protocol.mqttCore - DEBUG - Subscribe request 1 sent. 2017-07-01 02:14:37,561 - AWSIoTPythonSDK.core.protocol.mqttCore - DEBUG - Subscribe request 1 succeeded. Time consumption: 50.0ms. 2017-07-01 02:14:37,562 - AWSIoTPythonSDK.core.protocol.mqttCore - DEBUG - Recover subscribe context for the next request: subscribeSent: False 2017-07-01 02:14:39,565 - AWSIoTPythonSDK.core.protocol.mqttCore - DEBUG - Try to put a publish request 2 in the TCP stack. 2017-07-01 02:14:39,566 - AWSIoTPythonSDK.core.protocol.mqttCore - DEBUG - Publish request 2 succeeded. Received a new message: New Message 0 from topic: sdk/test/Python -------------- 2017-07-01 02:14:40,568 - AWSIoTPythonSDK.core.protocol.mqttCore - DEBUG - Try to put a publish request 3 in the TCP stack. 2017-07-01 02:14:40,569 - AWSIoTPythonSDK.core.protocol.mqttCore - DEBUG - Publish request 3 succeeded. Received a new message: New Message 1 from topic: sdk/test/Python -------------- 2017-07-01 02:14:41,571 - AWSIoTPythonSDK.core.protocol.mqttCore - DEBUG - Try to put a publish request 4 in the TCP stack. 2017-07-01 02:14:41,572 - AWSIoTPythonSDK.core.protocol.mqttCore - DEBUG - Publish request 4 succeeded. Received a new message: New Message 2 from topic: sdk/test/Python -------------- 2017-07-01 02:14:42,575 - AWSIoTPythonSDK.core.protocol.mqttCore - DEBUG - Try to put a publish request 5 in the TCP stack. 2017-07-01 02:14:42,576 - AWSIoTPythonSDK.core.protocol.mqttCore - DEBUG - Publish request 5 succeeded. Received a new message: New Message 3 from topic: sdk/test/Python -------------- 2017-07-01 02:14:43,578 - AWSIoTPythonSDK.core.protocol.mqttCore - DEBUG - Try to put a publish request 6 in the TCP stack. 2017-07-01 02:14:43,579 - AWSIoTPythonSDK.core.protocol.mqttCore - DEBUG - Publish request 6 succeeded. Received a new message: New Message 4 from topic: sdk/test/Python --------------
エラーなく実行され、メッセージが送信され続けているようです。コンソール側を確認すると、 デバイスからのメッセージを待機中
となっていたところが下記のように変わり、メッセージが受信されていることが確認できます。
上記画面の「ステップ 4: デバイスにメッセージを送信する」フォームに「Hello, IoT!!」のように入力して メッセージの送信
をクリックすると、Raspberry Pi 側でメッセージが受信され、下記のように出力されます。
Received a new message:
Hello, IoT!!
from topic:
sdk/test/Python
ここまででひとまずデバイスの登録から接続の確認までは完了です。AWS IoT コンソールのダッシュボードを表示すると、下記のように処理の状況が確認できます。
テスト用のサンプルはMQTTによる接続なので、プロトコルとしてMQTTがカウントされています。
ちなみにダッシュボードの情報を表示するには CloudWatch の表示権限が必要になります。今回はテストということで、 CloudWatchFullAccess
ポリシーをアタッチしました。実際のサービス提供時は最低限の権限に絞って許可した方が良いかと思います。
ひとまず今回は接続まででしたが、ダッシュボード上でデバイスの通信状況が確認できるというのはとても便利そうに思えました。他のAWSとの連携や、SORACOM Beamを通しての接続も簡単にできるようなので、色々と組み合わせて動かしていってみたいと思います。