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, | ||||
| 	} | ||||
| } | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user