mirror of
https://github.com/Brandon-Rozek/website.git
synced 2025-08-03 23:31:59 +00:00
New post
This commit is contained in:
parent
83962f82db
commit
7f268b8219
1 changed files with 556 additions and 0 deletions
556
content/blog/weather-forcecasts-cli-nws.md
Normal file
556
content/blog/weather-forcecasts-cli-nws.md
Normal file
|
@ -0,0 +1,556 @@
|
||||||
|
---
|
||||||
|
title: "Weather Forcecasts on the Command-Line with the National Weather Service API"
|
||||||
|
date: 2025-03-16T15:33:49-04:00
|
||||||
|
draft: true
|
||||||
|
tags: []
|
||||||
|
math: false
|
||||||
|
medium_enabled: false
|
||||||
|
---
|
||||||
|
|
||||||
|
The United States National Weather Service (NWS) has a [JSON API](https://www.weather.gov/documentation/services-web-api) which provides weather alerts and forecasts for free without having to create an API key[^1]. We'll use this resource to write a small bash script which gives today and tomorrow's weather forecast given a latitude and longitude.
|
||||||
|
|
||||||
|
[^1]: In this day and age, it almost feels too good to be true.
|
||||||
|
|
||||||
|
My goal is to have a small bash script which I can run in the terminal to get the forecast information. We'll use [`jq`](https://jqlang.org/) for handling the JSON data.
|
||||||
|
|
||||||
|
The NWS API does not provide the forecast directly given a latitude and longitude coordinates. Instead, we need to provide the specific [Weather Forecast Office (WFO)](https://www.weather.gov/srh/nwsoffices) responsible for that area plus their grid definitions for the latitude and longitude coordinate.
|
||||||
|
|
||||||
|
Luckily, we can query for that information as well.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
POINTS=$(curl -Ls "https://api.weather.gov/points/$LAT,$LON")
|
||||||
|
```
|
||||||
|
|
||||||
|
{{< unsafe >}}<details><summary>For 42.7289, -73.6915 it returns:</summary>{{</unsafe >}}
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"@context": [
|
||||||
|
"https://geojson.org/geojson-ld/geojson-context.jsonld",
|
||||||
|
{
|
||||||
|
"@version": "1.1",
|
||||||
|
"wx": "https://api.weather.gov/ontology#",
|
||||||
|
"s": "https://schema.org/",
|
||||||
|
"geo": "http://www.opengis.net/ont/geosparql#",
|
||||||
|
"unit": "http://codes.wmo.int/common/unit/",
|
||||||
|
"@vocab": "https://api.weather.gov/ontology#",
|
||||||
|
"geometry": {
|
||||||
|
"@id": "s:GeoCoordinates",
|
||||||
|
"@type": "geo:wktLiteral"
|
||||||
|
},
|
||||||
|
"city": "s:addressLocality",
|
||||||
|
"state": "s:addressRegion",
|
||||||
|
"distance": {
|
||||||
|
"@id": "s:Distance",
|
||||||
|
"@type": "s:QuantitativeValue"
|
||||||
|
},
|
||||||
|
"bearing": {
|
||||||
|
"@type": "s:QuantitativeValue"
|
||||||
|
},
|
||||||
|
"value": {
|
||||||
|
"@id": "s:value"
|
||||||
|
},
|
||||||
|
"unitCode": {
|
||||||
|
"@id": "s:unitCode",
|
||||||
|
"@type": "@id"
|
||||||
|
},
|
||||||
|
"forecastOffice": {
|
||||||
|
"@type": "@id"
|
||||||
|
},
|
||||||
|
"forecastGridData": {
|
||||||
|
"@type": "@id"
|
||||||
|
},
|
||||||
|
"publicZone": {
|
||||||
|
"@type": "@id"
|
||||||
|
},
|
||||||
|
"county": {
|
||||||
|
"@type": "@id"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"id": "https://api.weather.gov/points/42.7289,-73.6915",
|
||||||
|
"type": "Feature",
|
||||||
|
"geometry": {
|
||||||
|
"type": "Point",
|
||||||
|
"coordinates": [
|
||||||
|
-73.6915,
|
||||||
|
42.7289
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"properties": {
|
||||||
|
"@id": "https://api.weather.gov/points/42.7289,-73.6915",
|
||||||
|
"@type": "wx:Point",
|
||||||
|
"cwa": "ALY",
|
||||||
|
"forecastOffice": "https://api.weather.gov/offices/ALY",
|
||||||
|
"gridId": "ALY",
|
||||||
|
"gridX": 74,
|
||||||
|
"gridY": 67,
|
||||||
|
"forecast": "https://api.weather.gov/gridpoints/ALY/74,67/forecast",
|
||||||
|
"forecastHourly": "https://api.weather.gov/gridpoints/ALY/74,67/forecast/hourly",
|
||||||
|
"forecastGridData": "https://api.weather.gov/gridpoints/ALY/74,67",
|
||||||
|
"observationStations": "https://api.weather.gov/gridpoints/ALY/74,67/stations",
|
||||||
|
"relativeLocation": {
|
||||||
|
"type": "Feature",
|
||||||
|
"geometry": {
|
||||||
|
"type": "Point",
|
||||||
|
"coordinates": [
|
||||||
|
-73.707011,
|
||||||
|
42.724883
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"properties": {
|
||||||
|
"city": "Watervliet",
|
||||||
|
"state": "NY",
|
||||||
|
"distance": {
|
||||||
|
"unitCode": "wmoUnit:m",
|
||||||
|
"value": 1343.4228258697
|
||||||
|
},
|
||||||
|
"bearing": {
|
||||||
|
"unitCode": "wmoUnit:degree_(angle)",
|
||||||
|
"value": 70
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"forecastZone": "https://api.weather.gov/zones/forecast/NYZ053",
|
||||||
|
"county": "https://api.weather.gov/zones/county/NYC083",
|
||||||
|
"fireWeatherZone": "https://api.weather.gov/zones/fire/NYZ208",
|
||||||
|
"timeZone": "America/New_York",
|
||||||
|
"radarStation": "KENX"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
{{< unsafe >}}</details><br/>{{</unsafe >}}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
That's a lot of output! However, we only need three pieces of information:
|
||||||
|
|
||||||
|
- WFO office (ex: "ALY")
|
||||||
|
- Grid-X (ex: 74)
|
||||||
|
- Grid-Y (ex: 67)
|
||||||
|
|
||||||
|
We can use the following code to store this into variables using `jq`
|
||||||
|
|
||||||
|
```bash
|
||||||
|
OFFICE=$(echo $POINTS | jq -r .properties.gridId)
|
||||||
|
X=$(echo $POINTS | jq .properties.gridX)
|
||||||
|
Y=$(echo $POINTS | jq .properties.gridY)
|
||||||
|
```
|
||||||
|
|
||||||
|
From here, we can query for the weather forecast for that grid point.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
WEATHER=$(curl -Ls "https://api.weather.gov/gridpoints/$OFFICE/$X,$Y/forecast")
|
||||||
|
```
|
||||||
|
|
||||||
|
{{< unsafe >}}<details><summary>Show output:</summary>{{</unsafe >}}
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"@context": [
|
||||||
|
"https://geojson.org/geojson-ld/geojson-context.jsonld",
|
||||||
|
{
|
||||||
|
"@version": "1.1",
|
||||||
|
"wx": "https://api.weather.gov/ontology#",
|
||||||
|
"geo": "http://www.opengis.net/ont/geosparql#",
|
||||||
|
"unit": "http://codes.wmo.int/common/unit/",
|
||||||
|
"@vocab": "https://api.weather.gov/ontology#"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"type": "Feature",
|
||||||
|
"geometry": {
|
||||||
|
"type": "Polygon",
|
||||||
|
"coordinates": [
|
||||||
|
[
|
||||||
|
[
|
||||||
|
-73.6648,
|
||||||
|
42.7172
|
||||||
|
],
|
||||||
|
[
|
||||||
|
-73.6602,
|
||||||
|
42.7386
|
||||||
|
],
|
||||||
|
[
|
||||||
|
-73.6893,
|
||||||
|
42.742
|
||||||
|
],
|
||||||
|
[
|
||||||
|
-73.694,
|
||||||
|
42.720499999999994
|
||||||
|
],
|
||||||
|
[
|
||||||
|
-73.6648,
|
||||||
|
42.7172
|
||||||
|
]
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"properties": {
|
||||||
|
"units": "us",
|
||||||
|
"forecastGenerator": "BaselineForecastGenerator",
|
||||||
|
"generatedAt": "2025-03-16T19:59:48+00:00",
|
||||||
|
"updateTime": "2025-03-16T19:38:29+00:00",
|
||||||
|
"validTimes": "2025-03-16T13:00:00+00:00/P8D",
|
||||||
|
"elevation": {
|
||||||
|
"unitCode": "wmoUnit:m",
|
||||||
|
"value": 61.8744
|
||||||
|
},
|
||||||
|
"periods": [
|
||||||
|
{
|
||||||
|
"number": 1,
|
||||||
|
"name": "This Afternoon",
|
||||||
|
"startTime": "2025-03-16T15:00:00-04:00",
|
||||||
|
"endTime": "2025-03-16T18:00:00-04:00",
|
||||||
|
"isDaytime": true,
|
||||||
|
"temperature": 69,
|
||||||
|
"temperatureUnit": "F",
|
||||||
|
"temperatureTrend": "",
|
||||||
|
"probabilityOfPrecipitation": {
|
||||||
|
"unitCode": "wmoUnit:percent",
|
||||||
|
"value": null
|
||||||
|
},
|
||||||
|
"windSpeed": "22 mph",
|
||||||
|
"windDirection": "S",
|
||||||
|
"icon": "https://api.weather.gov/icons/land/day/wind_ovc?size=medium",
|
||||||
|
"shortForecast": "Cloudy",
|
||||||
|
"detailedForecast": "Cloudy, with a high near 69. South wind around 22 mph, with gusts as high as 43 mph. New rainfall amounts less than a tenth of an inch possible."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"number": 2,
|
||||||
|
"name": "Tonight",
|
||||||
|
"startTime": "2025-03-16T18:00:00-04:00",
|
||||||
|
"endTime": "2025-03-17T06:00:00-04:00",
|
||||||
|
"isDaytime": false,
|
||||||
|
"temperature": 50,
|
||||||
|
"temperatureUnit": "F",
|
||||||
|
"temperatureTrend": "",
|
||||||
|
"probabilityOfPrecipitation": {
|
||||||
|
"unitCode": "wmoUnit:percent",
|
||||||
|
"value": 100
|
||||||
|
},
|
||||||
|
"windSpeed": "5 to 21 mph",
|
||||||
|
"windDirection": "SW",
|
||||||
|
"icon": "https://api.weather.gov/icons/land/night/tsra,100?size=medium",
|
||||||
|
"shortForecast": "Showers And Thunderstorms",
|
||||||
|
"detailedForecast": "A chance of rain showers before 8pm, then showers and thunderstorms. Cloudy, with a low around 50. Southwest wind 5 to 21 mph, with gusts as high as 44 mph. Chance of precipitation is 100%. New rainfall amounts between three quarters and one inch possible."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"number": 3,
|
||||||
|
"name": "Monday",
|
||||||
|
"startTime": "2025-03-17T06:00:00-04:00",
|
||||||
|
"endTime": "2025-03-17T18:00:00-04:00",
|
||||||
|
"isDaytime": true,
|
||||||
|
"temperature": 53,
|
||||||
|
"temperatureUnit": "F",
|
||||||
|
"temperatureTrend": "",
|
||||||
|
"probabilityOfPrecipitation": {
|
||||||
|
"unitCode": "wmoUnit:percent",
|
||||||
|
"value": 60
|
||||||
|
},
|
||||||
|
"windSpeed": "5 to 12 mph",
|
||||||
|
"windDirection": "NW",
|
||||||
|
"icon": "https://api.weather.gov/icons/land/day/rain_showers,60/rain_showers,50?size=medium",
|
||||||
|
"shortForecast": "Rain Showers Likely",
|
||||||
|
"detailedForecast": "Rain showers likely. Cloudy. High near 53, with temperatures falling to around 46 in the afternoon. Northwest wind 5 to 12 mph. Chance of precipitation is 60%. New rainfall amounts between a half and three quarters of an inch possible."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"number": 4,
|
||||||
|
"name": "Monday Night",
|
||||||
|
"startTime": "2025-03-17T18:00:00-04:00",
|
||||||
|
"endTime": "2025-03-18T06:00:00-04:00",
|
||||||
|
"isDaytime": false,
|
||||||
|
"temperature": 31,
|
||||||
|
"temperatureUnit": "F",
|
||||||
|
"temperatureTrend": "",
|
||||||
|
"probabilityOfPrecipitation": {
|
||||||
|
"unitCode": "wmoUnit:percent",
|
||||||
|
"value": 30
|
||||||
|
},
|
||||||
|
"windSpeed": "7 to 10 mph",
|
||||||
|
"windDirection": "NW",
|
||||||
|
"icon": "https://api.weather.gov/icons/land/night/rain_showers,30/bkn?size=medium",
|
||||||
|
"shortForecast": "Chance Rain Showers then Mostly Cloudy",
|
||||||
|
"detailedForecast": "A chance of rain showers before 8pm. Mostly cloudy, with a low around 31. Northwest wind 7 to 10 mph. Chance of precipitation is 30%. New rainfall amounts between a tenth and quarter of an inch possible."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"number": 5,
|
||||||
|
"name": "Tuesday",
|
||||||
|
"startTime": "2025-03-18T06:00:00-04:00",
|
||||||
|
"endTime": "2025-03-18T18:00:00-04:00",
|
||||||
|
"isDaytime": true,
|
||||||
|
"temperature": 56,
|
||||||
|
"temperatureUnit": "F",
|
||||||
|
"temperatureTrend": "",
|
||||||
|
"probabilityOfPrecipitation": {
|
||||||
|
"unitCode": "wmoUnit:percent",
|
||||||
|
"value": null
|
||||||
|
},
|
||||||
|
"windSpeed": "7 mph",
|
||||||
|
"windDirection": "NW",
|
||||||
|
"icon": "https://api.weather.gov/icons/land/day/few?size=medium",
|
||||||
|
"shortForecast": "Sunny",
|
||||||
|
"detailedForecast": "Sunny, with a high near 56. Northwest wind around 7 mph."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"number": 6,
|
||||||
|
"name": "Tuesday Night",
|
||||||
|
"startTime": "2025-03-18T18:00:00-04:00",
|
||||||
|
"endTime": "2025-03-19T06:00:00-04:00",
|
||||||
|
"isDaytime": false,
|
||||||
|
"temperature": 35,
|
||||||
|
"temperatureUnit": "F",
|
||||||
|
"temperatureTrend": "",
|
||||||
|
"probabilityOfPrecipitation": {
|
||||||
|
"unitCode": "wmoUnit:percent",
|
||||||
|
"value": null
|
||||||
|
},
|
||||||
|
"windSpeed": "1 to 5 mph",
|
||||||
|
"windDirection": "NE",
|
||||||
|
"icon": "https://api.weather.gov/icons/land/night/few?size=medium",
|
||||||
|
"shortForecast": "Mostly Clear",
|
||||||
|
"detailedForecast": "Mostly clear, with a low around 35."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"number": 7,
|
||||||
|
"name": "Wednesday",
|
||||||
|
"startTime": "2025-03-19T06:00:00-04:00",
|
||||||
|
"endTime": "2025-03-19T18:00:00-04:00",
|
||||||
|
"isDaytime": true,
|
||||||
|
"temperature": 65,
|
||||||
|
"temperatureUnit": "F",
|
||||||
|
"temperatureTrend": "",
|
||||||
|
"probabilityOfPrecipitation": {
|
||||||
|
"unitCode": "wmoUnit:percent",
|
||||||
|
"value": null
|
||||||
|
},
|
||||||
|
"windSpeed": "2 to 9 mph",
|
||||||
|
"windDirection": "SE",
|
||||||
|
"icon": "https://api.weather.gov/icons/land/day/sct?size=medium",
|
||||||
|
"shortForecast": "Mostly Sunny",
|
||||||
|
"detailedForecast": "Mostly sunny, with a high near 65."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"number": 8,
|
||||||
|
"name": "Wednesday Night",
|
||||||
|
"startTime": "2025-03-19T18:00:00-04:00",
|
||||||
|
"endTime": "2025-03-20T06:00:00-04:00",
|
||||||
|
"isDaytime": false,
|
||||||
|
"temperature": 45,
|
||||||
|
"temperatureUnit": "F",
|
||||||
|
"temperatureTrend": "",
|
||||||
|
"probabilityOfPrecipitation": {
|
||||||
|
"unitCode": "wmoUnit:percent",
|
||||||
|
"value": null
|
||||||
|
},
|
||||||
|
"windSpeed": "9 mph",
|
||||||
|
"windDirection": "SE",
|
||||||
|
"icon": "https://api.weather.gov/icons/land/night/bkn?size=medium",
|
||||||
|
"shortForecast": "Mostly Cloudy",
|
||||||
|
"detailedForecast": "Mostly cloudy, with a low around 45."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"number": 9,
|
||||||
|
"name": "Thursday",
|
||||||
|
"startTime": "2025-03-20T06:00:00-04:00",
|
||||||
|
"endTime": "2025-03-20T18:00:00-04:00",
|
||||||
|
"isDaytime": true,
|
||||||
|
"temperature": 61,
|
||||||
|
"temperatureUnit": "F",
|
||||||
|
"temperatureTrend": "",
|
||||||
|
"probabilityOfPrecipitation": {
|
||||||
|
"unitCode": "wmoUnit:percent",
|
||||||
|
"value": 50
|
||||||
|
},
|
||||||
|
"windSpeed": "8 to 14 mph",
|
||||||
|
"windDirection": "S",
|
||||||
|
"icon": "https://api.weather.gov/icons/land/day/bkn/rain_showers,50?size=medium",
|
||||||
|
"shortForecast": "Mostly Cloudy then Chance Rain Showers",
|
||||||
|
"detailedForecast": "A chance of rain showers after 2pm. Mostly cloudy, with a high near 61. Chance of precipitation is 50%."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"number": 10,
|
||||||
|
"name": "Thursday Night",
|
||||||
|
"startTime": "2025-03-20T18:00:00-04:00",
|
||||||
|
"endTime": "2025-03-21T06:00:00-04:00",
|
||||||
|
"isDaytime": false,
|
||||||
|
"temperature": 33,
|
||||||
|
"temperatureUnit": "F",
|
||||||
|
"temperatureTrend": "",
|
||||||
|
"probabilityOfPrecipitation": {
|
||||||
|
"unitCode": "wmoUnit:percent",
|
||||||
|
"value": 70
|
||||||
|
},
|
||||||
|
"windSpeed": "8 to 12 mph",
|
||||||
|
"windDirection": "SW",
|
||||||
|
"icon": "https://api.weather.gov/icons/land/night/rain_showers,70/snow,70?size=medium",
|
||||||
|
"shortForecast": "Rain Showers Likely then Chance Rain And Snow Showers",
|
||||||
|
"detailedForecast": "Rain showers likely before 2am, then a chance of rain and snow showers. Mostly cloudy, with a low around 33. Chance of precipitation is 70%."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"number": 11,
|
||||||
|
"name": "Friday",
|
||||||
|
"startTime": "2025-03-21T06:00:00-04:00",
|
||||||
|
"endTime": "2025-03-21T18:00:00-04:00",
|
||||||
|
"isDaytime": true,
|
||||||
|
"temperature": 41,
|
||||||
|
"temperatureUnit": "F",
|
||||||
|
"temperatureTrend": "",
|
||||||
|
"probabilityOfPrecipitation": {
|
||||||
|
"unitCode": "wmoUnit:percent",
|
||||||
|
"value": 50
|
||||||
|
},
|
||||||
|
"windSpeed": "12 to 17 mph",
|
||||||
|
"windDirection": "NW",
|
||||||
|
"icon": "https://api.weather.gov/icons/land/day/snow,50/snow,30?size=medium",
|
||||||
|
"shortForecast": "Chance Rain And Snow Showers",
|
||||||
|
"detailedForecast": "A chance of rain and snow showers. Partly sunny, with a high near 41. Chance of precipitation is 50%."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"number": 12,
|
||||||
|
"name": "Friday Night",
|
||||||
|
"startTime": "2025-03-21T18:00:00-04:00",
|
||||||
|
"endTime": "2025-03-22T06:00:00-04:00",
|
||||||
|
"isDaytime": false,
|
||||||
|
"temperature": 30,
|
||||||
|
"temperatureUnit": "F",
|
||||||
|
"temperatureTrend": "",
|
||||||
|
"probabilityOfPrecipitation": {
|
||||||
|
"unitCode": "wmoUnit:percent",
|
||||||
|
"value": null
|
||||||
|
},
|
||||||
|
"windSpeed": "9 to 16 mph",
|
||||||
|
"windDirection": "NW",
|
||||||
|
"icon": "https://api.weather.gov/icons/land/night/snow/sct?size=medium",
|
||||||
|
"shortForecast": "Slight Chance Snow Showers then Partly Cloudy",
|
||||||
|
"detailedForecast": "A slight chance of snow showers before 8pm. Partly cloudy, with a low around 30."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"number": 13,
|
||||||
|
"name": "Saturday",
|
||||||
|
"startTime": "2025-03-22T06:00:00-04:00",
|
||||||
|
"endTime": "2025-03-22T18:00:00-04:00",
|
||||||
|
"isDaytime": true,
|
||||||
|
"temperature": 52,
|
||||||
|
"temperatureUnit": "F",
|
||||||
|
"temperatureTrend": "",
|
||||||
|
"probabilityOfPrecipitation": {
|
||||||
|
"unitCode": "wmoUnit:percent",
|
||||||
|
"value": null
|
||||||
|
},
|
||||||
|
"windSpeed": "9 to 13 mph",
|
||||||
|
"windDirection": "NW",
|
||||||
|
"icon": "https://api.weather.gov/icons/land/day/sct?size=medium",
|
||||||
|
"shortForecast": "Mostly Sunny",
|
||||||
|
"detailedForecast": "Mostly sunny, with a high near 52."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"number": 14,
|
||||||
|
"name": "Saturday Night",
|
||||||
|
"startTime": "2025-03-22T18:00:00-04:00",
|
||||||
|
"endTime": "2025-03-23T06:00:00-04:00",
|
||||||
|
"isDaytime": false,
|
||||||
|
"temperature": 34,
|
||||||
|
"temperatureUnit": "F",
|
||||||
|
"temperatureTrend": "",
|
||||||
|
"probabilityOfPrecipitation": {
|
||||||
|
"unitCode": "wmoUnit:percent",
|
||||||
|
"value": null
|
||||||
|
},
|
||||||
|
"windSpeed": "3 to 9 mph",
|
||||||
|
"windDirection": "NW",
|
||||||
|
"icon": "https://api.weather.gov/icons/land/night/bkn?size=medium",
|
||||||
|
"shortForecast": "Mostly Cloudy",
|
||||||
|
"detailedForecast": "Mostly cloudy, with a low around 34."
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
{{< unsafe >}}</details><br/>{{</unsafe >}}
|
||||||
|
|
||||||
|
The National Weather Service packs in so much weather information in just one API call! My favorite part is that they have a `detailedForecast` field which provides a nice human-readable description of the weather.
|
||||||
|
|
||||||
|
I don't know about you, but at any given time, I'm mostly curious about today and tomorrow's weather. Unless I'm planning a trip or need to be aware of an extreme weather event, the day's forecast mostly influences the clothes I wear.
|
||||||
|
|
||||||
|
The final part of this script is to grab the next three "periods" and display its `detailedForecast` field.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
for i in 0 1 2; do
|
||||||
|
echo "$WEATHER" | jq .properties.periods[$i] | jq -r '
|
||||||
|
"\(.name)
|
||||||
|
\(.detailedForecast)
|
||||||
|
"
|
||||||
|
'
|
||||||
|
done
|
||||||
|
```
|
||||||
|
|
||||||
|
Instead of having to read an entire JSON message to get the weather, we now have a description of the forecast coming up.
|
||||||
|
|
||||||
|
```
|
||||||
|
This Afternoon
|
||||||
|
Cloudy, with a high near 69. South wind around 22 mph, with gusts as high as 43 mph. New rainfall amounts less than a tenth of an inch possible.
|
||||||
|
|
||||||
|
Tonight
|
||||||
|
A chance of rain showers before 8pm, then showers and thunderstorms. Cloudy, with a low around 50. Southwest wind 5 to 21 mph, with gusts as high as 44 mph. Chance of precipitation is 100%. New rainfall amounts between three quarters and one inch possible.
|
||||||
|
|
||||||
|
Monday
|
||||||
|
Rain showers likely. Cloudy. High near 53, with temperatures falling to around 46 in the afternoon. Northwest wind 5 to 12 mph. Chance of precipitation is 60%. New rainfall amounts between a half and three quarters of an inch possible.
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
Look how short and sweet that output is! With that, we have all the steps needed in our script to grab the upcoming forecast using the NWS API. I created an alias called `myweather` so that I don't have to memorize the latitude or longitude of where I live.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
alias myweather='usweather 42.7289, -73.6915'
|
||||||
|
```
|
||||||
|
|
||||||
|
Here is the script that I call `usweather` in its entirety. I placed it in `~/.local/bin`.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
#!/bin/sh
|
||||||
|
# Script to query the US National Weather Forecast Office (WFO)
|
||||||
|
|
||||||
|
set -o errexit
|
||||||
|
set -o nounset
|
||||||
|
|
||||||
|
show_usage() {
|
||||||
|
echo "Usage: usweather [lat] [lon]"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# Check Argument Count
|
||||||
|
if [ "$#" -ne 2 ]; then
|
||||||
|
show_usage
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! command -v jq &> /dev/null; then
|
||||||
|
echo "jq is not installed"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# We need to figure out WFO specific parameters
|
||||||
|
POINTS=$(curl -Ls "https://api.weather.gov/points/$1,$2")
|
||||||
|
OFFICE=$(echo $POINTS | jq -r .properties.gridId)
|
||||||
|
X=$(echo $POINTS | jq .properties.gridX)
|
||||||
|
Y=$(echo $POINTS | jq .properties.gridY)
|
||||||
|
|
||||||
|
if [ "$OFFICE" = "null" ] || [ "$X" = "null" ] || [ "$Y" = "null" ]; then
|
||||||
|
echo -e "Error:\n $POINTS"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
WEATHER=$(curl -Ls "https://api.weather.gov/gridpoints/$OFFICE/$X,$Y/forecast")
|
||||||
|
|
||||||
|
# Provide the detailed forecast for the next three weather periods
|
||||||
|
for i in 0 1 2; do
|
||||||
|
echo "$WEATHER" | jq .properties.periods[$i] | jq -r '
|
||||||
|
"\(.name)
|
||||||
|
\(.detailedForecast)
|
||||||
|
"
|
||||||
|
'
|
||||||
|
done
|
||||||
|
|
||||||
|
```
|
||||||
|
|
Loading…
Add table
Reference in a new issue