66 lines
1.2 KiB
Go
66 lines
1.2 KiB
Go
|
package yr
|
||
|
|
||
|
import (
|
||
|
"cmp"
|
||
|
"fmt"
|
||
|
"slices"
|
||
|
|
||
|
"git.sr.ht/~timharek/yr-go/internal/met"
|
||
|
"git.sr.ht/~timharek/yr-go/internal/nominatim"
|
||
|
)
|
||
|
|
||
|
type Client struct {
|
||
|
met met.Met
|
||
|
nom nominatim.Nominatim
|
||
|
}
|
||
|
|
||
|
func New() (*Client, error) {
|
||
|
siteName := "git.sr.ht/~timharek/yr-go"
|
||
|
met, err := met.New(siteName)
|
||
|
if err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
nom, err := nominatim.New(siteName)
|
||
|
if err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
|
||
|
return &Client{met: *met, nom: *nom}, nil
|
||
|
}
|
||
|
|
||
|
type NowForecast struct {
|
||
|
Temperature float64
|
||
|
Percipitation float64
|
||
|
}
|
||
|
|
||
|
func (c *Client) Now(q string) (*NowForecast, error) {
|
||
|
coords, err := c.nom.Lookup(q)
|
||
|
if err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
|
||
|
f, err := c.met.Forecast(coords.Latitude, coords.Longitude, nil)
|
||
|
if err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
|
||
|
ts := f.Properties.Timeseries
|
||
|
|
||
|
if len(ts) == 0 {
|
||
|
return nil, fmt.Errorf("Forecast unavailable")
|
||
|
}
|
||
|
|
||
|
slices.SortFunc(ts, sortTimeSeries)
|
||
|
|
||
|
latest := ts[0].Data
|
||
|
|
||
|
return &NowForecast{
|
||
|
Temperature: latest.Instant.Details.AirTemperature,
|
||
|
Percipitation: latest.Next1_Hours.Details.PrecipitationAmount,
|
||
|
}, nil
|
||
|
}
|
||
|
|
||
|
func sortTimeSeries(a, b met.Timeseries) int {
|
||
|
return cmp.Compare(a.Time.Unix(), b.Time.Unix())
|
||
|
}
|