diff options
| author | Petri Hienonen <petri.hienonen@gmail.com> | 2026-02-11 16:31:13 +0200 |
|---|---|---|
| committer | Petri Hienonen <petri.hienonen@gmail.com> | 2026-02-11 16:31:13 +0200 |
| commit | b72a2839061c4ac3d54ecfccf65559c4bc34a4ac (patch) | |
| tree | 049a57f2d049f5cdc56120e4bd7138b9cd5c8af0 | |
| parent | fb9b665b79fccd8ef0a13a514dce11f0369e89df (diff) | |
| download | weather-b72a2839061c4ac3d54ecfccf65559c4bc34a4ac.tar.zst | |
Diffstat (limited to '')
| -rw-r--r-- | calculator.go | 20 | ||||
| -rw-r--r-- | converter.go | 10 | ||||
| -rw-r--r-- | forecast_test.go | 4 | ||||
| -rw-r--r-- | weather_mapper.go | 44 |
4 files changed, 61 insertions, 17 deletions
diff --git a/calculator.go b/calculator.go index 84ed8c8..dd2b583 100644 --- a/calculator.go +++ b/calculator.go @@ -7,16 +7,18 @@ import ( ) // CalculateFeelsLike calculates apparent temperature +// windSpeed is expected in km/h func CalculateFeelsLike(temp, humidity, windSpeed float64) float64 { - if temp <= 10 && windSpeed > 1.34 { - // Wind chill formula for cold temperatures - return 13.12 + 0.6215*temp - 11.37*math.Pow(windSpeed, 0.16) + 0.3965*temp*math.Pow(windSpeed, 0.16) - } else if temp >= 27 { - // Simplified heat index for warm temperatures - e := humidity / 100 * 6.105 * math.Exp(17.27*temp/(237.7+temp)) - return temp + 0.33*e - 0.70*windSpeed - 4.00 - } - return temp + if temp <= 10 && windSpeed > 4.8 { + // Wind chill formula (Environment Canada, wind in km/h) + vPow := math.Pow(windSpeed, 0.16) + return 13.12 + 0.6215*temp - 11.37*vPow + 0.3965*temp*vPow + } else if temp >= 27 { + // Simplified heat index for humid heat (Steadman's approximation) + e := humidity / 100 * 6.105 * math.Exp(17.27*temp/(237.7+temp)) + return temp + 0.33*e - 0.70*windSpeed - 4.00 + } + return temp } // SunCalculator calculates sunrise and sunset times diff --git a/converter.go b/converter.go index e843f35..efaed5b 100644 --- a/converter.go +++ b/converter.go @@ -83,9 +83,9 @@ func (fd *ForecastData) convertToCurrent(index int, timestamp int64, loc *time.L current.DewPoint = val } - // Extract wind speed (convert m/s to km/h) + // Extract wind speed (FMI provides m/s) if val, err := fd.getFloatValue(index, "WindSpeedMS"); err == nil && !math.IsNaN(val) { - current.WindSpeed = val * 3.6 + current.WindSpeed = val } // Extract wind direction @@ -93,9 +93,9 @@ func (fd *ForecastData) convertToCurrent(index int, timestamp int64, loc *time.L current.WindDeg = int(math.Round(val)) } - // Extract wind gust (convert m/s to km/h) + // Extract wind gust (m/s) if val, err := fd.getFloatValue(index, "WindGust"); err == nil && !math.IsNaN(val) { - current.WindGust = val * 3.6 + current.WindGust = val } // Extract cloud cover @@ -109,7 +109,7 @@ func (fd *ForecastData) convertToCurrent(index int, timestamp int64, loc *time.L } // Calculate feels-like temperature - current.FeelsLike = CalculateFeelsLike(current.Temp, float64(current.Humidity), current.WindSpeed) + current.FeelsLike = CalculateFeelsLike(current.Temp, float64(current.Humidity), current.WindSpeed*3.6) // Handle precipitation (convert from mm/h) if val, err := fd.getFloatValue(index, "PrecipitationRate"); err == nil && !math.IsNaN(val) && val > 0 { diff --git a/forecast_test.go b/forecast_test.go index 06a3dc7..6f641cb 100644 --- a/forecast_test.go +++ b/forecast_test.go @@ -15,8 +15,8 @@ func TestCalculateFeelsLike(t *testing.T) { windSpeed float64 want float64 }{ - {"Cold with wind", 5, 80, 10, 0.49}, // Approximate wind chill - {"Warm with humidity", 30, 80, 5, 32.65}, // Approximate heat index + {"Cold with wind", 5, 80, 10, 2.66}, // Approximate wind chill (km/h) + {"Warm with humidity", 30, 80, 5, 33.66}, // Approximate heat index (km/h) {"Moderate", 20, 50, 5, 20}, // No adjustment } diff --git a/weather_mapper.go b/weather_mapper.go index 9bfab01..35a90bf 100644 --- a/weather_mapper.go +++ b/weather_mapper.go @@ -25,7 +25,7 @@ func (wm *WeatherMapper) Map(symbol int, forecastTime, sunrise, sunset time.Time } // Determine day/night - isDay := forecastTime.After(sunrise) && forecastTime.Before(sunset) + isDay := !forecastTime.Before(sunrise) && forecastTime.Before(sunset) if isDay { weather.Icon += "d" } else { @@ -64,5 +64,47 @@ var FmiToOwm = map[int]Weather{ 41: {600, "Snow", "light snow", "13"}, 42: {601, "Snow", "snow", "13"}, 43: {602, "Snow", "heavy snow", "13"}, + 50: {300, "Drizzle", "drizzle", "09"}, + 51: {300, "Drizzle", "light drizzle", "09"}, + 52: {301, "Drizzle", "drizzle", "09"}, + 53: {302, "Drizzle", "heavy drizzle", "09"}, + 54: {302, "Drizzle", "heavy drizzle", "09"}, + 55: {302, "Drizzle", "heavy drizzle", "09"}, + 56: {313, "Rain", "freezing drizzle", "09"}, + 57: {314, "Rain", "heavy freezing drizzle", "09"}, + 58: {314, "Rain", "freezing drizzle", "09"}, + 59: {314, "Rain", "freezing drizzle", "09"}, + 60: {500, "Rain", "light rain", "10"}, + 61: {501, "Rain", "moderate rain", "10"}, + 62: {502, "Rain", "heavy rain", "10"}, + 63: {503, "Rain", "very heavy rain", "10"}, + 64: {504, "Rain", "extreme rain", "10"}, + 65: {504, "Rain", "extreme rain", "10"}, + 66: {511, "Rain", "freezing rain", "13"}, + 67: {511, "Rain", "freezing rain", "13"}, + 68: {611, "Snow", "sleet", "13"}, + 69: {612, "Snow", "sleet", "13"}, + 70: {600, "Snow", "light snow", "13"}, + 71: {601, "Snow", "snow", "13"}, + 72: {602, "Snow", "heavy snow", "13"}, + 73: {615, "Snow", "rain and snow", "13"}, + 74: {616, "Snow", "rain and snow", "13"}, + 75: {620, "Snow", "light shower snow", "13"}, + 76: {621, "Snow", "shower snow", "13"}, + 77: {622, "Snow", "heavy shower snow", "13"}, + 78: {622, "Snow", "heavy snow", "13"}, + 79: {622, "Snow", "heavy snow", "13"}, + 80: {520, "Rain", "light intensity shower rain", "09"}, + 81: {521, "Rain", "shower rain", "09"}, + 82: {522, "Rain", "heavy intensity shower rain", "09"}, + 83: {611, "Rain", "sleet", "13"}, + 84: {612, "Rain", "sleet", "13"}, + 85: {621, "Snow", "shower snow", "13"}, + 86: {622, "Snow", "heavy shower snow", "13"}, + 87: {602, "Snow", "heavy snow", "13"}, + 88: {602, "Snow", "heavy snow", "13"}, 91: {200, "Thunderstorm", "thunderstorm with light rain", "11"}, + 92: {202, "Thunderstorm", "thunderstorm with heavy rain", "11"}, + 93: {212, "Thunderstorm", "thunderstorm", "11"}, + 94: {221, "Thunderstorm", "ragged thunderstorm", "11"}, } |
