package main // TODO: allow free-text lookups of place names, rather than ids // TODO: decode weather type number // TODO: split out met office specific stuff to separate module // TODO: add other weather providers import ( "encoding/json" "flag" "fmt" "io/ioutil" "log" "net/http" ) const defid = "310118" type Response struct { BestFcst struct { Forecast struct { Location struct { Days []Day `json:"Day"` } } } } type Day struct { Date string `json:"@date"` DayValues struct { WeatherParameters WeatherParams } NightValues struct { WeatherParameters WeatherParams } TimeSteps struct { TimeStep []struct { Time string `json:"@time"` WeatherParameters WeatherParams } } } type WeatherParams struct { AQIndex int // Air Quality F float64 // Feels Like Temperature H int // Humidity P int // Pressure PP int // Precipitation Probability UV int // Max UV Index T float64 // Temperature V int // Visibility WD string // Wind Direction WG float64 // Wind Gust WS float64 // Wind Speed WT int // Weather Type } func main() { var r Response var id string flag.Parse() if flag.NArg() > 0 { id = flag.Arg(0) } else { id = defid } client := &http.Client{Transport: &http.Transport{}} resp, err := client.Get("https://www.metoffice.gov.uk/public/data/PWSCache/BestForecast/Forecast/" + id + ".json?concise=true") if err != nil { log.Fatal(err) } defer resp.Body.Close() b, err := ioutil.ReadAll(resp.Body) err = json.Unmarshal(b, &r) if err != nil { log.Fatal(err) } for _, d := range r.BestFcst.Forecast.Location.Days { fmt.Printf("-----------------------------\n") fmt.Printf("%s\n", d.Date) prettyWeather("Day ", d.DayValues.WeatherParameters) prettyWeather("Night ", d.NightValues.WeatherParameters) for _, t := range d.TimeSteps.TimeStep { prettyWeather(t.Time, t.WeatherParameters) } } } func prettyWeather(t string, w WeatherParams) { fmt.Printf("%s Type: %2d, Temp: %4.1f°C, Rain: %2d%%, Wind: %2.1fm/s\n", t, w.WT, w.T, w.PP, w.WS) }