# Parsing Weather.gov API

**URL:** https://discourse.nodered.org/t/parsing-weather-gov-api/57466
**Category:** General
**Created:** [29 January 2022 17:01 UTC](https://discourse.nodered.org/t/parsing-weather-gov-api/57466 "2022-01-29T17:01:58Z")
**Posts on this page:** 6
**Page:** 1

<div class="post-metadata">

### Author: ![TheadehAnank](https://avatars.discourse-cdn.com/v4/letter/t/7ea924/32.png) [@TheadehAnank](https://discourse.nodered.org/u/TheadehAnank)
#### Post date: [29 January 2022 17:01 UTC](https://discourse.nodered.org/t/parsing-weather-gov-api/57466/1 "2022-01-29T17:01:58Z")

</div>

[Weather.gov](http://Weather.gov) provides an API for US weather, partly documented here:  
[API Web Service](https://www.weather.gov/documentation/services-web-api)

The following example pulls localized weather data  
[https://api.weather.gov/gridpoints/ILM/89,69](https://api.weather.gov/gridpoints/ILM/89,69)

So, to grab the temperature at for a specific period I'd do something like:

```auto
let period=msg.payload.properties.temperature.values[n].validTime
let period_temp=msg.payload.properties.temperature.values[n].value

where n is an array representing some period in [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601) format

```

Any suggestion on the best approach to parsing this data in Node Red?

As an example, I'd like to get the temp/weather forecast for some arbitrary future time (say 6 hours from now). My first thought is to write a function node with a forEach loop, comparing Now to the validTime. I can see myself going deep down a rabbit hole trying to figure out the best approach. Posting some example flows for [weather.gov](http://weather.gov) seems to me would be useful to a lot of people.

---

<div class="post-metadata">

### Author: ![UnborN](https://avatars.discourse-cdn.com/v4/letter/u/4491bb/32.png) [@UnborN](https://discourse.nodered.org/u/UnborN)
#### Post date: [29 January 2022 17:16 UTC](https://discourse.nodered.org/t/parsing-weather-gov-api/57466/2 "2022-01-29T17:16:05Z")

</div>

You can use the find() method of javascript to find the first match of the data  
with some Jsonata in a Change node you can manipulate the Date format to match the API date format  
(as an example i created a Date based on todays date and time but rounded to the hour)

```auto
[{"id":"af724c25d3f6de5f","type":"inject","z":"54efb553244c241f","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"true","payloadType":"bool","x":150,"y":1420,"wires":[["71cf2282698b9b75"]]},{"id":"ab33310b81de87f4","type":"http request","z":"54efb553244c241f","name":"","method":"GET","ret":"obj","paytoqs":"ignore","url":"https://api.weather.gov/gridpoints/ILM/89,69","tls":"","persist":false,"proxy":"","authType":"","senderr":false,"x":530,"y":1420,"wires":[["38b783ee3fe21080"]]},{"id":"df27ee4e1d2497d4","type":"debug","z":"54efb553244c241f","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":870,"y":1420,"wires":[]},{"id":"38b783ee3fe21080","type":"function","z":"54efb553244c241f","name":"","func":"let values = msg.payload.properties.temperature.values\nlet selectTime = msg.selectTime\n\nmsg.payload = values.find(el => el.validTime.startsWith(selectTime))\n\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":700,"y":1420,"wires":[["df27ee4e1d2497d4"]]},{"id":"71cf2282698b9b75","type":"change","z":"54efb553244c241f","name":"","rules":[{"t":"set","p":"selectTime","pt":"msg","to":"$moment().format('YYYY-MM-DDTHH:00:00')","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":330,"y":1420,"wires":[["ab33310b81de87f4","90c4ec6922dd358d"]]},{"id":"90c4ec6922dd358d","type":"debug","z":"54efb553244c241f","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":510,"y":1340,"wires":[]}]

```

**[EDIT]**

Here is another example with the [Moment library](https://momentjs.com/docs/#/query/is-between/) loaded in the Function node ( [functionExternalModules](https://nodered.org/docs/user-guide/writing-functions#using-the-functionexternalmodules-option) )  
utilizing its `isBetween` method to filter data for a range of datetimes

![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/1/0/10f6b54e3919b197e9bb5a8361a4c31e4b5a4f70.png)

```auto
[{"id":"af724c25d3f6de5f","type":"inject","z":"54efb553244c241f","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"true","payloadType":"bool","x":150,"y":1420,"wires":[["ab33310b81de87f4"]]},{"id":"ab33310b81de87f4","type":"http request","z":"54efb553244c241f","name":"","method":"GET","ret":"obj","paytoqs":"ignore","url":"https://api.weather.gov/gridpoints/ILM/89,69","tls":"","persist":false,"proxy":"","authType":"","senderr":false,"x":350,"y":1420,"wires":[["90c4ec6922dd358d","38b783ee3fe21080"]]},{"id":"df27ee4e1d2497d4","type":"debug","z":"54efb553244c241f","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":770,"y":1420,"wires":[]},{"id":"38b783ee3fe21080","type":"function","z":"54efb553244c241f","name":"","func":"let values = msg.payload.properties.temperature.values\nlet startTime = moment().utc()\nlet endTime = moment().utc().add(6, 'hours')\nnode.warn({ startTime, endTime })\n\nmsg.payload = values.filter(el => moment(el.validTime.split(\"/\")[0]).isBetween(startTime, endTime))\n \nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[{"var":"moment","module":"moment"}],"x":560,"y":1420,"wires":[["df27ee4e1d2497d4"]]},{"id":"90c4ec6922dd358d","type":"debug","z":"54efb553244c241f","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":490,"y":1340,"wires":[]}]

```

---

<div class="post-metadata">

### Author: ![E1cid](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/e1cid/32/77971_2.png) [@E1cid](https://discourse.nodered.org/u/E1cid)
#### Post date: [29 January 2022 18:30 UTC](https://discourse.nodered.org/t/parsing-weather-gov-api/57466/3 "2022-01-29T18:30:53Z")

</div>

The forecast are in hourly sequence so array 0 will be 1 hour forecast, and 5 should be 6 hour forecast  
eg.

```auto
[{"id":"487bb69.cdeb548","type":"inject","z":"c791cbc0.84f648","name":"","props":[{"p":"payload"},{"p":"forecast","v":"5","vt":"num"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":190,"y":220,"wires":[["62b6106c.8a6c1"]]},{"id":"62b6106c.8a6c1","type":"change","z":"c791cbc0.84f648","name":"","rules":[{"t":"set","p":"url","pt":"msg","to":"https://api.weather.gov/points/39.7456,-97.0892","tot":"str"},{"t":"set","p":"headers.user-agent","pt":"msg","to":"my_user_agent","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":370,"y":240,"wires":[["c6c4a080.408b3"]]},{"id":"c6c4a080.408b3","type":"http request","z":"c791cbc0.84f648","name":"","method":"GET","ret":"obj","paytoqs":"ignore","url":"","tls":"","persist":false,"proxy":"","authType":"","x":570,"y":240,"wires":[["5c510ec6.b300b8"]]},{"id":"5c510ec6.b300b8","type":"change","z":"c791cbc0.84f648","name":"","rules":[{"t":"set","p":"url","pt":"msg","to":"payload.properties.forecastHourly","tot":"msg"},{"t":"delete","p":"headers","pt":"msg"},{"t":"set","p":"headers.user-agent","pt":"msg","to":"my_user_agent","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":590,"y":280,"wires":[["5f27466d.75f038"]]},{"id":"5f27466d.75f038","type":"http request","z":"c791cbc0.84f648","name":"","method":"GET","ret":"obj","paytoqs":"ignore","url":"","tls":"","persist":false,"proxy":"","authType":"","x":790,"y":280,"wires":[["4467f7ce.e212a8"]]},{"id":"4467f7ce.e212a8","type":"change","z":"c791cbc0.84f648","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"payload.properties.periods[$$.forecast]","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":1010,"y":280,"wires":[["dab1571e.83d498"]]},{"id":"dab1571e.83d498","type":"debug","z":"c791cbc0.84f648","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":1030,"y":200,"wires":[]}]

```

The data takes two requests, one to retrieve url for the grid reference of your coordinates, then one to retrieve the forecast json.

[edit] When first saw the results it looked like the forecast array was starting at the current time, due to timezone. But it appears they are not.  
so the in built Jsonata time fuctions should get you the result you require.  
e.g

```auto
[{"id":"487bb69.cdeb548","type":"inject","z":"c791cbc0.84f648","name":"","props":[{"p":"payload"},{"p":"forecast","v":"6","vt":"num"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":190,"y":220,"wires":[["62b6106c.8a6c1"]]},{"id":"62b6106c.8a6c1","type":"change","z":"c791cbc0.84f648","name":"","rules":[{"t":"set","p":"url","pt":"msg","to":"https://api.weather.gov/points/39.7456,-97.0892","tot":"str"},{"t":"set","p":"headers.user-agent","pt":"msg","to":"my_user_agent","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":370,"y":240,"wires":[["c6c4a080.408b3"]]},{"id":"c6c4a080.408b3","type":"http request","z":"c791cbc0.84f648","name":"","method":"GET","ret":"obj","paytoqs":"ignore","url":"","tls":"","persist":false,"proxy":"","authType":"","x":570,"y":240,"wires":[["5c510ec6.b300b8"]]},{"id":"5c510ec6.b300b8","type":"change","z":"c791cbc0.84f648","name":"","rules":[{"t":"set","p":"url","pt":"msg","to":"payload.properties.forecastHourly","tot":"msg"},{"t":"delete","p":"headers","pt":"msg"},{"t":"set","p":"headers.user-agent","pt":"msg","to":"my_user_agent","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":590,"y":280,"wires":[["5f27466d.75f038"]]},{"id":"5f27466d.75f038","type":"http request","z":"c791cbc0.84f648","name":"","method":"GET","ret":"obj","paytoqs":"ignore","url":"","tls":"","persist":false,"proxy":"","authType":"","x":790,"y":280,"wires":[["bdb1705b.6db87"]]},{"id":"bdb1705b.6db87","type":"change","z":"c791cbc0.84f648","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"payload.properties.periods[$toMillis(startTime) > $millis()+(3600000 * $$.forecast)][0]","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":1020,"y":280,"wires":[["dab1571e.83d498"]]},{"id":"dab1571e.83d498","type":"debug","z":"c791cbc0.84f648","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":1030,"y":200,"wires":[]}]

```

---

<div class="post-metadata">

### Author: ![TheadehAnank](https://avatars.discourse-cdn.com/v4/letter/t/7ea924/32.png) [@TheadehAnank](https://discourse.nodered.org/u/TheadehAnank)
#### Post date: [29 January 2022 21:51 UTC](https://discourse.nodered.org/t/parsing-weather-gov-api/57466/4 "2022-01-29T21:51:20Z")

</div>

I guess I'm drawn to doing things the hardway, lol! Though, some data I'm looking for isn't in that feed.

Do you know if there is a database of responses for [weather.gov](http://weather.gov)? For eample, there seems to be several variations for its "snowing" in the shortForecast property.

---

<div class="post-metadata">

### Author: ![E1cid](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/e1cid/32/77971_2.png) [@E1cid](https://discourse.nodered.org/u/E1cid)
#### Post date: [29 January 2022 22:28 UTC](https://discourse.nodered.org/t/parsing-weather-gov-api/57466/5 "2022-01-29T22:28:26Z")

</div>

> [@TheadehAnank](#):
>
> Do you know if there is a database of responses

[API Web Services](https://www.weather.gov/documentation/services-web-api)  
If you click specification on that page then you can expand all GET requests and see the responses, and further down the page are the schema's.

---

<div class="post-metadata">

### Author: ![system](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/1X/d073cd938eafa2e558d7c2cd59003b3ef4963033.png) [@system](https://discourse.nodered.org/u/system)
#### Post date: [30 March 2022 22:29 UTC](https://discourse.nodered.org/t/parsing-weather-gov-api/57466/6 "2022-03-30T22:29:14Z")

</div>

This topic was automatically closed 60 days after the last reply. New replies are no longer allowed.
