package main import ( "context" "os" "os/signal" "gitea.libretechconsulting.com/rmcguire/go-app/pkg/app" grpcopts "gitea.libretechconsulting.com/rmcguire/go-app/pkg/srv/grpc/opts" httpopts "gitea.libretechconsulting.com/rmcguire/go-app/pkg/srv/http/opts" "golang.org/x/sys/unix" "k8s.io/utils/ptr" weatherpb "gitea.libretechconsulting.com/rmcguire/ambient-local-exporter/api/v1alpha1/weather" "gitea.libretechconsulting.com/rmcguire/ambient-local-exporter/pkg/ambient" "gitea.libretechconsulting.com/rmcguire/ambient-local-exporter/pkg/ambient/ambienthttp" "gitea.libretechconsulting.com/rmcguire/ambient-local-exporter/pkg/ambient/config" weathergrpc "gitea.libretechconsulting.com/rmcguire/ambient-local-exporter/pkg/weather/grpc" "gitea.libretechconsulting.com/rmcguire/ambient-local-exporter/pkg/weather/state" ) const ( defaultMetricPrefix = "weather" defaultUpdatesToKeep = 120 ) func main() { ctx, cncl := signal.NotifyContext(context.Background(), os.Kill, os.Interrupt, unix.SIGTERM) defer cncl() // Read config and environment, prepare an appCtx, and merge // go-app config into ambient weather exporter app config ctx, awConfig := app.MustLoadConfigInto(ctx, &config.AmbientLocalExporterConfig{ MetricPrefix: defaultMetricPrefix, WeatherStations: make([]config.WeatherStation, 0), }) // Prepare the ambient exporter with our prepared config // and set up logging, tracing, etc.. aw := ambient.New(ctx, awConfig).Init() // Load http and grpc routes, prepare the app awApp := prepareApp(ctx, aw) // Run app and wait awApp.MustRun() <-awApp.Done() } func prepareApp(ctx context.Context, aw *ambient.AmbientWeather) *app.App { // Config updates / defaults if aw.Config.UpdatesToKeep == nil || *aw.Config.UpdatesToKeep < 1 { aw.Config.UpdatesToKeep = ptr.To(defaultUpdatesToKeep) } // Load ambient routes into app awApp := &app.App{ AppContext: ctx, // HTTP Endpoints for Ambient Weather Stations HTTP: &httpopts.AppHTTP{ Funcs: []httpopts.HTTPFunc{ { Path: "/weatherstation/updateweatherstation.php", HandlerFunc: aw.GetWundergroundHandlerFunc(ctx), }, { Path: "/data/report", HandlerFunc: aw.GetAWNHandlerFunc(ctx), }, }, // HTTP Listener that fixes broken requests generated by // some versions of awn firmware CustomListener: ambienthttp.NewAWNMutatingListener(ctx, aw.Config.HTTP.Listen), // Necessary to fix certain bad AWN firmware // Health check funcs HealthChecks: []httpopts.HealthCheckFunc{ // TODO: Implement func(ctx context.Context) error { return nil }, }, }, // GRPC Service for retrieving weather GRPC: &grpcopts.AppGRPC{ Services: []*grpcopts.GRPCService{ { Name: "Weather Service", Type: &weatherpb.AmbientLocalWeatherService_ServiceDesc, Service: weathergrpc.NewGRPCWeather(ctx, state.NewWeatherState( &state.Opts{ Ctx: ctx, KeepLast: *aw.Config.UpdatesToKeep, })), }, }, }, } return awApp }