Refactor and complete providers
This commit is contained in:
54
pkg/weather/enrich.go
Normal file
54
pkg/weather/enrich.go
Normal file
@ -0,0 +1,54 @@
|
||||
package weather
|
||||
|
||||
import "math"
|
||||
|
||||
// Attempts to complete missing fields that may not
|
||||
// be set by a specific provider, such as DewPoint and WindChill
|
||||
//
|
||||
// If enrich is called repeated with the same station ID, measurements
|
||||
// will be recorded to produce averages. This will be more stable
|
||||
// and support scaling if Redis is available
|
||||
// TODO: Implement average tracker
|
||||
func (u *WeatherUpdate) Enrich() {
|
||||
if u.WindChillF == 0 {
|
||||
u.WindChillF = CalculateWindChill(u.TempF, u.WindSpeedMPH)
|
||||
}
|
||||
|
||||
if u.DewPointF == 0 {
|
||||
u.DewPointF = CalculateDewPoint(u.TempF, float32(u.Humidity))
|
||||
}
|
||||
|
||||
if u.BaromAbsoluteIn == 0 {
|
||||
u.BaromAbsoluteIn = u.BaromRelativeIn
|
||||
}
|
||||
}
|
||||
|
||||
func CalculateDewPoint(tempF, humidity float32) float32 {
|
||||
// Convert temperature from Fahrenheit to Celsius
|
||||
tempC := (tempF - 32) * 5 / 9
|
||||
|
||||
// Calculate the dew point using the Magnus-Tetens approximation
|
||||
a := float32(17.27)
|
||||
b := float32(237.7)
|
||||
|
||||
alpha := (a*tempC)/(b+tempC) + float32(math.Log(float64(humidity)/100))
|
||||
dewPointC := (b * alpha) / (a - alpha)
|
||||
|
||||
// Convert dew point back to Fahrenheit
|
||||
dewPointF := (dewPointC * 9 / 5) + 32
|
||||
return dewPointF
|
||||
}
|
||||
|
||||
func CalculateWindChill(tempF float32, windSpeedMPH float32) float32 {
|
||||
if windSpeedMPH <= 3 {
|
||||
// Wind chill calculation doesn't apply for very low wind speeds
|
||||
return tempF
|
||||
}
|
||||
|
||||
// Formula for calculating wind chill
|
||||
return float32(
|
||||
35.74 + 0.6215*float64(tempF) -
|
||||
35.75*math.Pow(float64(windSpeedMPH), 0.16) +
|
||||
0.4275*float64(tempF)*
|
||||
math.Pow(float64(windSpeedMPH), 0.16))
|
||||
}
|
3
pkg/weather/metrics.go
Normal file
3
pkg/weather/metrics.go
Normal file
@ -0,0 +1,3 @@
|
||||
package weather
|
||||
|
||||
// TODO: Add OTEL Metrics
|
39
pkg/weather/types.go
Normal file
39
pkg/weather/types.go
Normal file
@ -0,0 +1,39 @@
|
||||
package weather
|
||||
|
||||
import (
|
||||
"time"
|
||||
)
|
||||
|
||||
// Stable intermediate struct containing superset of fields
|
||||
// between AWN and Wunderground style updates from Ambient devices
|
||||
type WeatherUpdate struct {
|
||||
DateUTC *time.Time
|
||||
StationType string
|
||||
TempF float32
|
||||
TempInsideF float32
|
||||
Humidity int
|
||||
HumidityInside int
|
||||
WindSpeedMPH float32
|
||||
WindGustMPH float32
|
||||
MaxDailyGust float32
|
||||
WindDir int
|
||||
WindDirAVG10m int
|
||||
UV int
|
||||
SolarRadiation float32
|
||||
HourlyRainIn float32
|
||||
EventRainIn float32
|
||||
DailyRainIn float32
|
||||
WeeklyRainIn float32
|
||||
MonthlyRainIn float32
|
||||
YearlyRainIn float32
|
||||
TotalRainIn float32
|
||||
BattOutdoorSensor int
|
||||
BattIndoorSensor int
|
||||
BattRainSensor int
|
||||
BaromRelativeIn float32
|
||||
BaromAbsoluteIn float32
|
||||
// These fields may be calculated
|
||||
// if not otherwise set
|
||||
DewPointF float32
|
||||
WindChillF float32
|
||||
}
|
Reference in New Issue
Block a user