Commit Graph

26 Commits

Author SHA1 Message Date
c12cf91115 normalizers: implemented openmeteo forecast normalizer. 2026-01-17 10:16:50 -06:00
b47f1b2051 sources: added an OpenMeteo forecast source. 2026-01-17 08:00:23 -06:00
b8804d32d2 refactor(normalizers): deduplicate synthetic station ID generation
- Add common SynthStationID helpers for coordinate-based providers
- Use shared helper for Open-Meteo and OpenWeather station ID synthesis
- Require both lat/lon when generating synthetic IDs to avoid misleading defaults
- Remove unused Open-Meteo normalizer wrapper code

This reduces cross-provider duplication while keeping provider-specific
mapping logic explicit and readable.
2026-01-16 22:13:44 -06:00
00e811f8f7 normalizers/nws: add NWS alerts normalizer and canonical alert mapping
- Introduce AlertsNormalizer to convert Raw NWS Alerts (SchemaRawNWSAlertsV1)
  into canonical WeatherAlert runs (SchemaWeatherAlertV1)
- Add minimal NWS alerts response/types to support GeoJSON FeatureCollection parsing
- Map NWS alert properties (event, headline, severity, timing, area, references)
  into model.WeatherAlert with best-effort timestamp handling
- Establish clear AsOf / EffectiveAt policy for alert runs to support stable
  deduplication and snapshot semantics
- Register the new alerts normalizer alongside existing NWS observation and
  forecast normalizers
2026-01-16 21:40:20 -06:00
2eb2d4b90f feat(nws, normalizers): add NWS hourly forecast normalization and enforce canonical float rounding
- Implement full NWS hourly forecast normalizer (raw.nws.hourly.forecast.v1 → weather.forecast.v1)
- Add GeoJSON forecast types and helpers for NWS gridpoint hourly payloads
- Normalize temperatures, winds, humidity, PoP, and infer WMO condition codes from forecast text/icons
- Treat forecast IssuedAt as EffectiveAt for stable, dedupe-friendly event IDs

- Introduce project-wide float rounding at normalization finalization
  - Round all float values in canonical payloads to 2 decimal places
  - Apply consistently across pointers, slices, maps, and nested structs
  - Preserve opaque structs (e.g., time.Time) unchanged

- Add SchemaRawNWSHourlyForecastV1 and align schema matching/comments
- Clean up NWS helper organization and comments
- Update documentation to reflect numeric wire-format and normalization policies

This establishes a complete, deterministic hourly forecast pipeline for NWS
and improves JSON output stability across all canonical weather schemas.
2026-01-16 10:28:32 -06:00
0fcc536885 Updates in preparation for adding forecast sources. 2026-01-16 00:04:37 -06:00
e10ba804ca model: add explicit JSON tags and document canonical payload contract
Add lowerCamelCase JSON tags to canonical model types (observation, forecast,
alert) to stabilize the emitted wire format and make payload structure explicit
for downstream sinks.

Introduce internal/model/doc.go to document these structs as versioned,
schema-governed payloads and clarify compatibility expectations (additive
changes preferred; breaking changes require schema bumps).

No functional behavior changes; this formalizes the canonical output contract
ahead of additional sinks and consumers.
2026-01-15 22:39:37 -06:00
f13f43cf56 refactor(providers): centralize provider-specific parsing and invariants
- Introduce internal/providers/nws with shared timestamp parsing used by both
  NWS sources and normalizers
- Migrate NWS observation source + normalizer to use the shared provider helper
  for consistent RFC3339/RFC3339Nano handling
- Introduce internal/providers/openweather with a shared URL invariant helper
  enforcing units=metric
- Remove duplicated OpenWeather URL validation logic from the observation source
- Align provider layering: move provider “contract/quirk” logic out of
  normalizers and into internal/providers
- Update normalizer and standards documentation to clearly distinguish:
  provider helpers (internal/providers) vs canonical mapping logic
  (internal/normalizers)

This refactor reduces duplication between sources and normalizers, clarifies
layering boundaries, and establishes a scalable pattern for future forecast
and alert implementations.
2026-01-15 20:40:53 -06:00
a341aee5df normalizers: Updated error handling within the JSON helper function. 2026-01-15 20:17:46 -06:00
d8db58c004 sources: standardize Event.ID on Source:EffectiveAt; simplify raw event helper
- Adopt an opinionated Event.ID policy across sources:
  - use upstream-provided ID when available
  - otherwise derive a stable ID from Source:EffectiveAt (RFC3339Nano, UTC)
  - fall back to Source:EmittedAt when EffectiveAt is unavailable
- Add common/id helper to centralize ID selection logic and keep sources consistent
- Simplify common event construction by collapsing SingleRawEventAt/SingleRawEvent
  into a single explicit SingleRawEvent helper (emittedAt passed in)
- Update NWS/Open-Meteo/OpenWeather observation sources to:
  - compute EffectiveAt first
  - generate IDs via the shared helper
  - build envelopes via the unified SingleRawEvent helper
- Improve determinism and dedupe-friendliness without changing schemas or payloads
2026-01-15 19:38:15 -06:00
d9474b5a5b v0.x: add reusable HTTP source spine; fix routing; upstream HTTP transport helper
- fix dispatch route compilation so empty Kinds matches all (nil), not none
- introduce internal/sources/common/HTTPSource to centralize HTTP polling boilerplate:
  - standard cfg parsing (url + user_agent)
  - default HTTP client + Accept/User-Agent headers
  - consistent error wrapping
- refactor observation sources (nws/openmeteo/openweather) to use HTTPSource
- upstream generic HTTP fetch/limits/timeout helper from weatherfeeder to feedkit:
  - move internal/sources/common/http.go -> feedkit/transport/http.go
  - keep behavior: status checks, max-body limit, default timeout
2026-01-15 19:11:58 -06:00
1790218d38 Updated documentation for internal consistency. v0.4.0 2026-01-15 10:47:59 -06:00
84c4efbc2e 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.
2026-01-15 10:41:56 -06:00
8968b6bdcd Refactor normalizers: dedupe JSON decode + event finalize
Add shared normalizer helpers to centralize payload extraction, JSON decoding,
and event finalization/validation.

Refactor NWS, Open-Meteo, and OpenWeather observation normalizers to use the
shared spine, removing repeated boilerplate while preserving provider-specific
mapping logic.
2026-01-15 10:36:18 -06:00
e92577c30e Moved shared OpenMeteo time parsing code into a shared internal/providers/openmeteo library. 2026-01-15 10:17:56 -06:00
675c5a6117 Removed model.Event and model.Kind from weatherfeeder, since these are imported from feedkit upstream. 2026-01-15 09:56:18 -06:00
59111a1c82 sources: standardize HTTP source config + factor raw-event boilerplate
- Require params.user_agent for all HTTP sources (uniform config across providers)
- Add common.RequireHTTPSourceConfig() to validate name/url/user_agent in one call
- Add common.NewHTTPClient() with DefaultHTTPTimeout for consistent client setup
- Add common.SingleRawEvent() to centralize event envelope construction + validation
- Refactor NWS/Open-Meteo/OpenWeather observation sources to use new helpers
2026-01-15 09:43:22 -06:00
e28ff49201 Moved common HTTP body fetch code into a shared helper function. 2026-01-15 08:58:56 -06:00
b21ed856e9 Fixed an ordering bug in wmo_text.go. 2026-01-15 08:14:20 -06:00
f43babdfd2 openmeteo: refactored the OpenMeteo source files to relocate normalization logic to internal/normalizers. 2026-01-14 12:10:32 -06:00
1f8ba05e19 Removed redundant event.go (we use feedkit's upstream implementation). 2026-01-14 12:00:48 -06:00
759fa31762 openweather: refactored the OpenWeather source files to relocate normalization logic to internal/normalizers. 2026-01-14 11:59:17 -06:00
0ba2602bcc nws: refactored the NWS source files to relocate normalization logic to internal/normalizers. 2026-01-14 11:18:21 -06:00
efc44e8c6a normalizers: added a structure for normalizers; refactoring sources -> sources+normalizers is still todo. 2026-01-14 10:35:16 -06:00
aa4774e0dd weatherfeeder: split the former maximumdirect.net/weatherd project in two.
feedkit now contains a reusable core, while weatherfeeder is a concrete implementation that includes weather-specific functions.
2026-01-13 18:14:21 -06:00
1e05b38347 Initial commit 2026-01-14 00:12:51 +00:00