diff options
-rw-r--r-- | nws/nws.go | 68 | ||||
-rw-r--r-- | nws/nws_test.go | 35 | ||||
-rw-r--r-- | version/version.go | 2 |
3 files changed, 104 insertions, 1 deletions
@@ -30,6 +30,7 @@ type PointProperties struct { GridY int Forecast string ForecastHourly string + ForecastGridData string RelativeLocation PointLocation } @@ -77,6 +78,24 @@ type FeatureCollection struct { Features []Feature } +type ForecastGrid struct { + Properties GridProperties +} + +type GridProperties struct { + RelativeHumidity GridHumidity +} + +type GridHumidity struct { + Uom string + Values []GridHumidityValue +} + +type GridHumidityValue struct { + ValidTime string + Value int +} + type Error struct { Title string Type string @@ -95,6 +114,7 @@ type ForecastBundle struct { var pCache *cache.Cache var fCache *cache.Cache var fhCache *cache.Cache +var fgCache *cache.Cache var aCache *cache.Cache var baseUrl *url.URL @@ -104,6 +124,7 @@ func init() { pCache = cache.NewCache() fCache = cache.NewCache() fhCache = cache.NewCache() + fgCache = cache.NewCache() aCache = cache.NewCache() // Parse NWS base url. @@ -326,6 +347,53 @@ func GetForecastHourly(point *Point) (*Forecast, *Error) { return forecast, nil } +// NWS forecast grid data endpoint. +func GetForecastGridData(point *Point) (*ForecastGrid, *Error) { + var nwsErr *Error + var expires time.Time + var body []byte + + if point == nil { + return nil, &Error{ + Title: "point is nil", + Type: "griddata-points-invalid", + Status: 500, + Detail: "point is nil", + } + } + if len(point.Properties.ForecastGridData) == 0 { + return nil, &Error{ + Title: "forecast grid data link is empty", + Type: "forecast-griddata-link-invalid", + Status: 500, + Detail: "forecast grid data link is empty", + } + } + + if body = fgCache.Get(point.Properties.ForecastGridData); len(body) == 0 { + // Get the forecast grid data + body, expires, nwsErr = get(point.Properties.ForecastGridData) + if nwsErr != nil { + return nil, nwsErr + } + // Cache it. + fgCache.Set(point.Properties.ForecastGridData, body, expires) + } + + // Unmarshal. + grid := new(ForecastGrid) + err := json.Unmarshal(body, grid) + if err != nil { + return nil, &Error{ + Title: "forecast grid data json unmarshal failed", + Type: "forecast-griddata-json-error", + Status: 500, + Detail: "forecast grid data json unmarshal failed", + } + } + return grid, nil +} + // NWS active alerts endpoint. func GetAlerts(lat, lng float32) (fc *FeatureCollection, err *Error) { // Alerts endpoint. diff --git a/nws/nws_test.go b/nws/nws_test.go index 88f1c2b..7ddd97f 100644 --- a/nws/nws_test.go +++ b/nws/nws_test.go @@ -151,6 +151,41 @@ func TestGetForecastHourly(t *testing.T) { } } +func TestGetForecastGridData(t *testing.T) { + // Get point. + np, nwsErr := Points(41.115, -83.177) + if nwsErr != nil { + t.Errorf("error: %v", nwsErr) + return + } + + // Get forecast grid data + grid, nwsErr := GetForecastGridData(np) + if nwsErr != nil { + t.Errorf("error: %v", nwsErr) + return + } + + if len(grid.Properties.RelativeHumidity.Values) < 1 { + t.Error("error: humidity values empty") + return + } + + // Verify humidity values. + for i, value := range grid.Properties.RelativeHumidity.Values { + if len(value.ValidTime) < 1 { + t.Errorf("humidity: %d: valid time invalid: %v", i, + value.ValidTime) + return + } + if value.Value < 1 { + t.Errorf("humidity: %d: value invalid: %v", i, + value.Value) + return + } + } +} + func TestNWSGetWrapper(t *testing.T) { // Initialize test NWS server. fails := 0 diff --git a/version/version.go b/version/version.go index fe9112e..c9d63d4 100644 --- a/version/version.go +++ b/version/version.go @@ -4,4 +4,4 @@ // Peach version. package version -const Version = "0.9.0" +const Version = "0.10.0.dev" |