From 46a213f3147788ebbc2299fe4f2be8d1d9580abd Mon Sep 17 00:00:00 2001 From: Ryan McGuire Date: Sat, 22 Mar 2025 14:04:20 -0400 Subject: [PATCH] support json schema --- Makefile | 3 + app.go | 61 +++++++ contrib/schema.json | 220 ++++++++++++++++++++++++++ go.mod | 18 ++- go.sum | 19 +++ main.go | 66 +++----- pkg/ambient/ambient.go | 16 +- pkg/ambient/config/config.go | 28 ++-- pkg/ambient/config/config_recorder.go | 20 +-- 9 files changed, 366 insertions(+), 85 deletions(-) create mode 100644 app.go create mode 100644 contrib/schema.json diff --git a/Makefile b/Makefile index f9545a4..cfac361 100644 --- a/Makefile +++ b/Makefile @@ -33,6 +33,9 @@ build: test done go build -ldflags "-X $(VER_PKG)=$(VERSION)" -o bin/${CMD_NAME} +schema: + go run . -schema > contrib/schema.json + docker: @echo "Building Docker image $(DOCKER_IMG):$(VERSION)" docker build \ diff --git a/app.go b/app.go new file mode 100644 index 0000000..4677f5b --- /dev/null +++ b/app.go @@ -0,0 +1,61 @@ +package main + +import ( + "context" + + "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" + + 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" + weathergrpc "gitea.libretechconsulting.com/rmcguire/ambient-local-exporter/pkg/weather/grpc" +) + +func prepareApp(ctx context.Context, aw *ambient.AmbientWeather) *app.App { + // 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, aw.GetRecorder()), + }, + }, + }, + } + + return awApp +} diff --git a/contrib/schema.json b/contrib/schema.json new file mode 100644 index 0000000..eb2a7e6 --- /dev/null +++ b/contrib/schema.json @@ -0,0 +1,220 @@ +{ + "definitions": { + "ConfigGRPCConfig": { + "properties": { + "enableInstrumentation": { + "type": "boolean" + }, + "enableReflection": { + "type": "boolean" + }, + "enabled": { + "type": "boolean" + }, + "listen": { + "type": "string" + }, + "logRequests": { + "type": "boolean" + } + }, + "type": "object" + }, + "ConfigHTTPConfig": { + "properties": { + "enabled": { + "type": "boolean" + }, + "idleTimeout": { + "type": "string" + }, + "listen": { + "type": "string" + }, + "logRequests": { + "type": "boolean" + }, + "readTimeout": { + "type": "string" + }, + "writeTimeout": { + "type": "string" + } + }, + "type": "object" + }, + "ConfigLogConfig": { + "properties": { + "enabled": { + "type": "boolean" + }, + "format": { + "type": "string" + }, + "level": { + "type": "string" + }, + "output": { + "type": "string" + }, + "timeFormat": { + "type": "string" + } + }, + "type": "object" + }, + "ConfigOTELConfig": { + "properties": { + "enabled": { + "type": "boolean" + }, + "metricIntervalSecs": { + "type": "integer" + }, + "prometheusEnabled": { + "type": "boolean" + }, + "prometheusPath": { + "type": "string" + }, + "stdoutEnabled": { + "type": "boolean" + } + }, + "type": "object" + }, + "ConfigRecorderConfig": { + "properties": { + "keepLast": { + "type": "integer" + }, + "redisConfig": { + "$ref": "#/definitions/ConfigRedisConfig" + }, + "type": { + "type": "string" + } + }, + "type": "object" + }, + "ConfigRedisConfig": { + "properties": { + "redisDB": { + "default": 0, + "type": "integer" + }, + "redisHost": { + "default": "127.0.0.1", + "type": "string" + }, + "redisPassword": { + "type": "string" + }, + "redisPort": { + "default": 6379, + "type": "integer" + }, + "redisTLS": { + "default": false, + "type": "boolean" + }, + "redisTLSInsecure": { + "default": false, + "type": "boolean" + }, + "redisUser": { + "type": "string" + } + }, + "type": "object" + }, + "ConfigWeatherStation": { + "properties": { + "awnPassKey": { + "type": "string" + }, + "dropMetrics": { + "items": { + "type": "string" + }, + "type": "array" + }, + "equipment": { + "type": "string" + }, + "keepMetrics": { + "items": { + "type": "string" + }, + "type": "array" + }, + "name": { + "type": "string" + }, + "proxyToAWN": { + "type": "boolean" + }, + "proxyToWunderground": { + "type": "boolean" + }, + "sensorMappings": { + "additionalProperties": { + "type": "string" + }, + "type": "object" + }, + "wundergroundID": { + "type": "string" + }, + "wundergroundPassword": { + "type": "string" + } + }, + "type": "object" + } + }, + "properties": { + "environment": { + "type": "string" + }, + "grpc": { + "$ref": "#/definitions/ConfigGRPCConfig" + }, + "http": { + "$ref": "#/definitions/ConfigHTTPConfig" + }, + "logging": { + "$ref": "#/definitions/ConfigLogConfig" + }, + "metricPrefix": { + "default": "weather", + "type": "string" + }, + "name": { + "type": "string" + }, + "otel": { + "$ref": "#/definitions/ConfigOTELConfig" + }, + "recorderConfig": { + "$ref": "#/definitions/ConfigRecorderConfig" + }, + "updatesToKeep": { + "default": 1, + "type": [ + "null", + "integer" + ] + }, + "version": { + "type": "string" + }, + "weatherStations": { + "items": { + "$ref": "#/definitions/ConfigWeatherStation" + }, + "type": "array" + } + }, + "type": "object" +} diff --git a/go.mod b/go.mod index f2fd345..e537fce 100644 --- a/go.mod +++ b/go.mod @@ -3,17 +3,18 @@ module gitea.libretechconsulting.com/rmcguire/ambient-local-exporter go 1.23.4 require ( - gitea.libretechconsulting.com/rmcguire/go-app v0.6.3 + gitea.libretechconsulting.com/rmcguire/go-app v0.7.0 github.com/go-resty/resty/v2 v2.16.5 github.com/gorilla/schema v1.4.1 - github.com/rs/zerolog v1.33.0 + github.com/redis/go-redis/v9 v9.7.3 + github.com/rs/zerolog v1.34.0 go.opentelemetry.io/otel v1.35.0 go.opentelemetry.io/otel/metric v1.35.0 go.opentelemetry.io/otel/trace v1.35.0 golang.org/x/sys v0.31.0 google.golang.org/grpc v1.71.0 google.golang.org/protobuf v1.36.5 - k8s.io/utils v0.0.0-20241210054802-24370beab758 + k8s.io/utils v0.0.0-20250321185631-1f6e0b77f77e ) require ( @@ -34,9 +35,10 @@ require ( github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/prometheus/client_golang v1.21.1 // indirect github.com/prometheus/client_model v0.6.1 // indirect - github.com/prometheus/common v0.62.0 // indirect - github.com/prometheus/procfs v0.15.1 // indirect - github.com/redis/go-redis/v9 v9.7.3 // indirect + github.com/prometheus/common v0.63.0 // indirect + github.com/prometheus/procfs v0.16.0 // indirect + github.com/swaggest/jsonschema-go v0.3.73 // indirect + github.com/swaggest/refl v1.3.1 // indirect go.opentelemetry.io/auto/sdk v1.1.0 // indirect go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.60.0 // indirect go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.60.0 // indirect @@ -51,7 +53,7 @@ require ( go.opentelemetry.io/proto/otlp v1.5.0 // indirect golang.org/x/net v0.37.0 // indirect golang.org/x/text v0.23.0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20250303144028-a0af3efb3deb // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20250303144028-a0af3efb3deb // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20250313205543-e70fdf4c4cb4 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20250313205543-e70fdf4c4cb4 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index 408872d..991e973 100644 --- a/go.sum +++ b/go.sum @@ -4,6 +4,8 @@ gitea.libretechconsulting.com/rmcguire/go-app v0.6.2 h1:vpEdZu7WI8qIil5NLf6OUF/T gitea.libretechconsulting.com/rmcguire/go-app v0.6.2/go.mod h1:S3/vdMEiRWWIdD0Fr+tjJc627VzxNzO4Ia2HgTBXe+g= gitea.libretechconsulting.com/rmcguire/go-app v0.6.3 h1:dXYHJxK/1vmWBj1wqbqEUncFt3O92agy9gNWoa9NpA0= gitea.libretechconsulting.com/rmcguire/go-app v0.6.3/go.mod h1:S3/vdMEiRWWIdD0Fr+tjJc627VzxNzO4Ia2HgTBXe+g= +gitea.libretechconsulting.com/rmcguire/go-app v0.7.0 h1:yhRRwV/dxN4Bey1Qv8/rHHV5QvALrZuDJFI+zFPc7sU= +gitea.libretechconsulting.com/rmcguire/go-app v0.7.0/go.mod h1:EM3Z9QcRD+b7UlKGA9y37ppfUBC0Reyf5sYEC6vFZcY= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/caarlos0/env/v11 v11.3.1 h1:cArPWC15hWmEt+gWk7YBi7lEXTXCvpaSdCiZE2X5mCA= @@ -65,17 +67,28 @@ github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= github.com/prometheus/common v0.62.0 h1:xasJaQlnWAeyHdUBeGjXmutelfJHWMRr+Fg4QszZ2Io= github.com/prometheus/common v0.62.0/go.mod h1:vyBcEuLSvWos9B1+CyL7JZ2up+uFzXhkqml0W5zIY1I= +github.com/prometheus/common v0.63.0 h1:YR/EIY1o3mEFP/kZCD7iDMnLPlGyuU2Gb3HIcXnA98k= +github.com/prometheus/common v0.63.0/go.mod h1:VVFF/fBIoToEnWRVkYoXEkq3R3paCoxG9PXP74SnV18= github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc= github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk= +github.com/prometheus/procfs v0.16.0 h1:xh6oHhKwnOJKMYiYBDWmkHqQPyiY40sny36Cmx2bbsM= +github.com/prometheus/procfs v0.16.0/go.mod h1:8veyXUu3nGP7oaCxhX6yeaM5u4stL2FeMXnCqhDthZg= github.com/redis/go-redis/v9 v9.7.3 h1:YpPyAayJV+XErNsatSElgRZZVCwXX9QzkKYNvO7x0wM= github.com/redis/go-redis/v9 v9.7.3/go.mod h1:bGUrSggJ9X9GUmZpZNEOQKaANxSGgOEBRltRTZHSvrA= github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII= github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o= github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= +github.com/rs/xid v1.6.0/go.mod h1:7XoLgs4eV+QndskICGsho+ADou8ySMSjJKDIan90Nz0= github.com/rs/zerolog v1.33.0 h1:1cU2KZkvPxNyfgEmhHAz/1A9Bz+llsdYzklWFzgp0r8= github.com/rs/zerolog v1.33.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss= +github.com/rs/zerolog v1.34.0 h1:k43nTLIwcTVQAncfCw4KZ2VY6ukYoZaBPNOE8txlOeY= +github.com/rs/zerolog v1.34.0/go.mod h1:bJsvje4Z08ROH4Nhs5iH600c3IkWhwp44iRc54W6wYQ= github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/swaggest/jsonschema-go v0.3.73 h1:gU1pBzF3pkZ1GDD3dRMdQoCjrA0sldJ+QcM7aSSPgvc= +github.com/swaggest/jsonschema-go v0.3.73/go.mod h1:qp+Ym2DIXHlHzch3HKz50gPf2wJhKOrAB/VYqLS2oJU= +github.com/swaggest/refl v1.3.1 h1:XGplEkYftR7p9cz1lsiwXMM2yzmOymTE9vneVVpaOh4= +github.com/swaggest/refl v1.3.1/go.mod h1:4uUVFVfPJ0NSX9FPwMPspeHos9wPFlCMGoPRllUbpvA= go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA= go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.60.0 h1:x7wzEgXfnzJcHDwStJT+mxOz4etr2EcexjqhBvmoakw= @@ -121,8 +134,12 @@ golang.org/x/time v0.6.0 h1:eTDhh4ZXt5Qf0augr54TN6suAUudPcawVZeIAPU7D4U= golang.org/x/time v0.6.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= google.golang.org/genproto/googleapis/api v0.0.0-20250303144028-a0af3efb3deb h1:p31xT4yrYrSM/G4Sn2+TNUkVhFCbG9y8itM2S6Th950= google.golang.org/genproto/googleapis/api v0.0.0-20250303144028-a0af3efb3deb/go.mod h1:jbe3Bkdp+Dh2IrslsFCklNhweNTBgSYanP1UXhJDhKg= +google.golang.org/genproto/googleapis/api v0.0.0-20250313205543-e70fdf4c4cb4 h1:IFnXJq3UPB3oBREOodn1v1aGQeZYQclEmvWRMN0PSsY= +google.golang.org/genproto/googleapis/api v0.0.0-20250313205543-e70fdf4c4cb4/go.mod h1:c8q6Z6OCqnfVIqUFJkCzKcrj8eCvUrz+K4KRzSTuANg= google.golang.org/genproto/googleapis/rpc v0.0.0-20250303144028-a0af3efb3deb h1:TLPQVbx1GJ8VKZxz52VAxl1EBgKXXbTiU9Fc5fZeLn4= google.golang.org/genproto/googleapis/rpc v0.0.0-20250303144028-a0af3efb3deb/go.mod h1:LuRYeWDFV6WOn90g357N17oMCaxpgCnbi/44qJvDn2I= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250313205543-e70fdf4c4cb4 h1:iK2jbkWL86DXjEx0qiHcRE9dE4/Ahua5k6V8OWFb//c= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250313205543-e70fdf4c4cb4/go.mod h1:LuRYeWDFV6WOn90g357N17oMCaxpgCnbi/44qJvDn2I= google.golang.org/grpc v1.71.0 h1:kF77BGdPTQ4/JZWMlb9VpJ5pa25aqvVqogsxNHHdeBg= google.golang.org/grpc v1.71.0/go.mod h1:H0GRtasmQOh9LkFoCPDu3ZrwUtD1YGE+b2vYBYd/8Ec= google.golang.org/protobuf v1.36.5 h1:tPhr+woSbjfYvY6/GPufUoYizxw1cF/yFoxJ2fmpwlM= @@ -134,3 +151,5 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= k8s.io/utils v0.0.0-20241210054802-24370beab758 h1:sdbE21q2nlQtFh65saZY+rRM6x6aJJI8IUa1AmH/qa0= k8s.io/utils v0.0.0-20241210054802-24370beab758/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +k8s.io/utils v0.0.0-20250321185631-1f6e0b77f77e h1:KqK5c/ghOm8xkHYhlodbp6i6+r+ChV2vuAuVRdFbLro= +k8s.io/utils v0.0.0-20250321185631-1f6e0b77f77e/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= diff --git a/main.go b/main.go index 8aa24ff..3b81db3 100644 --- a/main.go +++ b/main.go @@ -2,25 +2,24 @@ package main import ( "context" + "flag" + "fmt" "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" - 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" ) const ( defaultMetricPrefix = "weather" ) +var schema bool + func main() { ctx, cncl := signal.NotifyContext(context.Background(), os.Kill, os.Interrupt, unix.SIGTERM) defer cncl() @@ -36,6 +35,12 @@ func main() { // and set up logging, tracing, etc.. aw := ambient.New(ctx, awConfig).Init() + // Just show schema if that's all we were asked to do + if schema { + printSchema(awConfig) + os.Exit(0) + } + // Load http and grpc routes, prepare the app awApp := prepareApp(ctx, aw) @@ -44,49 +49,16 @@ func main() { <-awApp.Done() } -func prepareApp(ctx context.Context, aw *ambient.AmbientWeather) *app.App { - // Load ambient routes into app - awApp := &app.App{ - AppContext: ctx, +// flag.Parse will be called by go-app +func init() { + flag.BoolVar(&schema, "schema", false, "generate json schema and exit") +} - // 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, aw.GetRecorder()), - }, - }, - }, +func printSchema(config *config.AmbientLocalExporterConfig) { + bytes, err := app.CustomSchema(config) + if err != nil { + panic(err) } - return awApp + fmt.Println(string(bytes)) } diff --git a/pkg/ambient/ambient.go b/pkg/ambient/ambient.go index b060df3..364c22a 100644 --- a/pkg/ambient/ambient.go +++ b/pkg/ambient/ambient.go @@ -77,13 +77,17 @@ func (aw *AmbientWeather) Init() *AmbientWeather { // Choose weather recorder for grpc / api requests, // default is memory recorder var r recorders.Recorder - switch aw.Config.RecorderConfig.Type { - case config.TypeMemory: + if aw.Config == nil || aw.Config.RecorderConfig == nil { r = &memory.MemoryRecorder{} - case config.TypeRedis: - r = &redis.RedisRecorder{} - case config.TypeNoop: - r = &noop.NoopRecorder{} + } else { + switch aw.Config.RecorderConfig.Type { + case config.TypeMemory: + r = &memory.MemoryRecorder{} + case config.TypeRedis: + r = &redis.RedisRecorder{} + case config.TypeNoop: + r = &noop.NoopRecorder{} + } } aw.weatherRecorder = recorder.MustNewWeatherRecorder(&recorder.Opts{ diff --git a/pkg/ambient/config/config.go b/pkg/ambient/config/config.go index 4384c99..c21d4f4 100644 --- a/pkg/ambient/config/config.go +++ b/pkg/ambient/config/config.go @@ -6,25 +6,25 @@ import ( // This configuration includes all config from go-app/config.AppConfig type AmbientLocalExporterConfig struct { - MetricPrefix string `yaml:"metricPrefix" default:"weather" env:"AMBIENT_METRIC_PREFIX"` - UpdatesToKeep *int `yaml:"updatesToKeep" default:"1" env:"AMBIENT_UPDATES_TO_KEEP"` - WeatherStations []WeatherStation `yaml:"weatherStations"` // No env, too complex, not worth the time - RecorderConfig *RecorderConfig `yaml:"recorderConfig"` + MetricPrefix string `yaml:"metricPrefix" default:"weather" env:"AMBIENT_METRIC_PREFIX" json:"metricPrefix,omitempty"` + UpdatesToKeep *int `yaml:"updatesToKeep" default:"1" env:"AMBIENT_UPDATES_TO_KEEP" json:"updatesToKeep,omitempty"` + WeatherStations []WeatherStation `yaml:"weatherStations" json:"weatherStations,omitempty"` // No env, too complex, not worth the time + RecorderConfig *RecorderConfig `yaml:"recorderConfig" json:"recorderConfig,omitempty"` *config.AppConfig // Extends app config } type WeatherStation struct { - Name string `yaml:"name"` // Human Friendly Name (e.g. Back Yard Weather) - Equipment string `yaml:"equipment"` // Equipment Type (e.g. WS-5000) + Name string `yaml:"name" json:"name,omitempty"` // Human Friendly Name (e.g. Back Yard Weather) + Equipment string `yaml:"equipment" json:"equipment,omitempty"` // Equipment Type (e.g. WS-5000) // Required if proxying to awn/wu is enabled - WundergroundID string `yaml:"wundergroundID"` - WundergroundPassword string `yaml:"wundergroundPassword"` - AWNPassKey string `yaml:"awnPassKey"` + WundergroundID string `yaml:"wundergroundID" json:"wundergroundID,omitempty"` + WundergroundPassword string `yaml:"wundergroundPassword" json:"wundergroundPassword,omitempty"` + AWNPassKey string `yaml:"awnPassKey" json:"awnPassKey,omitempty"` // Proxy updates to AWN or Wunderground - ProxyToAWN bool `yaml:"proxyToAWN"` - ProxyToWunderground bool `yaml:"proxyToWunderground"` + ProxyToAWN bool `yaml:"proxyToAWN" json:"proxyToAWN,omitempty"` + ProxyToWunderground bool `yaml:"proxyToWunderground" json:"proxyToWunderground,omitempty"` // Unreliable / unwanted metrics by name of WeatherUpdate Field // will be excluded if present in discardMetrics @@ -33,8 +33,8 @@ type WeatherStation struct { // ignoring discardMetrics. // // Check weather.WeatherUpdateField for options - KeepMetrics []string `yaml:"keepMetrics"` - DropMetrics []string `yaml:"dropMetrics"` + KeepMetrics []string `yaml:"keepMetrics" json:"keepMetrics,omitempty"` + DropMetrics []string `yaml:"dropMetrics" json:"dropMetrics,omitempty"` // Relabels battery and sensor names // Temp+Humidity Sensors: @@ -44,5 +44,5 @@ type WeatherStation struct { // - OutdoorSensor // - RainSensor // - CO2Sensor - SensorMappings map[string]string `yaml:"sensorMappings"` + SensorMappings map[string]string `yaml:"sensorMappings" json:"sensorMappings,omitempty"` } diff --git a/pkg/ambient/config/config_recorder.go b/pkg/ambient/config/config_recorder.go index 7967def..d638600 100644 --- a/pkg/ambient/config/config_recorder.go +++ b/pkg/ambient/config/config_recorder.go @@ -9,17 +9,17 @@ const ( ) type RecorderConfig struct { - Type RecorderType `yaml:"type" env:"RECORDER_TYPE"` // memory|redis - KeepLast int `yaml:"keepLast" env:"RECORDER_KEEP_LAST"` - RedisConfig *RedisConfig + Type RecorderType `yaml:"type" env:"RECORDER_TYPE" json:"type,omitempty"` // memory|redis + KeepLast int `yaml:"keepLast" env:"RECORDER_KEEP_LAST" json:"keepLast,omitempty"` + RedisConfig *RedisConfig `json:"redisConfig,omitempty"` } type RedisConfig struct { - RedisHost string `yaml:"redisHost" env:"REDIS_HOST" default:"127.0.0.1"` - RedisPort int `yaml:"redisPort" env:"REDIS_PORT" default:"6379"` - RedisUser string `yaml:"redisUser" env:"REDIS_USER"` - RedisPassword string `yaml:"redisPassword" env:"REDIS_PASSWORD"` - RedisDB int `yaml:"redisDB" env:"REDIS_DB" default:"0"` - RedisTLS bool `yaml:"redisTLS" env:"REDIS_TLS" default:"false"` - RedisTLSInsecure bool `yaml:"redisTLSInsecure" env:"REDIS_TLS_INSECURE" default:"false"` + RedisHost string `yaml:"redisHost" env:"REDIS_HOST" default:"127.0.0.1" json:"redisHost,omitempty"` + RedisPort int `yaml:"redisPort" env:"REDIS_PORT" default:"6379" json:"redisPort,omitempty"` + RedisUser string `yaml:"redisUser" env:"REDIS_USER" json:"redisUser,omitempty"` + RedisPassword string `yaml:"redisPassword" env:"REDIS_PASSWORD" json:"redisPassword,omitempty"` + RedisDB int `yaml:"redisDB" env:"REDIS_DB" default:"0" json:"redisDB,omitempty"` + RedisTLS bool `yaml:"redisTLS" env:"REDIS_TLS" default:"false" json:"redisTLS,omitempty"` + RedisTLSInsecure bool `yaml:"redisTLSInsecure" env:"REDIS_TLS_INSECURE" default:"false" json:"redisTLSInsecure,omitempty"` }