From 5e58d52a0d7ccde9b4d5ea899b2e0eed4f3a84c1 Mon Sep 17 00:00:00 2001 From: johan12345 Date: Tue, 16 May 2023 21:33:59 +0200 Subject: [PATCH] Tesla AvailabilityDetector: add notice to sign in --- .../availability/EnBwAvailabilityDetector.kt | 4 +- .../NewMotionAvailabilityDetector.kt | 6 ++- .../availability/TeslaAvailabilityDetector.kt | 46 ++++++++++++------- .../vonforst/evmap/fragment/MapFragment.kt | 3 ++ .../preference/DataSettingsFragment.kt | 1 + app/src/main/res/layout/detail_view.xml | 16 ++++++- app/src/main/res/values-de/strings.xml | 1 + app/src/main/res/values/strings.xml | 1 + 8 files changed, 56 insertions(+), 22 deletions(-) diff --git a/app/src/main/java/net/vonforst/evmap/api/availability/EnBwAvailabilityDetector.kt b/app/src/main/java/net/vonforst/evmap/api/availability/EnBwAvailabilityDetector.kt index 7978108e..49cd46db 100644 --- a/app/src/main/java/net/vonforst/evmap/api/availability/EnBwAvailabilityDetector.kt +++ b/app/src/main/java/net/vonforst/evmap/api/availability/EnBwAvailabilityDetector.kt @@ -223,7 +223,7 @@ class EnBwAvailabilityDetector(client: OkHttpClient, baseUrl: String? = null) : "Slowenien", "Spanien", "Tschechien" - ) + ) && charger.network != "Tesla Supercharger" "openchargemap" -> country in listOf( "DE", "AT", @@ -242,7 +242,7 @@ class EnBwAvailabilityDetector(client: OkHttpClient, baseUrl: String? = null) : "SI", "ES", "CZ" - ) + ) && charger.chargepriceData?.network !in listOf("23", "3534") else -> false } } diff --git a/app/src/main/java/net/vonforst/evmap/api/availability/NewMotionAvailabilityDetector.kt b/app/src/main/java/net/vonforst/evmap/api/availability/NewMotionAvailabilityDetector.kt index d68cccdc..e02a0e1e 100644 --- a/app/src/main/java/net/vonforst/evmap/api/availability/NewMotionAvailabilityDetector.kt +++ b/app/src/main/java/net/vonforst/evmap/api/availability/NewMotionAvailabilityDetector.kt @@ -182,7 +182,11 @@ class NewMotionAvailabilityDetector(client: OkHttpClient, baseUrl: String? = nul override fun isChargerSupported(charger: ChargeLocation): Boolean { // NewMotion is our fallback - return true + return when (charger.dataSource) { + "goingelectric" -> charger.network != "Tesla Supercharger" + "openchargemap" -> charger.chargepriceData?.network !in listOf("23", "3534") + else -> false + } } } \ No newline at end of file diff --git a/app/src/main/java/net/vonforst/evmap/api/availability/TeslaAvailabilityDetector.kt b/app/src/main/java/net/vonforst/evmap/api/availability/TeslaAvailabilityDetector.kt index 7e3de840..f3a51376 100644 --- a/app/src/main/java/net/vonforst/evmap/api/availability/TeslaAvailabilityDetector.kt +++ b/app/src/main/java/net/vonforst/evmap/api/availability/TeslaAvailabilityDetector.kt @@ -5,6 +5,7 @@ import com.squareup.moshi.Json import com.squareup.moshi.JsonClass import com.squareup.moshi.Moshi import com.squareup.moshi.adapters.PolymorphicJsonAdapterFactory +import kotlinx.coroutines.runBlocking import net.vonforst.evmap.model.ChargeLocation import net.vonforst.evmap.model.Chargepoint import net.vonforst.evmap.model.Coordinate @@ -15,6 +16,7 @@ import retrofit2.http.Body import retrofit2.http.GET import retrofit2.http.POST import retrofit2.http.Query +import java.io.IOException import java.security.MessageDigest import java.security.SecureRandom import java.time.Instant @@ -55,8 +57,6 @@ interface TeslaAuthenticationApi { ) companion object { - private val charSet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" - fun create(client: OkHttpClient, baseUrl: String? = null): TeslaAuthenticationApi { val retrofit = Retrofit.Builder() .baseUrl(baseUrl ?: "https://auth.tesla.com") @@ -368,12 +368,17 @@ interface TeslaGraphQlApi { } companion object { - fun create(client: OkHttpClient, token: String, baseUrl: String? = null): TeslaGraphQlApi { + fun create( + client: OkHttpClient, + baseUrl: String? = null, + token: suspend () -> String + ): TeslaGraphQlApi { val clientWithInterceptor = client.newBuilder() .addInterceptor { chain -> + val t = runBlocking { token() } // add API key to every request val request = chain.request().newBuilder() - .header("Authorization", "Bearer $token") + .header("Authorization", "Bearer $t") .header("User-Agent", "okhttp/4.9.2") .header("x-tesla-user-agent", "TeslaApp/4.19.5-1667/3a5d531cc3/android/27") .header("Accept", "*/*") @@ -497,20 +502,27 @@ class TeslaAvailabilityDetector( } private suspend fun initApi(): TeslaGraphQlApi { + return api ?: run { - val now = Instant.now().epochSecond - val token = - tokenStore.teslaAccessToken.takeIf { tokenStore.teslaAccessTokenExpiry > now } - ?: run { - val refreshToken = tokenStore.teslaRefreshToken - ?: throw AvailabilityDetectorException("not signed in") - val response = - authApi.getToken(TeslaAuthenticationApi.RefreshTokenRequest(refreshToken)) - tokenStore.teslaAccessToken = response.accessToken - tokenStore.teslaAccessTokenExpiry = now + response.expiresIn - response.accessToken - } - val newApi = TeslaGraphQlApi.create(client, token, baseUrl) + val newApi = TeslaGraphQlApi.create(client, baseUrl) { + val now = Instant.now().epochSecond + val token = + tokenStore.teslaAccessToken.takeIf { tokenStore.teslaAccessTokenExpiry > now } + ?: run { + val refreshToken = tokenStore.teslaRefreshToken + ?: throw IOException("not signed in") + val response = + authApi.getToken( + TeslaAuthenticationApi.RefreshTokenRequest( + refreshToken + ) + ) + tokenStore.teslaAccessToken = response.accessToken + tokenStore.teslaAccessTokenExpiry = now + response.expiresIn + response.accessToken + } + token + } api = newApi newApi } diff --git a/app/src/main/java/net/vonforst/evmap/fragment/MapFragment.kt b/app/src/main/java/net/vonforst/evmap/fragment/MapFragment.kt index 2dfa782d..0b87e093 100644 --- a/app/src/main/java/net/vonforst/evmap/fragment/MapFragment.kt +++ b/app/src/main/java/net/vonforst/evmap/fragment/MapFragment.kt @@ -381,6 +381,9 @@ class MapFragment : Fragment(), OnMapReadyCallback, MapsActivity.FragmentCallbac val charger = vm.charger.value?.data ?: return@setOnClickListener charger.chargerUrl?.let { (activity as? MapsActivity)?.openUrl(it) } } + binding.detailView.btnLogin.setOnClickListener { + findNavController().navigate(R.id.settings_data) + } binding.detailView.imgPredictionSource.setOnClickListener { (activity as? MapsActivity)?.openUrl(getString(R.string.fronyx_url)) } diff --git a/app/src/main/java/net/vonforst/evmap/fragment/preference/DataSettingsFragment.kt b/app/src/main/java/net/vonforst/evmap/fragment/preference/DataSettingsFragment.kt index 53433f67..2df387f1 100644 --- a/app/src/main/java/net/vonforst/evmap/fragment/preference/DataSettingsFragment.kt +++ b/app/src/main/java/net/vonforst/evmap/fragment/preference/DataSettingsFragment.kt @@ -42,6 +42,7 @@ class DataSettingsFragment : BaseSettingsFragment() { override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) { setPreferencesFromResource(R.xml.settings_data, rootKey) teslaAccountPreference = findPreference("tesla_account")!! + refreshTeslaAccountStatus() } override fun onResume() { diff --git a/app/src/main/res/layout/detail_view.xml b/app/src/main/res/layout/detail_view.xml index b78d5c35..de342106 100644 --- a/app/src/main/res/layout/detail_view.xml +++ b/app/src/main/res/layout/detail_view.xml @@ -311,10 +311,11 @@ android:id="@+id/textView13" android:layout_width="0dp" android:layout_height="wrap_content" + android:layout_marginEnd="8dp" android:gravity="right|end" - android:text="@{availability.status == Status.SUCCESS ? @string/realtime_data_source(availability.data.source) : availability.status == Status.LOADING ? @string/realtime_data_loading : @string/realtime_data_unavailable}" + android:text="@{availability.status == Status.SUCCESS ? @string/realtime_data_source(availability.data.source) : availability.status == Status.LOADING ? @string/realtime_data_loading : availability.message == "not signed in" ? @string/realtime_data_login_needed : @string/realtime_data_unavailable}" android:textAppearance="@style/TextAppearance.Material3.BodySmall" - app:layout_constraintEnd_toStartOf="@+id/guideline2" + app:layout_constraintEnd_toStartOf="@+id/btnLogin" app:layout_constraintStart_toStartOf="@+id/guideline" app:layout_constraintTop_toBottomOf="@+id/connectors" tools:text="Echtzeitdaten nicht verfügbar" /> @@ -526,6 +527,17 @@ +