はじめに
AWS IoT Coreにエッジデバイスを登録して、AWS IoT Coreとエッジデバイスの間でメッセージを送受信する方法を紹介します。
エッジデバイスにランタイムをインストールすることなく、手軽にメッセージの送受信を行うことができます。
(エッジデバイスにAWS IoT Greengrass(V1)をインストールしてAWSと接続する方法はこちらをご覧ください。)
環境
動作確認済デバイス(OS)
- e-RT3 Plus F3RP70-2L1(Ubuntu 18.04 32bit)
- Raspberry Pi 4 Model B (Ubuntu Server 20.04 32bit)
これらのデバイスでは armhf アーキテクチャのパッケージが動作します。
エッジデバイスのクラウドへの登録
ポリシーの作成
デバイス-クラウド間でのメッセージの送受信を許可するポリシーを作成します。
左上のサービスメニューから「IoT Core」→「安全性」→「ポリシー」へ進み、「作成」をクリックします。
任意のポリシー名を入力し、「アドバンストモード」をクリックして以下の内容を入力します。<region>
, <account>
はリージョン名とアカウント名で置き換えてください。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"iot:Publish",
"iot:Receive"
],
"Resource": [
"arn:aws:iot:<region>:<account>:topic/test/topic"
]
},
{
"Effect": "Allow",
"Action": [
"iot:Subscribe"
],
"Resource": [
"arn:aws:iot:<region>:<account>:topicfilter/test/topic"
]
},
{
"Effect": "Allow",
"Action": [
"iot:Connect"
],
"Resource": [
"arn:aws:iot:<region>:<account>:client/test-*"
]
}
]
}
Note
リージョン名は右上のメニューで、アカウント名はこちらの手順で確認できます。
エッジデバイスの登録
AWS IoT Coreのモノにエッジデバイスを登録します。
「IoT Core」→「管理」→「モノ」へ進み、「モノを作成」をクリックします。
以下の設定でモノを作成します。
設定項目 | 設定内容 |
---|---|
作成するモノの数 | 1つのモノを作成 |
モノの名前 | 任意(この例では「testdevice」) |
デバイス証明書 | 新しい証明書を自動生成 |
ポリシーの設定では、ポリシーの作成で作成したポリシーを選択し「モノを作成」をクリックします。
証明書やキーファイルをダウンロードして「完了」をクリックします。
メッセージの送受信
エッジデバイスの準備
-
パッケージのインストール
必要なパッケージをインストールします。sudo apt update sudo apt install cmake python3-dev python3-venv
Raspberry Piの場合、デフォルトのコンパイラだとSDKのインストールができないため以下のパッケージもインストールします。
sudo apt install build-essential sudo apt install gcc-8
Note
エッジデバイスがproxy環境下にある場合はproxy設定が必要です。 -
仮想環境の準備とSDKのインストール
仮想環境を作成します。python3 -m venv venv source venv/bin/activate
以下のコマンドでSDKをインストールします。
e-RT3の場合(venv) username@ubuntu:~$ python3 -m pip install wheel (venv) username@ubuntu:~$ python3 -m pip install awsiotsdk
Raspberry Piの場合
コンパイラを指定してawsiotsdkをインストールします。(venv) username@ubuntu:~$ python3 -m pip install wheel (venv) username@ubuntu:~$ CC=/path/to/gcc-8 python3 -m pip install awsiotsdk
Note
gcc-8のパスは以下のコマンドで確認できます。username@ubuntu:~$ which gcc-8 /usr/bin/gcc-8
Note
インストール中にエンコード関連のエラーが出た場合は、ロケールを指定して実行してください。
実行例(venv) username@ubuntu:~$ LC_CTYPE=C.UTF-8 python3 -m pip install awsiotsdk
-
サンプルプログラムの準備
AWSのSDK2のサンプルプログラムであるpubsub.pyをデバイスの任意の場所に保存します(ライセンスはこちら)。Note
本記事ではタグ「v1.7.1」のコードを使用しています。エッジデバイスの登録でダウンロードした証明書やキーファイルをサンプルプログラムと同一のディレクトリに置きます。
メッセージのやり取り
以下のコマンドでサンプルプログラムを起動します。引数にはエンドポイント、エッジデバイスの登録でダウンロードした証明書、キーファイルを設定します。
(venv) username@ubuntu:~$ python3 pubsub.py --endpoint xxx.amazonaws.com --root-ca AmazonRootCA1.pem --cert xxx-certificate.pem.crt --key xxx-private.pem.key
Note
エッジデバイスがproxy環境下にある場合は追加のオプションが必要です。詳しくはproxy設定をご覧ください。
以下のような出力があれば成功です。
Connecting to xxx.amazonaws.com with client ID 'test-xxx'...
Connected!
Subscribing to topic 'test/topic'...
Subscribed with QoS.AT_LEAST_ONCE
Sending 10 message(s)
Publishing message to topic 'test/topic': Hello World! [1]
Received message from topic 'test/topic': b'"Hello World! [1]"'
Publishing message to topic 'test/topic': Hello World! [2]
Received message from topic 'test/topic': b'"Hello World! [2]"'
Publishing message to topic 'test/topic': Hello World! [3]
...
このプログラムはtest/topic
トピックにメッセージをpublishするとともに、test/topic
トピックをsubscribeし、10回メッセージを送受信すると終了します。
したがって、自分が送信したメッセージを自分で受信するという動きを10回繰り返して終了します。
D2Cメッセージの確認
クラウドにメッセージが到着していることを確認するには「IoT Core」→「テスト」→「MQTTテストクライアント」へ進み、test/topic
トピックをsubscribeします。
メッセージを受信すると画面下部に受信したメッセージが表示されます。
C2Dメッセージの確認
以下のコマンドで、メッセージをpublishしない設定でプログラムを起動します。
(venv) username@ubuntu:~$ python3 pubsub.py --endpoint xxx.amazonaws.com --root-ca AmazonRootCA1.pem --cert xxx-certificate.pem.crt --key xxx-private.pem.key --message ""
クラウドからメッセージを送信するには「トピックに公開する」からtest/topic
トピックにメッセージをpublishします。
エッジデバイスに以下のような出力があれば成功です。10回メッセージを受信するとプログラムが終了します。
...
Received message from topic 'test/topic': b'{\n "message": "This is a message from AWS"\n}'
...
補足
proxy設定
エッジデバイスがproxy環境下にある場合は以下のコマンドでプログラムを実行します。
(venv) username@ubuntu:~$ python3 pubsub.py --endpoint xxx.amazonaws.com --root-ca AmazonRootCA1.pem --cert xxx-certificate.pem.crt --key xxx-private.pem.key --proxy-host "proxy.example.com" --proxy-port xx
ユーザー名とパスワードが必要な場合は、プログラムの以下の箇所を書き換えます。
変更前
if (args.proxy_host):
proxy_options = http.HttpProxyOptions(host_name=args.proxy_host, port=args.proxy_port)
変更後
if (args.proxy_host):
proxy_options = http.HttpProxyOptions(host_name=args.proxy_host, port=args.proxy_port, auth_type = http.HttpProxyAuthenticationType.Basic, auth_username="<username>", auth_password="<password>")