In lesson 2.1.1, you retrieved a list of fields associated with your account. In this lesson you will learn how to add a new field. This is a necessary step in order for you to retrieve weather data for any location.
First we will load some necessary packages.
suppressWarnings(suppressMessages(library(aWhereAPI)))
httr::set_config(httr::config( ssl_verifypeer = 0L ))
library(magrittr)
library(openxlsx)Warning message:
: package ‘magrittr’ was built under R version 3.2.4Warning message:
: package ‘openxlsx’ was built under R version 3.2.4
Now, you will import some existing data with R that contains the necessary information about the new field to add. For reference, code for the call to retrieve your already-existing list of fields is provided.
data <- read.xlsx("example_trials.xlsx")
data$PlotSize <- data$PlotSize*1/4046.8564224 # convert to acres
head(data)| FarmerId | Year | Season | PlantingDate | HarvestingDate | Latitude | Longitude | Altitude | Plot | Subplot | Treat | RepNo | TreatmentDescription | Nsource | Nrate | Psource | Prate | Ksource | Krate | PlotSize | Crop | Variety | NetPlotHarvestArea | NoofRows | NoofPlantsStandCount | No.ofcobs | TotalCobFreshWeight | CobSubsampleFreshWeight | StoverTotalFreshWeight | StoverSubsampleFreshWeight | StoverSubsampleDryWeight | CoreSubsampleDryWeight | GrainSubsampleOvenDryWeight | CoreYield | StoverYield | GrainYield | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 1 | Farmer-1 | 2013 | Long rain | 41315 | 41450 | 1.09829 | 31.39215 | 1179 | 1 | 1 | 1 | 1 | Control | None | 0 | None | 0 | None | 0 | 0.009340583 | Maize | Kilima | 29.16 | 6 | 125 | 211 | 11 | 460 | 5 | 600 | 300 | 57 | 100 | NA | 0.5 | 0.9 |
| 2 | Farmer-1 | 2013 | Long rain | 41315 | 41450 | 1.09829 | 31.39215 | 1179 | 2 | 2 | 2 | 1 | Urea | Urea | 60 | None | 0 | None | 0 | 0.009340583 | Maize | Kilima | 29.16 | 6 | 125 | 228 | 15.5 | 510 | 7.9 | 600 | 270 | 57 | 270 | NA | 0.6 | 1.2 |
| 3 | Farmer-1 | 2013 | Long rain | 41315 | 41450 | 1.09829 | 31.39215 | 1179 | 3 | 3 | 3 | 1 | TSP + Urea | Urea | 60 | TSP | 20 | None | 0 | 0.009340583 | Maize | Kilima | 29.16 | 6 | 125 | 236 | 25 | 510 | 17 | 600 | 270 | 73 | 310 | NA | 1.2 | 2.6 |
| 4 | Farmer-1 | 2013 | Long rain | 41315 | 41450 | 1.09829 | 31.39215 | 1179 | 4 | 4 | 4 | 1 | Minjingu powder + urea | Urea | 60 | Minjingu powder | 20 | None | 0 | 0.009340583 | Maize | Kilima | 29.16 | 6 | 125 | 233 | 24 | 650 | 10 | 600 | 270 | 92 | 250 | NA | 1.2 | 1.5 |
| 5 | Farmer-1 | 2013 | Long rain | 41315 | 41450 | 1.09829 | 31.39215 | 1179 | 5 | 5 | 5 | 1 | Minjingu granular + urea | Urea | 60 | Minjingu granular | 20 | None | 0 | 0.009340583 | Maize | Kilima | 29.16 | 6 | 125 | 245 | 22.9 | 720 | 21 | 600 | 170 | 97 | 250 | NA | 1.1 | 2 |
| 6 | Farmer-1 | 2013 | Long rain | 41315 | 41450 | 1.09829 | 31.39215 | 1179 | 6 | 6 | 6 | 1 | Minjingu mazao + urea | Urea | 60 | Minjingu mazao | 20 | None | 0 | 0.009340583 | Maize | Kilima | 29.16 | 6 | 125 | 229 | 29.9 | 700 | 15 | 600 | 220 | 87 | 340 | NA | 1.3 | 1.9 |
api_key = "yizhexu@awhere.com"
api_secret = "********"
get_token(api_key, api_secret)
get_fields()| fieldName | Acres | farmId | field_id | Latitude | Longitude | |
|---|---|---|---|---|---|---|
| 1 | agra_uganda_vk | 0.0093 | agra_uganda | agra_uganda_1 | 1.2331 | 31.4979 |
| 2 | agra_uganda_vk | 0.0093406 | agra_uganda | agra_uganda_2 | 1.2331 | 31.498 |
| 3 | agra_uganda_vk | 0.0093406 | agra_uganda | agra_uganda_3 | 1.2331 | 31.498 |
| 4 | agra_uganda_vk | 0.009340583 | agra_uganda | agra_uganda_4 | 1.23315 | 31.49786 |
| 5 | awhere_headquarter | 1 | awhere_farmer_1 | awhere_headquarter | 39.92524 | 105.1066 |
| 6 | My First Field | 100 | Farm-100 | field1 | 39.8282 | -98.5795 |
The code below begins by updating the API endpoint to which we will send the request. It then constructs a data frame (similar to a table) with one row of data, and columns named "id", "name", "farmId", "acres", "latitude", and "longitude".
It is important to understand that JSON data is nested, meaning that it is constructed to contain different levels. Think of the structure like tree roots, with the trunk being the top level and the various roots branching off forming the nested sub-levels. Below, the code creating the data frame nests the latitude and longitude information under a top-level column named "centerPoint".
After the data frame (named postbody is created, we can easily convert it to JSON format using the R command "toJSON". You can view the API documentation showing how a properly-nested JSON request looks here.
api_endpoint <- "https://api.awhere.com/"
get_fields_url <- "v2/fields/"
i=5
postbody <- data.frame("id" = paste0("agra_uganda_", i),
"name" = "agra_uganda_vk",
"farmId" = "agra_uganda",
"acres" = data$PlotSize[[i]])
postbody$centerPoint <- data.frame("latitude" = data$Latitude[[i]], "longitude"= data$Longitude[[i]])
postbody <- toJSON(postbody, pretty=TRUE) %>% gsub("\\[|\\]", "", .)
postbody'{ "id" : "agra_uganda_5" , "name" : "agra_uganda_vk" , "farmId" : "agra_uganda" , "acres" : 0.0093406 , "centerPoint" : { "latitude" : 1.0983 , "longitude" : 31.392
}
}'
The postbody is not the actual request, rather it is the information within the request that you want the API to "post" to its servers. To send the API request, use the httr command "POST", and include the correct endpoint, postbody, and your valid token.
While the POST request below may look more complicated than described, the additional code is primarily formatting the content of the request. Small variations, like failing to specify the content_type, can sometimes cause the request to fail.
request <- POST(paste0(api_endpoint, get_fields_url),
body = postbody,
content_type('application/json'),
add_headers(Authorization = paste0("Bearer ",awhereEnv75247$token)))
content(request, as = "text")
No encoding supplied: defaulting to UTF-8.
'{"name":"agra_uganda_vk","acres":0.0093406,"centerPoint":{"latitude":1.0983,"longitude":31.392},"farmId":"agra_uganda","id":"agra_uganda_5","_links":{"self":{"href":"/v2/fields/agra_uganda_5"},"curies":[{"name":"awhere","href":"http://awhere.com/rels/{rel}","templated":true}],"awhere:observations":{"href":"/v2/weather/fields/agra_uganda_5/observations"},"awhere:forecasts":{"href":"/v2/weather/fields/agra_uganda_5/forecasts"},"awhere:plantings":{"href":"/v2/agronomics/fields/agra_uganda_5/plantings"},"awhere:agronomics":{"href":"/v2/agronomics/fields/agra_uganda_5/agronomicvalues"}}}'
The aWhereAPI package accomplishes the same function as the above codes, and significantly simplifies the problems of endpoints, nesting and formatting a POST request. Rather than require a specified endpoint, the command "CreateField" sends the call to the aWhere fields API by default. The command formats the JSON data and nests the latitude and longitude points for you rather than requiring advanced code, and sources your token from the R environment without being prompted.
i = 7
create_field(field_id = paste0("agra_uganda_", i),
latitude = data$Latitude[[i]], longitude= data$Longitude[[i]],
farm_id = "agra_uganda",
field_name = "agra_uganda_vk",
acres = data$PlotSize[[i]])No encoding supplied: defaulting to UTF-8.
Operation Complete