0

Hi I need to create a lambda function which will access the AWS thing and publish MQTT message, I'd like to get the published message on the ESP8266 which was connected to the thing as well, and controlled turn on/off the LED on ESP8266. So far I have uploaded the private.der, cert.der and ca.der to the ESP8266 absolutely, but it couldn't subscribed AWS IOT, please point me in the right tips then please share.

Code:

       #include <ESP8266WiFi.h>
       #include <PubSubClient.h>
       #include <NTPClient.h>
       #include <WiFiUdp.h>
       #include <ArduinoJson.h>
       #define OUT_TOPIC "$aws/things/devices/shadow/update"
       #define IN_TOPIC "$aws/things/devices/shadow/update/delta"
        const char* ssid = "sid";
        const char* password = "password";

        WiFiUDP ntpUDP;
        NTPClient timeClient(ntpUDP, "pool.ntp.org");

        const char* AWS_endpoint = "endpoint.amazonaws.com";//MQTT broker ip

        const char* json = "{\"state\":{\"reported\":{\"led\":\"off\"}}}";

        StaticJsonDocument<1024> doc;

        WiFiClientSecure espClient;
        PubSubClient mqttClient(espClient);//set MQTT port number to 8883 as per standard
        PubSubClient client(AWS_endpoint, 8883, espClient); 
        long lastMsg = 0;
        char msg[50];
        int value = 0;

        void setup_wifi() {

        delay(10);// We start by connecting to a WiFi network
        espClient.setBufferSizes(512, 512);
        Serial.println();
        Serial.print("Connecting to ");
        Serial.println(ssid);

        WiFi.begin(ssid, password);

        while (WiFi.status() != WL_CONNECTED) 
    {
        delay(500);
        Serial.print(".");
        }
        Serial.println("");
        Serial.println("WiFi connected");
        Serial.println("IP address: ");
        Serial.println(WiFi.localIP());

        timeClient.begin();
        while(!timeClient.update()){
        timeClient.forceUpdate();
        }

        espClient.setX509Time(timeClient.getEpochTime());

        int qos = 0;//Maximum size of data that can be communicated
        Serial.println(MQTT_MAX_PACKET_SIZE);
        if(mqttClient.subscribe(IN_TOPIC, qos)){
        Serial.println("Subscribed.");
        Serial.println("Success!!");
        }

        deserializeJson(doc, json);
        JsonObject obj = doc.as<JsonObject>();

        if(mqttClient.publish(OUT_TOPIC, json)){
        Serial.println("Published!!");
        }

        }

        void setup() {

        Serial.begin(115200);
        Serial.setDebugOutput(true);
        // initialize digital pin LED_BUILTIN as an output.
        pinMode(LED_BUILTIN, OUTPUT);
        setup_wifi();
        delay(1000);
        if (!SPIFFS.begin()) {
        Serial.println("Failed to mount file system");
        return;
        }

        Serial.print("Heap: "); Serial.println(ESP.getFreeHeap());

        //replace cert.crt eith your uploaded file name
        File cert = SPIFFS.open("/cert.der", "r"); 
        if (!cert) {
        Serial.println("Failed to open cert file");
        }
        else
        Serial.println("Success to open cert file");

        delay(1000);
        if (espClient.loadCertificate(cert))
        Serial.println("cert loaded");
        else
        Serial.println("cert not loaded");

        // Load private key file
        File private_key = SPIFFS.open("/private.der", "r");//replace private eith your uploaded file name
        if (!private_key) {
        Serial.println("Failed to open private cert file");
        }
        else
        Serial.println("Success to open private cert file");

        delay(1000);

        if (espClient.loadPrivateKey(private_key))
        Serial.println("private key loaded");
        else
        Serial.println("private key not loaded");
        // Load CA file
        File ca = SPIFFS.open("/ca.der", "r"); 
        //replace ca eith your uploaded file name
        if (!ca) {
        Serial.println("Failed to open ca ");
        }
        else
        Serial.println("Success to open ca");

        delay(1000);

        if(espClient.loadCACert(ca))
        Serial.println("ca loaded");
        else
        Serial.println("ca failed");
        Serial.print("Heap: "); 
        Serial.println(ESP.getFreeHeap());
        }

        void callback (char* topic, byte* payload, unsigned int length) {

        Serial.println("Received. topic=");
        Serial.println(topic);
        char subsc[length];
        for(int i=0; i<length; i++){
        subsc [i]=(char)payload[i];
        subsc [length]='\0';
        Serial.print(subsc);
        }
        Serial.print("\n");
        digitalWrite(LED_BUILTIN, HIGH);
        }

        void mqttLoop() {
        mqttClient.loop();
        delay(100);
        //digitalWrite(LED_pin, LOW);
        digitalWrite(LED_BUILTIN, LOW); 
        Serial.print(".");
        }
        void loop() {
4

1 回答 1

0

看起来您正在使用旧形式的WiFiClientSecure证书处理。我假设一切正常,并且您能够建立 SSL 连接。

IN_TOPIC需要稍微更新为:($aws/things/&lt;name-of-your-thing&gt;/shadow/update/accepted希望您知道是什么&lt;name-of-your-thing&gt;)。您可以从 AWS 控制台上的事物影子中获取此信息。

同样AWS_endpoint需要更新:它应该是&lt;random-stuff-specific-to-you&gt;.iot.&lt;region&gt;.amazonaws.com. 您也可以从与 MQTT 主题相同的位置找到它。

您只需要一个PubSubClient. 我假设您删除client并保留mqttClient. 您需要更新实例化以包括 AWS 终端节点和端口,就像您为客户端所做的那样。

在调用之前,mqttClient.subscribe(...)您需要注册回调:

  mqttClient.setCallback(::callback);

然后连接到 AWS:

  mqttClient.connect("some-unique-name");

最后,您需要编辑PubSubClient.h(在 Arduino/libraries/PubSubClient/src 中查找)以更新 MQTT_MAX_PACKET_SIZE。默认值为 128,我发现 AWS 的消息太小了。我做了我的1024:

  #define MQTT_MAX_PACKET_SIZE 1024

这似乎足够了。

一旦编译并运行,您将开始看到使用您订阅的主题调用的回调(...),您可以实现该函数来做任何您需要的事情。

PubSubClient 不会做太多错误报告来帮助诊断正在发生的事情。我目前正在对其进行一些重构并包含更多诊断信息,最终将发出拉取请求。在我走到那一步之前,让我知道你是否想要我的破解版本。

于 2020-01-04T07:12:07.087 回答