Connect weather.gov api

This commit is contained in:
Tommaso Berlose
2020-10-05 19:07:52 +02:00
parent e9c0cdd61c
commit bd4869540b
12 changed files with 216 additions and 32 deletions

View File

@ -44,6 +44,7 @@ object WeatherHelper {
fun removeWeather(context: Context) {
Preferences.remove(Preferences::weatherTemp)
Preferences.remove(Preferences::weatherRealTempUnit)
Preferences.remove(Preferences::weatherIcon)
MainWidget.updateWidget(context)
}
@ -80,6 +81,40 @@ object WeatherHelper {
})
}
fun getProviderInfoTitle(context: Context): String {
return context.getString(when(Constants.WeatherProvider.fromInt(Preferences.weatherProvider)) {
Constants.WeatherProvider.OPEN_WEATHER -> R.string.weather_provider_info_open_weather_title
Constants.WeatherProvider.WEATHER_BIT -> R.string.weather_provider_info_weatherbit_title
Constants.WeatherProvider.FORECA -> R.string.weather_provider_info_foreca_title
Constants.WeatherProvider.HERE -> R.string.weather_provider_info_here_title
Constants.WeatherProvider.ACCUWEATHER -> R.string.weather_provider_info_accuweather_title
Constants.WeatherProvider.WEATHER_GOV -> R.string.weather_provider_info_weather_gov_title
Constants.WeatherProvider.YR -> R.string.weather_provider_info_yr_title
Constants.WeatherProvider.SMHI -> R.string.weather_provider_info_smhi_title
Constants.WeatherProvider.WEATHER_CA -> R.string.weather_provider_info_weather_ca_title
Constants.WeatherProvider.BOM -> R.string.weather_provider_info_bom_title
Constants.WeatherProvider.METEOFRANCE -> R.string.weather_provider_info_meteofrance_title
else -> R.string.nothing
})
}
fun getProviderInfoSubtitle(context: Context): String {
return context.getString(when(Constants.WeatherProvider.fromInt(Preferences.weatherProvider)) {
Constants.WeatherProvider.OPEN_WEATHER -> R.string.weather_provider_info_open_weather_subtitle
Constants.WeatherProvider.WEATHER_BIT -> R.string.weather_provider_info_weatherbit_subtitle
Constants.WeatherProvider.FORECA -> R.string.weather_provider_info_foreca_subtitle
Constants.WeatherProvider.HERE -> R.string.weather_provider_info_here_subtitle
Constants.WeatherProvider.ACCUWEATHER -> R.string.weather_provider_info_accuweather_subtitle
Constants.WeatherProvider.WEATHER_GOV -> R.string.weather_provider_info_weather_gov_subtitle
Constants.WeatherProvider.YR -> R.string.weather_provider_info_yr_subtitle
Constants.WeatherProvider.SMHI -> R.string.weather_provider_info_smhi_subtitle
Constants.WeatherProvider.WEATHER_CA -> R.string.weather_provider_info_weather_ca_subtitle
Constants.WeatherProvider.BOM -> R.string.weather_provider_info_bom_subtitle
Constants.WeatherProvider.METEOFRANCE -> R.string.weather_provider_info_meteofrance_subtitle
else -> R.string.nothing
})
}
fun getProviderLink(): String {
return when(Constants.WeatherProvider.fromInt(Preferences.weatherProvider)) {
Constants.WeatherProvider.OPEN_WEATHER -> "https://home.openweathermap.org/users/sign_up"
@ -315,4 +350,43 @@ object WeatherHelper {
}
}
}
fun getWeatherGovIcon(iconString: String, isDaytime: Boolean): String = when {
iconString.contains("skc") -> "01"
iconString.contains("few") -> "02"
iconString.contains("sct") -> "03"
iconString.contains("bkn") -> "04"
iconString.contains("ovc") -> "04"
iconString.contains("wind_skc") -> "01"
iconString.contains("wind_few") -> "02"
iconString.contains("wind_sct") -> "03"
iconString.contains("wind_bkn") -> "04"
iconString.contains("wind_ovc") -> "04"
iconString.contains("snow") -> "13"
iconString.contains("rain_snow") -> "81"
iconString.contains("rain_sleet") -> "81"
iconString.contains("snow_sleet") -> "81"
iconString.contains("fzra") -> "81"
iconString.contains("rain_fzra") -> "81"
iconString.contains("snow_fzra") -> "81"
iconString.contains("sleet") -> "81"
iconString.contains("rain") -> "10"
iconString.contains("rain_showers") -> "10"
iconString.contains("rain_showers_hi") -> "10"
iconString.contains("tsra") -> "82"
iconString.contains("tsra_sct") -> "82"
iconString.contains("tsra_hi") -> "82"
iconString.contains("tornado") -> "80"
iconString.contains("hurricane") -> "80"
iconString.contains("tropical_storm") -> "09"
iconString.contains("dust") -> "Dust"
iconString.contains("smoke") -> "Smoke"
iconString.contains("haze") -> "50"
iconString.contains("hot") -> "01"
iconString.contains("cold") -> "13"
iconString.contains("blizzard") -> "80"
iconString.contains("fog") -> "82"
else -> ""
} + if (isDaytime) "d" else "n"
}

View File

@ -3,10 +3,13 @@ package com.tommasoberlose.anotherwidget.network
import android.content.Context
import android.util.Log
import com.google.gson.internal.LinkedTreeMap
import com.haroldadmin.cnradapter.NetworkResponse
import com.haroldadmin.cnradapter.executeWithRetry
import com.kwabenaberko.openweathermaplib.constants.Units
import com.kwabenaberko.openweathermaplib.implementation.OpenWeatherMapHelper
import com.kwabenaberko.openweathermaplib.implementation.callbacks.CurrentWeatherCallback
import com.kwabenaberko.openweathermaplib.models.currentweather.CurrentWeather
import com.tommasoberlose.anotherwidget.R
import com.tommasoberlose.anotherwidget.global.Constants
import com.tommasoberlose.anotherwidget.global.Preferences
import com.tommasoberlose.anotherwidget.helpers.WeatherHelper
@ -22,6 +25,9 @@ import java.lang.Exception
class WeatherNetworkApi(val context: Context) {
fun updateWeather() {
Preferences.weatherProviderError = ""
Preferences.weatherProviderLocationError = ""
if (Preferences.showWeather && Preferences.customLocationLat != "" && Preferences.customLocationLon != "") {
when (Constants.WeatherProvider.fromInt(Preferences.weatherProvider)) {
Constants.WeatherProvider.OPEN_WEATHER -> useOpenWeatherMap(context)
@ -56,6 +62,9 @@ class WeatherNetworkApi(val context: Context) {
})
} else {
Preferences.weatherProviderError = context.getString(R.string.weather_provider_error_missing_key)
Preferences.weatherProviderLocationError = ""
WeatherHelper.removeWeather(
context
)
@ -65,23 +74,65 @@ class WeatherNetworkApi(val context: Context) {
private fun useWeatherGov(context: Context) {
CoroutineScope(Dispatchers.IO).launch {
val repository = WeatherGovRepository()
try {
val points = repository.getGridPoints(
val pointsResponse = executeWithRetry(times = 5) {
repository.getGridPoints(
Preferences.customLocationLat,
Preferences.customLocationLon
)
val pp = points["properties"] as LinkedTreeMap<*,*>
val gridId = pp["gridId"] as String
val gridX = pp["gridX"] as Double
val gridY = pp["gridY"] as Double
val weather = repository.getWeather(gridId, gridX, gridY)
Log.d("ciao", weather.toString())
} catch (ex: Exception) {
Log.d("ciao", ex.localizedMessage)
}
when (pointsResponse) {
is NetworkResponse.Success -> {
try {
val pp = pointsResponse.body["properties"] as LinkedTreeMap<*, *>
val gridId = pp["gridId"] as String
val gridX = pp["gridX"] as Double
val gridY = pp["gridY"] as Double
when (val weatherResponse = repository.getWeather(
gridId,
gridX,
gridY,
if (Preferences.weatherTempUnit == "F") "us" else "si"
)) {
is NetworkResponse.Success -> {
try {
val props =
weatherResponse.body["properties"] as LinkedTreeMap<*, *>
val periods = props["periods"] as List<*>
val now = periods[0] as LinkedTreeMap<*, *>
val temp = now["temperature"] as Double
val fullIcon = now["icon"] as String
val isDaytime = now["isDaytime"] as Boolean
Preferences.weatherTemp = temp.toFloat()
Preferences.weatherIcon = WeatherHelper.getWeatherGovIcon(fullIcon, isDaytime)
Preferences.weatherRealTempUnit = Preferences.weatherTempUnit
MainWidget.updateWidget(context)
EventBus.getDefault().post(MainFragment.UpdateUiMessageEvent())
} catch (ex: Exception) {
}
}
}
} catch(ex: Exception) {
}
}
is NetworkResponse.ServerError -> {
if (pointsResponse.body?.containsKey("status") == true && (pointsResponse.body?.get("status") as Double).toInt() == 404) {
Preferences.weatherProviderError = ""
Preferences.weatherProviderLocationError = context.getString(R.string.weather_provider_error_wrong_location)
WeatherHelper.removeWeather(
context
)
}
}
}
}
}
}

View File

@ -1,12 +1,13 @@
package com.tommasoberlose.anotherwidget.network.api
import retrofit2.http.GET
import retrofit2.http.Path
import com.haroldadmin.cnradapter.NetworkResponse
import retrofit2.http.*
interface WeatherGovApiService {
@GET("points/{latitude},{longitude}")
suspend fun getGridPoints(@Path("latitude") latitude: String, @Path("longitude") longitude: String): HashMap<String, Any>
suspend fun getGridPoints(@Path("latitude") latitude: String, @Path("longitude") longitude: String): NetworkResponse<HashMap<String, Any>, HashMap<String, Any>>
@Headers("User-Agent: (Another Widget, tommaso.berlose@gmail.com)")
@GET("gridpoints/{gridId}/{gridX},{gridY}/forecast")
suspend fun getWeather(@Path("gridId") gridId: String, @Path("gridX") gridX: Int, @Path("gridY") gridY: Int): HashMap<String, Any>
suspend fun getWeather(@Path("gridId") gridId: String, @Path("gridX") gridX: Int, @Path("gridY") gridY: Int, @Query("units") unit: String): NetworkResponse<HashMap<String, Any>, HashMap<String, Any>>
}

View File

@ -1,15 +1,16 @@
package com.tommasoberlose.anotherwidget.network.repository
import com.haroldadmin.cnradapter.NetworkResponseAdapterFactory
import com.tommasoberlose.anotherwidget.network.api.WeatherGovApiService
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
class WeatherGovRepository() {
class WeatherGovRepository {
private val apiService: WeatherGovApiService = getRetrofit().create(WeatherGovApiService::class.java)
suspend fun getGridPoints(latitude: String, longitude: String) = apiService.getGridPoints(latitude, longitude)
suspend fun getWeather(gridId: String, gridX: Double, gridY: Double) = apiService.getWeather(gridId, gridX.toInt(), gridY.toInt())
suspend fun getWeather(gridId: String, gridX: Double, gridY: Double, unit: String) = apiService.getWeather(gridId, gridX.toInt(), gridY.toInt(), unit)
companion object {
private const val BASE_URL = "https://api.weather.gov/"
@ -17,6 +18,7 @@ class WeatherGovRepository() {
return Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(NetworkResponseAdapterFactory())
.build()
}
}

View File

@ -49,11 +49,22 @@ class WeatherProviderActivity : AppCompatActivity() {
viewModel.weatherProvider.observe(this, Observer {
weather_provider.editText?.setText(WeatherHelper.getProviderName(this, Constants.WeatherProvider.fromInt(Preferences.weatherProvider)!!).split("\n").first())
info_container.isVisible = WeatherHelper.isKeyRequired()
api_key_container.isVisible = WeatherHelper.isKeyRequired()
WeatherHelper.getProviderInfoTitle(this).let {
info_title.text = it
info_title.isVisible = it != ""
}
WeatherHelper.getProviderInfoSubtitle(this).let {
info_subtitle.text = it
info_subtitle.isVisible = it != ""
}
action_open_provider.text = WeatherHelper.getProviderLinkName(this)
})
viewModel.weatherProviderApi
}
private fun setListener() {
@ -80,7 +91,8 @@ class WeatherProviderActivity : AppCompatActivity() {
}
api_key.editText?.addTextChangedListener {
Preferences.weatherProviderApi = it?.toString() ?: ""
val key = it?.toString() ?: ""
Preferences.weatherProviderApi = key
}
}