more logging
This commit is contained in:
@@ -4,6 +4,7 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
"time"
|
"time"
|
||||||
@@ -20,27 +21,27 @@ func (o *OpenMeteo) Fetch(ctxDone <-chan struct{}, site Site, model string) (*Fo
|
|||||||
o.Client = &http.Client{Timeout: 15 * time.Second}
|
o.Client = &http.Client{Timeout: 15 * time.Second}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Hourly fields that are useful for bias-correction / training
|
// Hourly fields supported by the ECMWF endpoint.
|
||||||
hourly := []string{
|
hourly := []string{
|
||||||
"temperature_2m",
|
"temperature_2m",
|
||||||
"relative_humidity_2m",
|
|
||||||
"pressure_msl",
|
"pressure_msl",
|
||||||
"wind_speed_10m",
|
"wind_speed_10m",
|
||||||
"wind_gusts_10m",
|
"wind_gusts_10m",
|
||||||
"wind_direction_10m",
|
"wind_direction_10m",
|
||||||
"precipitation",
|
"precipitation",
|
||||||
"precipitation_probability",
|
|
||||||
"cloud_cover",
|
"cloud_cover",
|
||||||
|
"relative_humidity_1000hPa",
|
||||||
}
|
}
|
||||||
|
|
||||||
u, _ := url.Parse("https://api.open-meteo.com/v1/forecast")
|
u, _ := url.Parse("https://api.open-meteo.com/v1/ecmwf")
|
||||||
q := u.Query()
|
q := u.Query()
|
||||||
q.Set("latitude", fmt.Sprintf("%.6f", site.Latitude))
|
q.Set("latitude", fmt.Sprintf("%.6f", site.Latitude))
|
||||||
q.Set("longitude", fmt.Sprintf("%.6f", site.Longitude))
|
q.Set("longitude", fmt.Sprintf("%.6f", site.Longitude))
|
||||||
q.Set("hourly", join(hourly))
|
q.Set("hourly", join(hourly))
|
||||||
q.Set("timezone", "UTC")
|
q.Set("timezone", "UTC")
|
||||||
q.Set("models", model) // e.g. "ecmwf"
|
q.Set("wind_speed_unit", "ms")
|
||||||
q.Set("forecast_days", "7") // keep it short; you can increase later
|
q.Set("temperature_unit", "celsius")
|
||||||
|
q.Set("precipitation_unit", "mm")
|
||||||
u.RawQuery = q.Encode()
|
u.RawQuery = q.Encode()
|
||||||
|
|
||||||
ctx, cancel := context.WithCancel(context.Background())
|
ctx, cancel := context.WithCancel(context.Background())
|
||||||
@@ -55,6 +56,17 @@ func (o *OpenMeteo) Fetch(ctxDone <-chan struct{}, site Site, model string) (*Fo
|
|||||||
defer resp.Body.Close()
|
defer resp.Body.Close()
|
||||||
|
|
||||||
if resp.StatusCode/100 != 2 {
|
if resp.StatusCode/100 != 2 {
|
||||||
|
body, _ := io.ReadAll(io.LimitReader(resp.Body, 4096))
|
||||||
|
var apiErr struct {
|
||||||
|
Error bool `json:"error"`
|
||||||
|
Reason string `json:"reason"`
|
||||||
|
}
|
||||||
|
if err := json.Unmarshal(body, &apiErr); err == nil && apiErr.Reason != "" {
|
||||||
|
return nil, fmt.Errorf("open-meteo HTTP %d: %s", resp.StatusCode, apiErr.Reason)
|
||||||
|
}
|
||||||
|
if len(body) > 0 {
|
||||||
|
return nil, fmt.Errorf("open-meteo HTTP %d: %s", resp.StatusCode, string(body))
|
||||||
|
}
|
||||||
return nil, fmt.Errorf("open-meteo HTTP %d", resp.StatusCode)
|
return nil, fmt.Errorf("open-meteo HTTP %d", resp.StatusCode)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -76,13 +88,18 @@ func (o *OpenMeteo) Fetch(ctxDone <-chan struct{}, site Site, model string) (*Fo
|
|||||||
|
|
||||||
// Helpers pull float arrays (may be absent)
|
// Helpers pull float arrays (may be absent)
|
||||||
temp := floatArray(hr["temperature_2m"])
|
temp := floatArray(hr["temperature_2m"])
|
||||||
rh := floatArray(hr["relative_humidity_2m"])
|
rh := floatArray(hr["relative_humidity_1000hPa"])
|
||||||
|
if rh == nil {
|
||||||
|
rh = floatArray(hr["relative_humidity_2m"])
|
||||||
|
}
|
||||||
msl := floatArray(hr["pressure_msl"])
|
msl := floatArray(hr["pressure_msl"])
|
||||||
|
if msl == nil {
|
||||||
|
msl = floatArray(hr["surface_pressure"])
|
||||||
|
}
|
||||||
ws := floatArray(hr["wind_speed_10m"])
|
ws := floatArray(hr["wind_speed_10m"])
|
||||||
gust := floatArray(hr["wind_gusts_10m"])
|
gust := floatArray(hr["wind_gusts_10m"])
|
||||||
wd := floatArray(hr["wind_direction_10m"])
|
wd := floatArray(hr["wind_direction_10m"])
|
||||||
precip := floatArray(hr["precipitation"])
|
precip := floatArray(hr["precipitation"])
|
||||||
pprob := floatArray(hr["precipitation_probability"])
|
|
||||||
cloud := floatArray(hr["cloud_cover"])
|
cloud := floatArray(hr["cloud_cover"])
|
||||||
|
|
||||||
points := make([]HourlyForecastPoint, 0, len(times))
|
points := make([]HourlyForecastPoint, 0, len(times))
|
||||||
@@ -96,7 +113,7 @@ func (o *OpenMeteo) Fetch(ctxDone <-chan struct{}, site Site, model string) (*Fo
|
|||||||
WindGustMS: idx(gust, i),
|
WindGustMS: idx(gust, i),
|
||||||
WindDirDeg: idx(wd, i),
|
WindDirDeg: idx(wd, i),
|
||||||
PrecipMM: idx(precip, i),
|
PrecipMM: idx(precip, i),
|
||||||
PrecipProb: idx(pprob, i),
|
PrecipProb: nil,
|
||||||
CloudCover: idx(cloud, i),
|
CloudCover: idx(cloud, i),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package providers
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
"strconv"
|
"strconv"
|
||||||
@@ -71,6 +72,18 @@ func (c *WundergroundClient) Upload(ctx context.Context, u WUUpload) (string, er
|
|||||||
// Optional: a software identifier
|
// Optional: a software identifier
|
||||||
q.Set("softwaretype", "go-weatherstation-go")
|
q.Set("softwaretype", "go-weatherstation-go")
|
||||||
|
|
||||||
|
// Log sanitized params so it's clear what we're sending.
|
||||||
|
safe := url.Values{}
|
||||||
|
for k, vals := range q {
|
||||||
|
if k == "PASSWORD" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
for _, v := range vals {
|
||||||
|
safe.Add(k, v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
log.Printf("wunderground upload params %s", safe.Encode())
|
||||||
|
|
||||||
reqURL := wuEndpoint + "?" + q.Encode()
|
reqURL := wuEndpoint + "?" + q.Encode()
|
||||||
req, err := http.NewRequestWithContext(ctx, http.MethodGet, reqURL, nil)
|
req, err := http.NewRequestWithContext(ctx, http.MethodGet, reqURL, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
Reference in New Issue
Block a user