55 lines
1.5 KiB
Go
55 lines
1.5 KiB
Go
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))
|
|
}
|