From 4c93303f27763693f38e5e980bebebc52b15508c Mon Sep 17 00:00:00 2001 From: Ryan D McGuire Date: Tue, 7 Jan 2025 10:27:02 -0500 Subject: [PATCH] Consolidate battery metrics --- main.go | 6 ++-- pkg/ambient/ambient.go | 4 ++- pkg/provider/awn/provider.go | 66 +++++++++++++++++++++-------------- pkg/weather/metrics.go | 67 ++++++++++++++++++------------------ pkg/weather/types.go | 58 +++++++++++++++++-------------- 5 files changed, 111 insertions(+), 90 deletions(-) diff --git a/main.go b/main.go index 469b1d7..37b9114 100644 --- a/main.go +++ b/main.go @@ -16,10 +16,10 @@ func main() { ctx, cncl := signal.NotifyContext(context.Background(), os.Kill, unix.SIGTERM) defer cncl() + // Read config and environment, set up logging, load up + // an appCtx, and prepare ambient weather local exporter ctx = app.MustSetupConfigAndLogging(ctx) - - aw := ambient.New(ctx) - aw.MustInit() + aw := ambient.New(ctx).Init() awApp := app.App{ AppContext: ctx, diff --git a/pkg/ambient/ambient.go b/pkg/ambient/ambient.go index b7c1a75..aafa2cf 100644 --- a/pkg/ambient/ambient.go +++ b/pkg/ambient/ambient.go @@ -37,10 +37,12 @@ func New(appCtx context.Context) *AmbientWeather { } } -func (aw *AmbientWeather) MustInit() { +// Initialize with defaults, set logger from context +func (aw *AmbientWeather) Init() *AmbientWeather { aw.awnProvider = &awn.AWNProvider{} aw.wuProvider = &wunderground.WUProvider{} aw.l = zerolog.Ctx(aw.appCtx) + return aw } func (aw *AmbientWeather) GetAWNHandlerFunc(appCtx context.Context) func(http.ResponseWriter, *http.Request) { diff --git a/pkg/provider/awn/provider.go b/pkg/provider/awn/provider.go index 2cc8729..a7a3bd2 100644 --- a/pkg/provider/awn/provider.go +++ b/pkg/provider/awn/provider.go @@ -39,32 +39,46 @@ func MapAwnUpdate(awnUpdate *AmbientWeatherUpdate) *weather.WeatherUpdate { } return &weather.WeatherUpdate{ - StationType: awnUpdate.StationType, - DateUTC: &updateTime, - TempOutdoorF: awnUpdate.TempF, - HumidityOudoor: awnUpdate.Humidity, - WindSpeedMPH: awnUpdate.WindGustMPH, - WindGustMPH: awnUpdate.WindGustMPH, - MaxDailyGust: awnUpdate.MaxDailyGust, - WindDir: awnUpdate.WindDir, - WindDirAvg10m: awnUpdate.WindDirAVG10m, - UV: awnUpdate.UV, - SolarRadiation: awnUpdate.SolarRadiation, - HourlyRainIn: awnUpdate.HourlyRainIn, - EventRainIn: awnUpdate.EventRainIn, - DailyRainIn: awnUpdate.DailyRainIn, - WeeklyRainIn: awnUpdate.WeeklyRainIn, - MonthlyRainIn: awnUpdate.MonthlyRainIn, - YearlyRainIn: awnUpdate.YearlyRainIn, - TotalRainIn: awnUpdate.TotalRainIn, - BattOutdoorSensor: awnUpdate.BattOut, - BattIndoorSensor: awnUpdate.BattIn, - BattRainSensor: awnUpdate.BattRain, - BattCO2Sensor: awnUpdate.BattCO2, - TempIndoorF: awnUpdate.TempInF, - HumidityIndoor: awnUpdate.HumidityIn, - BaromRelativeIn: awnUpdate.BaromRelIn, - BaromAbsoluteIn: awnUpdate.BaromAbsIn, + StationType: awnUpdate.StationType, + DateUTC: &updateTime, + TempOutdoorF: awnUpdate.TempF, + HumidityOudoor: awnUpdate.Humidity, + WindSpeedMPH: awnUpdate.WindGustMPH, + WindGustMPH: awnUpdate.WindGustMPH, + MaxDailyGust: awnUpdate.MaxDailyGust, + WindDir: awnUpdate.WindDir, + WindDirAvg10m: awnUpdate.WindDirAVG10m, + UV: awnUpdate.UV, + SolarRadiation: awnUpdate.SolarRadiation, + HourlyRainIn: awnUpdate.HourlyRainIn, + EventRainIn: awnUpdate.EventRainIn, + DailyRainIn: awnUpdate.DailyRainIn, + WeeklyRainIn: awnUpdate.WeeklyRainIn, + MonthlyRainIn: awnUpdate.MonthlyRainIn, + YearlyRainIn: awnUpdate.YearlyRainIn, + TotalRainIn: awnUpdate.TotalRainIn, + Batteries: []weather.BatteryStatus{ + { + Component: "OutdoorSensor", + Status: awnUpdate.BattOut, + }, + { + Component: "IndoorSensor", + Status: awnUpdate.BattIn, + }, + { + Component: "RainSensor", + Status: awnUpdate.BattRain, + }, + { + Component: "CO2Sensor", + Status: awnUpdate.BattCO2, + }, + }, + TempIndoorF: awnUpdate.TempInF, + HumidityIndoor: awnUpdate.HumidityIn, + BaromRelativeIn: awnUpdate.BaromRelIn, + BaromAbsoluteIn: awnUpdate.BaromAbsIn, } } diff --git a/pkg/weather/metrics.go b/pkg/weather/metrics.go index 76f9840..3105c04 100644 --- a/pkg/weather/metrics.go +++ b/pkg/weather/metrics.go @@ -12,31 +12,29 @@ import ( 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 - BattOutdoorSensor metric.Int64Gauge - BattIndoorSensor metric.Int64Gauge - BattRainSensor metric.Int64Gauge - BaromRelativeIn metric.Float64Gauge - BaromAbsoluteIn metric.Float64Gauge - DewPointF metric.Float64Gauge - WindChillF metric.Float64Gauge + 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 @@ -90,12 +88,8 @@ func MustInitMetrics(appCtx context.Context) *WeatherMetrics { metric.WithDescription("Yearly Rain in Inches")) wm.TotalRainIn, _ = wm.meter.Float64Gauge("weather_total_rain_in", metric.WithDescription("Total Rain in Inches")) - wm.BattOutdoorSensor, _ = wm.meter.Int64Gauge("weather_batt_outdoor_sensor", - metric.WithDescription("Outdoor Equipment Battery")) - wm.BattIndoorSensor, _ = wm.meter.Int64Gauge("weather_batt_indoor_sensor", - metric.WithDescription("Indoor Equipmenet Battery")) - wm.BattRainSensor, _ = wm.meter.Int64Gauge("weather_batt_rain_sensor", - metric.WithDescription("Rain Sensor Battery")) + 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", @@ -136,13 +130,18 @@ func (wm *WeatherMetrics) Update(u *WeatherUpdate) { 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.BattOutdoorSensor.Record(wm.appCtx, int64(u.BattOutdoorSensor), metric.WithAttributeSet(attributes)) - wm.BattIndoorSensor.Record(wm.appCtx, int64(u.BattIndoorSensor), metric.WithAttributeSet(attributes)) - wm.BattRainSensor.Record(wm.appCtx, int64(u.BattRainSensor), 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) } diff --git a/pkg/weather/types.go b/pkg/weather/types.go index 7756a7a..3387e14 100644 --- a/pkg/weather/types.go +++ b/pkg/weather/types.go @@ -7,34 +7,40 @@ import ( // Stable intermediate struct containing superset of fields // between AWN and Wunderground style updates from Ambient devices type WeatherUpdate struct { - DateUTC *time.Time - StationType string - TempOutdoorF float64 - TempIndoorF float64 - HumidityOudoor int - HumidityIndoor int - WindSpeedMPH float64 - WindGustMPH float64 - MaxDailyGust float64 - WindDir int - WindDirAvg10m int - UV int - SolarRadiation float64 - HourlyRainIn float64 - EventRainIn float64 - DailyRainIn float64 - WeeklyRainIn float64 - MonthlyRainIn float64 - YearlyRainIn float64 - TotalRainIn float64 - BattOutdoorSensor int - BattIndoorSensor int - BattRainSensor int - BattCO2Sensor int - BaromRelativeIn float64 - BaromAbsoluteIn float64 + DateUTC *time.Time + StationType string + TempOutdoorF float64 + TempIndoorF float64 + HumidityOudoor int + HumidityIndoor int + WindSpeedMPH float64 + WindGustMPH float64 + MaxDailyGust float64 + WindDir int + WindDirAvg10m int + UV int + SolarRadiation float64 + HourlyRainIn float64 + EventRainIn float64 + DailyRainIn float64 + WeeklyRainIn float64 + MonthlyRainIn float64 + YearlyRainIn float64 + TotalRainIn float64 + Batteries []BatteryStatus + // BattOutdoorSensor int + // BattIndoorSensor int + // BattRainSensor int + // BattCO2Sensor int + BaromRelativeIn float64 + BaromAbsoluteIn float64 // These fields may be calculated // if not otherwise set DewPointF float64 WindChillF float64 } + +type BatteryStatus struct { + Component string + Status int +}