Add support for temp+humidity sensors
	
		
			
	
		
	
	
		
	
		
			All checks were successful
		
		
	
	
		
			
				
	
				Build and Publish / release (push) Successful in 6m32s
				
			
		
		
	
	
				
					
				
			
		
			All checks were successful
		
		
	
	Build and Publish / release (push) Successful in 6m32s
				
			This commit is contained in:
		| @@ -24,6 +24,7 @@ const ( | |||||||
| 	BattIndoorSensor  = "IndoorSensor" | 	BattIndoorSensor  = "IndoorSensor" | ||||||
| 	BattRainSensor    = "RainSensor" | 	BattRainSensor    = "RainSensor" | ||||||
| 	BattCO2Sensor     = "CO2Sensor" | 	BattCO2Sensor     = "CO2Sensor" | ||||||
|  | 	THSensor          = "TempHumiditySensor" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| func (awn *AWNProvider) Name() string { | func (awn *AWNProvider) Name() string { | ||||||
| @@ -89,11 +90,55 @@ func MapAwnUpdate(awnUpdate *AmbientWeatherUpdate) *weather.WeatherUpdate { | |||||||
| 				Component: BattCO2Sensor, | 				Component: BattCO2Sensor, | ||||||
| 				Status:    awnUpdate.BattCO2, | 				Status:    awnUpdate.BattCO2, | ||||||
| 			}, | 			}, | ||||||
|  | 			// Temp and Humidity Sensors | ||||||
|  | 			{ | ||||||
|  | 				Component: THSensor + "1", | ||||||
|  | 				Status:    awnUpdate.Batt1, | ||||||
|  | 			}, | ||||||
|  | 			{ | ||||||
|  | 				Component: THSensor + "2", | ||||||
|  | 				Status:    awnUpdate.Batt2, | ||||||
|  | 			}, | ||||||
|  | 			{ | ||||||
|  | 				Component: THSensor + "3", | ||||||
|  | 				Status:    awnUpdate.Batt3, | ||||||
|  | 			}, | ||||||
|  | 			{ | ||||||
|  | 				Component: THSensor + "4", | ||||||
|  | 				Status:    awnUpdate.Batt4, | ||||||
|  | 			}, | ||||||
|  | 			{ | ||||||
|  | 				Component: THSensor + "5", | ||||||
|  | 				Status:    awnUpdate.Batt5, | ||||||
|  | 			}, | ||||||
|  | 			{ | ||||||
|  | 				Component: THSensor + "6", | ||||||
|  | 				Status:    awnUpdate.Batt6, | ||||||
|  | 			}, | ||||||
|  | 			{ | ||||||
|  | 				Component: THSensor + "7", | ||||||
|  | 				Status:    awnUpdate.Batt7, | ||||||
|  | 			}, | ||||||
|  | 			{ | ||||||
|  | 				Component: THSensor + "8", | ||||||
|  | 				Status:    awnUpdate.Batt8, | ||||||
|  | 			}, | ||||||
| 		}, | 		}, | ||||||
| 		TempIndoorF:     awnUpdate.TempInF, | 		TempIndoorF:     awnUpdate.TempInF, | ||||||
| 		HumidityIndoor:  awnUpdate.HumidityIn, | 		HumidityIndoor:  awnUpdate.HumidityIn, | ||||||
| 		BaromRelativeIn: awnUpdate.BaromRelIn, | 		BaromRelativeIn: awnUpdate.BaromRelIn, | ||||||
| 		BaromAbsoluteIn: awnUpdate.BaromAbsIn, | 		BaromAbsoluteIn: awnUpdate.BaromAbsIn, | ||||||
|  | 		// TODO: Permit mapping to config name | ||||||
|  | 		TempHumiditySensors: []*weather.TempHumiditySensor{ | ||||||
|  | 			{Name: "Sensor1", TempF: awnUpdate.Temp1F, Humidity: awnUpdate.Humidity1}, | ||||||
|  | 			{Name: "Sensor2", TempF: awnUpdate.Temp2F, Humidity: awnUpdate.Humidity2}, | ||||||
|  | 			{Name: "Sensor3", TempF: awnUpdate.Temp3F, Humidity: awnUpdate.Humidity3}, | ||||||
|  | 			{Name: "Sensor4", TempF: awnUpdate.Temp4F, Humidity: awnUpdate.Humidity4}, | ||||||
|  | 			{Name: "Sensor5", TempF: awnUpdate.Temp5F, Humidity: awnUpdate.Humidity5}, | ||||||
|  | 			{Name: "Sensor6", TempF: awnUpdate.Temp6F, Humidity: awnUpdate.Humidity6}, | ||||||
|  | 			{Name: "Sensor7", TempF: awnUpdate.Temp7F, Humidity: awnUpdate.Humidity7}, | ||||||
|  | 			{Name: "Sensor8", TempF: awnUpdate.Temp8F, Humidity: awnUpdate.Humidity8}, | ||||||
|  | 		}, | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -28,4 +28,32 @@ type AmbientWeatherUpdate struct { | |||||||
| 	BaromAbsIn     *float64 `json:"baromabsin,omitempty" schema:"baromabsin"` | 	BaromAbsIn     *float64 `json:"baromabsin,omitempty" schema:"baromabsin"` | ||||||
| 	BattIn         *int     `json:"battin,omitempty" schema:"battin"` | 	BattIn         *int     `json:"battin,omitempty" schema:"battin"` | ||||||
| 	BattCO2        *int     `json:"batt_co2,omitempty" schema:"batt_co2"` | 	BattCO2        *int     `json:"batt_co2,omitempty" schema:"batt_co2"` | ||||||
|  | 	*AmbientTempHumiditySensors | ||||||
|  | } | ||||||
|  |  | ||||||
|  | type AmbientTempHumiditySensors struct { | ||||||
|  | 	Temp1F    *float64 `json:"temp1f,omitempty" schema:"temp1f"` | ||||||
|  | 	Temp2F    *float64 `json:"temp2f,omitempty" schema:"temp2f"` | ||||||
|  | 	Temp3F    *float64 `json:"temp3f,omitempty" schema:"temp3f"` | ||||||
|  | 	Temp4F    *float64 `json:"temp4f,omitempty" schema:"temp4f"` | ||||||
|  | 	Temp5F    *float64 `json:"temp5f,omitempty" schema:"temp5f"` | ||||||
|  | 	Temp6F    *float64 `json:"temp6f,omitempty" schema:"temp6f"` | ||||||
|  | 	Temp7F    *float64 `json:"temp7f,omitempty" schema:"temp7f"` | ||||||
|  | 	Temp8F    *float64 `json:"temp8f,omitempty" schema:"temp8f"` | ||||||
|  | 	Humidity1 *int     `json:"humidity1,omitempty" schema:"humidity1"` | ||||||
|  | 	Humidity2 *int     `json:"humidity2,omitempty" schema:"humidity2"` | ||||||
|  | 	Humidity3 *int     `json:"humidity3,omitempty" schema:"humidity3"` | ||||||
|  | 	Humidity4 *int     `json:"humidity4,omitempty" schema:"humidity4"` | ||||||
|  | 	Humidity5 *int     `json:"humidity5,omitempty" schema:"humidity5"` | ||||||
|  | 	Humidity6 *int     `json:"humidity6,omitempty" schema:"humidity6"` | ||||||
|  | 	Humidity7 *int     `json:"humidity7,omitempty" schema:"humidity7"` | ||||||
|  | 	Humidity8 *int     `json:"humidity8,omitempty" schema:"humidity8"` | ||||||
|  | 	Batt1     *int     `json:"batt1,omitempty" schema:"batt1"` | ||||||
|  | 	Batt2     *int     `json:"batt2,omitempty" schema:"batt2"` | ||||||
|  | 	Batt3     *int     `json:"batt3,omitempty" schema:"batt3"` | ||||||
|  | 	Batt4     *int     `json:"batt4,omitempty" schema:"batt4"` | ||||||
|  | 	Batt5     *int     `json:"batt5,omitempty" schema:"batt5"` | ||||||
|  | 	Batt6     *int     `json:"batt6,omitempty" schema:"batt6"` | ||||||
|  | 	Batt7     *int     `json:"batt7,omitempty" schema:"batt7"` | ||||||
|  | 	Batt8     *int     `json:"batt8,omitempty" schema:"batt8"` | ||||||
| } | } | ||||||
|   | |||||||
| @@ -4,13 +4,13 @@ import ( | |||||||
| 	"context" | 	"context" | ||||||
|  |  | ||||||
| 	"gitea.libretechconsulting.com/rmcguire/go-app/pkg/config" | 	"gitea.libretechconsulting.com/rmcguire/go-app/pkg/config" | ||||||
| 	"gitea.libretechconsulting.com/rmcguire/go-app/pkg/otel" |  | ||||||
| 	"github.com/rs/zerolog" |  | ||||||
| 	"go.opentelemetry.io/otel/attribute" | 	"go.opentelemetry.io/otel/attribute" | ||||||
| 	"go.opentelemetry.io/otel/metric" | 	"go.opentelemetry.io/otel/metric" | ||||||
| 	semconv "go.opentelemetry.io/otel/semconv/v1.26.0" | 	semconv "go.opentelemetry.io/otel/semconv/v1.26.0" | ||||||
| ) | ) | ||||||
|  |  | ||||||
|  | var MetricPrefix = "weather" | ||||||
|  |  | ||||||
| type WeatherMetrics struct { | type WeatherMetrics struct { | ||||||
| 	// Weather Metrics | 	// Weather Metrics | ||||||
| 	TempOutdoorF    metric.Float64Gauge | 	TempOutdoorF    metric.Float64Gauge | ||||||
| @@ -37,6 +37,10 @@ type WeatherMetrics struct { | |||||||
| 	DewPointF       metric.Float64Gauge | 	DewPointF       metric.Float64Gauge | ||||||
| 	WindChillF      metric.Float64Gauge | 	WindChillF      metric.Float64Gauge | ||||||
|  |  | ||||||
|  | 	// Temp and Humidity Sensors | ||||||
|  | 	SensorTempF    metric.Float64Gauge | ||||||
|  | 	SensorHumidity metric.Int64Gauge | ||||||
|  |  | ||||||
| 	// Internal Telemetry | 	// Internal Telemetry | ||||||
| 	UpdatesReceived metric.Int64Counter | 	UpdatesReceived metric.Int64Counter | ||||||
| 	appCtx          context.Context | 	appCtx          context.Context | ||||||
| @@ -45,92 +49,8 @@ type WeatherMetrics struct { | |||||||
| 	recorder        *MetricRecorder | 	recorder        *MetricRecorder | ||||||
| } | } | ||||||
|  |  | ||||||
| var MetricPrefix = "weather" |  | ||||||
|  |  | ||||||
| func MustInitMetrics(appCtx context.Context) *WeatherMetrics { |  | ||||||
| 	wm := &WeatherMetrics{ |  | ||||||
| 		appCtx:   appCtx, |  | ||||||
| 		cfg:      config.MustFromCtx(appCtx), |  | ||||||
| 		recorder: &MetricRecorder{ctx: appCtx, l: zerolog.Ctx(appCtx)}, |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	wm.meter = otel.GetMeter(appCtx, "weather", "metrics") |  | ||||||
|  |  | ||||||
| 	// Weather Metrics |  | ||||||
| 	wm.TempOutdoorF, _ = wm.meter.Float64Gauge(MetricPrefix+"_temp_outdoor_f", |  | ||||||
| 		metric.WithDescription("Outdoor Temperature in Faherenheit")) |  | ||||||
| 	wm.TempIndoorF, _ = wm.meter.Float64Gauge(MetricPrefix+"_temp_indoor_f", |  | ||||||
| 		metric.WithDescription("Indoor Temperature in Faherenheit")) |  | ||||||
| 	wm.HumidityOudoor, _ = wm.meter.Int64Gauge(MetricPrefix+"_humidity_outdoor", |  | ||||||
| 		metric.WithDescription("Outdoor Humidity %")) |  | ||||||
| 	wm.HumidityIndoor, _ = wm.meter.Int64Gauge(MetricPrefix+"_humidity_indoor", |  | ||||||
| 		metric.WithDescription("Indoor Humidity %")) |  | ||||||
| 	wm.WindSpeedMPH, _ = wm.meter.Float64Gauge(MetricPrefix+"_wind_speed_mph", |  | ||||||
| 		metric.WithDescription("Wind Speed in MPH")) |  | ||||||
| 	wm.WindGustMPH, _ = wm.meter.Float64Gauge(MetricPrefix+"_wind_gust_mph", |  | ||||||
| 		metric.WithDescription("Wind Gust in MPH")) |  | ||||||
| 	wm.MaxDailyGust, _ = wm.meter.Float64Gauge(MetricPrefix+"_max_daily_gust", |  | ||||||
| 		metric.WithDescription("Max Daily Wind Gust")) |  | ||||||
| 	wm.WindDir, _ = wm.meter.Int64Gauge(MetricPrefix+"_wind_dir", |  | ||||||
| 		metric.WithDescription("Wind Direction in Degrees")) |  | ||||||
| 	wm.WindDirAvg10m, _ = wm.meter.Int64Gauge(MetricPrefix+"_wind_dir_avg_10m", |  | ||||||
| 		metric.WithDescription("Wind Direction 10m Average")) |  | ||||||
| 	wm.UV, _ = wm.meter.Int64Gauge(MetricPrefix+"_uv", |  | ||||||
| 		metric.WithDescription("UV Index")) |  | ||||||
| 	wm.SolarRadiation, _ = wm.meter.Float64Gauge(MetricPrefix+"_solar_radiation", |  | ||||||
| 		metric.WithDescription("Solar Radiation in W/㎡")) |  | ||||||
| 	wm.HourlyRainIn, _ = wm.meter.Float64Gauge(MetricPrefix+"_hourly_rain_in", |  | ||||||
| 		metric.WithDescription("Hourly Rain in Inches")) |  | ||||||
| 	wm.EventRainIn, _ = wm.meter.Float64Gauge(MetricPrefix+"_event_rain_in", |  | ||||||
| 		metric.WithDescription("Event Rain in Inches")) |  | ||||||
| 	wm.DailyRainIn, _ = wm.meter.Float64Gauge(MetricPrefix+"_daily_rain_in", |  | ||||||
| 		metric.WithDescription("Daily Rain in Inches")) |  | ||||||
| 	wm.WeeklyRainIn, _ = wm.meter.Float64Gauge(MetricPrefix+"_weekly_rain_in", |  | ||||||
| 		metric.WithDescription("Weekly Rain in Inches")) |  | ||||||
| 	wm.MonthlyRainIn, _ = wm.meter.Float64Gauge(MetricPrefix+"_monthly_rain_in", |  | ||||||
| 		metric.WithDescription("Monthly Rain in Inches")) |  | ||||||
| 	wm.YearlyRainIn, _ = wm.meter.Float64Gauge(MetricPrefix+"_yearly_rain_in", |  | ||||||
| 		metric.WithDescription("Yearly Rain in Inches")) |  | ||||||
| 	wm.TotalRainIn, _ = wm.meter.Float64Gauge(MetricPrefix+"_total_rain_in", |  | ||||||
| 		metric.WithDescription("Total Rain in Inches")) |  | ||||||
| 	wm.BatteryStatus, _ = wm.meter.Int64Gauge(MetricPrefix+"_battery_status", |  | ||||||
| 		metric.WithDescription("Per-component battery status")) |  | ||||||
| 	wm.BaromRelativeIn, _ = wm.meter.Float64Gauge(MetricPrefix+"_barometric_pressure_relative_in", |  | ||||||
| 		metric.WithDescription("Relative Pressure in Inches of Mercury")) |  | ||||||
| 	wm.BaromAbsoluteIn, _ = wm.meter.Float64Gauge(MetricPrefix+"_barometric_pressure_absolute_in", |  | ||||||
| 		metric.WithDescription("Absolute Pressure in Inches of Mercury")) |  | ||||||
| 	wm.DewPointF, _ = wm.meter.Float64Gauge(MetricPrefix+"_dew_point_f", |  | ||||||
| 		metric.WithDescription("Dew Point in Faherenheit")) |  | ||||||
| 	wm.WindChillF, _ = wm.meter.Float64Gauge(MetricPrefix+"_wind_chill_f", |  | ||||||
| 		metric.WithDescription("Wind Chill in Faherenheit")) |  | ||||||
|  |  | ||||||
| 	// Internal Telemetry |  | ||||||
| 	wm.UpdatesReceived, _ = wm.meter.Int64Counter(MetricPrefix+"_updates_received", |  | ||||||
| 		metric.WithDescription("Metric Updates Processed by Exporter")) |  | ||||||
|  |  | ||||||
| 	return wm |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (wm *WeatherMetrics) Update(u *WeatherUpdate) { | func (wm *WeatherMetrics) Update(u *WeatherUpdate) { | ||||||
| 	attributes := []attribute.KeyValue{ | 	attributes := wm.GetAttributes(u) | ||||||
| 		semconv.ServiceVersion(wm.cfg.Version), |  | ||||||
| 		semconv.ServiceName(wm.cfg.Name), |  | ||||||
| 		semconv.DeploymentEnvironment(wm.cfg.Environment), |  | ||||||
| 	} |  | ||||||
| 	if u.StationType != nil { |  | ||||||
| 		attributes = append(attributes, |  | ||||||
| 			attribute.String("station_type", *u.StationType)) |  | ||||||
| 	} |  | ||||||
| 	if u.StationConfig != nil { |  | ||||||
| 		if u.StationConfig.Name != "" { |  | ||||||
| 			attributes = append(attributes, |  | ||||||
| 				attribute.String("station_name", u.StationConfig.Name)) |  | ||||||
| 		} |  | ||||||
| 		if u.StationConfig.Equipment != "" { |  | ||||||
| 			attributes = append(attributes, |  | ||||||
| 				attribute.String("station_equipment", u.StationConfig.Equipment)) |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	wm.recorder.Record(&RecordOpts{Float64Gauge: wm.TempOutdoorF, FloatVal: u.TempOutdoorF, Field: FieldTempOutdoorF, Attributes: attributes, Station: u.StationConfig}) | 	wm.recorder.Record(&RecordOpts{Float64Gauge: wm.TempOutdoorF, FloatVal: u.TempOutdoorF, Field: FieldTempOutdoorF, Attributes: attributes, Station: u.StationConfig}) | ||||||
| 	wm.recorder.Record(&RecordOpts{Float64Gauge: wm.TempIndoorF, FloatVal: u.TempIndoorF, Field: FieldTempIndoorF, Attributes: attributes, Station: u.StationConfig}) | 	wm.recorder.Record(&RecordOpts{Float64Gauge: wm.TempIndoorF, FloatVal: u.TempIndoorF, Field: FieldTempIndoorF, Attributes: attributes, Station: u.StationConfig}) | ||||||
| @@ -155,13 +75,73 @@ func (wm *WeatherMetrics) Update(u *WeatherUpdate) { | |||||||
| 	wm.recorder.Record(&RecordOpts{Float64Gauge: wm.DewPointF, FloatVal: u.DewPointF, Field: FieldDewPointF, Attributes: attributes, Station: u.StationConfig}) | 	wm.recorder.Record(&RecordOpts{Float64Gauge: wm.DewPointF, FloatVal: u.DewPointF, Field: FieldDewPointF, Attributes: attributes, Station: u.StationConfig}) | ||||||
| 	wm.recorder.Record(&RecordOpts{Float64Gauge: wm.WindChillF, FloatVal: u.WindChillF, Field: FieldWindChillF, Attributes: attributes, Station: u.StationConfig}) | 	wm.recorder.Record(&RecordOpts{Float64Gauge: wm.WindChillF, FloatVal: u.WindChillF, Field: FieldWindChillF, Attributes: attributes, Station: u.StationConfig}) | ||||||
|  |  | ||||||
| 	// Batteries | 	wm.RecordBatteries(u, attributes) | ||||||
| 	for _, battery := range u.Batteries { | 	wm.RecordTempHumiditySensors(u, attributes) | ||||||
| 		batAttr := attributes |  | ||||||
| 		batAttr = append(batAttr, attribute.String("component", battery.Component)) |  | ||||||
|  |  | ||||||
| 		wm.recorder.Record(&RecordOpts{Int64Gauge: wm.BatteryStatus, IntVal: battery.Status, Field: FieldBatteries, Attributes: batAttr, Station: u.StationConfig}) |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	wm.UpdatesReceived.Add(wm.appCtx, 1) | 	wm.UpdatesReceived.Add(wm.appCtx, 1) | ||||||
| } | } | ||||||
|  |  | ||||||
|  | func (wm *WeatherMetrics) RecordBatteries(u *WeatherUpdate, attr []attribute.KeyValue) { | ||||||
|  | 	for _, battery := range u.Batteries { | ||||||
|  | 		batAttr := attr | ||||||
|  | 		batAttr = append(batAttr, attribute.String("component", battery.Component)) | ||||||
|  |  | ||||||
|  | 		wm.recorder.Record(&RecordOpts{ | ||||||
|  | 			Int64Gauge: wm.BatteryStatus, | ||||||
|  | 			IntVal:     battery.Status, | ||||||
|  | 			Field:      FieldBatteries, | ||||||
|  | 			Attributes: batAttr, | ||||||
|  | 			Station:    u.StationConfig, | ||||||
|  | 		}) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (wm *WeatherMetrics) RecordTempHumiditySensors(u *WeatherUpdate, attr []attribute.KeyValue) { | ||||||
|  | 	if u == nil || u.TempHumiditySensors == nil { | ||||||
|  | 		return | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	for _, sensor := range u.TempHumiditySensors { | ||||||
|  | 		sensorAttr := attr | ||||||
|  | 		sensorAttr = append(sensorAttr, attribute.String("sensorName", sensor.Name)) | ||||||
|  |  | ||||||
|  | 		wm.recorder.Record(&RecordOpts{ | ||||||
|  | 			Float64Gauge: wm.SensorTempF, | ||||||
|  | 			FloatVal:     sensor.TempF, | ||||||
|  | 			Field:        FieldSensorTempF, | ||||||
|  | 			Attributes:   sensorAttr, | ||||||
|  | 			Station:      u.StationConfig, | ||||||
|  | 		}) | ||||||
|  | 		wm.recorder.Record(&RecordOpts{ | ||||||
|  | 			Int64Gauge: wm.SensorHumidity, | ||||||
|  | 			IntVal:     sensor.Humidity, | ||||||
|  | 			Field:      FieldSensorHumidity, | ||||||
|  | 			Attributes: sensorAttr, | ||||||
|  | 			Station:    u.StationConfig, | ||||||
|  | 		}) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (wm *WeatherMetrics) GetAttributes(u *WeatherUpdate) []attribute.KeyValue { | ||||||
|  | 	attributes := []attribute.KeyValue{ | ||||||
|  | 		semconv.ServiceVersion(wm.cfg.Version), | ||||||
|  | 		semconv.ServiceName(wm.cfg.Name), | ||||||
|  | 		semconv.DeploymentEnvironment(wm.cfg.Environment), | ||||||
|  | 	} | ||||||
|  | 	if u.StationType != nil { | ||||||
|  | 		attributes = append(attributes, | ||||||
|  | 			attribute.String("station_type", *u.StationType)) | ||||||
|  | 	} | ||||||
|  | 	if u.StationConfig != nil { | ||||||
|  | 		if u.StationConfig.Name != "" { | ||||||
|  | 			attributes = append(attributes, | ||||||
|  | 				attribute.String("station_name", u.StationConfig.Name)) | ||||||
|  | 		} | ||||||
|  | 		if u.StationConfig.Equipment != "" { | ||||||
|  | 			attributes = append(attributes, | ||||||
|  | 				attribute.String("station_equipment", u.StationConfig.Equipment)) | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return attributes | ||||||
|  | } | ||||||
|   | |||||||
							
								
								
									
										80
									
								
								pkg/weather/metrics_init.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										80
									
								
								pkg/weather/metrics_init.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,80 @@ | |||||||
|  | package weather | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"context" | ||||||
|  |  | ||||||
|  | 	"gitea.libretechconsulting.com/rmcguire/go-app/pkg/config" | ||||||
|  | 	"gitea.libretechconsulting.com/rmcguire/go-app/pkg/otel" | ||||||
|  | 	"github.com/rs/zerolog" | ||||||
|  | 	"go.opentelemetry.io/otel/metric" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | func MustInitMetrics(appCtx context.Context) *WeatherMetrics { | ||||||
|  | 	wm := &WeatherMetrics{ | ||||||
|  | 		appCtx:   appCtx, | ||||||
|  | 		cfg:      config.MustFromCtx(appCtx), | ||||||
|  | 		recorder: &MetricRecorder{ctx: appCtx, l: zerolog.Ctx(appCtx)}, | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	wm.meter = otel.GetMeter(appCtx, "weather", "metrics") | ||||||
|  |  | ||||||
|  | 	// Weather Metrics | ||||||
|  | 	wm.TempOutdoorF, _ = wm.meter.Float64Gauge(MetricPrefix+"_temp_outdoor_f", | ||||||
|  | 		metric.WithDescription("Outdoor Temperature in Faherenheit")) | ||||||
|  | 	wm.TempIndoorF, _ = wm.meter.Float64Gauge(MetricPrefix+"_temp_indoor_f", | ||||||
|  | 		metric.WithDescription("Indoor Temperature in Faherenheit")) | ||||||
|  | 	wm.HumidityOudoor, _ = wm.meter.Int64Gauge(MetricPrefix+"_humidity_outdoor", | ||||||
|  | 		metric.WithDescription("Outdoor Humidity %")) | ||||||
|  | 	wm.HumidityIndoor, _ = wm.meter.Int64Gauge(MetricPrefix+"_humidity_indoor", | ||||||
|  | 		metric.WithDescription("Indoor Humidity %")) | ||||||
|  | 	wm.WindSpeedMPH, _ = wm.meter.Float64Gauge(MetricPrefix+"_wind_speed_mph", | ||||||
|  | 		metric.WithDescription("Wind Speed in MPH")) | ||||||
|  | 	wm.WindGustMPH, _ = wm.meter.Float64Gauge(MetricPrefix+"_wind_gust_mph", | ||||||
|  | 		metric.WithDescription("Wind Gust in MPH")) | ||||||
|  | 	wm.MaxDailyGust, _ = wm.meter.Float64Gauge(MetricPrefix+"_max_daily_gust", | ||||||
|  | 		metric.WithDescription("Max Daily Wind Gust")) | ||||||
|  | 	wm.WindDir, _ = wm.meter.Int64Gauge(MetricPrefix+"_wind_dir", | ||||||
|  | 		metric.WithDescription("Wind Direction in Degrees")) | ||||||
|  | 	wm.WindDirAvg10m, _ = wm.meter.Int64Gauge(MetricPrefix+"_wind_dir_avg_10m", | ||||||
|  | 		metric.WithDescription("Wind Direction 10m Average")) | ||||||
|  | 	wm.UV, _ = wm.meter.Int64Gauge(MetricPrefix+"_uv", | ||||||
|  | 		metric.WithDescription("UV Index")) | ||||||
|  | 	wm.SolarRadiation, _ = wm.meter.Float64Gauge(MetricPrefix+"_solar_radiation", | ||||||
|  | 		metric.WithDescription("Solar Radiation in W/㎡")) | ||||||
|  | 	wm.HourlyRainIn, _ = wm.meter.Float64Gauge(MetricPrefix+"_hourly_rain_in", | ||||||
|  | 		metric.WithDescription("Hourly Rain in Inches")) | ||||||
|  | 	wm.EventRainIn, _ = wm.meter.Float64Gauge(MetricPrefix+"_event_rain_in", | ||||||
|  | 		metric.WithDescription("Event Rain in Inches")) | ||||||
|  | 	wm.DailyRainIn, _ = wm.meter.Float64Gauge(MetricPrefix+"_daily_rain_in", | ||||||
|  | 		metric.WithDescription("Daily Rain in Inches")) | ||||||
|  | 	wm.WeeklyRainIn, _ = wm.meter.Float64Gauge(MetricPrefix+"_weekly_rain_in", | ||||||
|  | 		metric.WithDescription("Weekly Rain in Inches")) | ||||||
|  | 	wm.MonthlyRainIn, _ = wm.meter.Float64Gauge(MetricPrefix+"_monthly_rain_in", | ||||||
|  | 		metric.WithDescription("Monthly Rain in Inches")) | ||||||
|  | 	wm.YearlyRainIn, _ = wm.meter.Float64Gauge(MetricPrefix+"_yearly_rain_in", | ||||||
|  | 		metric.WithDescription("Yearly Rain in Inches")) | ||||||
|  | 	wm.TotalRainIn, _ = wm.meter.Float64Gauge(MetricPrefix+"_total_rain_in", | ||||||
|  | 		metric.WithDescription("Total Rain in Inches")) | ||||||
|  | 	wm.BatteryStatus, _ = wm.meter.Int64Gauge(MetricPrefix+"_battery_status", | ||||||
|  | 		metric.WithDescription("Per-component battery status")) | ||||||
|  | 	wm.BaromRelativeIn, _ = wm.meter.Float64Gauge(MetricPrefix+"_barometric_pressure_relative_in", | ||||||
|  | 		metric.WithDescription("Relative Pressure in Inches of Mercury")) | ||||||
|  | 	wm.BaromAbsoluteIn, _ = wm.meter.Float64Gauge(MetricPrefix+"_barometric_pressure_absolute_in", | ||||||
|  | 		metric.WithDescription("Absolute Pressure in Inches of Mercury")) | ||||||
|  | 	wm.DewPointF, _ = wm.meter.Float64Gauge(MetricPrefix+"_dew_point_f", | ||||||
|  | 		metric.WithDescription("Dew Point in Faherenheit")) | ||||||
|  | 	wm.WindChillF, _ = wm.meter.Float64Gauge(MetricPrefix+"_wind_chill_f", | ||||||
|  | 		metric.WithDescription("Wind Chill in Faherenheit")) | ||||||
|  |  | ||||||
|  | 	// Temp and Humidity Sensors | ||||||
|  | 	wm.SensorTempF, _ = wm.meter.Float64Gauge(MetricPrefix+"_sensor_temp_f", | ||||||
|  | 		metric.WithDescription("Temperature Sensor in Faherenheit")) | ||||||
|  | 	wm.SensorHumidity, _ = wm.meter.Int64Gauge(MetricPrefix+"_sensor_humidity", | ||||||
|  | 		metric.WithDescription("Humidity % Sensor")) | ||||||
|  |  | ||||||
|  | 	// Internal Telemetry | ||||||
|  | 	wm.UpdatesReceived, _ = wm.meter.Int64Counter(MetricPrefix+"_updates_received", | ||||||
|  | 		metric.WithDescription("Metric Updates Processed by Exporter")) | ||||||
|  |  | ||||||
|  | 	return wm | ||||||
|  | } | ||||||
| @@ -38,8 +38,14 @@ type WeatherUpdate struct { | |||||||
| 	// if not otherwise set | 	// if not otherwise set | ||||||
| 	DewPointF  *float64 | 	DewPointF  *float64 | ||||||
| 	WindChillF *float64 | 	WindChillF *float64 | ||||||
| 	// First URL parameters given to AWN/Wunderground | 	// Extra Temp+Humidity Sensors | ||||||
| 	// if proxying is enabled | 	TempHumiditySensors []*TempHumiditySensor | ||||||
|  | } | ||||||
|  |  | ||||||
|  | type TempHumiditySensor struct { | ||||||
|  | 	Name     string | ||||||
|  | 	TempF    *float64 | ||||||
|  | 	Humidity *int | ||||||
| } | } | ||||||
|  |  | ||||||
| type BatteryStatus struct { | type BatteryStatus struct { | ||||||
| @@ -76,6 +82,8 @@ const ( | |||||||
| 	FieldBaromAbsoluteIn = "BaromAbsoluteIn" | 	FieldBaromAbsoluteIn = "BaromAbsoluteIn" | ||||||
| 	FieldDewPointF       = "DewPointF" | 	FieldDewPointF       = "DewPointF" | ||||||
| 	FieldWindChillF      = "WindChillF" | 	FieldWindChillF      = "WindChillF" | ||||||
|  | 	FieldSensorTempF     = "SensorTempF" | ||||||
|  | 	FieldSensorHumidity  = "SensorHumidity" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| func (u *WeatherUpdate) GetStationName() string { | func (u *WeatherUpdate) GetStationName() string { | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user