// Package forecast defines normalized weather data consumed by report builders. package forecast import ( "encoding/json" "time" ) type Bundle struct { FetchedAt time.Time `json:"fetchedAt"` Observation *Observation `json:"observation,omitempty"` Current *Current `json:"current,omitempty"` Hourly *ForecastRun `json:"hourly,omitempty"` Narrative *ForecastRun `json:"narrative,omitempty"` Alerts *AlertRun `json:"alerts,omitempty"` Discussion *Discussion `json:"discussion,omitempty"` Daily *ForecastRun `json:"daily,omitempty"` WeatherStory *WeatherStory `json:"weatherStory,omitempty"` Sources []Source `json:"sources"` Warnings []SourceWarning `json:"warnings,omitempty"` } type Source struct { Name string `json:"name"` Endpoint string `json:"endpoint,omitempty"` Query map[string]string `json:"query,omitempty"` FetchedAt time.Time `json:"fetchedAt"` IssuedAt *time.Time `json:"issuedAt,omitempty"` UpdatedAt *time.Time `json:"updatedAt,omitempty"` DataSHA256 string `json:"dataSha256,omitempty"` Missing bool `json:"missing,omitempty"` Warnings []SourceWarning `json:"warnings,omitempty"` } type SourceWarning struct { Source string `json:"source"` Code string `json:"code"` Severity string `json:"severity"` Message string `json:"message"` Endpoint string `json:"endpoint,omitempty"` CompletenessImpact string `json:"completenessImpact,omitempty"` } type Observation struct { StationID string `json:"stationId,omitempty"` StationName string `json:"stationName,omitempty"` Timestamp time.Time `json:"timestamp"` ConditionCode *int `json:"conditionCode,omitempty"` IsDay *bool `json:"isDay,omitempty"` TextDescription string `json:"textDescription,omitempty"` TemperatureC *float64 `json:"temperatureC,omitempty"` TemperatureF *float64 `json:"temperatureF,omitempty"` DewpointC *float64 `json:"dewpointC,omitempty"` DewpointF *float64 `json:"dewpointF,omitempty"` WindSpeedKmh *float64 `json:"windSpeedKmh,omitempty"` WindSpeedMph *float64 `json:"windSpeedMph,omitempty"` WindGustKmh *float64 `json:"windGustKmh,omitempty"` WindGustMph *float64 `json:"windGustMph,omitempty"` WindDirectionDegrees *float64 `json:"windDirectionDegrees,omitempty"` BarometricPressurePa *float64 `json:"barometricPressurePa,omitempty"` BarometricPressureInHg *float64 `json:"barometricPressureInHg,omitempty"` VisibilityMeters *float64 `json:"visibilityMeters,omitempty"` VisibilityMiles *float64 `json:"visibilityMiles,omitempty"` RelativeHumidityPercent *float64 `json:"relativeHumidityPercent,omitempty"` ApparentTemperatureC *float64 `json:"apparentTemperatureC,omitempty"` ApparentTemperatureF *float64 `json:"apparentTemperatureF,omitempty"` PresentWeather []json.RawMessage `json:"presentWeather,omitempty"` } type Current struct { ConditionText string `json:"conditionText,omitempty"` IsDay *bool `json:"isDay,omitempty"` RelativeHumidityPercent *float64 `json:"relativeHumidityPercent,omitempty"` WindDirectionDegrees *float64 `json:"windDirectionDegrees,omitempty"` TemperatureC *float64 `json:"temperatureC,omitempty"` TemperatureF *float64 `json:"temperatureF,omitempty"` ApparentTemperatureC *float64 `json:"apparentTemperatureC,omitempty"` ApparentTemperatureF *float64 `json:"apparentTemperatureF,omitempty"` DewpointC *float64 `json:"dewpointC,omitempty"` DewpointF *float64 `json:"dewpointF,omitempty"` WindSpeedKmh *float64 `json:"windSpeedKmh,omitempty"` WindSpeedMph *float64 `json:"windSpeedMph,omitempty"` } type ForecastRun struct { LocationID string `json:"locationId,omitempty"` LocationName string `json:"locationName,omitempty"` IssuedAt time.Time `json:"issuedAt"` UpdatedAt *time.Time `json:"updatedAt,omitempty"` Product string `json:"product"` Latitude *float64 `json:"latitude,omitempty"` Longitude *float64 `json:"longitude,omitempty"` ElevationMeters *float64 `json:"elevationMeters,omitempty"` ElevationFeet *float64 `json:"elevationFeet,omitempty"` Periods []ForecastPeriod `json:"periods"` } type ForecastPeriod struct { StartTime time.Time `json:"startTime"` EndTime time.Time `json:"endTime"` Name string `json:"name,omitempty"` IsDay *bool `json:"isDay,omitempty"` ConditionCode *int `json:"conditionCode,omitempty"` TextDescription string `json:"textDescription,omitempty"` TemperatureC *float64 `json:"temperatureC,omitempty"` TemperatureF *float64 `json:"temperatureF,omitempty"` TemperatureCMin *float64 `json:"temperatureCMin,omitempty"` TemperatureFMin *float64 `json:"temperatureFMin,omitempty"` TemperatureCMax *float64 `json:"temperatureCMax,omitempty"` TemperatureFMax *float64 `json:"temperatureFMax,omitempty"` DewpointC *float64 `json:"dewpointC,omitempty"` DewpointF *float64 `json:"dewpointF,omitempty"` WindSpeedKmh *float64 `json:"windSpeedKmh,omitempty"` WindSpeedMph *float64 `json:"windSpeedMph,omitempty"` WindGustKmh *float64 `json:"windGustKmh,omitempty"` WindGustMph *float64 `json:"windGustMph,omitempty"` WindDirectionDegrees *float64 `json:"windDirectionDegrees,omitempty"` BarometricPressurePa *float64 `json:"barometricPressurePa,omitempty"` BarometricPressureInHg *float64 `json:"barometricPressureInHg,omitempty"` VisibilityMeters *float64 `json:"visibilityMeters,omitempty"` VisibilityMiles *float64 `json:"visibilityMiles,omitempty"` ApparentTemperatureC *float64 `json:"apparentTemperatureC,omitempty"` ApparentTemperatureF *float64 `json:"apparentTemperatureF,omitempty"` CloudCoverPercent *float64 `json:"cloudCoverPercent,omitempty"` ProbabilityOfPrecipitationPercent *float64 `json:"probabilityOfPrecipitationPercent,omitempty"` PrecipitationAmountMm *float64 `json:"precipitationAmountMm,omitempty"` PrecipitationAmountIn *float64 `json:"precipitationAmountIn,omitempty"` SnowfallDepthMM *float64 `json:"snowfallDepthMM,omitempty"` SnowfallDepthIn *float64 `json:"snowfallDepthIn,omitempty"` UVIndex *float64 `json:"uvIndex,omitempty"` RelativeHumidityPercent *float64 `json:"relativeHumidityPercent,omitempty"` } type AlertRun struct { AsOf *time.Time `json:"asOf,omitempty"` Alerts []json.RawMessage `json:"alerts,omitempty"` Raw json.RawMessage `json:"raw,omitempty"` } type Discussion struct { OfficeID string `json:"officeId,omitempty"` OfficeName string `json:"officeName,omitempty"` Product string `json:"product"` IssuedAt time.Time `json:"issuedAt"` UpdatedAt *time.Time `json:"updatedAt,omitempty"` KeyMessages []string `json:"keyMessages,omitempty"` ShortTerm *DiscussionSection `json:"shortTerm,omitempty"` LongTerm *DiscussionSection `json:"longTerm,omitempty"` } type DiscussionSection struct { Qualifier string `json:"qualifier,omitempty"` Text string `json:"text,omitempty"` IssuedAt *time.Time `json:"issuedAt,omitempty"` } type WeatherStory struct { IssuedAt *time.Time `json:"issuedAt,omitempty"` UpdatedAt *time.Time `json:"updatedAt,omitempty"` Raw json.RawMessage `json:"raw,omitempty"` }