odelot / aws-mqtt-websockets

Implementation of a middleware to use AWS MQTT service through websockets, aiming the ESP8266 plataform
GNU Lesser General Public License v3.0
231 stars 67 forks source link

How to change the 'aws_topic' #29

Open JackyLinKT opened 6 years ago

JackyLinKT commented 6 years ago

Hello, I want to create dynamic mqtt topic, such as:

String  TmpStr = "";
TmpStr = "$aws/things/TestIot/shadow/get/accepted";//example, this topic will input from other channel
aws_topic = TmpStr.c_str();
subscribe();

The Esp8266 can response 'MQTT subscribed' and seems okay. But it can not receive any message.

If I change the code as:

aws_topic = "$aws/things/TestIot/shadow/get/accepted";
subscribe();

The Esp8266 work well.

How to change the 'aws_topic'?

waghekapil commented 6 years ago

@JackyLinKT If I understood correctly, you want to use dynamic MQTT topics in your firmware. Here is how I managed to use dynamic topics in my firmware.

const char* responseTopicName = ""; // Variable 
responseTopicName = parsed["response_topic_name"]; // Here I'm getting response topic from an MQTT message
int rc = client->publish(responseTopicName , *message);

Here parsed is an JsonObject.

In your example you are using Thing Shadow MQTT Topics. In that place you can use custom topics too, like:

char* sub_topic = "customTopic/06519942-652e-11e7-907b-a";
char* server_topic = "customTopic_server/";

OR

String customTopic = "myCustomTopic";
int rc = client->publish(customTopic.c_str() , *message);

Let me know your feedback.

JackyLinKT commented 6 years ago

@waghekapil Thanks your suggestion very much!

In my firmware, the MQTT topics will be transfer from external MCU via UART. The 'topic's strings was not 'constant string'. I change the firmware like below and it seems work well, maybe it was not best solution, please comment.

//const char* aws_topic_subscribe   =   "$aws/things/TestIot/shadow/get/accepted";
//const char* aws_topic_publish =   "$aws/things/TestIot/shadow/get";
char* aws_topic_subscribe   =   "$aws/things/TestIot/shadow/get/accepted";
char* aws_topic_publish     =   "$aws/things/TestIot/shadow/get";
            else if(TmpString.startsWith("sscr"))
            {
                int     TmpIdx;
                String  TmpStr = "";

                //via UART input string: kt+sscr&TestIot/shadow/get/accepted&
                TmpIdx = TmpString.indexOf('&');
                TmpString.remove(0, TmpIdx +1); //delete 'sscr/'

                //string: TestIot/shadow/get/accepted&
                TmpIdx = TmpString.indexOf('&');
                TmpStr = "$aws/things/";
                TmpStr += TmpString.substring(0, TmpIdx); //capture things
                               //string: $aws/things/TestIot/shadow/get/accepted&

                TmpIdx = TmpStr.length();

                char    TmpChar[TmpIdx+1];
                TmpStr.toCharArray(TmpChar, TmpIdx+1);
                                //TmpChar: $aws/things/TestIot/shadow/get/accepted&

                memcpy(aws_topic_subscribe, TmpChar, TmpIdx+1);
                               //aws_topic_subscribe: $aws/things/TestIot/shadow/get/accepted&

                ktsubscribe();

                Serial.println("KT+SSCR=OK");
            }
//subscribe to a mqtt topic
void ktsubscribe () {
   //subscript to a topic
    int rc = client->subscribe(aws_topic_subscribe, MQTT::QOS0, messageArrived);
    if (rc != 0) {
      Serial.print("rc from MQTT subscribe is ");
      Serial.println(rc);
      return;
    }
    Serial.println("MQTT subscribed");
}

The 'Publish' operation was same as above.

Please comment!

virgilioaray commented 6 years ago

Hello Read this, maybe help you

https://github.com/odelot/aws-mqtt-websockets/issues/34#issuecomment-365808478