bblanchon / ArduinoJson

📟 JSON library for Arduino and embedded C++. Simple and efficient.
https://arduinojson.org
MIT License
6.74k stars 1.12k forks source link

Can't get data to parse. #434

Closed tbarritt closed 7 years ago

tbarritt commented 7 years ago

Response I get back from a webhook get, comes in as param.asStr()

{"results":{"sunrise":"7:21:16 AM","sunset":"5:40:33 PM","solar_noon":"12:30:55 PM","day_length":"10:19:17","civil_twilight_begin":"6:54:00 AM","civil_twilight_end":"6:07:49 PM","nautical_twilight_begin":"6:22:57 AM","nautical_twilight_end":"6:38:52 PM","astronomical_twilight_begin":"5:52:26 AM","astronomical_twilight_end":"7:09:23 PM"},"status":"OK"}

How can I get that to work. I am new to parsing.

#define BLYNK_PRINT Serial
// Allow for receiving messages up to 512 bytes long
//#define BLYNK_MAX_READBYTES 512

#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
#include <ArduinoJson.h>

char auth[] = "*************************************";

// Your WiFi credentials.
char ssid[] = "*********************";
char pass[] = "******************";

StaticJsonBuffer<400> jsonBuffer;

BLYNK_WRITE(V0)
{

  Serial.println("WebHook data:");
  Serial.println(param.asStr());

  char json [] = **?????????????????????**

    Serial.println("json data:"); 
    Serial.println (json);

  JsonObject& root = jsonBuffer.parseObject(json);

  // Test if parsing succeeds.
  if (!root.success()) {
    Serial.println("parseObject() failed");
    return;
  }

    JsonObject& results = root["results"];
    const char* sunrise = results["sunrise"]; // "7:24:03 AM"
    const char* sunset = results["sunset"]; // "5:36:15 PM"
    const char* solar_noon = results["solar_noon"]; // "12:30:09 PM"
    const char* day_length = results["day_length"]; // "10:12:12"
    const char* civil_twilight_begin = results["civil_twilight_begin"]; // "6:56:34 AM"
    const char* civil_twilight_end = results["civil_twilight_end"]; // "6:03:45 PM"
    const char* nautical_twilight_begin = results["nautical_twilight_begin"]; // "6:25:18 AM"
    const char* nautical_twilight_end = results["nautical_twilight_end"]; // "6:35:01 PM"
    const char* astronomical_twilight_begin = results["astronomical_twilight_begin"]; // "5:54:38 AM"
    const char* astronomical_twilight_end = results["astronomical_twilight_end"]; // "7:05:40 PM"
    const char* status = root["status"]; // "OK"

  // Print values.
  Serial.print("sunrise\t\t"); Serial.println(sunrise);
  Serial.print("sunset\t\t"); Serial.println(sunset);
  Serial.print("day length\t");  Serial.println(day_length);
}

void setup()
{
  // Debug console
  Serial.begin(9600);
  Serial.println();
  Serial.println();
  Blynk.begin(auth, ssid, pass);

  Blynk.virtualWrite(V0, 1);
}

void loop()
{
  Blynk.run();
}
bblanchon commented 7 years ago

Hi @tbarritt,

The ArduinoJson Assistant says that you need a JsonBuffer of 512 bytes minimum.

Try to replace:

StaticJsonBuffer<400> jsonBuffer;

by

DynamicJsonBuffer jsonBuffer(600);

Also, don't use a global JsonBuffer.

See:

pieman64 commented 7 years ago

@bblanchon when did you set up the "Assistant", very cool?

bblanchon commented 7 years ago

@pieman64 I added it to the scripts/ folder in August 2016, then moved it to GitHub pages in November 2016. I plan on adding a lot for features; this is just the beginning ;-).

tbarritt commented 7 years ago

in your example the first string has no forward slashes, how do I get it in the format that will work??

image

bblanchon commented 7 years ago

The anti-slash in the example is a way to escape the quotes that would otherwise end the string. They do not appear in the resulting string.

In your case it's:

char json[] = "{\"results\":{\"sunrise\":\"7:21:16 AM\",\"sunset\":\"5:40:33 PM\",\"solar_noon\":\"12:30:55 PM\",\"day_length\":\"10:19:17\",\"civil_twilight_begin\":\"6:54:00 AM\",\"civil_twilight_end\":\"6:07:49 PM\",\"nautical_twilight_begin\":\"6:22:57 AM\",\"nautical_twilight_end\":\"6:38:52 PM\",\"astronomical_twilight_begin\":\"5:52:26 AM\",\"astronomical_twilight_end\":\"7:09:23 PM\"},\"status\":\"OK\"}";
tbarritt commented 7 years ago

I am still missing something. With the following I get initializer fails to determine size of 'json'.

#define BLYNK_PRINT Serial
// Allow for receiving messages up to 512 bytes long
//#define BLYNK_MAX_READBYTES 512

#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
#include <ArduinoJson.h>

char auth[] = "******************************************";

// Your WiFi credentials.
char ssid[] = "***************";
char pass[] = "**************";

BLYNK_WRITE(V0)
{
  Serial.println("WebHook data:");
  Serial.println(param.asStr());

  const size_t bufferSize = JSON_OBJECT_SIZE(2) + JSON_OBJECT_SIZE(10);

  DynamicJsonBuffer jsonBuffer(bufferSize);

  char json [] = param.asStr()

    Serial.println("json data:"); 
    Serial.println (json);

  // Test if parsing succeeds.
  if (!root.success()) {
    Serial.println("parseObject() failed");
    return;
  }

JsonObject& root = jsonBuffer.parseObject(json);

JsonObject& results = root["results"];
const char* results_sunrise = results["sunrise"]; // "1:28:54 PM"
const char* results_sunset = results["sunset"]; // "11:39:51 PM"
const char* results_solar_noon = results["solar_noon"]; // "6:34:22 PM"
const char* results_day_length = results["day_length"]; // "10:10:57"
const char* results_civil_twilight_begin = results["civil_twilight_begin"]; // "1:00:45 PM"
const char* results_civil_twilight_end = results["civil_twilight_end"]; // "12:08:00 AM"
const char* results_nautical_twilight_begin = results["nautical_twilight_begin"]; // "12:28:46 PM"
const char* results_nautical_twilight_end = results["nautical_twilight_end"]; // "12:39:59 AM"
const char* results_astronomical_twilight_begin = results["astronomical_twilight_begin"]; // "11:57:22 AM"
const char* results_astronomical_twilight_end = results["astronomical_twilight_end"]; // "1:11:23 AM"

const char* status = root["status"]; // "OK"

  // Print values.
  Serial.print("sunrise\t\t"); Serial.println(sunrise);
  Serial.print("sunset\t\t"); Serial.println(sunset);
  Serial.print("day length\t");  Serial.println(day_length);
}

void setup()
{
  // Debug console
  Serial.begin(9600);
  Serial.println();
  Serial.println();
  Blynk.begin(auth, ssid, pass);

  Blynk.virtualWrite(V0, 1);
}

void loop()
{
  Blynk.run();
}
bblanchon commented 7 years ago

Please try:

const size_t bufferSize = JSON_OBJECT_SIZE(2) + JSON_OBJECT_SIZE(10) + 400;
//...
JsonObject& root = jsonBuffer.parseObject(param.asStr());
tbarritt commented 7 years ago

That worked...

Thank you so much for the help...

bblanchon commented 7 years ago

Good :-) I added 400 bytes to allow duplication of the input in the JsonBuffer. This is required as param.asStr() is read-only. I think the ArduinoJson Assistant is quite misleading as it uses a mutable input, I'll change that ASAP.

Anyway, thanks for using ArduinoJson. Don't hesitate to add a GitHub star if you like this project :wink:

tbarritt commented 7 years ago

Any reason ArduinoJson would work on esp8266 and not a Nano with Ethernet?

bblanchon commented 7 years ago

@tbarritt The size of the JsonBuffer may be different for a Nano. If this doesn't solve your issue, please open a new issue and provide more detail (source, errors and log).