Proxy support for AWN/Wunderground

This commit is contained in:
2025-01-12 15:30:37 -05:00
parent 849dbfb6ff
commit 7fc1fc9b56
9 changed files with 228 additions and 39 deletions

View File

@ -2,18 +2,27 @@ package awn
import (
"context"
"errors"
"net/http"
"net/url"
"time"
"github.com/go-resty/resty/v2"
"github.com/gorilla/schema"
"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/codes"
"gitea.libretechconsulting.com/rmcguire/go-app/pkg/otel"
"gitea.libretechconsulting.com/rmcguire/ambient-weather-local-exporter/pkg/weather"
)
type AWNProvider struct{}
const providerName = "awn"
const (
providerName = "awn"
awnURL = "http://ambientweather.net/data/report"
)
func (awn *AWNProvider) Name() string {
return providerName
@ -32,6 +41,74 @@ func (awn *AWNProvider) ReqToWeather(_ context.Context, r *http.Request) (
return MapAwnUpdate(awnUpdate), nil
}
// Attempts to proxy the weather station update to awn
// SAMPLE:
// {"PASSKEY":["ABF7E052BC7325A32300ACC89112AA91"],"baromabsin":["28.895"],
// "baromrelin":["29.876"],"battin":["1"],"battout":["1"],"battrain":["1"],
// "dailyrainin":["0.000"],"dateutc":["2025-01-11 22:07:57"],"eventrainin":["0.000"],
// "hourlyrainin":["0.000"],"humidity":["76"],"humidityin":["31"],"maxdailygust":["7.83"],
// "monthlyrainin":["0.000"],"solarradiation":["14.21"],"stationtype":["WeatherHub_V1.0.1"],
// "tempf":["29.48"],"tempinf":["66.20"],"totalrainin":["0.000"],"uv":["0"],
// "weeklyrainin":["0.000"],"winddir":["66"],"winddir_avg10m":["268"],"windgustmph":["2.68"],
// "windspeedmph":["0.00"],"yearlyrainin":["0.000"]}
func (awn *AWNProvider) ProxyReq(ctx context.Context, update *weather.WeatherUpdate) error {
tracer := otel.GetTracer(ctx, "awnProvider", "proxyReq")
ctx, span := tracer.Start(ctx, "proxyToAWN")
defer span.End()
if update.WeatherServiceCredentials["PASSKEY"] == "" {
err := errors.New("no PASSKEY set in update")
span.RecordError(err)
return err
}
params := updateToAWNParams(update)
resp, err := resty.New().R().
SetContext(ctx).
SetQueryParamsFromValues(*params).
Get(awnURL)
if err != nil {
span.RecordError(err)
span.SetStatus(codes.Error, err.Error())
}
span.SetAttributes(
attribute.Int("statusCode", resp.StatusCode()),
attribute.String("body", string(resp.Body())),
)
return err
}
func updateToAWNParams(update *weather.WeatherUpdate) *url.Values {
params := &url.Values{}
params.Set("PASSKEY", update.WeatherServiceCredentials["PASSKEY"])
params.Set("dateutc", time.Now().Format(time.DateTime))
weather.SetURLVal(params, "baromabsin", update.BaromAbsoluteIn)
weather.SetURLVal(params, "baromrelin", update.BaromRelativeIn)
weather.SetURLVal(params, "dailyrainin", update.DailyRainIn)
weather.SetURLVal(params, "weeklyrainin", update.WeeklyRainIn)
weather.SetURLVal(params, "eventrainin", update.EventRainIn)
weather.SetURLVal(params, "hourlyrainin", update.HourlyRainIn)
weather.SetURLVal(params, "monthlyrainin", update.MonthlyRainIn)
weather.SetURLVal(params, "yearlyrainin", update.YearlyRainIn)
weather.SetURLVal(params, "totalrainin", update.TotalRainIn)
weather.SetURLVal(params, "humidity", update.HumidityOudoor)
weather.SetURLVal(params, "humidityin", update.HumidityIndoor)
weather.SetURLVal(params, "solarradiation", update.SolarRadiation)
weather.SetURLVal(params, "uv", update.UV)
weather.SetURLVal(params, "stationtype", update.StationType)
weather.SetURLVal(params, "tempf", update.TempOutdoorF)
weather.SetURLVal(params, "tempinf", update.TempIndoorF)
weather.SetURLVal(params, "winddir", update.WindDir)
weather.SetURLVal(params, "winddir_avg10m", update.WindDirAvg10m)
weather.SetURLVal(params, "windgustmph", update.WindGustMPH)
weather.SetURLVal(params, "windspeedmph", update.WindSpeedMPH)
weather.SetURLVal(params, "maxdailygust", update.MaxDailyGust)
return params
}
func MapAwnUpdate(awnUpdate *AmbientWeatherUpdate) *weather.WeatherUpdate {
updateTime := time.Now()
if awnUpdate.DateUTC != nil {
@ -41,6 +118,11 @@ func MapAwnUpdate(awnUpdate *AmbientWeatherUpdate) *weather.WeatherUpdate {
}
}
credentials := make(map[string]string)
if awnUpdate.PassKey != nil {
credentials["PASSKEY"] = *awnUpdate.PassKey
}
return &weather.WeatherUpdate{
DateUTC: &updateTime,
StationID: awnUpdate.PassKey,
@ -79,10 +161,11 @@ func MapAwnUpdate(awnUpdate *AmbientWeatherUpdate) *weather.WeatherUpdate {
Status: awnUpdate.BattCO2,
},
},
TempIndoorF: awnUpdate.TempInF,
HumidityIndoor: awnUpdate.HumidityIn,
BaromRelativeIn: awnUpdate.BaromRelIn,
BaromAbsoluteIn: awnUpdate.BaromAbsIn,
TempIndoorF: awnUpdate.TempInF,
HumidityIndoor: awnUpdate.HumidityIn,
BaromRelativeIn: awnUpdate.BaromRelIn,
BaromAbsoluteIn: awnUpdate.BaromAbsIn,
WeatherServiceCredentials: credentials,
}
}