ArduinoJSON: Filtering Data


The ArduinoJSON library, as the name suggests, helps you work with JSON objects on Arduino. In order to install it, go to the Library Manager and search for ArduinoJSON. Install the library by Benoit Blanchon.

This is one of the very heavily documented libraries. In fact, it has its own website − https://arduinojson.org/. You can find answers to several questions on this website.

In this article, we will look at how to filter data from a larger JSON and produce a smaller JSON.

Once you download the ArduinoJSON library, go to: File→Examples→ArduinoJSON

Example

The example we should look at is the JsonFilterExample. The code is −

#include <ArduinoJson.h>

void setup() {
   // Initialize serial port
   Serial.begin(9600);
   while (!Serial) continue;

   // The huge input: an extract from OpenWeatherMap response
   const __FlashStringHelper* input_json = F("{\"cod\":\"200\",\"message\":0,\"list [{\"dt\":1581498000,\"main\":{"
   "\"temp\":3.23,\"feels_like\":- 3.63,\"temp_min\":3.23,\"temp_max\":4.62,"

"\"pressure\":1014,\"sea_level\":1014,\"grnd_level\":1010,\"humidity\":" "58,\"temp_kf\":-
1.39},\"weather\":[{\"id\":800,\"main\":\"Clear\","
   "\"description\":\"clear "

"sky\",\"icon\":\"01d\"}],\"clouds\":{\"all\":0},\"wind\":{\"speed\":6." "19,\"deg\":266},\"sys\":{\"pod\":\"d\"},\"dt_txt\":\"2020-02-12 "

"09:00:00\"},{\"dt\":1581508800,\"main\":{\"temp\":6.09,\"feels_like\":-
"
"1.07,\"temp_min\":6.09,\"temp_max\":7.13,\"pressure\":1015,\"sea_"
   "level\":1015,\"grnd_level\":1011,\"humidity\":48,\"temp_kf\":- 1.04},

"\"weather\":[{\"id\":800,\"main\":\"Clear\",\"description\":\"clear "

"sky\",\"icon\":\"01d\"}],\"clouds\":{\"all\":9},\"wind\":{\"speed\":6."
   "64,\"deg\":268},\"sys\":{\"pod\":\"d\"},\"dt_txt\":\"2020-02-12 "

"12:00:00\"}],\"city\":{\"id\":2643743,\"name\":\"London\",\"coord\":{"
   "\"lat\":51.5085,\"lon\":- 0.1257},\"country\":\"GB\",\"population\":"

"1000000,\"timezone\":0,\"sunrise\":1581492085,\"sunset\":1581527294}}");

   // The filter: it contains "true" for each value we want to keep
   StaticJsonDocument<200> filter;
   filter["list"][0]["dt"] = true;
   filter["list"][0]["main"]["temp"] = true;

   // Deserialize the document
   StaticJsonDocument<400> doc;
   deserializeJson(doc, input_json, DeserializationOption::Filter(filter));
   // Print the result
   serializeJsonPretty(doc, Serial);
}

void loop() {
   // not used in this example
}

As you can see, at the beginning of the sketch, a very large JSON is loaded into the flash. This is a very large JSON. If you visualize it in the pretty format, this is how it looks −

{
   "cod":"200",
   "message":0,
   "list":[
      {
         "dt":1581498000,
         "main":{
            "temp":3.23,
            "feels_like":-3.63,
            "temp_min":3.23,
            "temp_max":4.62,
            "pressure":1014,
            "sea_level":1014,
            "grnd_level":1010,
            "humidity":58,
            "temp_kf":-1.39
         },
         "weather":[
            {
               "id":800,
               "main":"Clear",
               "description":"clear sky",
               "icon":"01d"
            }
         ],
         "clouds":{
            "all":0
         },
         "wind":{
            "speed":6.19,
            "deg":266
         },
         "sys":{
            "pod":"d"
         },
         "dt_txt":"2020-02-12 09:00:00"
      },
      {
         "dt":1581508800,
         "main":{
            "temp":6.09,
            "feels_like":-1.07,
            "temp_min":6.09,
            "temp_max":7.13,
            "pressure":1015,
            "sea_level":1015,
            "grnd_level":1011,
            "humidity":48,
            "temp_kf":-1.04
         },
         "weather":[
            {
               "id":800,
               "main":"Clear",
               "description":"clear sky",
               "icon":"01d"
            }
         ],
         "clouds":{
            "all":9
         },
         "wind":{
            "speed":6.64,
            "deg":268
         },
         "sys":{
            "pod":"d"
         },
         "dt_txt":"2020-02-12 12:00:00"
      }
   ],
   "city":{
      "id":2643743,
      "name":"London",
      "coord":{
         "lat":51.5085,
         "lon":-0.1257
      },
      "country":"GB",
      "population":1000000,
      "timezone":0,
      "sunrise":1581492085,
      "sunset":1581527294
   }
}

Now, we don't want all of this data in our JSON document. Therefore, we then define a filter of the keys we want to keep. As you can see, we want to keep the 'dt' key from the 'list' array, and the nested 'temp' key from the 'main' key of the 'list' array. Therefore, we create a new JSON Document filter, which contains these keys.

StaticJsonDocument<200> filter;
filter["list"][0]["dt"] = true;
filter["list"][0]["main"]["temp"] = true;

The filter JSON would look like −

{
   "list": [
      {"dt":true}
      { "main": {
         {"temp": true}
      }
   ]
}

In the deserializeJson function, we add a third argument, which implements this filter.

deserializeJson(doc, input_json, DeserializationOption::Filter(filter));

Output

Now, when we print this JSON document on the Serial Monitor, the output is −

As you can see, only the keys that you specified are present in the output. Thus, a very large JSON has been reduced to a smaller one, using filtering. This saves space, and reduces complexity.

To give another example, if you wanted to keep the "message" key and the "country" and "population" keys from the "city" key, your filter JSON would look like −

StaticJsonDocument<200> filter;
filter["message"] = true;
filter["city"]["country"] = true;
filter["city"]["population"] = true;

And the Serial Monitor output will look like −

Updated on: 26-Jul-2021

558 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements