【问题标题】:MQTT google cloud connection with ESP8266MQTT 谷歌云连接与 ESP8266
【发布时间】:2019-04-22 12:18:42
【问题描述】:

我正在尝试使用 Arduino IDE 并使用此库 https://github.com/GoogleCloudPlatform/google-cloud-iot-arduino 将温度数据从 NodeMCU 发送到 Google Cloud。我在 google iot core 上创建了一个注册表和一个设备,并在那里上传了公钥(ES256)。在我这边,我通过 SPIFFS 在 ESP8266 上上传了 csa 证书,并在“ciotc_config.h”中正确设置了所有参数和私钥字符串。当我尝试连接时,我会在串行监视器中看到以下输出重复:

14:11:14.342 -> Connecting to WiFi
14:11:15.725 -> Waiting on time sync...
14:11:15.866 -> Success to open ca file
14:11:15.913 -> loaded
14:11:15.913 -> 
14:11:15.913 -> connecting...Refreshing JWT
14:11:19.797 -> 
14:11:19.797 -> connected!
14:11:19.843 -> 
14:11:19.843 -> connecting...Refreshing JWT
14:11:23.727 -> 
14:11:23.727 -> connected!
14:11:23.774 -> 
14:11:23.774 -> connecting...Refreshing JWT

等等……

设备>配置和状态历史下的云仪表板中未收到数据,我可以看到黄色警告“设备尚未确认”

似乎我无法连接MQTT,因为数据没有发送,我不知道如何真正理解错误在哪里。你们有什么想法吗?

谢谢

#include "DHT.h"
#include <CloudIoTCore.h>
#include "esp8266_mqtt.h"

#define DHTPIN 2 // what digital pin we're connected to
#define DHTTYPE DHT11 // DHT 11
unsigned long lastMillis = 0;
DHT dht(DHTPIN, DHTTYPE);

void setup() {
  Serial.begin(115200);
  setupCloudIoT(); // Creates globals for MQTT
  dht.begin();
}

void loop() {
  mqttClient->loop();
  delay(10);  // <- fixes some issues with WiFi stability

  if (!mqttClient->connected()) {
    connect();
  }

  if (millis() - lastMillis > 20000) {
    lastMillis = millis();
  String payload =
      String("{\"timestamp\":") + time(nullptr) +
      String(",\"temperature\":") + dht.readTemperature() +
      String(",\"humidity\":") + dht.readHumidity() +
      String("}");
    publishTelemetry(payload);
  }
}

更新: 带调试的串行监视器输出:

19:16:17.266 -> SDK:3.0.0-dev(c0f7b44)/Core:2.5.0=20500000/lwIP:STABLE-2_1_2_RELEASE/glue:1.1/BearSSL:6778687
19:16:17.266 -> sta config unchangedscandone
19:16:17.313 -> Connecting to WiFi
19:16:17.313 -> wifi evt: 2
19:16:17.406 -> scandone
19:16:17.406 -> state: 0 -> 2 (b0)
19:16:17.406 -> state: 2 -> 3 (0)
19:16:17.406 -> state: 3 -> 5 (10)
19:16:17.406 -> add 0
19:16:17.406 -> aid 14
19:16:17.406 -> cnt 
19:16:17.453 -> 
19:16:17.453 -> connected with Internet, channel 6
19:16:17.453 -> dhcp client start...
19:16:17.453 -> wifi evt: 0
19:16:19.282 -> ip:XX.X.X.X,mask:XXX.XXX.XXX.X,gw:XX.X.X.XXX
19:16:19.282 -> wifi evt: 3
19:16:19.282 -> Waiting on time sync...
19:16:19.751 -> SPIFFSImpl: allocating %zd+%z d+%z  d=%z   d bytes
19:16:19.751 -> SPIFFSImpl: mounting fs @100000, size=2fb000, block=2000, page=100
19:16:19.798 -> SPIFFSImpl: mount rc=0
19:16:19.798 -> Success to open ca file
19:16:19.845 -> loaded
19:16:19.845 -> SPIFFS_close: fd=1
19:16:19.845 -> 
19:16:19.845 -> connecting...Refreshing JWT
19:16:23.255 -> [hostByName] request IP for: mqtt.googleapis.com
19:16:23.301 -> [hostByName] Host: mqtt.googleapis.com IP: XX.XXX.XXX.XXX
19:16:23.301 -> :ref 1
19:16:23.395 -> :wr 224 0
19:16:23.395 -> :wrc 224 224 0
19:16:23.395 -> :ack 224
19:16:23.395 -> :rn 536
19:16:23.395 -> :rd 5, 536, 0
19:16:23.395 -> :rdi 536, 5
19:16:23.442 -> :rd 87, 536, 5
19:16:23.442 -> :rdi 531, 87
19:16:23.442 -> :rd 5, 536, 92
19:16:23.442 -> :rdi 444, 5
19:16:23.442 -> :rd 439, 536, 97
19:16:23.442 -> :rdi 439, 439
19:16:23.442 -> :c0 439, 536
19:16:23.676 -> :rn 536
19:16:23.676 -> :rd 536, 536, 0
19:16:23.676 -> :rdi 536, 536
19:16:23.676 -> :c0 536, 536
19:16:23.770 -> :rn 1072
19:16:23.770 -> :rch 1072, 536
19:16:23.770 -> :rd 1471, 1608, 0
19:16:23.770 -> :rdi 536, 536
19:16:23.770 -> :c 536, 536, 1608
19:16:23.770 -> :rdi 536, 536
19:16:23.770 -> :c 536, 536, 1072
19:16:23.770 -> :rdi 536, 399
19:16:24.086 -> :rch 536, 177
19:16:24.086 -> 
19:16:24.086 -> connected!
19:16:24.086 -> 
19:16:24.086 -> connecting...Refreshing JWT
19:16:27.510 -> [hostByName] request IP for: mqtt.googleapis.com
19:16:27.510 -> [hostByName] Host: mqtt.googleapis.com IP: XX.XXX.XXX.XXX
19:16:27.510 -> pm open,type:2 0
19:16:27.510 -> :close
19:16:27.510 -> :ur 1
19:16:27.510 -> :del
19:16:27.510 -> :ref 1
19:16:27.604 -> :wr 224 0
19:16:27.604 -> :wrc 224 224 0
19:16:27.651 -> :ack 224
19:16:27.651 -> :rn 536
19:16:27.651 -> :rch 536, 536
19:16:27.651 -> :rch 1072, 536
19:16:27.651 -> :rch 1608, 536
19:16:27.651 -> :rd 5, 2144, 0
19:16:27.651 -> :rdi 536, 5
19:16:27.651 -> :rd 87, 2144, 5
19:16:27.651 -> :rdi 531, 87
19:16:27.651 -> :rd 5, 2144, 92
19:16:27.651 -> :rdi 444, 5
19:16:27.651 -> :rd 2047, 2144, 97
19:16:27.651 -> :rdi 439, 439
19:16:27.651 -> :c 439, 536, 2144
19:16:27.651 -> :rdi 536, 536
19:16:27.651 -> :c 536, 536, 1608
19:16:27.651 -> :rdi 536, 536
19:16:27.651 -> :c 536, 536, 1072
19:16:27.651 -> :rdi 536, 536
19:16:27.651 -> :c0 536, 536
19:16:27.885 -> :rn 536
19:16:27.885 -> :rch 536, 177
19:16:27.885 -> :rd 399, 713, 0
19:16:27.885 -> :rdi 536, 399
19:16:28.073 -> 
19:16:28.073 -> connected!
19:16:28.120 -> 
19:16:28.120 -> connecting...Refreshing JWT

UPDATE2:JWT 验证和凭据调试

在从 Serial Monitor 获得的凭证和 JWT 下方:

18:54:41.890 -> Waiting on time sync...
18:54:42.904 -> Success to open ca file
18:54:42.938 -> loaded
18:54:42.971 -> projects/iot-esp8266-new/locations/us-central1/registries/iotcore-registry/devices/esp8266
18:54:42.971 -> Refreshing JWT
18:54:46.318 -> XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
18:54:46.351 -> 
18:54:46.351 -> connecting...Refreshing JWT

生成的 JWT 已通过 PyJWT 验证如下:

import jwt
public_key =  open('ec_public.pem').read()
token = 'XXXXXXXXXXXXXXXXXXXXXXXXXXX'
payload = jwt.decode(token, public_key, algorithms=['ES256'], audience="iot-esp8266-new")
payload
{'iat': 1556988880, 'exp': 1556992480, 'aud': 'iot-esp8266-new'}

【问题讨论】:

  • 日志表明您实际上正在获得连接并失去它。对于其他 MQTT 代理,如果设备有权连接,但随后尝试订阅它缺乏权限的另一个主题,则可能会发生这种情况。这里的很多设备固件都在库中,我会先检查云配置。
  • 嗨@MBer,谢谢你的回答......我看到它几乎立即连接和断开连接......我认为在云端我做了我必须做的一切,我激活了计费, api 和 pubsub,然后创建了项目、注册表和设备并在那里附加了公钥,实际上我不知道我还应该做什么......
  • 祝你好运 - 除非遇到同样问题的人停下来,否则如果没有来自 Cloud Pub/Sub 的日志,解决问题将很困难。
  • 几个问题:你安装了哪个版本的库? 8266 有哪个 SDK?通过在 IDE 中的 Tools > Core Debug Level > Verbose 下设置调试级别,在 Arduino 中启用更详细的调试可能会有所帮助。
  • 您是否将 Google 的根证书放在设备上?只需确保您所说的 csa 证书既是您在创建设备时向设备注册表注册的 SSL 密钥对的私有部分,又是您从 pki.google.com/roots.pem 获得的根证书。

标签: google-cloud-platform mqtt iot arduino-esp8266


【解决方案1】:

更新 ESP8266 社区 SDK 的 2.5.x 分支发生了变化。该库将需要更新以支持它以及 2.4.x 库,它们尚未完成。目前,最简单的方法是使用 2.4.2 SDK,或者您可以use the workaround mentioned in the library documentation 直到发布修复程序。

之前的回复

我已经证实 1.0.5 版本的库可以与 ESP8266 硬件一起使用。您可能想尝试打印参数并确保它们设置正确。这可能是最简单的替换方法:

  if (!mqttClient->connected()) {
    connect();
  }

在您的主项目文件中使用以下行:

  if (!mqttClient->connected()) {
    // Example debug line
    Serial.println(device->getClientId());
    Serial.println(getJwt());
    // End debug line
    connect();
  }

如果配置看起来正确,您可能想尝试使用 jwt.io 之类的东西来验证 JWT。为此在库中添加一个助手是有意义的。

【讨论】:

  • 嗨@class 谢谢你的回答。在提出这个问题之前,我已经使用 getJwt() 进行了调试,我再次重新检查。配置看起来不错,生成的 JWT 看起来也不错。这次我用 PyJwt 验证了它,请参阅问题中的更新。 PS:我使用的是 NodeMCU。你觉得有关系吗?谢谢
  • 更新答案。
  • 嗨@class 我确认版本 2.4.2 连接正常。谢谢。