Tesla AvailabilityDetector: add notice to sign in

This commit is contained in:
johan12345
2023-05-16 21:33:59 +02:00
parent eddc1f9b61
commit 5e58d52a0d
8 changed files with 56 additions and 22 deletions

View File

@@ -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
}
}

View File

@@ -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
}
}
}

View File

@@ -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
}

View File

@@ -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))
}

View File

@@ -42,6 +42,7 @@ class DataSettingsFragment : BaseSettingsFragment() {
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
setPreferencesFromResource(R.xml.settings_data, rootKey)
teslaAccountPreference = findPreference<Preference>("tesla_account")!!
refreshTeslaAccountStatus()
}
override fun onResume() {

View File

@@ -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 == &quot;not signed in&quot; ? @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 @@
</LinearLayout>
</HorizontalScrollView>
<Button
android:id="@+id/btnLogin"
style="@style/Widget.Material3.Button.TextButton.Dialog"
android:layout_width="wrap_content"
android:layout_height="40dp"
android:text="@string/login"
app:goneUnless="@{availability.status == Status.ERROR &amp;&amp; availability.message == &quot;not signed in&quot;}"
app:layout_constraintBottom_toBottomOf="@+id/textView13"
app:layout_constraintEnd_toStartOf="@+id/guideline2"
app:layout_constraintTop_toTopOf="@+id/textView13" />
</androidx.constraintlayout.widget.ConstraintLayout>
</com.google.android.material.card.MaterialCardView>

View File

@@ -26,6 +26,7 @@
<string name="amenities">Ausstattung</string>
<string name="general_info">Allgemein</string>
<string name="realtime_data_unavailable">Echtzeitstatus nicht verfügbar</string>
<string name="realtime_data_login_needed">Tesla-Account für Echtzeitdaten benötigt</string>
<string name="realtime_data_loading">Prüfe Echtzeitstatus…</string>
<string name="realtime_data_source">Quelle Echtzeitdaten (beta): %s</string>
<string name="source">Quelle: %s</string>

View File

@@ -26,6 +26,7 @@
<string name="amenities">Amenities</string>
<string name="general_info">General info</string>
<string name="realtime_data_unavailable">Real-time status unavailable</string>
<string name="realtime_data_login_needed">Tesla account needed for real-time data</string>
<string name="realtime_data_loading">Checking real-time status…</string>
<string name="realtime_data_source">Real-time status source (beta): %s</string>
<string name="source">Source: %s</string>