Proxy support for AWN/Wunderground
This commit is contained in:
@ -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,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -11,5 +11,6 @@ import (
|
||||
// Ambient Weather Network HTTP requests to a stable struct
|
||||
type AmbientProvider interface {
|
||||
ReqToWeather(context.Context, *http.Request) (*weather.WeatherUpdate, error)
|
||||
ProxyReq(context.Context, *weather.WeatherUpdate) error
|
||||
Name() string
|
||||
}
|
||||
|
@ -13,7 +13,10 @@ import (
|
||||
|
||||
type WUProvider struct{}
|
||||
|
||||
const providerName = "weatherunderground"
|
||||
const (
|
||||
providerName = "weatherunderground"
|
||||
wuURL = "http://rtupdate.wunderground.com/weatherstation/updateweatherstation.php"
|
||||
)
|
||||
|
||||
func (wu *WUProvider) Name() string {
|
||||
return providerName
|
||||
@ -32,6 +35,29 @@ func (wu *WUProvider) ReqToWeather(_ context.Context, r *http.Request) (
|
||||
return MapWUUpdate(wuUpdate), nil
|
||||
}
|
||||
|
||||
func (wu *WUProvider) ProxyReq(ctx context.Context, update *weather.WeatherUpdate) error {
|
||||
// tracer := otel.GetTracer(ctx, "wuProvider", "proxyReq")
|
||||
// ctx, span := tracer.Start(ctx, "proxyToWunderground")
|
||||
// defer span.End()
|
||||
//
|
||||
// resp, err := resty.New().R().
|
||||
// SetContext(ctx).
|
||||
// SetQueryParamsFromValues(r.URL.Query()).
|
||||
// Get(wuURL)
|
||||
// if err != nil {
|
||||
// span.SetStatus(codes.Error, err.Error())
|
||||
// span.RecordError(err)
|
||||
// }
|
||||
//
|
||||
// span.SetAttributes(
|
||||
// attribute.Int("statusCode", resp.StatusCode()),
|
||||
// attribute.String("body", string(resp.Body())),
|
||||
// )
|
||||
//
|
||||
// return err
|
||||
return nil
|
||||
}
|
||||
|
||||
func MapWUUpdate(wuUpdate *WundergroundUpdate) *weather.WeatherUpdate {
|
||||
updateTime := time.Now()
|
||||
|
||||
@ -42,25 +68,32 @@ func MapWUUpdate(wuUpdate *WundergroundUpdate) *weather.WeatherUpdate {
|
||||
}
|
||||
}
|
||||
|
||||
credentials := make(map[string]string)
|
||||
if wuUpdate.ID != nil && wuUpdate.Password != nil {
|
||||
credentials["ID"] = *wuUpdate.ID
|
||||
credentials["Password"] = *wuUpdate.Password
|
||||
}
|
||||
|
||||
return &weather.WeatherUpdate{
|
||||
DateUTC: &updateTime,
|
||||
StationID: wuUpdate.ID,
|
||||
StationType: wuUpdate.SoftwareType,
|
||||
TempOutdoorF: wuUpdate.Tempf,
|
||||
HumidityOudoor: wuUpdate.Humidity,
|
||||
WindSpeedMPH: wuUpdate.WindGustMPH,
|
||||
WindGustMPH: wuUpdate.WindGustMPH,
|
||||
WindDir: wuUpdate.WindDir,
|
||||
UV: wuUpdate.UV,
|
||||
SolarRadiation: wuUpdate.SolarRadiation,
|
||||
HourlyRainIn: wuUpdate.RainIn,
|
||||
DailyRainIn: wuUpdate.DailyRainIn,
|
||||
WeeklyRainIn: wuUpdate.WeeklyRainIn,
|
||||
MonthlyRainIn: wuUpdate.MonthlyRainIn,
|
||||
YearlyRainIn: wuUpdate.YearlyRainIn,
|
||||
TempIndoorF: wuUpdate.IndoorTempF,
|
||||
HumidityIndoor: wuUpdate.IndoorHumidity,
|
||||
BaromRelativeIn: wuUpdate.BaromIn,
|
||||
DateUTC: &updateTime,
|
||||
StationID: wuUpdate.ID,
|
||||
StationType: wuUpdate.SoftwareType,
|
||||
TempOutdoorF: wuUpdate.Tempf,
|
||||
HumidityOudoor: wuUpdate.Humidity,
|
||||
WindSpeedMPH: wuUpdate.WindGustMPH,
|
||||
WindGustMPH: wuUpdate.WindGustMPH,
|
||||
WindDir: wuUpdate.WindDir,
|
||||
UV: wuUpdate.UV,
|
||||
SolarRadiation: wuUpdate.SolarRadiation,
|
||||
HourlyRainIn: wuUpdate.RainIn,
|
||||
DailyRainIn: wuUpdate.DailyRainIn,
|
||||
WeeklyRainIn: wuUpdate.WeeklyRainIn,
|
||||
MonthlyRainIn: wuUpdate.MonthlyRainIn,
|
||||
YearlyRainIn: wuUpdate.YearlyRainIn,
|
||||
TempIndoorF: wuUpdate.IndoorTempF,
|
||||
HumidityIndoor: wuUpdate.IndoorHumidity,
|
||||
BaromRelativeIn: wuUpdate.BaromIn,
|
||||
WeatherServiceCredentials: credentials,
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user