[Solved] Arduino Language National Weather Service API request WeatherStation

I am trying obtain weather data from the National Weather Service (NWS) API. They have some example request strings on the website API Web Service. I would like help translating those into Arduino code. Also there are some specific headers required in the request string 1) Accept, 2) version and 3)User-agent that I can't seem to port over to Arduino.

Any help in pointing me to a useful resource is appreciated!!

Thanks.

Tim

Hi,
Have you googled

National Weather Service (NWS) arduino

Tom... :slight_smile:

"Arduino Language" is standard C/C++.

Tom,

Thanks for the reply. I have spent at least 8 hours web searching every conceivable link between Arduino and NWS. No one has posted a project or demo code requesting NWS API data using Arduino. I also am not able to find any specifics on the three headers mentioned, just a few examples.

The answer is so tantalizingly close!

Tim

J,

Thanks for replying.

I have also searched C++ and NWS API.

If I post a working code written in PHP perhaps someone could translate to C++.

New post soon.

You don't need anything specific to Arduino and NWS. You just need something that will hit a web endpoint and show you the results. Look here.

Tweak that to point to the forecast you're interested in and just dump it to serial to start with. Later you can parse what you need out of the JSON response.

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

All,

Karma is CORRECT!

A simpler request string, with no headers at all, seems to work fine.

Thanks for all the help!

Tim

Hi,
Can you please post your working code?
This will help anyone trying do accomplish what you have.

Please read; http://forum.arduino.cc/index.php/topic,148850.0.html
and use code tags.

Thanks.. Tom.. :slight_smile: