summaryrefslogtreecommitdiffstats
path: root/nws
diff options
context:
space:
mode:
Diffstat (limited to 'nws')
-rw-r--r--nws/nws.go68
-rw-r--r--nws/nws_test.go35
2 files changed, 103 insertions, 0 deletions
diff --git a/nws/nws.go b/nws/nws.go
index 67b351c..4fcc15b 100644
--- a/nws/nws.go
+++ b/nws/nws.go
@@ -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