JsonParserGeneratorRK and Multipart responses

I’m working on a project where I’m publishing data up to a custom API and subscribing to the response to update a display on my device. I’m moving away from a mustache based response as it feels really brittle and awkward to add new values in without messing up devices running older firmware. It also doesn’t handle empty values in a way that parses back correctly(If I’m looking for A, B, C, D, if B is NULL, then B will read C instead and everything else will be shifted incorrectly).

For this reason I’m looking to just parse the full JSON response from my API, and trying to use the Jsonparser by @rickkas7.

I seem to be running into an issue due to the multipart response, I’m using the example given but it doesn’t seem to be working for my webhook.

Webhook:

API Response:

Relevant Code:

JsonParser jsonParser; //Global object
Particle.subscribe(System.deviceID() + "/hook-response/er/", temperatureHandler, MY_DEVICES);

void temperatureHandler(const char *event, const char *data) {
  int responseIndex = 0;

	const char *slashOffset = strchr(event, '/');
	if (slashOffset) {
		responseIndex = atoi(slashOffset + 1);
    Serial.println("offest");
	}
  Serial.println("rspIndex " + String(responseIndex));

	if (responseIndex == 0) {
		jsonParser.clear();
	}
	jsonParser.addString(data);

	if (jsonParser.parse()) {
    // API resonse complete
		parseTempResponse(jsonParser);
	}
}

void parseTempResponse(JsonParser &jp){
 Serial.println("Webhook response recieved!");

  String status,  tempStatus, humidityStatus;
  float temp, highTemp,  lowTemp;
  int humidity, highHumidity, lowHumidity;
  String rspTime, rspUnit;

  int interval = jp.getReference().key("next_reading_interval").valueInt();
  jp.getOuterValueByKey("status", status);
  jp.getOuterValueByKey("temp_status", tempStatus);
  jp.getOuterValueByKey("humidity_status", humidityStatus);
  jp.getOuterValueByKey("temp", temp);
  jp.getOuterValueByKey("past_high_temp", highTemp);
  jp.getOuterValueByKey("past_low_temp", lowTemp);
  jp.getOuterValueByKey("humidity", humidity);
  jp.getOuterValueByKey("past_high_humidity", highHumidity);
  jp.getOuterValueByKey("past_low_humidity", lowHumidity);
  jp.getOuterValueByKey("timestamp", rspTime);
  jp.getOuterValueByKey("temp_unit", rspUnit);
  bool soundWarning = jp.getReference().key("probe").key("sound_warning").valueBool();
  bool soundCritical = jp.getReference().key("probe").key("sound_critical").valueBool();

  Serial.println("Reported interval: " + String(interval));
  Serial.println("Reported status: " + status);
  Serial.println("Reported Temp status: " + tempStatus);
  Serial.println("Reported Humidity status: " + humidityStatus);
  Serial.println("Reported Temp: " + String(temp));
  Serial.println("Reported High: " + String(highTemp));
  Serial.println("Reported Low: " + String(lowTemp));
  Serial.println("Reported Humidity: " + String(humidity));
  Serial.println("Reported High: " + String(highHumidity));
  Serial.println("Reported Low: " + String(lowHumidity));
  Serial.println("Reported Time: " + rspTime);
  Serial.println("Reported Unit: " + rspUnit);
  Serial.println();
  // Processing logic
}

Serial output after publish:

offest
rspIndex 0
offest
rspIndex 0
Webhook response recieved!
Reported interval: 0
Reported status:
Reported Temp status:
Reported Humidity status:
Reported Temp: 0.000000
Reported High: 0.000000
Reported High: 536889288
Reported Low: 0
Reported Time:
Reported Unit:

It looks like the slash offset isn’t being calculated correctly, but I’m not sure why.
I also have an observed that if I use a static JsonParser JsonParserStatic<2048, 100> jsonParser; I don’t get any serial response from parseTempResponse().

You probably want to use strrchr. It's finding the first slash, the first character of the event name. It should be finding the last slash, the one right before the part number. It's wrong in the sample code.

1 Like

Version 0.0.7 of the JsonParserGeneratorRK library has a fixed 3-subscription example.

1 Like

Can confirm that fixed my issue. Thanks a bunch! :grinning: