Parsing EasyIoT Server data
Created by: essenemari
Hi bblanchon,
First of all: i'm extremely impressed with your Arduino Json library and documentation that you provided. AWESOME!
I tried to read data from EasyIoT server, to be detailed: need a value of "Value" from "N4S0", simulation here: http://www.laart.eu/esp8266/2
Thanks to yours great documentation, I was able to parse what I want only if data to parse was significantly cut (http://www.laart.eu/esp8266/1). (FYI): noticed that on Wednesday night my time your calculator stopped working.
My understnding is that your library, per design, needs to have all data to parse in memory, but I'm lost since I noticed (Serial.println(jsonBuffer.size());
) that it stops parsing when bufer size is about 4500 B which should be handled by ESP8266-01 (or am I mistaken?).
Can you, please, advise if data that i would like to parse (http://www.laart.eu/esp8266/2) is not too big for the library design? Maybe just need to take another approach or correct my code, however based on examples that I found here, assuming that I am exceeding all the memory limits and it just will not work. Can you confirm that it will work or not?
Hope that my question will be also useful for others which use EasyIoT server.
Once again, thank you for your library!
Regards, Artur
// Sample Arduino Json Web Client // Downloads and parse http://jsonplaceholder.typicode.com/users/1 // // Copyright Benoit Blanchon 2014-2017 // MIT License // // Arduino JSON library // https://github.com/bblanchon/ArduinoJson // If you like this project, please add a star!
#include <ArduinoJson.h>
#include <ESP8266WiFi.h>
WiFiClient client;
#define AP_SSID ""
#define AP_PASSWORD ""
const char* server = "www.laart.eu"; // server's address
const char* resource = "/esp8266/1"; // http resource
//const char* server = "jsonplaceholder.typicode.com"; // server's address
//const char* resource = "/users/1"; // http resource
const unsigned long BAUD_RATE = 115200; // serial connection speed
const unsigned long HTTP_TIMEOUT = 10000; // max respone time from server
//const size_t MAX_CONTENT_SIZE = 2048; // max size of the HTTP response
//StaticJsonBuffer<35000> jsonBuffer;
// The type of data that we want to extract from the page
struct UserData {
char name[32];
//char company[32];
};
// ARDUINO entry point #1: runs once when you press reset or power the board
void setup() {
initSerial();
initEthernet();
}
// ARDUINO entry point #2: runs over and over again forever
void loop() {
if (connect(server)) {
if (sendRequest(server, resource) && skipResponseHeaders()) {
UserData userData;
if (readReponseContent(&userData)) {
printUserData(&userData);
}
}
disconnect();
}
wait();
}
// Initialize Serial port
void initSerial() {
Serial.begin(BAUD_RATE);
while (!Serial) {
; // wait for serial port to initialize
}
Serial.println("Serial ready");
}
// Initialize Ethernet library
void initEthernet() {
Serial.print("Connecting to AP");
WiFi.begin(AP_SSID, AP_PASSWORD);
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected");
}
// Open connection to the HTTP server
bool connect(const char* hostName) {
Serial.print("Connect to ");
Serial.println(hostName);
bool ok = client.connect(hostName, 80);
Serial.println(ok ? "Connected" : "Connection Failed!");
return ok;
}
// Send the HTTP GET request to the server
bool sendRequest(const char* host, const char* resource) {
Serial.print("GET ");
Serial.println(resource);
client.print("GET ");
client.print(resource);
client.println(" HTTP/1.0");
client.print("Host: ");
client.println(host);
client.println("Connection: close");
client.println();
delay(300);
return true;
}
// Skip HTTP headers so that we are at the beginning of the response's body
bool skipResponseHeaders() {
// HTTP headers end with an empty line
char endOfHeaders[] = "\r\n\r\n";
client.setTimeout(HTTP_TIMEOUT);
bool ok = client.find(endOfHeaders);
if (!ok) {
Serial.println("No response or invalid response!");
}
return ok;
}
bool readReponseContent(struct UserData* userData) {
// Compute optimal size of the JSON buffer according to what we need to parse.
// This is only required if you use StaticJsonBuffer.
// Allocate a temporary memory pool
//DynamicJsonBuffer jsonBuffer(BUFFER_SIZE);
DynamicJsonBuffer jsonBuffer;
Serial.println("DynamicJsonBuffer-debug-before1: ");
Serial.println(jsonBuffer.size());
JsonObject& root = jsonBuffer.parseObject(client);
JsonArray& ModulesArray = root["Modules"].asArray();
Serial.println("DynamicJsonBuffer-debug-before2: ");
Serial.println(jsonBuffer.size());
if (!root.success()) {
Serial.println("JSON parsing failed!");
return false;
}
String keyLevel1 ="";
String value1 = "";
String keyLevel2="";
for (int i=0; i < sizeof(ModulesArray); i++){
JsonObject& root2 = ModulesArray[i];
for (JsonObject::iterator it=root2.begin(); it!=root2.end(); ++it){
keyLevel1=it->key;
value1 = it->value.asString();
// Serial.println(it->key);
if(keyLevel1=="Address" && value1=="N4S0"){
JsonArray& propArray = root2["Properties"].asArray();
for (int j=0; j<sizeof(propArray); j++){
JsonObject& root3 = propArray[j];
for (JsonObject::iterator it3=root3.begin(); it3!=root3.end(); ++it3){
keyLevel2=it3->key;
if(keyLevel2=="Value"){
Serial.println("My value for N4S0: ");
Serial.println(it3->value.asString());
Serial.println("---");
}
Serial.println("DynamicJsonBuffer-debug-before2: ");
Serial.println(jsonBuffer.size());
// Serial.println("table prop:");
//Serial.println(it3->key);
// Serial.println(it3->value.asString());
}
// strcpy(userData->name, propArray[j]);
// Serial.println(userData->name);
//Serial.println(propArray[j]);
}
//Serial.println("cycki");
//Serial.println(it->value.asString());
// Serial.println("---");
}
//Serial.println(it->key);
//Serial.println(it->value.asString());
//Serial.println("---");
}
}
/*JsonObject& data = root["data"];
for (auto dataobj : data){
Serial.println("data: ");
Serial.println(dataobj.key);
}*/
/*for (int i=0; i < sizeof(nestedArray); i++){
strcpy(userData->name, nestedArray[i]);
Serial.println(userData->name);
}*/
// Here were copy the strings we're interested in
//strcpy(userData->name, root["sensor"]);
//strcpy(userData->name, root["Modules"]["Address"]);
//strcpy(userData->name, nestedArray[0]);
// It's not mandatory to make a copy, you could just use the pointers
// Since, they are pointing inside the "content" buffer, so you need to make
// sure it's still in memory when you read the string
return true;
}
// Print the data extracted from the JSON
void printUserData(const struct UserData* userData) {
//Serial.print("Name = ");
// Serial.println(userData->name);
//Serial.print("Company = ");
//Serial.println(userData->company);
}
// Close the connection with the HTTP server
void disconnect() {
Serial.println("Disconnect");
client.stop();
}
// Pause for a 1 minute
void wait() {
Serial.println("Wait 2 seconds");
delay(2000);
}