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 Answers 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"}
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
-
what question does this answer?2023年05月07日 05:31:42 +00:00Commented May 7, 2023 at 5:31
-
The one of successfully parsing an arduinojson object. And access key, value pairs it holdsMiguel Tomás– Miguel Tomás2023年05月07日 05:33:56 +00:00Commented May 7, 2023 at 5:33
-
that is not the question asked on top of this page2023年05月07日 05:36:29 +00:00Commented May 7, 2023 at 5:36
-
Read between the lines ?Miguel Tomás– Miguel Tomás2023年05月07日 05:37:06 +00:00Commented May 7, 2023 at 5:37
-
the existing accepted answer shows what the problem was2023年05月07日 05:39:07 +00:00Commented May 7, 2023 at 5:39
deserializeJson()
to see if it can even parse it as valid JSON. Maybe you need'{"callbackTopic" : "xyz"}'
(single quotes round the outside) to preserve the quotes on the inside.'{"callbackTopic" : "xyz"}'
. Thanks why the message with "" works whencallbackTopic
value is numericxyz
as a valid "thing".payload[length] = '0円';
how do you know there is a length + 1 position available?