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)) }