#IoTに関するAWS
- AWS IoT
- AWS IoT 1-click
- AWS Greengrass Core
- AWS FreeRTOS
いくつかある...
非常に関心があるのでいずれ使ってみようと思います。
#AWS IoT
IoTデバイスをバックエンドやクラウドサービスと連携することができる。
通信はHTTPSやMQTT通信を用いることができる。
#使用マイコン・環境
- ESP-WROOM-32
- Arduino IDE
#MQTTプロトコルについて
1990年代後半に開発されたプロトコル!
TCP/IPベースに規定されたプロトコル!
MQTTは軽量で、しかも柔軟性がとても高いプロトコル!
M2M(Machine-to-Machine)を重要視するIoTにおいて、とてもぴったりなプロトコル!
利点
IoTではハードウェアやネットワークの面において、非常に厳しい環境で開発する場合がある。
- 待ち時間や帯域幅、デバイス面での条件が厳しい場合
- 双方向通信-Publish/Subscribe
- 1対多通信
- プロトコルヘッダサイズが小さく軽量(HTTP:50バイト,MQTT:2バイト)
- 電力消費量
- 非同期通信
- 負荷
- 通信量
- 頻繁な通信=>大量に送れる
欠点は信頼性ですかね。同期通信ではないですし...
サーバークライアント間がHTTPSやHTTPでなくMQTTだとやはり向いてないですよね。
#クライアント証明
AWS IoTでは「モノ」「ポリシー」の登録。
最初に証明書を発行してもらい、RooTCA、Private_Key、Certificateをダウンロード!
#Arduinoでのスケッチ
WiFiClientSecure.h - Wifi接続がよりSecureにできるようになるライブラリ
PubSubClient.h - Port:8883でMQTT通信ができるようになるライブラリ
これらを使っていきます。
#include <WiFiClientSecure.h>
#include <PubSubClient.h>
const char* ssid = "[SSID]";
const char* password = "[Password]";
const char* server = "[end point]";
const int port = 8883;
const char* Root_CA = \
"-----BEGIN CERTIFICATE-----\n" \
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\n" \
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\n" \
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\n" \
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\n" \
"-----END CERTIFICATE-----\n";
const char* Client_cert = \
"-----BEGIN CERTIFICATE-----\n" \
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" \
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" \
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" \
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" \
"-----END CERTIFICATE-----\n";
const char* Client_private = \
"-----BEGIN RSA PRIVATE KEY-----\n" \
"cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc\n" \
"cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc\n" \
"cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc\n" \
"cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc\n" \
"-----END RSA PRIVATE KEY-----\n";
WiFiClientSecure client;
PubSubClient mqttClient(client);
void connectAWSIoT() {
while (!mqttClient.connected()) {
if (mqttClient.connect("ESP32")) {
Serial.println("Connected.");
} else {
Serial.print("Failed. Error state=");
Serial.print(mqttClient.state());
// Wait 5 seconds before retrying
delay(5000);
}
}
}
void setup()
{
Serial.begin(115200);
delay(10);
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.begin(ssid, password);
delay(1000);
Serial.println(Root_CA);
Serial.println(Client_cert);
Serial.println(Client_private);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
client.setCACert(Root_CA);
client.setCertificate(Client_cert);
client.setPrivateKey(Client_private);
mqttClient.setServer(server, port);
mqttClient.setCallback(mqttCallback);
connectAWSIoT();
}
long messageSentAt = 0;
int Value = 0;
char pubMessage[128];
void mqttCallback (char* topic, byte* payload, unsigned int length) {
Serial.print("Received. topic=");
Serial.println(topic);
for (int i = 0; i < length; i++) {
Serial.print((char)payload[i]);
}
Serial.print("\n");
}
void mqttLoop() {
if (!mqttClient.connected()) {
connectAWSIoT();
}
mqttClient.loop();
}
void loop() {
mqttLoop();
}
#こりゃダメだ
エラーコードは-1
エラーの原因
MQTT_DISCONNECTED - the client is disconnected cleanly
MQTTでAWS IoTのモノまで到達できていないそう...
#考えられる原因
-
証明書が有効になってない -> アタッチ済み
-
証明書や鍵の割り当て -> 何回か行なったが心配 ←怪しい
-
ポリシー -> 全権限許可
-
ポート -> 8883(MQTTの場合)
-
エンドポイント -> 間違いなさそう
-
AWS IoTはTLS.1.2のみ対応 -> ESP32:WifiClientSecureもTLS.1.2対応
-
PubSubClient::connectの引数 ← 怪しい
- プログラム上では失敗してるが?
#証明書をOpensslコマンドで確認
rootca2.pem - RootCA
[AWS_name]-certificate.pem - Certificate
[AWS_name]-private.pem - Private Key
$ openssl s_client -connect [AWS_name].iot.ap-northeast-1.amazonaws.com:8443 -CAfile rootca2.pem -cert [AWS_name]-certificate.pem -key [AWS_name]-private.pem
CONNECTED(00000003)
depth=2 C = US, O = "VeriSign, Inc.", OU = VeriSign Trust Network, OU = "(c) 2006 VeriSign, Inc. - For authorized use only", CN = VeriSign Class 3 Public Primary Certification Authority - G5
verify return:1
depth=1 C = US, O = Symantec Corporation, OU = Symantec Trust Network, CN = Symantec Class 3 Secure Server CA - G4
verify return:1
depth=0 C = US, ST = Washington, L = Seattle, O = "Amazon.com, Inc.", CN = *.iot.ap-northeast-1.amazonaws.com
verify return:1
接続できてるので証明書の問題ではない。
(あるとしてもコピーミス)
#不可解
ところでこの接続成功はなに
ということはArduinoのプログラムがやはり怪しい...
#追記-接続完了!
犯人はこのコード
if (mqttClient.connect("ESP32")) {
Serial.println("Connected.");
} else {
Serial.print("Failed. Error state=");
Serial.print(mqttClient.state());
// Wait 5 seconds before retrying
delay(5000);
}
mqttClient.connect("ESP32")
"ESP32"というのがDocumentとにらめっこした挙句、ClientIDということがわかりました。
ClientIDはAWSのポリシーで設定しておく必要があります。
デフォルトのTopicのままだとアクセスできない状態なので、以下のようにClientに変更して設定したClientIDにアクセスできるようになる。
今回ならこんな感じ
[ESP32] -> ClientID
{
"Version": "2018-7-1",
"Statement": [{
"Effect": "Allow",
"Action": ["iot:Connect"],
"Resource": [
"arn:aws:iot:[us-east-1:123456789012]:client/ESP32"
]
}]
mqttClient.connect("ESP32")が失敗してただけで、AWS IoTに接続はできていた。
Arduinoのコード上でdisconnectedが表記されていたのはそのため。
つまり上記は何も不可解でもなかった。
#展望
ここから AWS lambdaやCognitoと連携して、サービスをつくっていく
#参考文献
MQTT
- https://kfep.jp/solution/iot-mqtt/mqtt
-
https://www.ibm.com/developerworks/jp/iot/library/iot-mqtt-why-good-for-iot/index.html
AWS IoT - https://www.1ft-seabass.jp/memo/2017/07/31/esp32-developer-aws-iot-tips/
- https://blog.maripo.org/2017/07/esp32-aws-iot-troubleshooting/
- https://docs.aws.amazon.com/ja_jp/iot/latest/developerguide/protocols.html
-
http://ken5owata.hatenablog.com/entry/2017/10/22/102207
エラー - https://docs.aws.amazon.com/ja_jp/iot/latest/developerguide/basic-policy-variables.html