2

I am trying to retrieve JSON mqtt message I received in ESP32.

void mqttMsgCallback(char* topic, byte* payload, unsigned int length) {
    payload[length] = '\0';
    String _message = String((char*)payload);
    String _topic = String(topic);
    if (_topic.equals("Sys.GetInfo/"+getMacAddr()) == 1)
    {
      Serial.println("Message arrived for sys.GetInfo");
      StaticJsonDocument <256> msg1;
      Serial.println(_message);
      deserializeJson(msg1,_message);
      String callbackTopic = msg1["callbackTopic"];
      Serial.println(callbackTopic);
    }
}

The issue is when I publish mosquitto_pub -t "Sys.GetInfo/2462ABFC2CD0" -m "{"callbackTopic" : "1234"}" it works well like callbackTopic as 1234.

but when I publish mosquitto_pub -t "Sys.GetInfo/2462ABFC2CD0" -m "{"callbackTopic" : "xyz"}" it prints callbackTopic value as null. Please point me if I an missing something.

Arduino version 1.8.15 ArduinoJson : 6.18.2 Borad : ESP32

Thanks

2 Answers2

2

Your shell is stripping the " from inside the string. If you run the command:

$ echo "{"callbackTopic" : "xyz"}"

you get:

{callbackTopic : xyz}

so you see all the quotes are stripped. xyz isn't something that ArduinoJSON can parse. But 1234 is, so with the quotes stripped it's still considered valid.

You need to ensure the quotes aren't removed. There's two ways of doing this: escaping them, or encapsulating the string in single quotes which gives a more "literal" interpretation of the contents than double quotes:

Escaping:

"{\"callbackTopic\" : \"xyz\"}"

Single quotes:

'{"callbackTopic" : "xyz"}'

Either of those when used as a parameter to a command work - like:

$ echo '{"callbackTopic" : "xyz"}'
{"callbackTopic" : "xyz"}
Majenko
  • 105,851
  • 5
  • 82
  • 139
-1

To parse an ArduinoJSON one simply needs to

  String JSONpayload = "some JSON here";
  StaticJsonDocument <512> geoLocationInfoJson;
  DeserializationError error = deserializeJson(geoLocationInfoJson, JSONpayload);
  if (error) {
    this->mserial->printStrln("Error deserializing JSON");
  }

To use the values within the StaticJsonDocument one first needs to

if ( geoLocationInfoJson.isNull() == true ){
  String dataStr="NULL geoLocation data.\n";
  Serial.print( dataStr); 
  return true;
}

next, is required to verify if a key exists. If TRUE, then is mandatory first to get the desired value into a corresponding data type, like below, and only afterward work on it, for instance, send it as a BLE message string:

if(this->interface->geoLocationInfoJson.containsKey("lat")){
  float lat = this->interface->geoLocationInfoJson["lat"];
  dataStr += "Latitude: "+ String(lat,4) + "\n";
}
if(this->interface->geoLocationInfoJson.containsKey("lon")){
  float lon = this->interface->geoLocationInfoJson["lon"];
  dataStr += "Longitude: "+ String(lon,4) + "\n";
}

if(this->interface->geoLocationInfoJson.containsKey("regionName")) dataStr += String(this->interface->geoLocationInfoJson["regionName"].as<char*>()) + ", ";

The full code above is available on this GitHub repository:

https://github.com/aeonSolutions/aeonlabs-ESP32-C-Base-Firmware-Libraries

Juraj
  • 18,264
  • 4
  • 31
  • 49
Miguel Tomás
  • 219
  • 1
  • 9