normalizers/openweather: extract shared helpers into common.go

Refactor OpenWeather normalizers to improve structure and reuse by moving
provider-specific helper functions out of observation.go and into a new
common.go.

This keeps observation.go focused on schema matching and domain mapping,
preserves the “one normalizer per file” convention, and establishes a clear
home for helpers that will be shared by future OpenWeather forecast and alert
normalizers.

No functional behavior changes; this is a pure internal refactor.
This commit is contained in:
2026-01-15 10:41:56 -06:00
parent 8968b6bdcd
commit 84c4efbc2e
2 changed files with 71 additions and 49 deletions

View File

@@ -3,7 +3,6 @@ package openweather
import (
"context"
"fmt"
"strings"
"time"
@@ -132,51 +131,3 @@ func buildObservation(parsed owmResponse) (model.WeatherObservation, time.Time,
return obs, ts, nil
}
func primaryCondition(list []owmWeather) (id int, desc string, icon string) {
if len(list) == 0 {
return 0, "", ""
}
w := list[0]
return w.ID, strings.TrimSpace(w.Description), strings.TrimSpace(w.Icon)
}
func inferIsDay(icon string, dt, sunrise, sunset int64) *bool {
// Prefer icon suffix.
icon = strings.TrimSpace(icon)
if icon != "" {
last := icon[len(icon)-1]
switch last {
case 'd':
v := true
return &v
case 'n':
v := false
return &v
}
}
// Fall back to sunrise/sunset bounds if provided.
if dt > 0 && sunrise > 0 && sunset > 0 {
v := dt >= sunrise && dt < sunset
return &v
}
return nil
}
func openWeatherIconURL(icon string) string {
icon = strings.TrimSpace(icon)
if icon == "" {
return ""
}
return fmt.Sprintf("https://openweathermap.org/img/wn/%s@2x.png", icon)
}
func openWeatherStationID(parsed owmResponse) string {
if parsed.ID != 0 {
return fmt.Sprintf("OPENWEATHER(%d)", parsed.ID)
}
// Fallback: synthesize from coordinates.
return fmt.Sprintf("OPENWEATHER(%.5f,%.5f)", parsed.Coord.Lat, parsed.Coord.Lon)
}