2025-03-06 17:20:02 -05:00

154 lines
4.0 KiB
Go

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
}