package weather import ( "context" "gitea.libretechconsulting.com/rmcguire/go-app/pkg/config" "gitea.libretechconsulting.com/rmcguire/go-app/pkg/otel" "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/metric" semconv "go.opentelemetry.io/otel/semconv/v1.26.0" ) type WeatherMetrics struct { // Weather Metrics TempOutdoorF metric.Float64Gauge TempIndoorF metric.Float64Gauge HumidityOudoor metric.Int64Gauge HumidityIndoor metric.Int64Gauge WindSpeedMPH metric.Float64Gauge WindGustMPH metric.Float64Gauge MaxDailyGust metric.Float64Gauge WindDir metric.Int64Gauge WindDirAvg10m metric.Int64Gauge UV metric.Int64Gauge SolarRadiation metric.Float64Gauge HourlyRainIn metric.Float64Gauge EventRainIn metric.Float64Gauge DailyRainIn metric.Float64Gauge WeeklyRainIn metric.Float64Gauge MonthlyRainIn metric.Float64Gauge YearlyRainIn metric.Float64Gauge TotalRainIn metric.Float64Gauge BatteryStatus metric.Int64Gauge BaromRelativeIn metric.Float64Gauge BaromAbsoluteIn metric.Float64Gauge DewPointF metric.Float64Gauge WindChillF metric.Float64Gauge // Internal Telemetry UpdatesReceived metric.Int64Counter appCtx context.Context cfg *config.AppConfig meter metric.Meter } func MustInitMetrics(appCtx context.Context) *WeatherMetrics { wm := &WeatherMetrics{ appCtx: appCtx, cfg: config.MustFromCtx(appCtx), } wm.meter = otel.GetMeter(appCtx, "weather", "metrics") // Weather Metrics wm.TempOutdoorF, _ = wm.meter.Float64Gauge("weather_temp_outdoor_f", metric.WithDescription("Outdoor Temperature in Faherenheit")) wm.TempIndoorF, _ = wm.meter.Float64Gauge("weather_temp_indoor_f", metric.WithDescription("Indoor Temperature in Faherenheit")) wm.HumidityOudoor, _ = wm.meter.Int64Gauge("weather_humidity_oudoor", metric.WithDescription("Outdoor Humidity %")) wm.HumidityIndoor, _ = wm.meter.Int64Gauge("weather_humidity_indoor", metric.WithDescription("Indoor Humidity %")) wm.WindSpeedMPH, _ = wm.meter.Float64Gauge("weather_wind_speed_mph", metric.WithDescription("Wind Speed in MPH")) wm.WindGustMPH, _ = wm.meter.Float64Gauge("weather_wind_gust_mph", metric.WithDescription("Wind Gust in MPH")) wm.MaxDailyGust, _ = wm.meter.Float64Gauge("weather_max_daily_gust", metric.WithDescription("Max Daily Wind Gust")) wm.WindDir, _ = wm.meter.Int64Gauge("weather_wind_dir", metric.WithDescription("Wind Direction in Degrees")) wm.WindDirAvg10m, _ = wm.meter.Int64Gauge("weather_wind_dir_avg_10m", metric.WithDescription("Wind Direction 10m Average")) wm.UV, _ = wm.meter.Int64Gauge("weather_uv", metric.WithDescription("UV Index")) wm.SolarRadiation, _ = wm.meter.Float64Gauge("weather_solar_radiation", metric.WithDescription("Solar Radiation in W/㎡")) wm.HourlyRainIn, _ = wm.meter.Float64Gauge("weather_hourly_rain_in", metric.WithDescription("Hourly Rain in Inches")) wm.EventRainIn, _ = wm.meter.Float64Gauge("weather_event_rain_in", metric.WithDescription("Event Rain in Inches")) wm.DailyRainIn, _ = wm.meter.Float64Gauge("weather_daily_rain_in", metric.WithDescription("Daily Rain in Inches")) wm.WeeklyRainIn, _ = wm.meter.Float64Gauge("weather_weekly_rain_in", metric.WithDescription("Weekly Rain in Inches")) wm.MonthlyRainIn, _ = wm.meter.Float64Gauge("weather_monthly_rain_in", metric.WithDescription("Monthly Rain in Inches")) wm.YearlyRainIn, _ = wm.meter.Float64Gauge("weather_yearly_rain_in", metric.WithDescription("Yearly Rain in Inches")) wm.TotalRainIn, _ = wm.meter.Float64Gauge("weather_total_rain_in", metric.WithDescription("Total Rain in Inches")) wm.BatteryStatus, _ = wm.meter.Int64Gauge("battery_status", metric.WithDescription("Per-component battery status")) wm.BaromRelativeIn, _ = wm.meter.Float64Gauge("weather_barometric_pressure_relative_in", metric.WithDescription("Relative Pressure in Inches of Mercury")) wm.BaromAbsoluteIn, _ = wm.meter.Float64Gauge("weather_barometric_pressure_absolute_in", metric.WithDescription("Absolute Pressure in Inches of Mercury")) wm.DewPointF, _ = wm.meter.Float64Gauge("weather_dew_point_f", metric.WithDescription("Dew Point in Faherenheit")) wm.WindChillF, _ = wm.meter.Float64Gauge("weather_wind_chill_f", metric.WithDescription("Wind Chill in Faherenheit")) // Internal Telemetry wm.UpdatesReceived, _ = wm.meter.Int64Counter("weather_updates_received", metric.WithDescription("Metric Updates Processed by Exporter")) return wm } func (wm *WeatherMetrics) Update(u *WeatherUpdate) { attributes := attribute.NewSet( semconv.ServiceVersion(wm.cfg.Version), attribute.String("station_type", u.StationType), ) wm.TempOutdoorF.Record(wm.appCtx, u.TempOutdoorF, metric.WithAttributeSet(attributes)) wm.TempIndoorF.Record(wm.appCtx, u.TempIndoorF, metric.WithAttributeSet(attributes)) wm.HumidityOudoor.Record(wm.appCtx, int64(u.HumidityOudoor), metric.WithAttributeSet(attributes)) wm.HumidityIndoor.Record(wm.appCtx, int64(u.HumidityIndoor), metric.WithAttributeSet(attributes)) wm.WindSpeedMPH.Record(wm.appCtx, u.WindSpeedMPH, metric.WithAttributeSet(attributes)) wm.WindGustMPH.Record(wm.appCtx, u.WindGustMPH, metric.WithAttributeSet(attributes)) wm.MaxDailyGust.Record(wm.appCtx, u.MaxDailyGust, metric.WithAttributeSet(attributes)) wm.WindDir.Record(wm.appCtx, int64(u.WindDir), metric.WithAttributeSet(attributes)) wm.WindDirAvg10m.Record(wm.appCtx, int64(u.WindDirAvg10m), metric.WithAttributeSet(attributes)) wm.UV.Record(wm.appCtx, int64(u.UV), metric.WithAttributeSet(attributes)) wm.SolarRadiation.Record(wm.appCtx, u.SolarRadiation, metric.WithAttributeSet(attributes)) wm.HourlyRainIn.Record(wm.appCtx, u.HourlyRainIn, metric.WithAttributeSet(attributes)) wm.EventRainIn.Record(wm.appCtx, u.EventRainIn, metric.WithAttributeSet(attributes)) wm.DailyRainIn.Record(wm.appCtx, u.DailyRainIn, metric.WithAttributeSet(attributes)) wm.WeeklyRainIn.Record(wm.appCtx, u.WeeklyRainIn, metric.WithAttributeSet(attributes)) wm.MonthlyRainIn.Record(wm.appCtx, u.MonthlyRainIn, metric.WithAttributeSet(attributes)) wm.YearlyRainIn.Record(wm.appCtx, u.YearlyRainIn, metric.WithAttributeSet(attributes)) wm.TotalRainIn.Record(wm.appCtx, u.TotalRainIn, metric.WithAttributeSet(attributes)) wm.BaromRelativeIn.Record(wm.appCtx, u.BaromRelativeIn, metric.WithAttributeSet(attributes)) wm.BaromAbsoluteIn.Record(wm.appCtx, u.BaromAbsoluteIn, metric.WithAttributeSet(attributes)) wm.DewPointF.Record(wm.appCtx, u.DewPointF, metric.WithAttributeSet(attributes)) wm.WindChillF.Record(wm.appCtx, u.WindChillF, metric.WithAttributeSet(attributes)) // Batteries for _, battery := range u.Batteries { wm.BatteryStatus.Record(wm.appCtx, int64(battery.Status), metric.WithAttributeSet(attributes), metric.WithAttributes(attribute.String("component", battery.Component)), ) } wm.UpdatesReceived.Add(wm.appCtx, 1) }