Refactor and complete providers
This commit is contained in:
81
pkg/ambient/ambient.go
Normal file
81
pkg/ambient/ambient.go
Normal file
@ -0,0 +1,81 @@
|
||||
// This provides a shim between HTTP GET requests sent
|
||||
// by ambient devices, and the providers that may be
|
||||
// configured (awn, wunderground)
|
||||
package ambient
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"gitea.libretechconsulting.com/rmcguire/go-app/pkg/otel"
|
||||
"github.com/rs/zerolog"
|
||||
"go.opentelemetry.io/otel/attribute"
|
||||
"go.opentelemetry.io/otel/codes"
|
||||
|
||||
"gitea.libretechconsulting.com/rmcguire/ambient-weather-local-exporter/pkg/provider"
|
||||
"gitea.libretechconsulting.com/rmcguire/ambient-weather-local-exporter/pkg/provider/awn"
|
||||
"gitea.libretechconsulting.com/rmcguire/ambient-weather-local-exporter/pkg/provider/wunderground"
|
||||
)
|
||||
|
||||
// These providers implement support for the update sent
|
||||
// when either "AmbientWeather" or "Wunderground" are selected
|
||||
// in the "Custom" section of the AWNet app, or the web UI
|
||||
// of an Ambient WeatherHub
|
||||
var (
|
||||
awnProvider = &awn.AWNProvider{}
|
||||
wuProvider = &wunderground.WUProvider{}
|
||||
)
|
||||
|
||||
func GetAWNHandlerFunc(appCtx context.Context) func(http.ResponseWriter, *http.Request) {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
handleProviderRequest(appCtx, awnProvider, w, r)
|
||||
}
|
||||
}
|
||||
|
||||
func GetWundergroundHandlerFunc(appCtx context.Context) func(http.ResponseWriter, *http.Request) {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
handleProviderRequest(appCtx, wuProvider, w, r)
|
||||
}
|
||||
}
|
||||
|
||||
// Takes an HTTP requests and convers it to a
|
||||
// stable type. Enrich is called on the type to complete
|
||||
// any missing fields as the two providers supported by Ambient
|
||||
// devices (awn/wunderground) produce different fields
|
||||
func handleProviderRequest(
|
||||
appCtx context.Context,
|
||||
p provider.AmbientProvider,
|
||||
w http.ResponseWriter,
|
||||
r *http.Request,
|
||||
) {
|
||||
l := zerolog.Ctx(appCtx)
|
||||
tracer := otel.GetTracer(appCtx, p.Name()+".http.handler")
|
||||
|
||||
ctx, span := tracer.Start(r.Context(), p.Name()+".update")
|
||||
span.SetAttributes(attribute.String("provider", p.Name()))
|
||||
defer span.End()
|
||||
|
||||
l.Trace().Str("p", p.Name()).
|
||||
Any("query", r.URL.Query()).Send()
|
||||
|
||||
// Convert to WeatherUpdate
|
||||
update, err := p.ReqToWeather(ctx, r)
|
||||
if err != nil {
|
||||
l.Err(err).Send()
|
||||
span.RecordError(err)
|
||||
span.SetStatus(codes.Error,
|
||||
fmt.Sprintf("failed to handle %s update: %s",
|
||||
p.Name(), err.Error()))
|
||||
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
w.Write([]byte(err.Error()))
|
||||
}
|
||||
|
||||
// Calculate any fields that may be missing
|
||||
// such as dew point and wind chill
|
||||
update.Enrich()
|
||||
|
||||
l.Trace().Any("update", update).Send()
|
||||
w.Write([]byte("ok"))
|
||||
}
|
@ -1,61 +0,0 @@
|
||||
package ambient
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io"
|
||||
"net/http"
|
||||
|
||||
"gitea.libretechconsulting.com/rmcguire/go-app/pkg/otel"
|
||||
"github.com/rs/zerolog"
|
||||
|
||||
"gitea.libretechconsulting.com/rmcguire/ambient-weather-local-exporter/pkg/awn"
|
||||
)
|
||||
|
||||
func GetAWNHandlerFunc(appCtx context.Context) func(http.ResponseWriter, *http.Request) {
|
||||
l := zerolog.Ctx(appCtx)
|
||||
tracer := otel.GetTracer(appCtx, "awn.http.handler")
|
||||
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
_, span := tracer.Start(r.Context(), "update")
|
||||
defer span.End()
|
||||
|
||||
bodyBytes, err := io.ReadAll(r.Body)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
}
|
||||
|
||||
l.Trace().Bytes("body", bodyBytes)
|
||||
l.Trace().Any("request", r.URL.Query()).Send()
|
||||
|
||||
update, err := awn.UnmarshalQueryParams(r.URL.Query())
|
||||
if err != nil {
|
||||
l.Err(err).Send()
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
w.Write([]byte(err.Error()))
|
||||
}
|
||||
|
||||
l.Trace().Any("update", update).Send()
|
||||
|
||||
w.Write([]byte("ok"))
|
||||
}
|
||||
}
|
||||
|
||||
func GetWundergroundHandlerFunc(appCtx context.Context) func(http.ResponseWriter, *http.Request) {
|
||||
l := zerolog.Ctx(appCtx)
|
||||
tracer := otel.GetTracer(appCtx, "wunderground.http.handler")
|
||||
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
_, span := tracer.Start(r.Context(), "update")
|
||||
defer span.End()
|
||||
|
||||
bodyBytes, err := io.ReadAll(r.Body)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
}
|
||||
|
||||
l.Trace().Bytes("body", bodyBytes)
|
||||
l.Trace().Any("request", r.URL.Query()).Send()
|
||||
|
||||
w.Write([]byte("ok"))
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user