#はじめに
Greengrass(V1)は、Greengrassをインストールしたデバイス(コアデバイス)がMQTTブローカーの役割を果たし、グループ内のデバイス間でMQTTメッセージのやり取りを行うことができます。
今回は、Greengrassグループへのデバイスの追加とGreengrassデバイス間で通信をやり取りするまでを確認します。
以降、公式ドキュメントの以下を参考にしています。
参考:モジュール 4: AWS IoT Greengrass グループでのデバイスの操作
#1 Greengrassグループへのデバイス追加
Greengrassグループへのデバイス追加として、以下2つの手順を確認しました。
- Greengrassグループに新規のデバイスを追加
- モノとして登録済みのデバイスをGreengrassグループに追加
なお、今回はラズパイとMacをそれぞれ追加しています。
##1-1 新規のデバイスをグループに追加
IoT Coreに未登録のデバイスをGreengrassグループに追加します。
1.IoT Coreのマネジメントコンソールで左のメニューから Greengrass > クラシック(V1) > グループ の順にクリック
2.今回追加する対象のGreengrassグループをクリック
3.デバイス > 「デバイスの追加」の順にクリック
4.「新しいデバイスの作成」をクリック
5.任意の名前を入力して「次へ」をクリック
6.今回は1-clickデプロイを利用することとし、「デフォルトを使用」をクリック
7.以下のファイルをダウンロードし、「完了」をクリック
- デバイス証明書、パブリックキー、プライベートキーをまとめたtar.gzファイル
- ルートCA ※Amazon Root CA 1をダウンロード
- 作成時にポリシーが証明書にアタッチされ、証明書もアクティブになっている
- IoT Coreのモノとしても登録される
- Greengrass > クラシック(V1) > デバイス にはグループがデプロイされるまで表示されない
#1-2 モノと登録済のデバイスをグループに追加
既にIoT Coreにモノとして登録されているデバイスをGreengrassのグループに追加します。
なお、IoT Coreへのモノの登録方法はこちらをご参照ください。
参考:AWS IoT Coreに「1-Click証明書作成」と「CSRによる作成」の2つの方法でプロビジョニングを実施してみる
1.IoT Coreのマネジメントコンソールで左のメニューから Greengrass > クラシック(V1) > グループ の順にクリック
2.今回追加する対象のGreengrassグループをクリック
3.デバイス > 「デバイスの追加」の順にクリック
4.「IoT Thingを選択する」をクリック
5.追加するモノを選択して「完了」をクリック
6.完了すると、グループにデバイスが追加される
#2 Greengrassデバイス間で通信
次にGreengrassデバイス間で通信できることを確認します。
今回は、AWS IoT Device SDK for Pythonの/samples/greengrass配下にある basicDiscovery.py
を利用します。
GitHub:AWS IoT Device SDK for Python
#2-1 グループのデプロイ
クラウドで行った設定をGreengrassコアデバイスにデプロイします。
また、デプロイ前にGreengrassデバイス間で通信できるよう、サブスクリプションの設定を行います。
1.IoT Coreのマネジメントコンソールで左のメニューから Greengrass > クラシック(V1) > グループ の順にクリック
2.対象のGreengrassグループをクリック
3.サブスクリプションをクリック
4.今回はgg-test-001がhell/world/pubsubにパブリッシュしたメッセージをgg-test-002でサブスクライブできるよう、以下の通り設定して「完了」をクリック
- ソース:gg-test-001
- ターゲット:hello/world/pubsub
- topic:gg-test-002
5.サブスクリプションに追加されたことを確認する
6.アクション > デプロイ の順にクリック
7.「正常に完了しました」と表示されることを確認する
#2-2 basicDicovery.py によるPub/Subの実施
basicDiscovery.py
でGreengrassデバイス間の通信が出来ることを確認します。
参考:通信をテストする
1.「1-1 新規のデバイスをグループに追加」で取得したtar.gzファイルとルートCA証明書をGreengrassデバイスのディレクトリに格納する
※今回はMacにDeviceというディレクトリを作成して以降手順を実施
2.tar.gzファイルを解凍
cd Device
tar -xzf xxxxxxxxxx-setup.tar.gz
※解凍後、ディレクトリには以下のファイルが存在する
- xxxxxxxxxx-setup.tar.gz
- xxxxxxxxxx.private.key
- xxxxxxxxxx.public.key
- xxxxxxxxxx.cert.perm
- AmazonRootCA1.pem ※ルート証明書
3.AWS IoT Device SDK for Pythonをインストールする
※以降の作業はPublishするデバイス、Subscribeするデバイス双方ともに必要
参考:をインストールするAWS IoT Device SDK for Python
#2.7未満、3.3未満の場合はバージョンアップが必要
python --version
#OpenSSLは1.01以降が必要
python
>>>import ssl
>>>print ssl.OPENSSL_VERSION
#確認したらPythonシェルを終了
>>>exit()
#AWS IoT Device SDK for Pythonをインストールする
cd ~
git clone https://github.com/aws/aws-iot-device-sdk-python.git
cd aws-iot-device-sdk-python
sudo python setup.py install
4.AWS IoT Device SDK for Pythonのサンプルコード basicDicovery.py
を証明書を格納したディレクトリにコピーする
#証明書を格納したディレクトリに移動
cd /xxx/xxx/Device
#basicDicovery.py をコピー
cp ~/aws-iot-device-sdk-python/samples/greengrass/basicDicovery.py ./
5.AWS IoT Coreのマネジメントコンソールで左のメニューから設定をクリックし、エンドポイント情報をコピーする
※有効になっていない場合は有効にする
6.Publishを行う
※サブスクリプションでソースに指定したデバイスから実施
python basicDiscovery.py --endpoint [エンドポイントのURL] \
--rootCA [ルート証明書] --cert [デバイス証明書] --key [秘密鍵] \
--thingName [モノの名前] --topic 'hello/world/pubsub' --mode publish \
--message 'Hello World'
#成功すると以下のメッセージが "sequence"をインクリメントしながら流れ続ける(Ctrl + C で止まる)
2021-03-29 16:26:37,233 - AWSIoTPythonSDK.core.protocol.mqtt_core - INFO - Performing sync publish...
Published topic hello/world/pubsub: {"message": "Hello World", "sequence": 0}
7.Subscribeを行う
※サブスクリプションでターゲットに指定したデバイスから実施
python basicDiscovery.py --endpoint [エンドポイントのURL] \
--rootCA [ルート証明書] --cert [デバイス証明書] --key [秘密鍵] \
--thingName [モノの名前] --topic 'hello/world/pubsub' --mode subscribe
#成功すると以下の通り、PublishされたメッセージをSubscribeしつづける(Ctrl + C で止まる)
2021-03-29 16:26:38,712 - AWSIoTPythonSDK.core.protocol.internal.workers - DEBUG - Produced [message] event
2021-03-29 16:26:38,712 - AWSIoTPythonSDK.core.protocol.internal.workers - DEBUG - Dispatching [message] event
2021-03-29 16:26:38,712 - AWSIoTPythonSDK.core.protocol.internal.clients - DEBUG - Invoking custom event callback...
Received message on topic hello/world/pubsub: b'{"message": "Hello World", "sequence": 1}'
#3 トラブルシューティング
上記の通り、basicDiscovery.py
を実行した際に、Pub/Subともに以下の通りエラーが発生してしまいました(抜粋)。
- Pub側:
ConnectionRefusedError: [Errno 111] Connection refused
- Sub側:
ConnectionRefusedError: [Errno 61] Connection refused
Connectionが明示的に拒絶されているので、権限周り、接続設定を調べました。
- デバイス証明書が有効になっているか
- デバイス証明書にポリシーがアタッチされているか
- ポリシーは通信を許可しているか
- サブスクリプションの設定は間違っていないか
しかし、いずれも問題はありませんでした。
また、いずれのデバイスでもIoT Coreと直接やり取りする basicPubSub.py
も実行し、こちらでは疎通が確認できました。
そのため、Greengrass側の設定ミスであることが分かります。
※basicPubSub.py
もAWS IoT Device SDK for Pythonのサンプルコード
結果として、コマンド実行時の以下メッセージが解決の決め手になりました。
Trying to connect to core at 127.0.0.1:8883
Greengrassコアデバイスに接続しに行くはずが、localhostのループバックアドレスに接続しようとしていました。
GreengrassデバイスはIoT CoreからGreengrassコアデバイスの情報を取得して、接続しにいきます。
そのため、IoT CoreのマネジメントコンソールでGreengrassのコア情報を確認すると以下の通りでした。
ここの接続情報の一番上を使って接続しているようでした。
上記画面の編集をクリックし、127.0.0.1を削除してからコマンドを再度実行すると、エラーは解消されました。
#4 おわりに
Greengrassのグループへのデバイス追加、メッセージのやり取りまでを確認できました。
自動接続情報の検出で、127.0.0.1を拾ってきてしまうのは困りものですが、レアケースなのでしょうか?
ここはもう少し調べてみようと思います。