Add UV Index to current weather and forecast (#159)
This commit is contained in:
parent
be7ca192b2
commit
5169048143
@ -294,9 +294,9 @@ fun lerpWeather(
|
||||
weatherCode = closestWeatherData.weatherCode,
|
||||
isForecast = closestWeatherData.isForecast,
|
||||
isNight = closestWeatherData.isNight,
|
||||
uvi = start.uvi + (end.uvi - start.uvi) * factor
|
||||
)
|
||||
}
|
||||
|
||||
fun lerpWeatherTime(
|
||||
weatherData: List<WeatherData>?,
|
||||
currentWeatherData: WeatherData
|
||||
|
||||
@ -17,6 +17,7 @@ import de.timklge.karooheadwind.datatypes.SealevelPressureDataType
|
||||
import de.timklge.karooheadwind.datatypes.SurfacePressureDataType
|
||||
import de.timklge.karooheadwind.datatypes.TailwindAndRideSpeedDataType
|
||||
import de.timklge.karooheadwind.datatypes.TemperatureDataType
|
||||
import de.timklge.karooheadwind.datatypes.UviDataType
|
||||
import de.timklge.karooheadwind.datatypes.TemperatureForecastDataType
|
||||
import de.timklge.karooheadwind.datatypes.WeatherForecastDataType
|
||||
import de.timklge.karooheadwind.datatypes.WindDirectionAndSpeedDataType
|
||||
@ -83,7 +84,8 @@ class KarooHeadwindExtension : KarooExtension("karoo-headwind", BuildConfig.VERS
|
||||
WindDirectionAndSpeedDataType(karooSystem, applicationContext),
|
||||
RelativeGradeDataType(karooSystem, applicationContext),
|
||||
RelativeElevationGainDataType(karooSystem, applicationContext),
|
||||
TemperatureDataType(karooSystem, applicationContext)
|
||||
TemperatureDataType(karooSystem, applicationContext),
|
||||
UviDataType(karooSystem, applicationContext)
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@ -65,14 +65,14 @@ import kotlinx.coroutines.flow.flow
|
||||
import kotlinx.coroutines.launch
|
||||
import java.time.Instant
|
||||
import java.time.ZoneId
|
||||
import java.time.format.DateTimeFormatter
|
||||
import java.time.temporal.ChronoUnit
|
||||
import kotlin.math.abs
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
abstract class ForecastDataType(private val karooSystem: KarooSystemService, typeId: String) : DataTypeImpl("karoo-headwind", typeId) {
|
||||
@Composable
|
||||
abstract fun RenderWidget(arrowBitmap: Bitmap,
|
||||
abstract fun RenderWidget(
|
||||
arrowBitmap: Bitmap,
|
||||
current: WeatherInterpretation,
|
||||
windBearing: Int,
|
||||
windSpeed: Int,
|
||||
@ -85,7 +85,9 @@ abstract class ForecastDataType(private val karooSystem: KarooSystemService, typ
|
||||
dateLabel: String?,
|
||||
distance: Double?,
|
||||
isImperial: Boolean,
|
||||
isNight: Boolean)
|
||||
isNight: Boolean,
|
||||
uvi: Double
|
||||
)
|
||||
|
||||
@OptIn(ExperimentalGlanceRemoteViewsApi::class)
|
||||
private val glance = GlanceRemoteViews()
|
||||
@ -107,6 +109,7 @@ abstract class ForecastDataType(private val karooSystem: KarooSystemService, typ
|
||||
val weatherData = (0..<12).map {
|
||||
val forecastTime = timeAtFullHour + it * 60 * 60
|
||||
val forecastTemperature = 20.0 + (-20..20).random()
|
||||
val forecastUvi = 0.0 + (0..12).random().toDouble()
|
||||
val forecastPrecipitation = 0.0 + (0..10).random()
|
||||
val forecastPrecipitationProbability = (0..100).random()
|
||||
val forecastWeatherCode = WeatherInterpretation.getKnownWeatherCodes().random()
|
||||
@ -127,7 +130,8 @@ abstract class ForecastDataType(private val karooSystem: KarooSystemService, typ
|
||||
windGusts = forecastWindGusts,
|
||||
weatherCode = forecastWeatherCode,
|
||||
isForecast = true,
|
||||
isNight = it < 2
|
||||
isNight = it < 2,
|
||||
uvi = forecastUvi
|
||||
)
|
||||
}
|
||||
|
||||
@ -149,7 +153,8 @@ abstract class ForecastDataType(private val karooSystem: KarooSystemService, typ
|
||||
windGusts = 10.0,
|
||||
weatherCode = WeatherInterpretation.getKnownWeatherCodes().random(),
|
||||
isForecast = false,
|
||||
isNight = false
|
||||
isNight = false,
|
||||
uvi = 2.0
|
||||
),
|
||||
coords = GpsCoordinates(0.0, 0.0, distanceAlongRoute = index * distancePerHour),
|
||||
timezone = "UTC",
|
||||
@ -333,7 +338,8 @@ abstract class ForecastDataType(private val karooSystem: KarooSystemService, typ
|
||||
dateLabel = if (hasNewDate) formattedDate else null,
|
||||
distance = null,
|
||||
isImperial = settingsAndProfile.isImperial,
|
||||
isNight = data.current.isNight
|
||||
isNight = data.current.isNight,
|
||||
uvi = data.current.uvi
|
||||
)
|
||||
|
||||
previousDate = formattedDate
|
||||
@ -359,7 +365,8 @@ abstract class ForecastDataType(private val karooSystem: KarooSystemService, typ
|
||||
dateLabel = if (hasNewDate) formattedDate else null,
|
||||
distance = if (settingsAndProfile.settings.showDistanceInForecast) distanceFromCurrent else null,
|
||||
isImperial = settingsAndProfile.isImperial,
|
||||
isNight = weatherData?.isNight == true
|
||||
isNight = weatherData?.isNight == true,
|
||||
uvi = weatherData?.uvi ?: 0.0
|
||||
)
|
||||
|
||||
previousDate = formattedDate
|
||||
|
||||
@ -94,6 +94,7 @@ abstract class LineGraphForecastDataType(private val karooSystem: KarooSystemSer
|
||||
val forecastWindSpeed = 0.0 + (0..10).random()
|
||||
val forecastWindDirection = 0.0 + (0..360).random()
|
||||
val forecastWindGusts = 0.0 + (0..10).random()
|
||||
val forcastUvi = 0.0 + (0..12).random()
|
||||
WeatherData(
|
||||
time = forecastTime,
|
||||
temperature = forecastTemperature,
|
||||
@ -108,7 +109,8 @@ abstract class LineGraphForecastDataType(private val karooSystem: KarooSystemSer
|
||||
windGusts = forecastWindGusts,
|
||||
weatherCode = forecastWeatherCode,
|
||||
isForecast = true,
|
||||
isNight = it < 2
|
||||
isNight = it < 2,
|
||||
uvi = forcastUvi
|
||||
)
|
||||
}
|
||||
|
||||
@ -130,7 +132,8 @@ abstract class LineGraphForecastDataType(private val karooSystem: KarooSystemSer
|
||||
windGusts = 10.0,
|
||||
weatherCode = WeatherInterpretation.getKnownWeatherCodes().random(),
|
||||
isForecast = false,
|
||||
isNight = false
|
||||
isNight = false,
|
||||
uvi = 2.0
|
||||
),
|
||||
coords = GpsCoordinates(0.0, 0.0, distanceAlongRoute = index * distancePerHour),
|
||||
timezone = "UTC",
|
||||
|
||||
@ -0,0 +1,12 @@
|
||||
package de.timklge.karooheadwind.datatypes
|
||||
|
||||
import android.content.Context
|
||||
import de.timklge.karooheadwind.weatherprovider.WeatherData
|
||||
import io.hammerhead.karooext.KarooSystemService
|
||||
import io.hammerhead.karooext.models.UserProfile
|
||||
|
||||
class UviDataType(karooSystemService: KarooSystemService, context: Context) : BaseDataType(karooSystemService, context, "uvi"){
|
||||
override fun getValue(data: WeatherData, userProfile: UserProfile): Double {
|
||||
return data.uvi
|
||||
}
|
||||
}
|
||||
@ -23,6 +23,7 @@ class WeatherForecastDataType(karooSystem: KarooSystemService) : ForecastDataTyp
|
||||
distance: Double?,
|
||||
isImperial: Boolean,
|
||||
isNight: Boolean,
|
||||
uvi: Double,
|
||||
) {
|
||||
Weather(
|
||||
arrowBitmap = arrowBitmap,
|
||||
|
||||
@ -17,6 +17,7 @@ data class WeatherData(
|
||||
val windGusts: Double,
|
||||
val weatherCode: Int,
|
||||
val isForecast: Boolean,
|
||||
val isNight: Boolean
|
||||
val isNight: Boolean,
|
||||
val uvi: Double,
|
||||
)
|
||||
|
||||
|
||||
@ -18,6 +18,7 @@ data class OpenMeteoWeatherData(
|
||||
@SerialName("wind_gusts_10m") val windGusts: Double,
|
||||
@SerialName("weather_code") val weatherCode: Int,
|
||||
@SerialName("is_day") val isDay: Int,
|
||||
@SerialName("uv_index") val uvi: Double,
|
||||
) {
|
||||
fun toWeatherData(): WeatherData = WeatherData(
|
||||
temperature = temperature,
|
||||
@ -33,6 +34,7 @@ data class OpenMeteoWeatherData(
|
||||
time = time,
|
||||
isForecast = false,
|
||||
isNight = isDay == 0,
|
||||
uvi = uvi
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@ -19,6 +19,7 @@ data class OpenMeteoWeatherForecastData(
|
||||
@SerialName("pressure_msl") val sealevelPressure: List<Double>,
|
||||
@SerialName("is_day") val isDay: List<Int>,
|
||||
@SerialName("relative_humidity_2m") val relativeHumidity: List<Int>,
|
||||
@SerialName("uv_index") val uvi: List<Double>,
|
||||
) {
|
||||
fun toWeatherData(): List<WeatherData> {
|
||||
return time.mapIndexed { index, t ->
|
||||
@ -37,6 +38,7 @@ data class OpenMeteoWeatherForecastData(
|
||||
surfacePressure = surfacePressure[index],
|
||||
sealevelPressure = sealevelPressure[index],
|
||||
relativeHumidity = relativeHumidity[index],
|
||||
uvi = uvi[index]
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@ -30,7 +30,7 @@ class OpenMeteoWeatherProvider : WeatherProvider {
|
||||
// https://api.open-meteo.com/v1/forecast?latitude=52.52&longitude=13.41¤t=is_day,surface_pressure,pressure_msl,temperature_2m,relative_humidity_2m,precipitation,weather_code,cloud_cover,wind_speed_10m,wind_direction_10m,wind_gusts_10m&hourly=temperature_2m,precipitation_probability,precipitation,weather_code,wind_speed_10m,wind_direction_10m,wind_gusts_10m&timeformat=unixtime&past_hours=1&forecast_days=1&forecast_hours=12
|
||||
val lats = gpsCoordinates.joinToString(",") { String.format(Locale.US, "%.6f", it.lat) }
|
||||
val lons = gpsCoordinates.joinToString(",") { String.format(Locale.US, "%.6f", it.lon) }
|
||||
val url = "https://api.open-meteo.com/v1/forecast?latitude=${lats}&longitude=${lons}¤t=is_day,surface_pressure,pressure_msl,temperature_2m,relative_humidity_2m,precipitation,weather_code,cloud_cover,wind_speed_10m,wind_direction_10m,wind_gusts_10m&hourly=temperature_2m,precipitation_probability,precipitation,weather_code,wind_speed_10m,wind_direction_10m,wind_gusts_10m,is_day,surface_pressure,pressure_msl,relative_humidity_2m,cloud_cover&timeformat=unixtime&past_hours=0&forecast_days=1&forecast_hours=12&wind_speed_unit=ms"
|
||||
val url = "https://api.open-meteo.com/v1/forecast?latitude=${lats}&longitude=${lons}¤t=is_day,surface_pressure,pressure_msl,uv_index,temperature_2m,relative_humidity_2m,precipitation,weather_code,cloud_cover,wind_speed_10m,wind_direction_10m,wind_gusts_10m&hourly=uv_index,temperature_2m,precipitation_probability,precipitation,weather_code,wind_speed_10m,wind_direction_10m,wind_gusts_10m,is_day,surface_pressure,pressure_msl,relative_humidity_2m,cloud_cover&timeformat=unixtime&past_hours=0&forecast_days=1&forecast_hours=12&wind_speed_unit=ms"
|
||||
|
||||
Log.d(KarooHeadwindExtension.TAG, "Http request to ${url}...")
|
||||
|
||||
|
||||
@ -20,7 +20,8 @@ data class OpenWeatherMapForecastData(
|
||||
val pop: Double,
|
||||
val rain: Rain? = null,
|
||||
val snow: Snow? = null,
|
||||
val weather: List<Weather>
|
||||
val weather: List<Weather>,
|
||||
val uvi: Double,
|
||||
) {
|
||||
fun toWeatherData(currentWeatherData: OpenWeatherMapWeatherData): WeatherData {
|
||||
val dtInstant = Instant.ofEpochSecond(dt)
|
||||
@ -32,6 +33,7 @@ data class OpenWeatherMapForecastData(
|
||||
val sunsetTime = sunsetInstant.atZone(ZoneOffset.UTC).toLocalTime()
|
||||
|
||||
return WeatherData(
|
||||
uvi = uvi,
|
||||
temperature = temp,
|
||||
relativeHumidity = humidity,
|
||||
precipitation = rain?.h1 ?: 0.0,
|
||||
|
||||
@ -19,9 +19,11 @@ data class OpenWeatherMapWeatherData(
|
||||
val wind_gust: Double? = null,
|
||||
val rain: Rain? = null,
|
||||
val snow: Snow? = null,
|
||||
val uvi: Double,
|
||||
val weather: List<Weather>){
|
||||
|
||||
fun toWeatherData(): WeatherData = WeatherData(
|
||||
uvi = uvi,
|
||||
temperature = temp,
|
||||
relativeHumidity = humidity,
|
||||
precipitation = rain?.h1 ?: 0.0,
|
||||
|
||||
@ -22,6 +22,8 @@
|
||||
<string name="sealevelPressure">Sealevel pressure</string>
|
||||
<string name="sealevelPressure_description">Atmospheric pressure at sea level in configured unit</string>
|
||||
<string name="weather_forecast">Weather Forecast</string>
|
||||
<string name="uvi">UV Index</string>
|
||||
<string name="uvi_description">Current UV Index at current location</string>
|
||||
<string name="weather_forecast_description">Current hourly weather forecast</string>
|
||||
<string name="temperature_forecast">Temperature Forecast</string>
|
||||
<string name="temperature_forecast_description">Current hourly temperature forecast</string>
|
||||
|
||||
@ -131,6 +131,13 @@
|
||||
icon="@drawable/thermometer"
|
||||
typeId="temperature" />
|
||||
|
||||
<DataType
|
||||
description="@string/uvi_description"
|
||||
displayName="@string/uvi"
|
||||
graphical="false"
|
||||
icon="@drawable/thermometer"
|
||||
typeId="uvi" />
|
||||
|
||||
<DataType
|
||||
description="@string/relativeGrade_description"
|
||||
displayName="@string/relativeGrade"
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user