mirror of
https://github.com/ev-map/EVMap.git
synced 2025-12-27 17:17:45 -05:00
Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0c5bd69205 | ||
|
|
72e98cf611 | ||
|
|
0fefffda2f | ||
|
|
49e555ef04 | ||
|
|
d6d1e915ee | ||
|
|
546d7a11ce |
@@ -20,8 +20,8 @@ android {
|
||||
minSdk = 21
|
||||
targetSdk = 34
|
||||
// NOTE: always increase versionCode by 2 since automotive flavor uses versionCode + 1
|
||||
versionCode = 224
|
||||
versionName = "1.9.3"
|
||||
versionCode = 226
|
||||
versionName = "1.9.4"
|
||||
|
||||
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
|
||||
}
|
||||
@@ -306,7 +306,7 @@ dependencies {
|
||||
implementation("com.google.guava:guava:29.0-android")
|
||||
implementation("com.github.pengrad:mapscaleview:1.6.0")
|
||||
implementation("com.github.romandanylyk:PageIndicatorView:b1bad589b5")
|
||||
implementation("com.github.erfansn:locale-config-x:1.0.0")
|
||||
implementation("com.github.ev-map:locale-config-x:e9e56b4111")
|
||||
|
||||
// Android Auto
|
||||
val carAppVersion = "1.4.0"
|
||||
@@ -323,6 +323,9 @@ dependencies {
|
||||
// duplicates classes from mapbox-sdk-services
|
||||
exclude("org.maplibre.gl", "android-sdk-geojson")
|
||||
}
|
||||
implementation("org.maplibre.gl:android-sdk:10.3.2-pre2") {
|
||||
exclude("org.maplibre.gl", "android-sdk-geojson")
|
||||
}
|
||||
|
||||
// Google Places
|
||||
googleImplementation("com.google.android.libraries.places:places:3.5.0")
|
||||
|
||||
@@ -136,7 +136,7 @@ class MapsActivity : AppCompatActivity(),
|
||||
.createPendingIntent()
|
||||
}
|
||||
} else if (intent?.scheme == "https" && intent?.data?.host == "www.goingelectric.de") {
|
||||
val id = intent.data?.pathSegments?.last()?.toLongOrNull()
|
||||
val id = intent.data?.pathSegments?.lastOrNull()?.toLongOrNull()
|
||||
if (id != null) {
|
||||
if (prefs.dataSource != "goingelectric") {
|
||||
prefs.dataSource = "goingelectric"
|
||||
@@ -157,7 +157,7 @@ class MapsActivity : AppCompatActivity(),
|
||||
}
|
||||
} else if (intent?.scheme == "https" && intent?.data?.host in listOf("openchargemap.org", "map.openchargemap.io")) {
|
||||
val id = when (intent.data?.host) {
|
||||
"openchargemap.org" -> intent.data?.pathSegments?.last()?.toLongOrNull()
|
||||
"openchargemap.org" -> intent.data?.pathSegments?.lastOrNull()?.toLongOrNull()
|
||||
"map.openchargemap.io" -> intent.data?.getQueryParameter("id")?.toLongOrNull()
|
||||
else -> null
|
||||
}
|
||||
|
||||
@@ -52,32 +52,31 @@ class TeslaGuestAvailabilityDetector(
|
||||
|
||||
val (detailsA, guestPricing) = coroutineScope {
|
||||
val details = async {
|
||||
api.getChargingSiteDetails(
|
||||
TeslaChargingGuestGraphQlApi.GetChargingSiteDetailsRequest(
|
||||
TeslaChargingGuestGraphQlApi.GetChargingSiteInformationVariables(
|
||||
api.getSiteDetails(
|
||||
TeslaChargingGuestGraphQlApi.GetSiteDetailsRequest(
|
||||
TeslaChargingGuestGraphQlApi.GetSiteDetailsVariables(
|
||||
TeslaChargingGuestGraphQlApi.Identifier(
|
||||
TeslaChargingGuestGraphQlApi.ChargingSiteIdentifier(
|
||||
trtId
|
||||
trtId, TeslaChargingGuestGraphQlApi.Experience.ADHOC
|
||||
)
|
||||
),
|
||||
TeslaChargingGuestGraphQlApi.Experience.ADHOC
|
||||
)
|
||||
)
|
||||
).data.site ?: throw AvailabilityDetectorException("no candidates found.")
|
||||
).data.chargingNetwork?.site
|
||||
?: throw AvailabilityDetectorException("no candidates found.")
|
||||
}
|
||||
val guestPricing = async {
|
||||
api.getChargingSiteDetails(
|
||||
TeslaChargingGuestGraphQlApi.GetChargingSiteDetailsRequest(
|
||||
TeslaChargingGuestGraphQlApi.GetChargingSiteInformationVariables(
|
||||
api.getSiteDetails(
|
||||
TeslaChargingGuestGraphQlApi.GetSiteDetailsRequest(
|
||||
TeslaChargingGuestGraphQlApi.GetSiteDetailsVariables(
|
||||
TeslaChargingGuestGraphQlApi.Identifier(
|
||||
TeslaChargingGuestGraphQlApi.ChargingSiteIdentifier(
|
||||
trtId
|
||||
trtId, TeslaChargingGuestGraphQlApi.Experience.GUEST
|
||||
)
|
||||
),
|
||||
TeslaChargingGuestGraphQlApi.Experience.GUEST
|
||||
)
|
||||
)
|
||||
).data.site?.pricing
|
||||
).data.chargingNetwork?.site?.pricing
|
||||
}
|
||||
details to guestPricing
|
||||
}
|
||||
@@ -103,12 +102,9 @@ class TeslaGuestAvailabilityDetector(
|
||||
"charger has unknown connectors"
|
||||
)
|
||||
|
||||
val chargerDetails = details.chargersAvailable.chargerDetails
|
||||
val chargers = details.chargers.associateBy { it.id }
|
||||
var detailsSorted = chargerDetails
|
||||
.sortedBy { chargers[it.id]?.labelLetter }
|
||||
.sortedBy { chargers[it.id]?.labelNumber }
|
||||
|
||||
var detailsSorted = details.chargerList
|
||||
.sortedBy { c -> c.labelLetter }
|
||||
.sortedBy { c -> c.labelNumber }
|
||||
|
||||
if (detailsSorted.size != scV2Connectors.sumOf { it.count } + scV3Connectors.sumOf { it.count }) {
|
||||
// apparently some connectors are missing in Tesla data
|
||||
@@ -120,7 +116,7 @@ class TeslaGuestAvailabilityDetector(
|
||||
detailsSorted + List(numMissing) {
|
||||
TeslaChargingGuestGraphQlApi.ChargerDetail(
|
||||
ChargerAvailability.UNKNOWN,
|
||||
""
|
||||
"", ""
|
||||
)
|
||||
}
|
||||
} else {
|
||||
@@ -151,7 +147,7 @@ class TeslaGuestAvailabilityDetector(
|
||||
}
|
||||
|
||||
val statusMap = detailsMap.mapValues { it.value.map { it.availability.toStatus() } }
|
||||
val labelsMap = detailsMap.mapValues { it.value.map { chargers[it.id]?.label } }
|
||||
val labelsMap = detailsMap.mapValues { it.value.map { it.label } }
|
||||
|
||||
val pricing = details.pricing.copy(memberRates = guestPricing.await()?.userRates)
|
||||
|
||||
|
||||
@@ -1,12 +1,8 @@
|
||||
package net.vonforst.evmap.api.availability.tesla
|
||||
|
||||
import com.squareup.moshi.Json
|
||||
import com.squareup.moshi.JsonAdapter
|
||||
import com.squareup.moshi.JsonClass
|
||||
import com.squareup.moshi.JsonReader
|
||||
import com.squareup.moshi.JsonWriter
|
||||
import com.squareup.moshi.Moshi
|
||||
import com.squareup.moshi.Types
|
||||
import okhttp3.CacheControl
|
||||
import okhttp3.OkHttpClient
|
||||
import retrofit2.Retrofit
|
||||
@@ -15,7 +11,6 @@ import retrofit2.http.Body
|
||||
import retrofit2.http.GET
|
||||
import retrofit2.http.POST
|
||||
import retrofit2.http.Query
|
||||
import java.lang.reflect.Type
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
||||
interface TeslaCuaApi {
|
||||
@@ -71,24 +66,22 @@ interface TeslaCuaApi {
|
||||
|
||||
interface TeslaChargingGuestGraphQlApi {
|
||||
@POST("graphql")
|
||||
suspend fun getChargingSiteDetails(
|
||||
@Body request: GetChargingSiteDetailsRequest,
|
||||
@Query("operationName") operationName: String = "getGuestChargingSiteDetails"
|
||||
suspend fun getSiteDetails(
|
||||
@Body request: GetSiteDetailsRequest,
|
||||
@Query("operationName") operationName: String = "GetSiteDetails"
|
||||
): GetChargingSiteDetailsResponse
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class GetChargingSiteDetailsRequest(
|
||||
override val variables: GetChargingSiteInformationVariables,
|
||||
override val operationName: String = "getGuestChargingSiteDetails",
|
||||
data class GetSiteDetailsRequest(
|
||||
override val variables: GetSiteDetailsVariables,
|
||||
override val operationName: String = "GetSiteDetails",
|
||||
override val query: String =
|
||||
"\n query getGuestChargingSiteDetails(\$identifier: ChargingSiteIdentifierInput!, \$deviceLocale: String!, \$experience: ChargingExperienceEnum!) {\n site(\n identifier: \$identifier\n deviceLocale: \$deviceLocale\n experience: \$experience\n ) {\n activeOutages\n address {\n countryCode\n }\n chargers {\n id\n label\n }\n chargersAvailable {\n chargerDetails {\n id\n availability\n }\n }\n holdAmount {\n holdAmount\n currencyCode\n }\n maxPowerKw\n name\n programType\n publicStallCount\n id\n pricing(experience: \$experience) {\n userRates {\n activePricebook {\n charging {\n uom\n rates\n buckets {\n start\n end\n }\n bucketUom\n currencyCode\n programType\n vehicleMakeType\n touRates {\n enabled\n activeRatesByTime {\n startTime\n endTime\n rates\n }\n }\n }\n parking {\n uom\n rates\n buckets {\n start\n end\n }\n bucketUom\n currencyCode\n programType\n vehicleMakeType\n touRates {\n enabled\n activeRatesByTime {\n startTime\n endTime\n rates\n }\n }\n }\n congestion {\n uom\n rates\n buckets {\n start\n end\n }\n bucketUom\n currencyCode\n programType\n vehicleMakeType\n touRates {\n enabled\n activeRatesByTime {\n startTime\n endTime\n rates\n }\n }\n }\n }\n }\n }\n }\n}\n "
|
||||
"\n query GetSiteDetails(\$siteId: SiteIdInput!) {\n chargingNetwork {\n site(siteId: \$siteId) {\n address {\n countryCode\n }\n chargerList {\n id\n label\n availability\n }\n holdAmount {\n amount\n currencyCode\n }\n maxPowerKw\n name\n programType\n publicStallCount\n trtId\n pricing {\n userRates {\n activePricebook {\n charging {\n ...ChargingRate\n }\n parking {\n ...ChargingRate\n }\n congestion {\n ...ChargingRate\n }\n }\n }\n }\n }\n }\n}\n \n fragment ChargingRate on ChargingUserRate {\n uom\n rates\n buckets {\n start\n end\n }\n bucketUom\n currencyCode\n programType\n vehicleMakeType\n touRates {\n enabled\n activeRatesByTime {\n startTime\n endTime\n rates\n }\n }\n}\n "
|
||||
) : GraphQlRequest()
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class GetChargingSiteInformationVariables(
|
||||
val identifier: Identifier,
|
||||
val experience: Experience,
|
||||
val deviceLocale: String = "de-DE",
|
||||
data class GetSiteDetailsVariables(
|
||||
val siteId: Identifier,
|
||||
)
|
||||
|
||||
enum class Experience {
|
||||
@@ -97,22 +90,22 @@ interface TeslaChargingGuestGraphQlApi {
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class Identifier(
|
||||
val siteId: ChargingSiteIdentifier
|
||||
val byTrtId: ChargingSiteIdentifier
|
||||
)
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class ChargingSiteIdentifier(
|
||||
val id: Long,
|
||||
val siteType: SiteType = SiteType.SUPERCHARGER
|
||||
val trtId: Long,
|
||||
val chargingExperience: Experience,
|
||||
val programType: String = "PTSCH",
|
||||
val locale: String = "de-DE",
|
||||
)
|
||||
|
||||
enum class SiteType {
|
||||
@Json(name = "SITE_TYPE_SUPERCHARGER")
|
||||
SUPERCHARGER
|
||||
}
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class GetChargingSiteDetailsResponse(val data: GetChargingSiteDetailsResponseDataNetwork)
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class GetChargingSiteDetailsResponse(val data: GetChargingSiteDetailsResponseData)
|
||||
data class GetChargingSiteDetailsResponseDataNetwork(val chargingNetwork: GetChargingSiteDetailsResponseData?)
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class GetChargingSiteDetailsResponseData(val site: ChargingSiteInformation?)
|
||||
@@ -120,9 +113,8 @@ interface TeslaChargingGuestGraphQlApi {
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class ChargingSiteInformation(
|
||||
val activeOutages: List<Outage>?,
|
||||
val chargers: List<ChargerId>,
|
||||
val chargersAvailable: ChargersAvailable,
|
||||
val id: Long,
|
||||
val chargerList: List<ChargerDetail>,
|
||||
val trtId: Long,
|
||||
val maxPowerKw: Int,
|
||||
val name: String,
|
||||
val pricing: Pricing,
|
||||
@@ -130,9 +122,10 @@ interface TeslaChargingGuestGraphQlApi {
|
||||
)
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class ChargerId(
|
||||
val id: String,
|
||||
data class ChargerDetail(
|
||||
val availability: ChargerAvailability,
|
||||
val label: String?,
|
||||
val id: String
|
||||
) {
|
||||
val labelNumber
|
||||
get() = label?.replace(Regex("""\D"""), "")?.toInt()
|
||||
@@ -140,15 +133,6 @@ interface TeslaChargingGuestGraphQlApi {
|
||||
get() = label?.replace(Regex("""\d"""), "")
|
||||
}
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class ChargersAvailable(val chargerDetails: List<ChargerDetail>)
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class ChargerDetail(
|
||||
val availability: ChargerAvailability,
|
||||
val id: String
|
||||
)
|
||||
|
||||
companion object {
|
||||
fun create(
|
||||
client: OkHttpClient,
|
||||
|
||||
@@ -452,7 +452,10 @@ class GoingElectricApiWrapper(
|
||||
if (responses.map { it.isSuccessful }.all { it }
|
||||
&& plugsResponse.body()!!.status == STATUS_OK
|
||||
&& chargeCardsResponse.body()!!.status == STATUS_OK
|
||||
&& networksResponse.body()!!.status == STATUS_OK) {
|
||||
&& networksResponse.body()!!.status == STATUS_OK
|
||||
&& plugsResponse.body()!!.result != null
|
||||
&& chargeCardsResponse.body()!!.result != null
|
||||
&& networksResponse.body()!!.result != null) {
|
||||
Resource.success(
|
||||
GEReferenceData(
|
||||
plugsResponse.body()!!.result!!,
|
||||
|
||||
2
fastlane/metadata/android/de-DE/changelogs/226.txt
Normal file
2
fastlane/metadata/android/de-DE/changelogs/226.txt
Normal file
@@ -0,0 +1,2 @@
|
||||
Fehler behoben:
|
||||
- Abstürze behoben
|
||||
2
fastlane/metadata/android/en-US/changelogs/226.txt
Normal file
2
fastlane/metadata/android/en-US/changelogs/226.txt
Normal file
@@ -0,0 +1,2 @@
|
||||
Bugfixes:
|
||||
- Fixed crashes
|
||||
Reference in New Issue
Block a user