package awn import ( "context" "errors" "net/url" "time" "gitea.libretechconsulting.com/rmcguire/go-app/pkg/otel" "github.com/go-resty/resty/v2" "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/codes" "gitea.libretechconsulting.com/rmcguire/ambient-weather-local-exporter/pkg/weather" ) // 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.StationConfig.AWNPassKey == "" { 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("dateutc", time.Now().Format(time.DateTime)) weather.SetURLVal(params, "PASSKEY", &update.StationConfig.AWNPassKey) 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) // Batteries for _, status := range update.Batteries { switch status.Component { case BattOutdoorSensor: weather.SetURLVal(params, "battin", status.Status) case BattIndoorSensor: weather.SetURLVal(params, "battout", status.Status) case BattRainSensor: weather.SetURLVal(params, "battrain", status.Status) case BattCO2Sensor: weather.SetURLVal(params, "batt_co2", status.Status) } } return params }