Ryan D McGuire
19823ea08f
All checks were successful
Build and Publish / release (push) Successful in 3m51s
90 lines
2.1 KiB
Go
90 lines
2.1 KiB
Go
package weather
|
|
|
|
import (
|
|
"math"
|
|
"net/url"
|
|
"strconv"
|
|
|
|
"gitea.libretechconsulting.com/rmcguire/ambient-weather-local-exporter/pkg/ambient/config"
|
|
)
|
|
|
|
// Attempts to complete missing fields that may not
|
|
// be set by a specific provider, such as DewPoint and WindChill
|
|
func (u *WeatherUpdate) Enrich(weatherStations ...*config.WeatherStation) {
|
|
if u == nil {
|
|
return
|
|
}
|
|
|
|
if u.WindChillF == nil && u.TempOutdoorF != nil && u.WindSpeedMPH != nil {
|
|
wc := CalculateWindChill(*u.TempOutdoorF, *u.WindSpeedMPH)
|
|
u.WindChillF = &wc
|
|
}
|
|
|
|
if u.DewPointF == nil && (u.TempOutdoorF != nil && u.HumidityOudoor != nil) {
|
|
if *u.TempOutdoorF != 0 || *u.HumidityOudoor != 0 {
|
|
dp := CalculateDewPoint(*u.TempOutdoorF, float64(*u.HumidityOudoor))
|
|
u.DewPointF = &dp
|
|
}
|
|
}
|
|
|
|
if u.BaromAbsoluteIn == nil && u.BaromRelativeIn != nil {
|
|
u.BaromAbsoluteIn = u.BaromRelativeIn
|
|
}
|
|
}
|
|
|
|
func CalculateDewPoint(tempF, humidity float64) float64 {
|
|
// Convert temperature from Fahrenheit to Celsius
|
|
tempC := (tempF - 32) * 5 / 9
|
|
|
|
// Calculate the dew point using the Magnus-Tetens approximation
|
|
a := float64(17.27)
|
|
b := float64(237.7)
|
|
|
|
alpha := (a*tempC)/(b+tempC) + math.Log(humidity/100)
|
|
dewPointC := (b * alpha) / (a - alpha)
|
|
|
|
// Convert dew point back to Fahrenheit
|
|
dewPointF := (dewPointC * 9 / 5) + 32
|
|
return dewPointF
|
|
}
|
|
|
|
func CalculateWindChill(tempF float64, windSpeedMPH float64) float64 {
|
|
if windSpeedMPH <= 3 {
|
|
// Wind chill calculation doesn't apply for very low wind speeds
|
|
return tempF
|
|
}
|
|
|
|
// Formula for calculating wind chill
|
|
return 35.74 + 0.6215*tempF -
|
|
35.75*math.Pow(windSpeedMPH, 0.16) +
|
|
0.4275*tempF*math.Pow(windSpeedMPH, 0.16)
|
|
}
|
|
|
|
// Helper function to set values from fields
|
|
// typically from a WeatherUpdate
|
|
func SetURLVal(vals *url.Values, key string, value any) {
|
|
if value == nil {
|
|
return
|
|
}
|
|
|
|
switch v := value.(type) {
|
|
case *float64:
|
|
if v == nil {
|
|
return
|
|
}
|
|
str := strconv.FormatFloat(*v, 'f', 4, 64)
|
|
vals.Set(key, str)
|
|
case *int:
|
|
if v == nil {
|
|
return
|
|
}
|
|
str := strconv.FormatInt(int64(*v), 10)
|
|
vals.Set(key, str)
|
|
case *string:
|
|
if v == nil {
|
|
return
|
|
}
|
|
vals.Set(key, *v)
|
|
}
|
|
}
|