I have read LukeUSMC (Semper Fi brother!) excellent tutorial.
I know I can use a webhook response template to parse the response from Ubidots but it seems like overkill as the JSON I get back from Ubidots is simply this:
{
“battery”: [{“status_code”:201}]
“hourly”: [{“status_code”:201}]
“temp”: [{“status_code”:201}]
“daily”: [{“status_code”:201}]
}
note: the order in which the variables are listed can vary.
I know I could create a response template to separate these values with tildes but it seems the biggest advantage of the response template is reducing the size of the data that needs to be transmitted to the Electron and this response is already short.
For my purposes, I am only interested in the response code that is associated with “hourly”. I came up with the code below which works but, if there is a better way or if I should reconsider response templates, I am all ears. Thank you.
void myHandler(const char *event, const char *data)
{
Serial.println(data);
if (!data) { // First check to see if there is any data
Serial.print("No data returned from WebHook ");
Serial.println(event);
return;
}
String response = data; // If there is data - copy it into a String variable
int datainResponse = response.indexOf("hourly") + 24; // Find the "hourly" field and add 24 to get to the value
String responseCodeString = response.substring(datainResponse,datainResponse+3); // Trim all but the value
int responseCode = responseCodeString.toInt(); // Put this into an int for comparisons
switch (responseCode) { // From the Ubidots API refernce https://ubidots.com/docs/api/#response-codes
case 200:
Serial.println("Request successfully completed");
case 201:
Serial.println("Successful request - new data point created");
break;
case 400:
Serial.println("Bad request - check JSON body");
break;
case 403:
Serial.println("Forbidden token not valid");
break;
case 404:
Serial.println("Not found - verify variable and device ID");
break;
case 405:
Serial.println("Method not allowed for API endpoint chosen");
break;
case 501:
Serial.println("Internal error");
break;
default:
Serial.print("Ubidots Response Code: "); // Non-listed code - generic response
Serial.println(responseCode);
break;
}
}
It is a personal preference sometimes. Are you planning to parse more JSON in the future? In the Particle IDE, I have worked with the JsonStreamingParser (1.0.5). It needs a small change to be re-usable as a global variable. The other issue is you will need to create different “listener” classes to deal with different JSON structures/responses. I can see it possibly being useful here if your planning to do other JSON parsing.
Here is some sample code. The JSON above isn’t quite formatted correctly and caused a little bit of head banging until I realized the commas were missing. I tweaked the JsonStreamingParser ever so slightly to allow the object to be re-used with new strings.
When all is said and done, it pulls out the response you need. This opens up the avenue to pull out whatever parts you need. I included the bad response just so you see what the library does with badly behaved JSON.
Wow, thank you. I guess the question is as you said, how often do I intent to parse JSON. I need to spend some time learning about C++ Object as I am used to Wiring.
Am I right in assuming that your approach was required since this is a non-standard JSON format?
Again, thank you for taking the time to help me get my head around this.
Wait a minute, are you saying the response is non-JSON? What generates that response? [Edit: in your original post you say it is a JSON response, it actually isn't - it is missing commas after each line]
The library I showed wants a well formed JSON response.
Well, I was trying to figure out how to specify the value I wanted and tried this on-line JSON viewer which was linked in another post in the forum: http://jsonviewer.stack.hu/
It said this was not properly formatted JSON. It was only happy once I added commas between the fields.