Problem: How to obtain data from National Weather Service (NWS) Application Programming Interface (API) using Arduino software and ESP32 hardware.
I am able to successfully obtain data from several other API’s using Arduino. Specifically, Thingspeak API, Wunderground API, OpenWeatherMap API, US Navy Astronomy Website API, Aeris API, and time information from pool.ntp.org.
Typically, the above API’s require an API Key to access data. NWS API requires three “headers” in the request string, User-Agent header, Accept header, and version header. I am not able to find how to format these headers successfully in arduno.
If I paste the following URL into a browser, https://api.weather.gov/points/47.8189,-90.4167
I get the expected response in the browser. https://api.weather.gov/gridpoints/DLH/142,117 gives the expected JSON format forecast.
RapidAPI at National Weather Service API: How To Use the API with Free API Key | RapidAPI
States:
The API will use Accept headers to modify the response returned. See the FAQ tab for more information. Parameters include:
Version of the API, defaults to the oldest
Format of the response, default in specifications
An example of the Accept header would be "Accept: application/vnd.noaa.dwml+xml;version=1"
Authentication
A User Agent will still be required to identify your application. This string can be anything, and the more unique to your application the less likely it will be affected by a security event. If you include contact information (website or email), we can contact you if your string is associated to a security event. This will be replaced with an API key in the future.
Kimball Rexford at https://kimballrexford.com/national-weather-service-nws-new-api/ state:
To stream anything from https://api.weather.gov you must first set the stream header to include the Accept, Version and User-Agent. If you do not set the header the stream will return empty. NWS asks that you include your website and email address in the User-Agent so the they can contact you if need be.
Here is the code posted on https://kimballrexford.com/national-weather-service-nws-new-api/
Apparently written in PHP language:
// National Weather Service (NWS) API
// Getting started code example
// Posted: February 17, 2017
// Author: Kimball Rexford
// URL: https://kimballrexford.com/national-weather-service-nws-new-api/
// Add your contact details here:
$UserAgent = "YOURWEBSITE (your@emailaddress.com)";
// Set the weather location here:
$lat = 43.0204;
$lng = -71.6002;
// HTTP stream options:
$opts = array(
'http'=>array(
'method'=>"GET",
'header'=>"Accept: application/geo+json;version=1\r\n" .
"User-agent: $UserAgent\r\n"
)
);
$context = stream_context_create($opts);
//stream the /points/lat,lng:
$pointMetaUrl = "https://api.weather.gov/points/$lat,$lng";
$pointMetaFile = file_get_contents($pointMetaUrl, false, $context);
$pointMetaArray = json_decode($pointMetaFile, true);
echo "
pointMetaArray - ";
print_r($pointMetaArray); // <-- a look at $pointMetaArray
echo "
";
// get forecastGridData which is the /gridpoints/office/x/y URL:
$forecastGridData = $pointMetaArray["properties"]["forecastGridData"];
//stream detailed gridded forecast:
$gridDataFile = file_get_contents($forecastGridData, false, $context);
$gridDataArray = json_decode($gridDataFile, true);
// get temperature grid:
$temp = $gridDataArray["properties"]["temperature"]["values"];
echo "
temperatures - ";
print_r($temp); // <-- a look at temperatures returned
echo "
";
// get probabilityOfPrecipitation grid:
$pop = $gridDataArray["properties"]["probabilityOfPrecipitation"]["values"];
echo "
probabilityOfPrecipitation - ";
print_r($pop); // <-- a look at probabilityOfPrecipitation returned
echo "
";
// to look at $gridDataArray:
//echo "
$gridDataArray - ";
//print_r($gridDataArray);
//echo "
";
Next is an example in Arduino that successfully obtains weather data from OpenweatherMap.
#include <WiFi.h>
#include <HTTPClient.h>
const char* ssid = "XXXX";
const char* password = "XXXX";
const String endpoint = "http://api.openweathermap.org/data/2.5/weather?q=Minneapolis, US&APPID=";
const String key = "XXXX";
void setup() {
Serial.begin(115200);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.println("Connecting to WiFi..");
}
Serial.println("Connected to the WiFi network");
}
void loop() {
if ((WiFi.status() == WL_CONNECTED)) { //Check the current connection status
HTTPClient http;
http.begin(endpoint + key); //Specify the URL
int httpCode = http.GET(); //Make the request
if (httpCode > 0) { //Check for the returning code
String payload = http.getString();
Serial.println(httpCode);
Serial.println(payload);
}
else {
Serial.println("Error on HTTP request");
}
http.end(); //Free the resources
}
delay(30000);
}
So, I am trying to what is done in the PHP sketch, but do it with Arduino (C++) code.
Also, how to format the headers to be acceptable to NWS, so that will return the data string.
Any help is greatly appreciated.
Tim