Use 1h or 3h rain values as appropriate (#6593)

This commit is contained in:
Lyle Hanson 2019-11-08 14:10:16 -06:00 committed by Daniel Nelson
parent 6fd1453942
commit 4d08f2f404
3 changed files with 295 additions and 6 deletions

View File

@ -56,7 +56,7 @@ condition ID, icon, and main is at [weather conditions][].
- cloudiness (int, percent) - cloudiness (int, percent)
- humidity (int, percent) - humidity (int, percent)
- pressure (float, atmospheric pressure hPa) - pressure (float, atmospheric pressure hPa)
- rain (float, rain volume for the last 3 hours in mm) - rain (float, rain volume for the last 1-3 hours (depending on API response) in mm)
- sunrise (int, nanoseconds since unix epoch) - sunrise (int, nanoseconds since unix epoch)
- sunset (int, nanoseconds since unix epoch) - sunset (int, nanoseconds since unix epoch)
- temperature (float, degrees) - temperature (float, degrees)

View File

@ -179,6 +179,7 @@ type WeatherEntry struct {
Temp float64 `json:"temp"` Temp float64 `json:"temp"`
} `json:"main"` } `json:"main"`
Rain struct { Rain struct {
Rain1 float64 `json:"1h"`
Rain3 float64 `json:"3h"` Rain3 float64 `json:"3h"`
} `json:"rain"` } `json:"rain"`
Sys struct { Sys struct {
@ -227,6 +228,13 @@ func gatherWeatherUrl(r io.Reader) (*Status, error) {
return status, nil return status, nil
} }
func gatherRain(e WeatherEntry) float64 {
if e.Rain.Rain1 > 0 {
return e.Rain.Rain1
}
return e.Rain.Rain3
}
func gatherWeather(acc telegraf.Accumulator, status *Status) { func gatherWeather(acc telegraf.Accumulator, status *Status) {
for _, e := range status.List { for _, e := range status.List {
tm := time.Unix(e.Dt, 0) tm := time.Unix(e.Dt, 0)
@ -235,7 +243,7 @@ func gatherWeather(acc telegraf.Accumulator, status *Status) {
"cloudiness": e.Clouds.All, "cloudiness": e.Clouds.All,
"humidity": e.Main.Humidity, "humidity": e.Main.Humidity,
"pressure": e.Main.Pressure, "pressure": e.Main.Pressure,
"rain": e.Rain.Rain3, "rain": gatherRain(e),
"sunrise": time.Unix(e.Sys.Sunrise, 0).UnixNano(), "sunrise": time.Unix(e.Sys.Sunrise, 0).UnixNano(),
"sunset": time.Unix(e.Sys.Sunset, 0).UnixNano(), "sunset": time.Unix(e.Sys.Sunset, 0).UnixNano(),
"temperature": e.Main.Temp, "temperature": e.Main.Temp,
@ -274,7 +282,7 @@ func gatherForecast(acc telegraf.Accumulator, status *Status) {
"cloudiness": e.Clouds.All, "cloudiness": e.Clouds.All,
"humidity": e.Main.Humidity, "humidity": e.Main.Humidity,
"pressure": e.Main.Pressure, "pressure": e.Main.Pressure,
"rain": e.Rain.Rain3, "rain": gatherRain(e),
"temperature": e.Main.Temp, "temperature": e.Main.Temp,
"wind_degrees": e.Wind.Deg, "wind_degrees": e.Wind.Deg,
"wind_speed": e.Wind.Speed, "wind_speed": e.Wind.Speed,

View File

@ -146,6 +146,145 @@ const groupWeatherResponse = `
} }
` `
const rainWeatherResponse = `
{
"cnt": 2,
"list": [{
"dt": 1544194800,
"id": 111,
"main": {
"humidity": 87,
"pressure": 1007,
"temp": 9.25
},
"name": "Paris",
"sys": {
"country": "FR",
"id": 6550,
"message": 0.002,
"sunrise": 1544167818,
"sunset": 1544198047,
"type": 1
},
"visibility": 10000,
"weather": [
{
"description": "light intensity drizzle",
"icon": "09d",
"id": 300,
"main": "Drizzle"
}
],
"rain": {
"1h": 1.000
},
"wind": {
"deg": 290,
"speed": 8.7
}
},
{
"dt": 1544194800,
"id": 222,
"main": {
"humidity": 87,
"pressure": 1007,
"temp": 9.25
},
"name": "Paris",
"sys": {
"country": "FR",
"id": 6550,
"message": 0.002,
"sunrise": 1544167818,
"sunset": 1544198047,
"type": 1
},
"visibility": 10000,
"weather": [
{
"description": "light intensity drizzle",
"icon": "09d",
"id": 300,
"main": "Drizzle"
}
],
"rain": {
"3h": 3.000
},
"wind": {
"deg": 290,
"speed": 8.7
}
},
{
"dt": 1544194800,
"id": 333,
"main": {
"humidity": 87,
"pressure": 1007,
"temp": 9.25
},
"name": "Paris",
"sys": {
"country": "FR",
"id": 6550,
"message": 0.002,
"sunrise": 1544167818,
"sunset": 1544198047,
"type": 1
},
"visibility": 10000,
"weather": [
{
"description": "light intensity drizzle",
"icon": "09d",
"id": 300,
"main": "Drizzle"
}
],
"rain": {
"1h": 1.300,
"3h": 999
},
"wind": {
"deg": 290,
"speed": 8.7
}
},
{
"dt": 1544194800,
"id": 444,
"main": {
"humidity": 87,
"pressure": 1007,
"temp": 9.25
},
"name": "Paris",
"sys": {
"country": "FR",
"id": 6550,
"message": 0.002,
"sunrise": 1544167818,
"sunset": 1544198047,
"type": 1
},
"visibility": 10000,
"weather": [
{
"description": "light intensity drizzle",
"icon": "09d",
"id": 300,
"main": "Drizzle"
}
],
"wind": {
"deg": 290,
"speed": 8.7
}
}]
}
`
const batchWeatherResponse = ` const batchWeatherResponse = `
{ {
"cnt": 3, "cnt": 3,
@ -405,6 +544,148 @@ func TestWeatherGeneratesMetrics(t *testing.T) {
testutil.RequireMetricsEqual(t, expected, acc.GetTelegrafMetrics()) testutil.RequireMetricsEqual(t, expected, acc.GetTelegrafMetrics())
} }
// Ensure that results containing "1h", "3h", both, or no rain values are parsed correctly
func TestRainMetrics(t *testing.T) {
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
var rsp string
if r.URL.Path == "/data/2.5/group" {
rsp = rainWeatherResponse
w.Header()["Content-Type"] = []string{"application/json"}
} else {
panic("Cannot handle request")
}
fmt.Fprintln(w, rsp)
}))
defer ts.Close()
n := &OpenWeatherMap{
BaseUrl: ts.URL,
AppId: "noappid",
CityId: []string{"111", "222", "333", "444"},
Fetch: []string{"weather"},
Units: "metric",
}
n.Init()
var acc testutil.Accumulator
err := n.Gather(&acc)
require.NoError(t, err)
expected := []telegraf.Metric{
// City with 1h rain value
testutil.MustMetric(
"weather",
map[string]string{
"city_id": "111",
"forecast": "*",
"city": "Paris",
"country": "FR",
"condition_id": "300",
"condition_main": "Drizzle",
},
map[string]interface{}{
"cloudiness": int64(0),
"humidity": int64(87),
"pressure": 1007.0,
"temperature": 9.25,
"rain": 1.0,
"sunrise": int64(1544167818000000000),
"sunset": int64(1544198047000000000),
"wind_degrees": 290.0,
"wind_speed": 8.7,
"visibility": 10000,
"condition_description": "light intensity drizzle",
"condition_icon": "09d",
},
time.Unix(1544194800, 0),
),
// City with 3h rain value
testutil.MustMetric(
"weather",
map[string]string{
"city_id": "222",
"forecast": "*",
"city": "Paris",
"country": "FR",
"condition_id": "300",
"condition_main": "Drizzle",
},
map[string]interface{}{
"cloudiness": int64(0),
"humidity": int64(87),
"pressure": 1007.0,
"temperature": 9.25,
"rain": 3.0,
"sunrise": int64(1544167818000000000),
"sunset": int64(1544198047000000000),
"wind_degrees": 290.0,
"wind_speed": 8.7,
"visibility": 10000,
"condition_description": "light intensity drizzle",
"condition_icon": "09d",
},
time.Unix(1544194800, 0),
),
// City with both 1h and 3h rain values, prefer the 1h value
testutil.MustMetric(
"weather",
map[string]string{
"city_id": "333",
"forecast": "*",
"city": "Paris",
"country": "FR",
"condition_id": "300",
"condition_main": "Drizzle",
},
map[string]interface{}{
"cloudiness": int64(0),
"humidity": int64(87),
"pressure": 1007.0,
"temperature": 9.25,
"rain": 1.3,
"sunrise": int64(1544167818000000000),
"sunset": int64(1544198047000000000),
"wind_degrees": 290.0,
"wind_speed": 8.7,
"visibility": 10000,
"condition_description": "light intensity drizzle",
"condition_icon": "09d",
},
time.Unix(1544194800, 0),
),
// City with no rain values
testutil.MustMetric(
"weather",
map[string]string{
"city_id": "444",
"forecast": "*",
"city": "Paris",
"country": "FR",
"condition_id": "300",
"condition_main": "Drizzle",
},
map[string]interface{}{
"cloudiness": int64(0),
"humidity": int64(87),
"pressure": 1007.0,
"temperature": 9.25,
"rain": 0.0,
"sunrise": int64(1544167818000000000),
"sunset": int64(1544198047000000000),
"wind_degrees": 290.0,
"wind_speed": 8.7,
"visibility": 10000,
"condition_description": "light intensity drizzle",
"condition_icon": "09d",
},
time.Unix(1544194800, 0),
),
}
testutil.RequireMetricsEqual(t, expected, acc.GetTelegrafMetrics())
}
func TestBatchWeatherGeneratesMetrics(t *testing.T) { func TestBatchWeatherGeneratesMetrics(t *testing.T) {
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
var rsp string var rsp string