Rename weather icons, add monochrome variant

This commit is contained in:
MM20
2026-02-13 11:16:17 +01:00
parent d8e95e9f64
commit de8e83aa38
13 changed files with 759 additions and 727 deletions

View File

@@ -1,121 +1,128 @@
package de.mm20.launcher2.weather
import kotlin.math.abs
data class DailyForecast(
val timestamp: Long,
val minTemp: Double,
val maxTemp: Double,
val hourlyForecasts: List<Forecast>,
val icon: Int = getAverageIcon(hourlyForecasts)
val timestamp: Long,
val minTemp: Double,
val maxTemp: Double,
val hourlyForecasts: List<Forecast>,
val icon: Int = getAverageIcon(hourlyForecasts)
) {
companion object {
private fun getAverageIcon(forecasts: List<Forecast>): Int {
if (forecasts.size == 1) {
return forecasts[0].icon
}
var clear = 0f
var clouds = 0f
var rain = 0f
var thunder = 0f
var wind = 0f
var snow = 0f
for (f in forecasts) {
when (f.icon) {
Forecast.SHOWERS, Forecast.HAIL -> {
rain += 2f
clouds += 1f
}
Forecast.THUNDERSTORM_WITH_RAIN -> {
rain += 2f
thunder += 5f
clouds += 1f
}
Forecast.THUNDERSTORM -> {
thunder += 5f
clouds += 1f
}
Forecast.BROKEN_CLOUDS, Forecast.MOSTLY_CLOUDY -> {
clouds += 0.7f
clear += 0.3f
}
var hail = 0f
var precipitation = 0f
var total = 0f
for (fc in forecasts) {
val f = if (fc.night) 0.8f else 1f
when (fc.icon) {
Forecast.CLEAR -> clear += f
Forecast.OVERCAST -> clouds += f
Forecast.PARTLY_CLOUDY -> {
clouds += 0.3f
clear += 0.7f
clouds += f * 0.5f
clear += f * 0.5f
}
Forecast.CLOUDY -> {
clouds += 1f
Forecast.RAIN -> {
rain += f
clouds += f
precipitation += f
}
Forecast.HEAVY_RAIN -> {
rain += f * 1.5f
clouds += f
precipitation += f
}
Forecast.LIGHT_RAIN -> {
rain += f * 0.75f
clouds += f
precipitation += f
}
Forecast.SNOW -> {
snow += 2f
clouds += 1f
}
Forecast.DRIZZLE -> {
rain += 1f
}
Forecast.HEAVY_THUNDERSTORM -> {
thunder += 8f
}
Forecast.HEAVY_THUNDERSTORM_WITH_RAIN -> {
thunder += 8f
clouds += 1f
snow += f
clouds += f
precipitation += f
}
Forecast.SLEET -> {
rain += 1f
snow += 1f
snow += f * 0.5f
rain += f * 0.5f
clouds += f
precipitation += f
}
Forecast.STORM -> {
wind += 8f
Forecast.HAIL -> {
hail += f
clouds += f
precipitation += f
}
Forecast.THUNDER -> {
thunder += f
clouds += f
}
Forecast.THUNDERSTORM -> {
thunder += f
rain += f * 1.5f
clouds += f
precipitation += f
}
Forecast.WIND -> {
wind += 5f
}
Forecast.CLEAR -> {
clear += 1f
wind += f
clouds += f
}
}
total += f
}
if (wind / total >= 0.05f) {
return Forecast.WIND
}
if (precipitation / total >= 0.3f) {
return when {
hail > snow && hail > rain -> Forecast.HAIL
snow > rain && snow / rain > 2f -> Forecast.SNOW
snow / rain <= 2f && rain / snow <= 2f -> Forecast.SLEET
thunder > 0f -> Forecast.THUNDERSTORM
(rain + snow + hail) / precipitation >= 1.25f -> Forecast.HEAVY_RAIN
(rain + snow + hail) / precipitation <= 0.8725f -> Forecast.LIGHT_RAIN
else -> Forecast.RAIN
}
}
val pairs = listOf(
"clear" to clear,
"clouds" to clouds,
"rain" to rain,
"thunder" to thunder,
"wind" to wind,
"snow" to snow
).sortedByDescending { it.second }
val first = pairs[0]
val second = pairs[1]
when (first.first) {
"wind" -> return if (first.second / forecasts.size > 6f) Forecast.STORM else Forecast.WIND
"thunder" -> {
val heavy = first.second / forecasts.size > 6f
val withRain = second.first == "rain"
if (heavy && withRain) return Forecast.HEAVY_THUNDERSTORM_WITH_RAIN
if (heavy && !withRain) return Forecast.HEAVY_THUNDERSTORM
if (!heavy && withRain) return Forecast.THUNDERSTORM_WITH_RAIN
return Forecast.THUNDERSTORM
}
"rain" -> {
val heavy = first.second / forecasts.size > 0.8f
val withSnow = second.first == "snow" && abs(1 - (first.second / second.second)) < 0.2
if (withSnow) return Forecast.SLEET
if (heavy) return Forecast.SHOWERS
return Forecast.DRIZZLE
}
"snow" -> {
val withRain = second.first == "rain" && abs(1 - (first.second / second.second)) < 0.2
if (withRain) return Forecast.SLEET
return Forecast.SNOW
}
else -> {
if (clouds == 0f) return Forecast.CLEAR
if (clear == 0f) return Forecast.CLOUDY
if (clouds > clear) {
if (clear > snow && clear > rain) return Forecast.MOSTLY_CLOUDY
if (clear < snow && clear < rain) return Forecast.SLEET
if (clear < snow && clear > rain) return Forecast.SNOW
if (clear > snow && clear < rain) return Forecast.DRIZZLE
}
return Forecast.PARTLY_CLOUDY
}
if (thunder / total >= 0.05f) {
return Forecast.THUNDER
}
if (clear / clouds < 0.2f) {
return Forecast.OVERCAST
}
if (clouds / clear < 0.1f) {
return Forecast.CLEAR
}
return Forecast.PARTLY_CLOUDY
}
}
}

View File

@@ -1,135 +1,143 @@
package de.mm20.launcher2.weather
import de.mm20.launcher2.database.entities.ForecastEntity
import de.mm20.launcher2.weather.Forecast.Companion.BROKEN_CLOUDS
import de.mm20.launcher2.weather.Forecast.Companion.CLEAR
import de.mm20.launcher2.weather.Forecast.Companion.CLOUDY
import de.mm20.launcher2.weather.Forecast.Companion.COLD
import de.mm20.launcher2.weather.Forecast.Companion.DRIZZLE
import de.mm20.launcher2.weather.Forecast.Companion.EXTREME_COLD
import de.mm20.launcher2.weather.Forecast.Companion.EXTREME_HEAT
import de.mm20.launcher2.weather.Forecast.Companion.FOG
import de.mm20.launcher2.weather.Forecast.Companion.HAIL
import de.mm20.launcher2.weather.Forecast.Companion.HAZE
import de.mm20.launcher2.weather.Forecast.Companion.HEAVY_THUNDERSTORM
import de.mm20.launcher2.weather.Forecast.Companion.HEAVY_THUNDERSTORM_WITH_RAIN
import de.mm20.launcher2.weather.Forecast.Companion.HOT
import de.mm20.launcher2.weather.Forecast.Companion.MOSTLY_CLOUDY
import de.mm20.launcher2.weather.Forecast.Companion.NONE
import de.mm20.launcher2.weather.Forecast.Companion.HEAVY_RAIN
import de.mm20.launcher2.weather.Forecast.Companion.LIGHT_RAIN
import de.mm20.launcher2.weather.Forecast.Companion.OVERCAST
import de.mm20.launcher2.weather.Forecast.Companion.PARTLY_CLOUDY
import de.mm20.launcher2.weather.Forecast.Companion.SHOWERS
import de.mm20.launcher2.weather.Forecast.Companion.RAIN
import de.mm20.launcher2.weather.Forecast.Companion.SLEET
import de.mm20.launcher2.weather.Forecast.Companion.SNOW
import de.mm20.launcher2.weather.Forecast.Companion.STORM
import de.mm20.launcher2.weather.Forecast.Companion.THUNDER
import de.mm20.launcher2.weather.Forecast.Companion.THUNDERSTORM
import de.mm20.launcher2.weather.Forecast.Companion.THUNDERSTORM_WITH_RAIN
import de.mm20.launcher2.weather.Forecast.Companion.UNKNOWN
import de.mm20.launcher2.weather.Forecast.Companion.WIND
data class Forecast(
val timestamp: Long,
/** The temperature, in Kelvin **/
val temperature: Double,
/** The min temperature, in Kelvin **/
val minTemp: Double? = null,
/** The max temperature, in Kelvin **/
val maxTemp: Double? = null,
/** The temperature, in hPa **/
val pressure: Double? = null,
/** The temperature, in percent **/
val humidity: Double? = null,
/** The icon, one of [NONE], [CLEAR], [CLOUDY], [COLD], [DRIZZLE], [HAZE], [FOG],
* [HAIL], [HEAVY_THUNDERSTORM], [HEAVY_THUNDERSTORM_WITH_RAIN], [HOT], [MOSTLY_CLOUDY],
* [PARTLY_CLOUDY], [SHOWERS], [SLEET], [SNOW], [STORM], [THUNDERSTORM],
* [THUNDERSTORM_WITH_RAIN], [WIND], [BROKEN_CLOUDS]**/
val icon: Int,
/** A text describing the current weather condition **/
val condition: String,
/** The clouds, percentage **/
val clouds: Int? = null,
/** Wind speed, in m/s **/
val windSpeed: Double? = null,
/** wind direction, in degrees **/
val windDirection: Double? = null,
/** rain, in mm per hour **/
val precipitation: Double? = null,
/** whether this forecast is during night time (whether a moon icon should be used instead of sun) **/
val night: Boolean = false,
/** Location string **/
val location: String,
/** Provider name **/
val provider: String,
/** Url to the provider and more weather information **/
val providerUrl: String = "",
/** Rain probability, in percent [0..100]. null if not available **/
val precipProbability: Int? = null,
/** Timestamp (in millis) when when this forecast was created **/
val updateTime: Long
val timestamp: Long,
/** The temperature, in Kelvin **/
val temperature: Double,
/** The min temperature, in Kelvin **/
val minTemp: Double? = null,
/** The max temperature, in Kelvin **/
val maxTemp: Double? = null,
/** The temperature, in hPa **/
val pressure: Double? = null,
/** The temperature, in percent **/
val humidity: Double? = null,
/** The icon, one of [UNKNOWN], [CLEAR], [OVERCAST], [EXTREME_COLD], [LIGHT_RAIN], [HAZE],
* [FOG], [HAIL], [EXTREME_HEAT], [PARTLY_CLOUDY], [RAIN], [HEAVY_RAIN] [SLEET], [SNOW],
* [THUNDER], [THUNDERSTORM], [WIND]**/
val icon: Int,
/** A text describing the current weather condition **/
val condition: String,
/** The clouds, percentage **/
val clouds: Int? = null,
/** Wind speed, in m/s **/
val windSpeed: Double? = null,
/** wind direction, in degrees **/
val windDirection: Double? = null,
/** rain, in mm per hour **/
val precipitation: Double? = null,
/** whether this forecast is during nighttime (whether a moon icon should be used instead of sun) **/
val night: Boolean = false,
/** Location string **/
val location: String,
/** Provider name **/
val provider: String,
/** Url to the provider and more weather information **/
val providerUrl: String = "",
/** Rain probability, in percent [0..100]. null if not available **/
val precipProbability: Int? = null,
/** Timestamp (in millis) when this forecast was created **/
val updateTime: Long
) {
fun toDatabaseEntity(): ForecastEntity {
return ForecastEntity(
timestamp = timestamp,
clouds = clouds ?: -1,
condition = condition,
humidity = humidity ?: -1.0,
icon = icon,
location = location,
maxTemp = maxTemp ?: -1.0,
minTemp = minTemp ?: -1.0,
night = night,
pressure = pressure ?: -1.0,
provider = provider,
providerUrl = providerUrl,
precipitation = precipitation ?: -1.0,
precipProbability = precipProbability ?: -1,
temperature = temperature,
updateTime = updateTime,
windDirection = windDirection ?: -1.0,
windSpeed = windSpeed ?: -1.0,
snow = -1.0,
snowProbability = -1
timestamp = timestamp,
clouds = clouds ?: -1,
condition = condition,
humidity = humidity ?: -1.0,
icon = icon,
location = location,
maxTemp = maxTemp ?: -1.0,
minTemp = minTemp ?: -1.0,
night = night,
pressure = pressure ?: -1.0,
provider = provider,
providerUrl = providerUrl,
precipitation = precipitation ?: -1.0,
precipProbability = precipProbability ?: -1,
temperature = temperature,
updateTime = updateTime,
windDirection = windDirection ?: -1.0,
windSpeed = windSpeed ?: -1.0,
snow = -1.0,
snowProbability = -1
)
}
constructor(entity: ForecastEntity) : this(
timestamp = entity.timestamp,
clouds = entity.clouds.takeIf { it >= 0 },
condition = entity.condition,
humidity = entity.humidity.takeIf { it >= 0.0 },
icon = entity.icon,
location = entity.location,
maxTemp = entity.maxTemp.takeIf { it >= 0.0 },
minTemp = entity.minTemp.takeIf { it >= 0.0 },
night = entity.night,
pressure = entity.pressure.takeIf { it >= 0.0 },
provider = entity.provider,
providerUrl = entity.providerUrl,
precipitation = entity.precipitation.takeIf { it >= 0.0 },
precipProbability = entity.precipProbability.takeIf { it >= 0 },
temperature = entity.temperature,
updateTime = entity.updateTime,
windDirection = entity.windDirection.takeIf { it >= 0.0 },
windSpeed = entity.windSpeed.takeIf { it >= 0.0 },
timestamp = entity.timestamp,
clouds = entity.clouds.takeIf { it >= 0 },
condition = entity.condition,
humidity = entity.humidity.takeIf { it >= 0.0 },
icon = entity.icon,
location = entity.location,
maxTemp = entity.maxTemp.takeIf { it >= 0.0 },
minTemp = entity.minTemp.takeIf { it >= 0.0 },
night = entity.night,
pressure = entity.pressure.takeIf { it >= 0.0 },
provider = entity.provider,
providerUrl = entity.providerUrl,
precipitation = entity.precipitation.takeIf { it >= 0.0 },
precipProbability = entity.precipProbability.takeIf { it >= 0 },
temperature = entity.temperature,
updateTime = entity.updateTime,
windDirection = entity.windDirection.takeIf { it >= 0.0 },
windSpeed = entity.windSpeed.takeIf { it >= 0.0 },
)
companion object {
const val NONE = -1
const val UNKNOWN = -1
const val CLEAR = 0
const val CLOUDY = 1
const val COLD = 2
const val DRIZZLE = 3
const val OVERCAST = 1
const val EXTREME_COLD = 2
const val LIGHT_RAIN = 3
const val HAZE = 4
const val FOG = 5
const val HAIL = 6
const val HEAVY_THUNDERSTORM = 7
const val HEAVY_THUNDERSTORM_WITH_RAIN = 8
const val HOT = 9
const val MOSTLY_CLOUDY = 10
const val EXTREME_HEAT = 9
const val PARTLY_CLOUDY = 11
const val SHOWERS = 12
const val RAIN = 12
const val SLEET = 13
const val SNOW = 14
const val STORM = 15
const val THUNDERSTORM = 16
const val THUNDERSTORM_WITH_RAIN = 17
const val THUNDER = 16
const val THUNDERSTORM = 17
const val WIND = 18
const val HEAVY_RAIN = 20
@Deprecated("Deprecated", ReplaceWith("THUNDER"))
const val HEAVY_THUNDERSTORM = 7
@Deprecated("Deprecated", ReplaceWith("THUNDERSTORM"))
const val HEAVY_THUNDERSTORM_WITH_RAIN = 8
@Deprecated("Deprecated", ReplaceWith("PARTLY_CLOUDY"))
const val MOSTLY_CLOUDY = 10
@Deprecated("Deprecated", ReplaceWith("WIND"))
const val STORM = 15
@Deprecated("Deprecated", ReplaceWith("PARTLY_CLOUDY"))
const val BROKEN_CLOUDS = 19
}
}

View File

@@ -1,47 +0,0 @@
package de.mm20.launcher2.weather
data class Weather2(
val timestamp: Long,
val temperature: Double,
val minTemp: Double,
val maxTemp: Double,
val pressure: Double,
val humidity: Double,
val icon: Int,
val condition: String,
val clouds: String,
val windSpeed: Double,
val windDirection: Double,
val rain: Double,
val snow: Double,
val night: Boolean,
val location: String,
val provider: String,
val providerUrl: String
) {
companion object {
const val NONE = -1
const val CLEAR = 0
const val CLOUDY = 1
const val COLD = 2
const val DRIZZLE = 3
const val HAZE = 4
const val FOG = 5
const val HAIL = 6
const val HEAVY_THUNDERSTORM = 7
const val HEAVY_THUNDERSTORM_WITH_RAIN = 8
const val HOT = 9
const val MOSTLY_CLOUDY = 10
const val PARTLY_CLOUDY = 11
const val SHOWERS = 12
const val SLEET = 13
const val SNOW = 14
const val STORM = 15
const val THUNDERSTORM = 16
const val THUNDERSTORM_WITH_RAIN = 17
const val WIND = 18
const val BROKEN_CLOUDS = 19
}
}

View File

@@ -102,8 +102,8 @@ class BreezyWeatherProvider(
return when (id) {
800 -> WeatherIcon.Clear
801 -> WeatherIcon.PartlyCloudy
803 -> WeatherIcon.Cloudy
500 -> WeatherIcon.Showers
803 -> WeatherIcon.Overcast
500 -> WeatherIcon.Rain
600 -> WeatherIcon.Snow
771 -> WeatherIcon.Wind
741 -> WeatherIcon.Fog
@@ -111,7 +111,7 @@ class BreezyWeatherProvider(
611 -> WeatherIcon.Sleet
511 -> WeatherIcon.Hail
210 -> WeatherIcon.Thunderstorm
211 -> WeatherIcon.ThunderstormWithRain
211 -> WeatherIcon.Thunderstorm
else -> WeatherIcon.Unknown
}
}

View File

@@ -87,10 +87,10 @@ internal class BrightSkyProvider(
return when (icon) {
"clear-day", "clear-night" -> Forecast.CLEAR
"partly-cloudy-day", "partly-cloudy-night" -> Forecast.PARTLY_CLOUDY
"cloudy" -> Forecast.CLOUDY
"cloudy" -> Forecast.OVERCAST
"fog" -> Forecast.FOG
"wind" -> Forecast.WIND
"rain" -> Forecast.SHOWERS
"rain" -> Forecast.RAIN
"sleet" -> Forecast.SLEET
"snow" -> Forecast.SNOW
"hail" -> Forecast.HAIL

View File

@@ -232,32 +232,35 @@ internal class MetNoProvider(
private fun iconForCode(code: String): Int {
return when (code.substringBefore("_")) {
"clearsky" -> Forecast.CLEAR
"fair" -> Forecast.PARTLY_CLOUDY
"partlycloudy" -> Forecast.MOSTLY_CLOUDY
"cloudy" -> Forecast.CLOUDY
"rainshowers", "rain", "lightrainshowers", "lightrain" -> Forecast.DRIZZLE
"rainshowersandthunder", "snowandthunder", "snowshowersandthunder",
"lightssnowshowersandthunder", "lightsleetandthunder",
"lightsnowandthunder" -> Forecast.THUNDERSTORM
"sleetshowers", "sleet", "lightsleetshowers", "heavysleetshowers", "lightsleet",
"heavysleet" -> Forecast.SLEET
"snowshowers", "snow", "lightsnowshowers", "heavysnowshowers", "lightsnow",
"heavysnow" -> Forecast.SNOW
"heavyrain", "heavyrainshowers" -> Forecast.SHOWERS
"heavyrainandthunder", "sleetshowersandthunder", "rainandthunder", "sleetandthunder",
"lightrainshowersandthunder", "heavyrainshowersandthunder",
"lightssleetshowersandthunder", "lightrainandthunder" -> Forecast.THUNDERSTORM_WITH_RAIN
"clearsky", "fair" -> Forecast.CLEAR
"partlycloudy" -> Forecast.PARTLY_CLOUDY
"cloudy" -> Forecast.OVERCAST
"fog" -> Forecast.FOG
"heavysleetshowersandthunder",
"heavysleetandthunder" -> Forecast.HEAVY_THUNDERSTORM_WITH_RAIN
"heavysnowshowersandthunder", "heavysnowandthunder" -> Forecast.HEAVY_THUNDERSTORM
else -> Forecast.NONE
"lightrain", "lightrainshowers" -> Forecast.LIGHT_RAIN
"heavyrain", "heavyrainshowers" -> Forecast.HEAVY_RAIN
"rain" -> Forecast.RAIN
"lightsleet", "lightsleetshowers", "heavysleet", "heavysleetshowers", "sleet" -> Forecast.SLEET
"snow", "lightsnow", "lightsnowshowers", "heavysnow", "heavysnowshowers" -> Forecast.SNOW
"rainandthunder",
"heavyrainandthunder",
"heavyrainshowersandthunder",
"lightrainshowersandthunder",
"lightrainandthunder",
"rainshowersandthunder",
"lightssnowshowersandthunder",
"lightsnowshowersandthunder",
"snowshowersandthunder",
"heavysnowandthunder",
"heavysnowshowersandthunder",
"heavysleetandthunder",
"lightssleetshowersandthunder",
"sleetshowersandthunder" -> Forecast.THUNDERSTORM
else -> Forecast.UNKNOWN
}
}

View File

@@ -162,27 +162,20 @@ internal class OpenWeatherMapProvider(
private fun iconForId(id: Int): Int {
return when (id) {
200, 201, in 230..232 -> Forecast.THUNDERSTORM_WITH_RAIN
202 -> Forecast.HEAVY_THUNDERSTORM_WITH_RAIN
210, 211 -> Forecast.THUNDERSTORM
212, 221 -> Forecast.HEAVY_THUNDERSTORM
in 300..302, in 310..312 -> Forecast.DRIZZLE
313, 314, 321, in 500..504, 511, in 520..522, 531 -> Forecast.SHOWERS
200, 201, 202, in 230..232 -> Forecast.THUNDERSTORM
210, 211, 212, 221 -> Forecast.THUNDER
in 300..302, in 310..312, 500, 520 -> Forecast.LIGHT_RAIN
313, 314, 321, 501, 511, 521, 531 -> Forecast.RAIN
502, 503, 504, 522 -> Forecast.HEAVY_RAIN
in 600..602 -> Forecast.SNOW
611, 612, 615, 616, in 620..622 -> Forecast.SLEET
701, 711, 731, 741, 761, 762 -> Forecast.FOG
721 -> Forecast.HAZE
771, 781, in 900..902, in 958..962 -> Forecast.STORM
701, 711, 741 -> Forecast.FOG
721, 731, 751, 761, 762 -> Forecast.HAZE
771, 781 -> Forecast.WIND
800 -> Forecast.CLEAR
801 -> Forecast.PARTLY_CLOUDY
802 -> Forecast.BROKEN_CLOUDS
803 -> Forecast.MOSTLY_CLOUDY
804, 951 -> Forecast.CLOUDY
903 -> Forecast.COLD
904 -> Forecast.HOT
905, in 952..957 -> Forecast.WIND
906 -> Forecast.HAIL
else -> Forecast.NONE
801, 802, 803 -> Forecast.PARTLY_CLOUDY
804-> Forecast.OVERCAST
else -> Forecast.UNKNOWN
}
}

View File

@@ -5,14 +5,9 @@ import android.database.Cursor
import android.net.Uri
import android.os.CancellationSignal
import android.util.Log
import androidx.core.database.getDoubleOrNull
import androidx.core.database.getIntOrNull
import androidx.core.database.getLongOrNull
import androidx.core.database.getStringOrNull
import de.mm20.launcher2.crashreporter.CrashReporter
import de.mm20.launcher2.plugin.PluginApi
import de.mm20.launcher2.plugin.config.WeatherPluginConfig
import de.mm20.launcher2.plugin.contracts.PluginContract
import de.mm20.launcher2.plugin.contracts.WeatherPluginContract
import de.mm20.launcher2.plugin.contracts.WeatherPluginContract.ForecastColumns
import de.mm20.launcher2.plugin.contracts.WeatherPluginContract.LocationColumns
@@ -142,26 +137,35 @@ internal class PluginWeatherProvider(
private fun getIcon(icon: String): Int {
return when (icon) {
"Clear" -> Forecast.CLEAR
"Cloudy" -> Forecast.CLOUDY
"Cold" -> Forecast.COLD
"Drizzle" -> Forecast.DRIZZLE
"Haze" -> Forecast.HAZE
"Fog" -> Forecast.FOG
"Hail" -> Forecast.HAIL
"HeavyThunderstorm" -> Forecast.HEAVY_THUNDERSTORM
"HeavyThunderstormWithRain" -> Forecast.HEAVY_THUNDERSTORM_WITH_RAIN
"Hot" -> Forecast.HOT
"MostlyCloudy" -> Forecast.MOSTLY_CLOUDY
"PartlyCloudy" -> Forecast.PARTLY_CLOUDY
"Showers" -> Forecast.SHOWERS
"Overcast" -> Forecast.OVERCAST
"Rain" -> Forecast.RAIN
"LightRain" -> Forecast.LIGHT_RAIN
"HeavyRain" -> Forecast.HEAVY_RAIN
"Sleet" -> Forecast.SLEET
"Snow" -> Forecast.SNOW
"Storm" -> Forecast.STORM
"Hail" -> Forecast.HAIL
"Thunder" -> Forecast.THUNDER
"Thunderstorm" -> Forecast.THUNDERSTORM
"ThunderstormWithRain" -> Forecast.THUNDERSTORM_WITH_RAIN
"Wind" -> Forecast.WIND
"BrokenClouds" -> Forecast.BROKEN_CLOUDS
else -> Forecast.NONE
"ExtremeHeat" -> Forecast.EXTREME_HEAT
"ExtremeCold" -> Forecast.EXTREME_COLD
// Deprecated values
"Cloudy" -> Forecast.OVERCAST
"Storm" -> Forecast.WIND
"HeavyThunderstorm" -> Forecast.THUNDER
"HeavyThunderstormWithRain" -> Forecast.THUNDERSTORM
"ThunderstormWithRain" -> Forecast.THUNDERSTORM
"MostlyCloudy" -> Forecast.PARTLY_CLOUDY
"BrokenClouds" -> Forecast.PARTLY_CLOUDY
"Hot" -> Forecast.EXTREME_HEAT
"Cold" -> Forecast.EXTREME_COLD
"Showers" -> Forecast.RAIN
"Drizzle" -> Forecast.LIGHT_RAIN
else -> Forecast.UNKNOWN
}
}