ESP8266でMQTTクライアントを動かす(1)

昨日構築したArduino環境でESP8266にてMQTTクライアント(MQTT Subscriber/Publisher)を動かしてみます。接続先はInternet上のMQTTサーバ(MQTT Broker)をターゲットにします。ですので、通信路がSSLで保護されるのが最低条件です。

先日インストールしたAdafruit MQTTライブラリでいろいろ試してみたのですが上手く行かず、異なる方法を模索しました。また、その他のライブラリなども検討したり試してみたりしましたが、一長一短で、結構悩みました。

で、たどり着いた方法はこちらのサイトを参考にさせていただいて、 PubSubClient というMQTTクライアントを使いました。(基本的には、記載されている内容そのままです)

まずは「ツール」⇒「ライブラリを管理」を選択します。そして、「PubSub」で検索して「PubSubClient」をインストールします。

インストール後、スケッチ例の PubSubClient の中の mqtt_esp8266 というサンプルプログラムを開きます。

変更箇所は、初めの方の

WiFiClient espClient;

WiFiClientSecure espClient;        // 接続にTLSを使う

に変更します。また、後半の

setup_wifi();
client.setServer(mqtt_server, 1883);
client.setCallback(callback);

setup_wifi();
espClient.allowSelfSignedCerts();           // 接続先のサーバーのFingerPrintを確認する
espClient.setFingerprint(mqttFingerPrint);  // 照合すべき値を設定する 
client.setServer(mqtt_server, 8883);        // 接続先のポートを 1883 ⇒ 8883 に変更する
client.setCallback(callback);

また、SSL接続時のエラーを表示するため、真ん中やや下の部分を

Serial.print("failed, rc=");
Serial.print(client.state());
Serial.println(" try again in 5 seconds");
// Wait 5 seconds before retrying
delay(5000);

から

Serial.print("failed, rc=");
Serial.println(client.state());     // 改行追加
char buf[256];                      // SSLエラー表示のためのバッファ確保
espClient.getLastSSLError(buf,256); // エラーメッセージ取得
Serial.print("SSL error: ");        // エラーメッセージ表示
Serial.println(buf);                // 
Serial.println(" try again in 5 seconds");
// Wait 5 seconds before retrying
delay(5000);

に変更します。この少し前にある部分で、

// Attempt to connect
if (client.connect(clientId.c_str())) {
  Serial.println("connected");

を今回はMQTTサーバでパスワード認証をかけているので、

// Attempt to connect
if (client.connect(clientId.c_str(),mqtt_user,mqtt_pass)) {
  Serial.println("connected");

に変更します。

さらに、冒頭の部分に、接続用のパラメータを記述します。

const char* ssid = "接続先WiFiのSSID";           // WiFiの接続先のSSID
const char* password = "WiFiのパスワード";        // WiFiの接続用のパスワード
const char* mqtt_server = "MQTTサーバのFQDN";    // MQTTサーバーのホスト名
const char* mqtt_user = "MQTTサーバのユーザー名";  // MQTTのユーザー名
const char* mqtt_pass = "MQTTサーバのパスワード";  // MQTTのパスワード
const char* mqttFingerPrint = "接続先のフィンガープリント" // ホストのフィンガープリント

フィンガープリントは以下のようにして取得した値です。

~$ openssl s_client -connect MQTTサーバのFQDN:8883 < /dev/null 2>/dev/null | openssl x509 -fingerprint -noout -in /dev/stdin
SHA1 Fingerprint=XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX

これでESP8266を搭載したボードに書き込んでやると、無事にテストができました。
(シリアルモニタでモニタすると確認できます)

ESP8266からは outTopic に向けて2秒周期でPublishされ続けるとともに、inTopicをScbscribeしています。ですので、別のPC上で

~$ mosquitto_sub -h MQTTサーバのFQDN -t outTopic -p 8883 --capath /etc/ssl/certs/ -u MQTTサーバのユーザー名 -P MQTTサーバのパスワード

として、Subscribeしてやると、MQTTにてESP8266がSubscribeした内容が確認できます。また、別のPC上で

~$ mosquitto_pub -h MQTTサーバのFQDN -t inTopic -p 8883 --capath /etc/ssl/certs/ -m "メッセージ" -u MQTTサーバのユーザー名 -P MQTTサーバのパスワード

で Publish したメッセージを確認できます。また、メッセージの先頭が “1” の場合にはESP-WROOM02が乗った基板に搭載されているLEDが点灯します。”1″以外の場合には消灯しますので、こちらでも確認できます。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)