はじめに
こんにちは! KAGでエンジニアやっているh_id32です!
埃かぶってるRaspberryPiが家にあったので、勉強がてらAWS IoTに接続してみます。
今回は基本的なチュートリアルにとどめていますが、第二弾、第三弾と続けていきGreengrass/Device Shadowにも触れられたらなと思っています。
IoT Coreのクイック接続でRaspberryPiと接続できるか試してみよう
まずは疎通確認も兼ねてAWS IoT Coreのクイック接続を利用して自宅環境のRaspberryPiと通信ができるか試してみます。
使用機材
今回自宅に余っていたRaspberryPiをそのまま使うがコンセプトなため、初期設定などには触れません。
AWS IoT
AWSのマネジメントコンソールからIoT Coreを選択
-
デバイスを準備する
記載されているping コマンドをRaspberryPiから実行しAWSのサーバに接続できるか確認
ping hoge.iot.ap-northeast-1.amazonaws.com
PING hoge.ap-northeast-1.amazonaws.com(2400:.... (2400:...)) 56 data bytes 64 bytes from 2400:... (2400:...): icmp_seq=1 ttl=250 time=5.30 ms 64 bytes from 2400:... (2400:...): icmp_seq=1 ttl=250 time=5.13 ms
よかった!成功ですね。
ここで失敗する場合はネットワーク周りの環境を見直しましょう。 -
デバイスを登録して保護する
IoTデバイスの名前としてモノの名前を設定します。「raspberry_pi_3」で作ります。
-
プラットフォームとSDKを選択
RaspberryPiなため、Linuxを選択しSDKはPythonを選択
-
接続キットをダウンロード
ダウンロードした接続キットをscpなどを使ってRaspberryPiに送りそれを解凍する
-rw-r--r-- 1 pi pi 6423 Dec 17 14:10 connect_device_package.zip pi@raspberrypi:~/awsiot $ pi@raspberrypi:~/awsiot $ unzip connect_device_package.zip Archive: connect_device_package.zip extracting: raspberry_pi_3.cert.pem extracting: raspberry_pi_3.public.key extracting: raspberry_pi_3.private.key extracting: raspberry_pi_3-Policy extracting: start.sh pi@raspberrypi:~/awsiot $
-
解凍してできた start.shに権限を付与
pi@raspberrypi:~/awsiot $ chmod +x start.sh pi@raspberrypi:~/awsiot $ ls -l total 28 -rw-r--r-- 1 pi pi 6423 Dec 17 14:10 connect_device_package.zip -rw-r--r-- 1 pi pi 1224 Dec 17 05:07 raspberry_pi_3.cert.pem -rw-r--r-- 1 pi pi 1098 Dec 17 05:07 raspberry_pi_3-Policy -rw-r--r-- 1 pi pi 1675 Dec 17 05:07 raspberry_pi_3.private.key -rw-r--r-- 1 pi pi 451 Dec 17 05:07 raspberry_pi_3.public.key -rwxr-xr-x 1 pi pi 1367 Dec 17 05:07 start.sh
-
start.shを実行
SDKをダウンロードししサンプルアプリケーションを走らせます
pi@raspberrypi:~/awsiot $ ./start.sh Downloading AWS IoT Root CA certificate from AWS... % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 1188 100 1188 0 0 4790 0 --:--:-- --:--:-- --:--:-- 4790 Cloning the AWS SDK... Cloning into 'aws-iot-device-sdk-python-v2'... remote: Enumerating objects: 2472, done. remote: Counting objects: 100% (953/953), done. remote: Compressing objects: 100% (250/250), done. remote: Total 2472 (delta 783), reused 774 (delta 689), pack-reused 1519 Receiving objects: 100% (2472/2472), 2.11 MiB | 4.94 MiB/s, done. Resolving deltas: 100% (1614/1614), done. Installing AWS SDK... Looking in indexes: https://pypi.org/simple, https://www.piwheels.org/simple Processing ./aws-iot-device-sdk-python-v2 Collecting awscrt==0.20.0 Downloading awscrt-0.20.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (7.7 MB) |████████████████████████████████| 7.7 MB 48 kB/s Building wheels for collected packages: awsiotsdk Building wheel for awsiotsdk (setup.py) ... done Created wheel for awsiotsdk: filename=awsiotsdk-1.0.0.dev0-py3-none-any.whl size=73575 sha256=cba38b9290b0313161ed583523f4e42963cdd0807a8616ed9231f6e9c19454ac Stored in directory: /home/pi/.cache/pip/wheels/af/fc/a4/e58680f127da99f9fd9c68f33e690c8e9e7a8d796345826e61 Successfully built awsiotsdk Installing collected packages: awscrt, awsiotsdk Successfully installed awscrt-0.20.0 awsiotsdk-1.0.0.dev0
SDKのインストールが完了したのちしばらくするとサンプルアプリケーションが動作しはじめます。
Running pub/sub sample application... Connecting to hoge.iot.ap-northeast-1.amazonaws.com with client ID 'basicPubSub'... Connection Successful with return code: 0 session present: False Connected! Subscribing to topic 'sdk/test/python'... Subscribed with QoS.AT_LEAST_ONCE Sending messages until program killed Publishing message to topic 'sdk/test/python': Hello World! [1] Received message from topic 'sdk/test/python': b'"Hello World! [1]"' Publishing message to topic 'sdk/test/python': Hello World! [2] Received message from topic 'sdk/test/python': b'"Hello World! [2]"' Publishing message to topic 'sdk/test/python': Hello World! [3] Received message from topic 'sdk/test/python': b'"Hello World! [3]"' Publishing message to topic 'sdk/test/python': Hello World! [4] Received message from topic 'sdk/test/python': b'"Hello World! [4]"' Publishing message to topic 'sdk/test/python': Hello World! [5] Received message from topic 'sdk/test/python': b'"Hello World! [5]"' Publishing message to topic 'sdk/test/python': Hello World! [6] Received message from topic 'sdk/test/python': b'"Hello World! [6]"' Publishing message to topic 'sdk/test/python': Hello World! [7] Received message from topic 'sdk/test/python': b'"Hello World! [7]"' Publishing message to topic 'sdk/test/python': Hello World! [8] Received message from topic 'sdk/test/python': b'"Hello World! [8]"' Publishing message to topic 'sdk/test/python': Hello World! [9] Received message from topic 'sdk/test/python': b'"Hello World! [9]"' Publishing message to topic 'sdk/test/python': Hello World! [10] Received message from topic 'sdk/test/python': b'"Hello World! [10]"' Publishing message to topic 'sdk/test/python': Hello World! [11] Received message from topic 'sdk/test/python': b'"Hello World! [11]"' Publishing message to topic 'sdk/test/python': Hello World! [12] Received message from topic 'sdk/test/python': b'"Hello World! [12]"' Publishing message to topic 'sdk/test/python': Hello World! [13] Received message from topic 'sdk/test/python': b'"Hello World! [13]"'
AWSのコンソールを確認するとサンプルアプリケーションで送信されたメッセージがサブスクリプションされていることを確認できます。
これにてクイック接続を用いたAWS IoTとの連携は完了となります。
思ったより簡単に疎通ができてびっくりですね!
次はAWSが用意しているAWS IoT Device Clientを用いたチュートリアルをやってみます。
AWS IoT Device Client でデモを構築する
チュートリアルは以下の4つの順となっています。デバイスの準備はほぼほぼ完了しているため一部の手順をスキップします。
- チュートリアル: AWS IoT Device Client 用のデバイスの準備
- チュートリアル: AWS IoT Device Client のインストールと設定
- チュートリアル: AWS IoT Device Client との MQTT メッセージ通信をデモンストレーションする
- チュートリアル: AWS IoT Device Client でのリモートアクション (ジョブ) をデモンストレーションする
チュートリアル: AWS IoT Device Client 用のデバイスの準備
AWS Command Line Interface をインストールする
手順に則りAWS CLIをインストール
export PATH=$PATH:~/.local/bin # configures the path to include the directory with the AWS CLI
git clone https://github.com/aws/aws-cli.git # download the AWS CLI code from GitHub
cd aws-cli && git checkout v2 # go to the directory with the repo and checkout version 2
pip3 install -r requirements.txt # install the prerequisite software
pip3 install . # install the AWS CLI
バージョンを確認し、2.2以降であることを確認
pi@raspberrypi:~ $ aws --version
aws-cli/2.15.2 Python/3.9.2 Linux/6.1.21-v8+ source/aarch64.debian.11 prompt/off
pi@raspberrypi:~ $
AWS アカウント 認証情報を設定する
AWSのIAMユーザを作成し、raspberrypi用のAWSアカウントを作成します。
※最低限の権限だけ付与することをお勧めします。
AWS アカウント 認証情報を設定する
作成したIAMユーザの認証情報を設定する
aws configure
AWS Access Key ID [None]: hoge
AWS Secret Access Key [None]: fuga
Default region name [None]: ap-northeast-1
Default output format [None]: json
以下のコマンドを実行し、AWSの認証情報が正しく設定されていることを確認
pi@raspberrypi:~/aws-cli $ aws iot describe-endpoint --endpoint-type iot:Data-ATS
{
"endpointAddress": "hogehoge.iot.ap-northeast-1.amazonaws.com"
}
pi@raspberrypi:~/aws-cli $
チュートリアル: AWS IoT Device Client のインストールと設定
AWS IoT Device Client をダウンロードして保存する
Raspberry Pi に AWS IoT Device Client をダウンロードしてビルドします。
cd ~
git clone https://github.com/awslabs/aws-iot-device-client aws-iot-device-client
mkdir ~/aws-iot-device-client/build && cd ~/aws-iot-device-client/build
cmake ..
AWS IoT Device Client をビルドします。
このコマンドは完了までに、最大で 15 分かかるらしいです。
cmake --build . --target aws-iot-device-client
次のコマンドを実行してテストします。
pi@raspberrypi:~/aws-iot-device-client/build $ ./aws-iot-device-client --help
AWS IoT Device Client BINARY
For more documentation, see https://github.com/awslabs/aws-iot-device-client
Available sub-commands:
--help: Get more help on commands
--version: Output current version
--export-default-settings <JSON-File-Location>: Export default settings for the AWS IoT Device Client binary to the specified file and exit program
--config-file <JSON-File-Location>: Take settings defined in the specified JSON file and start the binary
--log-level <[DEBUG, INFO, WARN, ERROR]>: Specify the log level for the AWS IoT Device Client
--log-type <[STDOUT, FILE]>: Specify the logger implementation to use.
--log-file <File-Location>: Write logs to specified log file when using the file logger.
--enable-sdk-logging Enable SDK Logging.
....
...
..
.
pi@raspberrypi:~/aws-iot-device-client/build $
コマンド成功してホッとしました。
チュートリアルで使用するディレクトリを作成する
次のコマンドを実行して、必要なディレクトリを作成します。
mkdir ~/dc-configs
mkdir ~/policies
mkdir ~/messages
mkdir ~/certs/testconn
mkdir ~/certs/pubsub
mkdir ~/certs/jobs
chmod 745 ~
chmod 700 ~/certs/testconn
chmod 700 ~/certs/pubsub
chmod 700 ~/certs/jobs
AWS IoT で Raspberry Pi をプロビジョニングする
デバイスのデバイス証明書ファイルを作成
mkdir ~/certs/testconn
aws iot create-keys-and-certificate \
--set-as-active \
--certificate-pem-outfile "~/certs/testconn/device.pem.crt" \
--public-key-outfile "~/certs/testconn/public.pem.key" \
--private-key-outfile "~/certs/testconn/private.pem.key"
AWS IoT リソースの作成
権限絞っていたためAWS CloudShellを使ってリソース作成しました!めっちゃ便利ですね!
AWS アカウント のデバイスデータエンドポイントのアドレスを取得します。
aws iot describe-endpoint --endpoint-type IoT:Data-ATS
Raspberry Pi 用の AWS IoT のモノのリソースを作成します。
aws iot create-thing --thing-name "DevCliTestThing"
ポリシードキュメントを作成します。
(こういった作業もCloudShellでできるんですね、すごい。。。!)
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"iot:Publish",
"iot:Subscribe",
"iot:Receive",
"iot:Connect"
],
"Resource": [
"*"
]
}
]
}
ポリシードキュメントを使用して AWS IoT ポリシーを作成します。
aws iot create-policy \
--policy-name "DevCliTestThingPolicy" \
--policy-document "file://~/dev_cli_test_thing_policy.json"
ポリシーをデバイス証明書にアタッチします。
aws iot attach-policy \
--policy-name "DevCliTestThingPolicy" \
--target "certificateArn"
デバイス証明書を AWS IoT のモノのリソースにアタッチします。
aws iot attach-thing-principal \
--thing-name "DevCliTestThing" \
--principal "certificateArn"
AWS IoT Device Client を設定して接続をテストする
~/dc-configs/dc-testconn-config.json
に以下のjsonを配置します。
{
"endpoint": "hogehoge-ats.iot.us-west-2.amazonaws.com",
"cert": "~/certs/testconn/device.pem.crt",
"key": "~/certs/testconn/private.pem.key",
"root-ca": "~/certs/AmazonRootCA1.pem",
"thing-name": "DevCliTestThing",
"logging": {
"enable-sdk-logging": true,
"level": "DEBUG",
"type": "STDOUT",
"file": ""
},
"jobs": {
"enabled": false,
"handler-directory": ""
},
"tunneling": {
"enabled": false
},
"device-defender": {
"enabled": false,
"interval": 300
},
"fleet-provisioning": {
"enabled": false,
"template-name": "",
"template-parameters": "",
"csr-file": "",
"device-key": ""
},
"samples": {
"pub-sub": {
"enabled": true,
"publish-topic": "test/dc/pubtopic",
"publish-file": "",
"subscribe-topic": "test/dc/subtopic",
"subscribe-file": ""
}
},
"config-shadow": {
"enabled": false
},
"sample-shadow": {
"enabled": false,
"shadow-name": "",
"shadow-input-file": "",
"shadow-output-file": ""
}
}
権限を644に設定します。
pi@raspberrypi:~ $ chmod 644 ~/dc-configs/dc-testconn-config.json
作成したjsonファイルを指定して AWS IoT Device Client を実行します。
手順にはないのですが、実行ユーザの権限によってはディレクトリが作成できないというエラーが出てしまうため
以下のコマンドで作成しましょう。
sudo mkdir /var/log/aws-iot-device-client
sudo chmod 745 /var/log/aws-iot-device-client
sudo chown pi:pi /var/log/aws-iot-device-client
pi@raspberrypi:~/aws-iot-device-client/build $ ./aws-iot-device-client --config-file ~/dc-configs/dc-testconn-config.json
2023-12-19T14:19:33.612Z [WARN] {Config.cpp}: Key {publish-file} was provided in the JSON configuration file with an empty value
2023-12-19T14:19:33.612Z [WARN] {Config.cpp}: Key {subscribe-file} was provided in the JSON configuration file with an empty value
2023-12-19T14:19:33.612Z [INFO] {Config.cpp}: Successfully fetched JSON config file: {
....
...
..
.
2023-12-19T14:20:01.556Z [INFO] {Main.cpp}: Pub Sub Sample has stopped
2023-12-19T14:20:01.556Z [INFO] {Main.cpp}: All features have stopped
2023-12-19T14:20:01.556Z [DEBUG] {SharedCrtResourceManager.cpp}: Attempting to disconnect MQTT connection
2023-12-19T14:20:01.559Z [INFO] {SharedCrtResourceManager.cpp}: MQTT Connection is now disconnected
pi@raspberrypi:~/aws-iot-device-client/build $
AWSコンソールのMQTTテストクライアントでメッセージがサブスクライブできていることを確認します。
Hello World!出ました!やったー!!!!
さいごに
今回はAWSが用意しているチュートリアルのうち、2つ目まで完了させました。
クイック接続と同じくMQTTメッセージを確認するといった結果は変わらないのに、手順はこうも違うのですね。
今回権限の関係でいくつかのコマンドをCloudShellから叩いたのですが、これが追加費用なしで利用可能なのに驚きました。
続きのチュートリアルは次の記事で予定しています!!!! ではでは!!
チュートリアル: AWS IoT Device Client との MQTT メッセージ通信をデモンストレーションする
チュートリアル: AWS IoT Device Client でのリモートアクション (ジョブ) をデモンストレーションする