Preserve metric forecast units and overnight alerts

This commit is contained in:
2026-08-13 00:45:08 +00:00
parent 8fafacf921
commit 8e49ba88c7
5 changed files with 230 additions and 45 deletions

View File

@@ -211,7 +211,7 @@ func BuildDailySummary(bundle *weatherdata.Bundle, date time.Time, location *tim
for _, window := range windows {
periods := SelectHourlyPeriods(bundle.Hourly, window.Period)
daypartSummary := SummarizeDaypart(window.Name, window.Period, periods)
daypartSummary.AlertOverlaps = overlapsWithin(alerts, window.Period)
daypartSummary.AlertOverlaps = AlertOverlaps(bundle.Alerts, window.Period)
summary.Dayparts = append(summary.Dayparts, daypartSummary)
}
return summary, nil
@@ -258,10 +258,10 @@ func SummarizeDaypart(name string, period timeutil.Period, periods []weatherdata
for _, forecastPeriod := range periods {
addRangeValue(&summary.Temperature, periodTemperatureValues(forecastPeriod)...)
addRangeValue(&summary.ApparentTemperature, valueFromPointers(forecastPeriod.ApparentTemperatureF, forecastPeriod.ApparentTemperatureC)...)
addRangeValue(&summary.ApparentTemperature, temperatureF(forecastPeriod.ApparentTemperatureF, forecastPeriod.ApparentTemperatureC))
setMaxTimedValue(&summary.MaxPrecipitationProbability, forecastPeriod.ProbabilityOfPrecipitationPercent, forecastPeriod.StartTime)
setMaxTimedValue(&summary.PeakWindSpeed, firstValue(forecastPeriod.WindSpeedMph, forecastPeriod.WindSpeedKmh), forecastPeriod.StartTime)
setMaxTimedValue(&summary.PeakWindGust, firstValue(forecastPeriod.WindGustMph, forecastPeriod.WindGustKmh), forecastPeriod.StartTime)
setMaxTimedValue(&summary.PeakWindSpeed, milesPerHour(forecastPeriod.WindSpeedMph, forecastPeriod.WindSpeedKmh), forecastPeriod.StartTime)
setMaxTimedValue(&summary.PeakWindGust, milesPerHour(forecastPeriod.WindGustMph, forecastPeriod.WindGustKmh), forecastPeriod.StartTime)
text := strings.TrimSpace(forecastPeriod.TextDescription)
if text != "" {
@@ -278,29 +278,33 @@ func SummarizeDaypart(name string, period timeutil.Period, periods []weatherdata
}
func periodTemperatureValues(period weatherdata.ForecastPeriod) []*float64 {
values := []*float64{}
values = append(values, valueFromPointers(period.TemperatureF, period.TemperatureC)...)
values = append(values, valueFromPointers(period.TemperatureFMin, period.TemperatureCMin)...)
values = append(values, valueFromPointers(period.TemperatureFMax, period.TemperatureCMax)...)
return values
return []*float64{
temperatureF(period.TemperatureF, period.TemperatureC),
temperatureF(period.TemperatureFMin, period.TemperatureCMin),
temperatureF(period.TemperatureFMax, period.TemperatureCMax),
}
}
func valueFromPointers(values ...*float64) []*float64 {
for _, value := range values {
if value != nil {
return []*float64{value}
}
func temperatureF(fahrenheit *float64, celsius *float64) *float64 {
if fahrenheit != nil {
return fahrenheit
}
return nil
if celsius == nil {
return nil
}
converted := *celsius*9/5 + 32
return &converted
}
func firstValue(values ...*float64) *float64 {
for _, value := range values {
if value != nil {
return value
}
func milesPerHour(mph *float64, kmh *float64) *float64 {
if mph != nil {
return mph
}
return nil
if kmh == nil {
return nil
}
converted := *kmh / 1.609344
return &converted
}
func addRangeValue(target *Range, values ...*float64) {
@@ -364,15 +368,13 @@ func mentionsThunder(text string) bool {
}
func numericIndicators(period weatherdata.ForecastPeriod) Indicators {
windGust := firstValue(period.WindGustMph, period.WindGustKmh)
windSpeed := firstValue(period.WindSpeedMph, period.WindSpeedKmh)
windGust := milesPerHour(period.WindGustMph, period.WindGustKmh)
windSpeed := milesPerHour(period.WindSpeedMph, period.WindSpeedKmh)
temperature := temperatureF(period.TemperatureF, period.TemperatureC)
indicators := Indicators{}
if period.TemperatureF != nil {
indicators.Heat = *period.TemperatureF >= 95
indicators.Cold = *period.TemperatureF <= 32
} else if period.TemperatureC != nil {
indicators.Heat = *period.TemperatureC >= 35
indicators.Cold = *period.TemperatureC <= 0
if temperature != nil {
indicators.Heat = *temperature >= 95
indicators.Cold = *temperature <= 32
}
if windGust != nil && *windGust >= 35 || windSpeed != nil && *windSpeed >= 25 {
indicators.Wind = true
@@ -501,14 +503,3 @@ func intersect(left timeutil.Period, right timeutil.Period) timeutil.Period {
}
return timeutil.Period{Start: start, End: end}
}
func overlapsWithin(alerts []AlertOverlap, period timeutil.Period) []AlertOverlap {
var out []AlertOverlap
for _, alert := range alerts {
if alert.Period.Overlaps(period) {
alert.Overlap = intersect(alert.Period, period)
out = append(out, alert)
}
}
return out
}