package awn import ( "context" "net/http" "net/url" "time" "github.com/gorilla/schema" "gitea.libretechconsulting.com/rmcguire/ambient-local-exporter/pkg/weather" ) type AWNProvider struct{} const ( providerName = "awn" awnURL = "http://ambientweather.net/data/report" ) // Battery Sensors const ( BattOutdoorSensor = "OutdoorSensor" BattIndoorSensor = "IndoorSensor" BattRainSensor = "RainSensor" BattCO2Sensor = "CO2Sensor" THSensor = "TempHumiditySensor" ) func (awn *AWNProvider) Name() string { return providerName } // Takes an inbound request from the ambient device and maps // to a stable struct for weather updates func (awn *AWNProvider) ReqToWeather(_ context.Context, r *http.Request) ( *weather.WeatherUpdate, error, ) { awnUpdate, err := UnmarshalQueryParams(r.URL.Query()) if err != nil { return nil, err } return MapAwnUpdate(awnUpdate), nil } func MapAwnUpdate(awnUpdate *AmbientWeatherUpdate) *weather.WeatherUpdate { updateTime := time.Now() if awnUpdate.DateUTC != nil { ut, err := time.Parse(time.DateTime, *awnUpdate.DateUTC) if err == nil { updateTime = ut } } return &weather.WeatherUpdate{ DateUTC: &updateTime, StationID: awnUpdate.PassKey, StationType: awnUpdate.StationType, TempOutdoorF: awnUpdate.TempF, HumidityOudoor: awnUpdate.Humidity, WindSpeedMPH: awnUpdate.WindSpeedMPH, 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: BattOutdoorSensor, Status: awnUpdate.BattOut, }, { Component: BattIndoorSensor, Status: awnUpdate.BattIn, }, { Component: BattRainSensor, Status: awnUpdate.BattRain, }, { Component: BattCO2Sensor, 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, HumidityIndoor: awnUpdate.HumidityIn, BaromRelativeIn: awnUpdate.BaromRelIn, BaromAbsoluteIn: awnUpdate.BaromAbsIn, TempHumiditySensors: []*weather.TempHumiditySensor{ {Name: THSensor + "1", TempF: awnUpdate.Temp1F, Humidity: awnUpdate.Humidity1}, {Name: THSensor + "2", TempF: awnUpdate.Temp2F, Humidity: awnUpdate.Humidity2}, {Name: THSensor + "3", TempF: awnUpdate.Temp3F, Humidity: awnUpdate.Humidity3}, {Name: THSensor + "4", TempF: awnUpdate.Temp4F, Humidity: awnUpdate.Humidity4}, {Name: THSensor + "5", TempF: awnUpdate.Temp5F, Humidity: awnUpdate.Humidity5}, {Name: THSensor + "6", TempF: awnUpdate.Temp6F, Humidity: awnUpdate.Humidity6}, {Name: THSensor + "7", TempF: awnUpdate.Temp7F, Humidity: awnUpdate.Humidity7}, {Name: THSensor + "8", TempF: awnUpdate.Temp8F, Humidity: awnUpdate.Humidity8}, }, } } func UnmarshalQueryParams(query url.Values) (*AmbientWeatherUpdate, error) { update := new(AmbientWeatherUpdate) decoder := schema.NewDecoder() if err := decoder.Decode(update, query); err != nil { return nil, err } return update, nil }