Introduction
This article is a brief explanation of how to create a simple application that demonstrates the usage of the Mashery API on the Intel® Galileo board. The application fetches the current weather of a particular location, is written in C, and uses libcurl, the Mashery Web API and a light-weight parson for parsing the JSON data.
To fetch the weather data, the application uses Free Weather API and needs an API key. You can get the API key by registering here.
Compilation
Import the source files into a project created by selecting File -> Other Project -> Yocto C Project. As mentioned earlier, the application uses libcurl and parson, hence they have to be added in the Makefile.am
located under the src
folder. parson.c must be added to PROJXX_SOURCES and -lcurl to XX_LDFLAGS.
PROJXX_SOURCES = weather.c parser.c XX_LDFLAGS = -lcurl
Mashery API
The application uses the Free Weather API provided by World Weather Online APIs to fetch the weather information. For example, the API below fetches the weather data for Barcelona, Spain and specifies a JSON response format.
http://api.worldweatheronline.com/free/v1/weather.ashx?q=Barcelona&format=json&num_of_days=5&key=*****
libcurl
The libcurl library is used to request weather data using the above URL. The curl_easy_init()
function starts a libcurl session and returns a CURL easy handle used in future operations.
The curl_easy_setopt()
function can be used to set the URL using the CURLOPT_URL
option.
CURL *curl_handle; FILE * fptr; /* URL for the API call */ char *url="http://api.worldweatheronline.com/free/v1/weather.ashx?q=Barcelona&format=json&num_of_days=1&key=***"; CURLcode res; curl_handle = curl_easy_init(); if(curl_handle) { curl_easy_setopt(curl_handle, CURLOPT_URL, url); curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, write_data); fptr = fopen(output_filename,"w+"); if(!fptr) { printf("Exiting, error opening file"); /* always cleanup */ curl_easy_cleanup(curl_handle); return 1; } /* write content to the file handle */ curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, fptr); res = curl_easy_perform(curl_handle); printf("\nWeather Report Query Status:: %d\n", res); fclose (fptr); curl_easy_cleanup(curl_handle); } return 0;
The response can be read using the same function call with the CURLOPT_WRITEFUNCTION
option. A pointer to the function with prototype size_t function(char *ptr, size_t size, size_t nmemb, void *userdata);
is passed as an argument, which will be called when data is received. This data is stored as a file stream. The received data is stored in a file using option CURLOPT_WRITEDATA
by passing a file pointer as argument. The file transfer is performed while making a call to curl_easy_perform(curl_handle)
. Make sure to clean up the handle once the data is saved in a file by making a call to curl_easy_cleanup(curl_handle)
.
Parson
Parson, a light weight JSON parser was used to parse the received JSON data. The json_parse_file()
function takes file name as arguments, parses the JSON and returns NULL on error. A call to json_value_get_object
returns the root object from the data. The required information, specifically the weather code, can be retrieved from the object using json_object_dotget_array, which returns an array with the target objects.
JSON_Value *root_value; JSON_Array *array; JSON_Object *root_object, *CCobject; const char *weatherValue; int ret_val = -1; char cleanup_file[256]; sprintf(cleanup_file, "rm -f %s", output_filename); /* now parse the json file */ root_value = json_parse_file(output_filename); if (json_value_get_type(root_value) != JSONObject) { return; } /* get the root object */ root_object = json_value_get_object(root_value); /* Now get the required array from the root object*/ array = json_object_dotget_array(root_object, "data.current_condition"); if (array != NULL) { /* The array has target objects, so get the object of first array element*/ CCobject = json_array_get_object(array,0); /* Now with the target object retrieve the values */ weatherValue = json_object_get_string(CCobject, "weatherCode"); ret_val = updateWeatherData(atoi(weatherValue)); printf("Return Value = %d\n", ret_val); } else { printf("Empty array\n"); } /* cleanup code */ json_value_free(root_value); system(cleanup_file); return 0;
The object in the first array contains the target data. Using json_array_get_object
, the object can be retrieved and the needed value is associated with the object. json_object_get_string
will return the value (weather code) while taking the object and the key “weatherCode” as arguments.
updateWeatherData
This function determines the weather condition based on the given weather code. Based on the condition, it calls the writeToGPIOPort
function to turn ON the appropriate LED.
writeToGPIOPort
This function takes the port as input and makes a call to openGPIOFile
to open the port in write mode. The openGIOFile
function sets the direction to "OUT" and returns the fileHandle in O_WRONLY
mode. This handle is used to either turn ON or OFF the LED.