Added WindGust to current weather

This commit is contained in:
Winni Neessen 2023-06-23 12:05:40 +02:00
parent a7feae910b
commit 4d60f35c6a
Signed by: wneessen
GPG key ID: 5F3AF39B820C119D
5 changed files with 113 additions and 33 deletions

View file

@ -48,11 +48,13 @@ type APICurrentWeatherData struct {
PressureMSL *APIFloat `json:"pressureMsl,omitempty"`
// Temperature represents the temperature in °C
Temperature *APIFloat `json:"temp,omitempty,omitempty"`
// Windspeed represents the wind speed in knots
Windspeed *APIFloat `json:"windSpeed,omitempty,omitempty"`
// Winddirection represents the direction from which the wind
// WindDirection represents the direction from which the wind
// originates in degree (0=N, 90=E, 180=S, 270=W)
Winddirection *APIFloat `json:"windDirection,omitempty"`
WindDirection *APIFloat `json:"windDirection,omitempty"`
// WindGust represents the wind gust speed in m/s
WindGust *APIFloat `json:"windGust,omitempty"`
// WindSpeed represents the wind speed in m/s
WindSpeed *APIFloat `json:"windSpeed,omitempty"`
// WeatherSymbol is a text representation of the current weather
// conditions
WeatherSymbol *APIString `json:"weatherSymbol,omitempty"`
@ -269,17 +271,36 @@ func (cw CurrentWeather) WeatherSymbol() Condition {
// If the data point is not available in the CurrentWeather it will return
// Direction in which the "not available" field will be true.
func (cw CurrentWeather) WindDirection() Direction {
if cw.Data.Winddirection == nil {
if cw.Data.WindDirection == nil {
return Direction{na: true}
}
v := Direction{
dt: cw.Data.Winddirection.DateTime,
n: FieldWinddirection,
dt: cw.Data.WindDirection.DateTime,
n: FieldWindDirection,
s: SourceUnknown,
fv: cw.Data.Winddirection.Value,
fv: cw.Data.WindDirection.Value,
}
if cw.Data.Winddirection.Source != nil {
v.s = StringToSource(*cw.Data.Winddirection.Source)
if cw.Data.WindDirection.Source != nil {
v.s = StringToSource(*cw.Data.WindDirection.Source)
}
return v
}
// WindGust returns the wind gust data point as Speed.
// If the data point is not available in the CurrentWeather it will return
// Speed in which the "not available" field will be true.
func (cw CurrentWeather) WindGust() Speed {
if cw.Data.WindGust == nil {
return Speed{na: true}
}
v := Speed{
dt: cw.Data.WindGust.DateTime,
n: FieldWindGust,
s: SourceUnknown,
fv: cw.Data.WindGust.Value,
}
if cw.Data.WindGust.Source != nil {
v.s = StringToSource(*cw.Data.WindGust.Source)
}
return v
}
@ -288,17 +309,17 @@ func (cw CurrentWeather) WindDirection() Direction {
// If the data point is not available in the CurrentWeather it will return
// Speed in which the "not available" field will be true.
func (cw CurrentWeather) WindSpeed() Speed {
if cw.Data.Windspeed == nil {
if cw.Data.WindSpeed == nil {
return Speed{na: true}
}
v := Speed{
dt: cw.Data.Windspeed.DateTime,
n: FieldWindspeed,
dt: cw.Data.WindSpeed.DateTime,
n: FieldWindSpeed,
s: SourceUnknown,
fv: cw.Data.Windspeed.Value,
fv: cw.Data.WindSpeed.Value,
}
if cw.Data.Windspeed.Source != nil {
v.s = StringToSource(*cw.Data.Windspeed.Source)
if cw.Data.WindSpeed.Source != nil {
v.s = StringToSource(*cw.Data.WindSpeed.Source)
}
return v
}

View file

@ -703,6 +703,63 @@ func TestClient_CurrentWeatherByLocation_WindDirection(t *testing.T) {
}
}
func TestClient_CurrentWeatherByLocation_WindGust(t *testing.T) {
tt := []struct {
// Location name
loc string
// CurWeather speed
s *Speed
}{
{"Ehrenfeld, Germany", &Speed{
dt: time.Date(2023, 5, 23, 7, 0, 0, 0, time.Local),
s: SourceAnalysis,
fv: 7.770000,
}},
{"Berlin, Germany", &Speed{
dt: time.Date(2023, 5, 23, 7, 0, 0, 0, time.Local),
s: SourceAnalysis,
fv: 5.570000,
}},
{"Neermoor, Germany", nil},
}
c := New(withMockAPI())
if c == nil {
t.Errorf("failed to create new Client, got nil")
return
}
for _, tc := range tt {
t.Run(tc.loc, func(t *testing.T) {
cw, err := c.CurrentWeatherByLocation(tc.loc)
if err != nil {
t.Errorf("CurrentWeatherByLocation failed: %s", err)
return
}
if tc.s != nil && tc.s.String() != cw.WindGust().String() {
t.Errorf("CurrentWeatherByLocation failed, expected wind gust "+
"string: %s, got: %s", tc.s.String(), cw.WindGust())
}
if tc.s != nil && tc.s.Value() != cw.WindGust().Value() {
t.Errorf("CurrentWeatherByLocation failed, expected wind gust "+
"float: %f, got: %f", tc.s.Value(), cw.WindGust().Value())
}
if tc.s != nil && cw.WindGust().Source() != tc.s.s {
t.Errorf("CurrentWeatherByLocation failed, expected source: %s, but got: %s",
tc.s.s, cw.WindGust().Source())
}
if tc.s == nil {
if cw.WindGust().IsAvailable() {
t.Errorf("CurrentWeatherByLocation failed, expected wind gust "+
"to have no data, but got: %s", cw.WindGust())
}
if !math.IsNaN(cw.WindGust().Value()) {
t.Errorf("CurrentWeatherByLocation failed, expected wind gust "+
"to return NaN, but got: %s", cw.WindGust().String())
}
}
})
}
}
func TestClient_CurrentWeatherByLocation_WindSpeed(t *testing.T) {
tt := []struct {
// Location name

View file

@ -62,10 +62,12 @@ const (
FieldTemperatureMin
// FieldWeatherSymbol represents the weather symbol data point
FieldWeatherSymbol
// FieldWinddirection represents the WindDirection data point
FieldWinddirection
// FieldWindspeed represents the WindSpeed data point
FieldWindspeed
// FieldWindDirection represents the WindDirection data point
FieldWindDirection
// FieldWindGust represents the WindGust data point
FieldWindGust
// FieldWindSpeed represents the WindSpeed data point
FieldWindSpeed
)
// Enum for different Timespan values

View file

@ -76,11 +76,11 @@ type APIObservationData struct {
// Temperature5cm represents the minimum temperature 5cm above
// ground in °C
Temperature5cmMin *APIFloat `json:"temp5cmMin,omitempty"`
// Winddirection represents the direction from which the wind
// WindDirection represents the direction from which the wind
// originates in degree (0=N, 90=E, 180=S, 270=W)
Winddirection *APIFloat `json:"windDirection,omitempty"`
// Windspeed represents the wind speed in knots
Windspeed *APIFloat `json:"windSpeed,omitempty"`
WindDirection *APIFloat `json:"windDirection,omitempty"`
// WindSpeed represents the wind speed in knots
WindSpeed *APIFloat `json:"windSpeed,omitempty"`
}
// ObservationLatestByStationID returns the latest Observation values from the
@ -370,14 +370,14 @@ func (o Observation) GlobalRadiation(ts Timespan) Radiation {
// If the data point is not available in the Observation it will return
// Direction in which the "not available" field will be true.
func (o Observation) WindDirection() Direction {
if o.Data.Winddirection == nil {
if o.Data.WindDirection == nil {
return Direction{na: true}
}
return Direction{
dt: o.Data.Winddirection.DateTime,
n: FieldWinddirection,
dt: o.Data.WindDirection.DateTime,
n: FieldWindDirection,
s: SourceObservation,
fv: o.Data.Winddirection.Value,
fv: o.Data.WindDirection.Value,
}
}
@ -385,13 +385,13 @@ func (o Observation) WindDirection() Direction {
// If the data point is not available in the Observation it will return
// Speed in which the "not available" field will be true.
func (o Observation) WindSpeed() Speed {
if o.Data.Windspeed == nil {
if o.Data.WindSpeed == nil {
return Speed{na: true}
}
return Speed{
dt: o.Data.Windspeed.DateTime,
n: FieldWindspeed,
dt: o.Data.WindSpeed.DateTime,
n: FieldWindSpeed,
s: SourceObservation,
fv: o.Data.Windspeed.Value * 0.5144444444,
fv: o.Data.WindSpeed.Value * 0.5144444444,
}
}

View file

@ -1218,7 +1218,7 @@ func TestClient_ObservationLatestByStationID_WindSpeed(t *testing.T) {
}
if tc.p != nil && tc.p.Value() != o.WindSpeed().Value() {
t.Errorf("ObservationLatestByStationID failed, expected windspeed "+
"float: %f, got: %f, %+v", tc.p.Value(), o.WindSpeed().Value(), o.Data.Windspeed)
"float: %f, got: %f, %+v", tc.p.Value(), o.WindSpeed().Value(), o.Data.WindSpeed)
}
if tc.p != nil && tc.p.dt.Unix() != o.WindSpeed().DateTime().Unix() {
t.Errorf("ObservationLatestByStationID failed, expected datetime: %s, got: %s",