// Copyright © 2022 siddharth ravikumar // SPDX-License-Identifier: ISC package weather import ( "fmt" "strings" "time" "ricketyspace.net/peach/nws" "ricketyspace.net/peach/version" ) type Weather struct { Title string Version string Location string Now WeatherNow Q2HTimeline WeatherTimeline // Q2H forecast of the next 12 hours. BiDailyTimeline WeatherTimeline // BiDaily forecast for the next 3 days. } type WeatherNow struct { Temperature int TemperatureUnit string Forecast string WindSpeed string WindDirection string } type WeatherPeriod struct { Name string Forecast string Hour int Temperature int TemperatureUnit string } type WeatherTimeline struct { Periods []WeatherPeriod } func NewWeather(lat, lng float32) (*Weather, error, int) { fBundle, nwsErr := nws.GetForecastBundle(lat, lng) if nwsErr != nil { return nil, nwsErr, nwsErr.Status } w := new(Weather) w.Location = fmt.Sprintf("%s, %s", strings.ToLower(fBundle.Point.Properties.RelativeLocation.Properties.City), strings.ToLower(fBundle.Point.Properties.RelativeLocation.Properties.State), ) w.Title = w.Location w.Version = version.Version w.Now = WeatherNow{ Temperature: fBundle.ForecastHourly.Properties.Periods[0].Temperature, TemperatureUnit: fBundle.ForecastHourly.Properties.Periods[0].TemperatureUnit, Forecast: fBundle.ForecastHourly.Properties.Periods[0].ShortForecast, WindSpeed: fBundle.ForecastHourly.Properties.Periods[0].WindSpeed, WindDirection: fBundle.ForecastHourly.Properties.Periods[0].WindDirection, } // Build Q2H timeline for the 12 hours. q2hPeriods := []WeatherPeriod{} max := 6 for i, period := range fBundle.ForecastHourly.Properties.Periods { if i%2 != 0 { continue // Take every other period } t, err := time.Parse(time.RFC3339, period.StartTime) if err != nil { return nil, err, 500 } p := WeatherPeriod{ Forecast: period.DetailedForecast, Hour: t.Hour(), Temperature: period.Temperature, TemperatureUnit: period.TemperatureUnit, } q2hPeriods = append(q2hPeriods, p) if len(q2hPeriods) == max { break } } w.Q2HTimeline = WeatherTimeline{ Periods: q2hPeriods, } // Build BiDaily timeline for the next 3 days. bdPeriods := []WeatherPeriod{} max = 8 for _, period := range fBundle.Forecast.Properties.Periods { p := WeatherPeriod{ Name: period.Name, Forecast: period.DetailedForecast, Temperature: period.Temperature, TemperatureUnit: period.TemperatureUnit, } bdPeriods = append(bdPeriods, p) if len(bdPeriods) == max { break } } w.BiDailyTimeline = WeatherTimeline{ Periods: bdPeriods, } return w, nil, 200 }