Skip to content

Commit

Permalink
implement chargeprice feedback dialog
Browse files Browse the repository at this point in the history
  • Loading branch information
johan12345 committed Aug 5, 2022
1 parent 4135740 commit 19b87b7
Show file tree
Hide file tree
Showing 26 changed files with 952 additions and 351 deletions.
4 changes: 2 additions & 2 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -165,8 +165,8 @@ dependencies {
implementation 'com.squareup.okhttp3:okhttp-urlconnection:4.9.0'
implementation 'com.squareup.moshi:moshi-kotlin:1.13.0'
implementation 'com.squareup.moshi:moshi-adapters:1.13.0'
implementation 'moe.banana:moshi-jsonapi:3.5.0'
implementation 'moe.banana:moshi-jsonapi-retrofit-converter:3.5.0'
implementation 'com.markomilos.jsonapi:jsonapi-adapters:1.0.1'
implementation 'com.markomilos.jsonapi:jsonapi-retrofit:1.0.1'
implementation 'io.coil-kt:coil:1.1.0'
implementation 'com.github.johan12345:StfalconImageViewer:5082ebd392'
implementation "com.mikepenz:aboutlibraries-core:$about_libs_version"
Expand Down
5 changes: 5 additions & 0 deletions app/src/debug/res/values/donottranslate.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="chargeprice_api_url">https://staging-api.chargeprice.app/v1/</string>
<string name="chargeprice_key">20c0d68918c9dc96c564784b711a6570</string>
</resources>
100 changes: 52 additions & 48 deletions app/src/google/java/net/vonforst/evmap/auto/ChargepriceScreen.kt
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,13 @@ import androidx.car.app.model.*
import androidx.core.content.ContextCompat
import androidx.core.graphics.drawable.IconCompat
import androidx.lifecycle.lifecycleScope
import jsonapi.Meta
import jsonapi.Relationship
import jsonapi.Relationships
import jsonapi.ResourceIdentifier
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import moe.banana.jsonapi2.HasMany
import moe.banana.jsonapi2.HasOne
import moe.banana.jsonapi2.JsonBuffer
import moe.banana.jsonapi2.ResourceIdentifier
import net.vonforst.evmap.R
import net.vonforst.evmap.api.chargeprice.*
import net.vonforst.evmap.model.ChargeLocation
Expand All @@ -34,7 +34,10 @@ class ChargepriceScreen(ctx: CarContext, val charger: ChargeLocation) : Screen(c
private val prefs = PreferenceDataSource(ctx)
private val db = AppDatabase.getInstance(carContext)
private val api by lazy {
ChargepriceApi.create(carContext.getString(R.string.chargeprice_key))
ChargepriceApi.create(
carContext.getString(R.string.chargeprice_key),
carContext.getString(R.string.chargeprice_api_url)
)
}
private var prices: List<ChargePrice>? = null
private var meta: ChargepriceChargepointMeta? = null
Expand Down Expand Up @@ -94,7 +97,7 @@ class ChargepriceScreen(ctx: CarContext, val charger: ChargeLocation) : Screen(c
)
.build().intent
intent.data =
Uri.parse("https://www.chargeprice.app/?poi_id=${charger.id}&poi_source=${getDataAdapter()}")
Uri.parse(ChargepriceApi.getPoiUrl(charger))
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
try {
carContext.startActivity(intent)
Expand Down Expand Up @@ -169,39 +172,44 @@ class ChargepriceScreen(ctx: CarContext, val charger: ChargeLocation) : Screen(c
}

private fun loadPrices(model: Model?) {
val dataAdapter = getDataAdapter() ?: return
val dataAdapter = ChargepriceApi.getDataAdapter(charger) ?: return
val manufacturer = model?.manufacturer?.value
val modelName = getVehicleModel(model?.manufacturer?.value, model?.name?.value)
lifecycleScope.launch {
try {
val car = determineVehicle(manufacturer, modelName)
val cpStation = ChargepriceStation.fromEvmap(charger, car.compatibleEvmapConnectors)
val result = api.getChargePrices(ChargepriceRequest().apply {
this.dataAdapter = dataAdapter
station = cpStation
vehicle = HasOne(car)
tariffs = if (!prefs.chargepriceMyTariffsAll) {
val myTariffs = prefs.chargepriceMyTariffs ?: emptySet()
HasMany<ChargepriceTariff>(*myTariffs.map {
ResourceIdentifier(
"tariff",
it
)
}.toTypedArray()).apply {
meta = JsonBuffer.create(
ChargepriceApi.moshi.adapter(ChargepriceRequestTariffMeta::class.java),
ChargepriceRequestTariffMeta(ChargepriceInclude.ALWAYS)
val result = api.getChargePrices(
ChargepriceRequest(
dataAdapter = dataAdapter,
station = cpStation,
vehicle = car,
options = ChargepriceOptions(
batteryRange = batteryRange.map { it.toDouble() },
providerCustomerTariffs = prefs.chargepriceShowProviderCustomerTariffs,
maxMonthlyFees = if (prefs.chargepriceNoBaseFee) 0.0 else null,
currency = prefs.chargepriceCurrency,
allowUnbalancedLoad = prefs.chargepriceAllowUnbalancedLoad
),
relationships = if (!prefs.chargepriceMyTariffsAll) {
val myTariffs = prefs.chargepriceMyTariffs ?: emptySet()
Relationships(
"tariffs" to Relationship.ToMany(
myTariffs.map {
ResourceIdentifier(
"tariff",
id = it
)
},
meta = Meta.from(
ChargepriceRequestTariffMeta(ChargepriceInclude.ALWAYS),
ChargepriceApi.moshi
)
)
)
}
} else null
options = ChargepriceOptions(
batteryRange = batteryRange.map { it.toDouble() },
providerCustomerTariffs = prefs.chargepriceShowProviderCustomerTariffs,
maxMonthlyFees = if (prefs.chargepriceNoBaseFee) 0.0 else null,
currency = prefs.chargepriceCurrency,
allowUnbalancedLoad = prefs.chargepriceAllowUnbalancedLoad
)
}, ChargepriceApi.getChargepriceLanguage())
} else null
), ChargepriceApi.getChargepriceLanguage()
)

val myTariffs = prefs.chargepriceMyTariffs

Expand All @@ -215,30 +223,32 @@ class ChargepriceScreen(ctx: CarContext, val charger: ChargeLocation) : Screen(c
invalidate()
return@launch
}
meta =
(result.meta.get<ChargepriceMeta>(ChargepriceApi.moshi.adapter(ChargepriceMeta::class.java)) as ChargepriceMeta).chargePoints.filterIndexed { i, cp ->
charger.chargepointsMerged[i].type in car.compatibleEvmapConnectors
}.maxByOrNull {
it.power
}

prices = result.map { cp ->
val metaMapped =
result.meta!!.map(ChargepriceMeta::class.java, ChargepriceApi.moshi)!!
meta = metaMapped.chargePoints.filterIndexed { i, cp ->
charger.chargepointsMerged[i].type in car.compatibleEvmapConnectors
}.maxByOrNull {
it.power
}

prices = result.data!!.map { cp ->
val filteredPrices =
cp.chargepointPrices.filter {
it.plug == chargepoint.plug && it.power == chargepoint.power
}
if (filteredPrices.isEmpty()) {
null
} else {
cp.clone().apply {
cp.copy(
chargepointPrices = filteredPrices
}
)
}
}.filterNotNull()
.sortedBy { it.chargepointPrices.first().price }
.sortedByDescending {
prefs.chargepriceMyTariffsAll ||
myTariffs != null && it.tariff?.get()?.id in myTariffs
myTariffs != null && it.tariff?.id in myTariffs
}
invalidate()
} catch (e: IOException) {
Expand Down Expand Up @@ -316,10 +326,4 @@ class ChargepriceScreen(ctx: CarContext, val charger: ChargeLocation) : Screen(c
}
return vehicles[0]
}

private fun getDataAdapter(): String? = when (charger.dataSource) {
"goingelectric" -> ChargepriceApi.DATA_SOURCE_GOINGELECTRIC
"openchargemap" -> ChargepriceApi.DATA_SOURCE_OPENCHARGEMAP
else -> null
}
}
10 changes: 8 additions & 2 deletions app/src/google/java/net/vonforst/evmap/auto/SettingsScreens.kt
Original file line number Diff line number Diff line change
Expand Up @@ -283,7 +283,10 @@ class ChargepriceSettingsScreen(ctx: CarContext) : Screen(ctx) {

class SelectVehiclesScreen(ctx: CarContext) : MultiSelectSearchScreen<ChargepriceCar>(ctx) {
private val prefs = PreferenceDataSource(carContext)
private var api = ChargepriceApi.create(carContext.getString(R.string.chargeprice_key))
private var api = ChargepriceApi.create(
carContext.getString(R.string.chargeprice_key),
carContext.getString(R.string.chargeprice_api_url)
)
override val isMultiSelect = true
override val shouldShowSelectAll = false

Expand All @@ -308,7 +311,10 @@ class SelectVehiclesScreen(ctx: CarContext) : MultiSelectSearchScreen<Chargepric

class SelectTariffsScreen(ctx: CarContext) : MultiSelectSearchScreen<ChargepriceTariff>(ctx) {
private val prefs = PreferenceDataSource(carContext)
private var api = ChargepriceApi.create(carContext.getString(R.string.chargeprice_key))
private var api = ChargepriceApi.create(
carContext.getString(R.string.chargeprice_key),
carContext.getString(R.string.chargeprice_api_url)
)
override val isMultiSelect = true
override val shouldShowSelectAll = true

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,16 @@ package net.vonforst.evmap.api.chargeprice
import android.content.Context
import com.facebook.stetho.okhttp3.StethoInterceptor
import com.squareup.moshi.Moshi
import com.squareup.moshi.kotlin.reflect.KotlinJsonAdapterFactory
import moe.banana.jsonapi2.ArrayDocument
import moe.banana.jsonapi2.JsonApiConverterFactory
import moe.banana.jsonapi2.ResourceAdapterFactory
import com.squareup.moshi.adapters.PolymorphicJsonAdapterFactory
import jsonapi.Document
import jsonapi.JsonApiFactory
import jsonapi.retrofit.DocumentConverterFactory
import net.vonforst.evmap.BuildConfig
import net.vonforst.evmap.model.ChargeLocation
import okhttp3.Cache
import okhttp3.OkHttpClient
import retrofit2.Retrofit
import retrofit2.converter.moshi.MoshiConverterFactory
import retrofit2.http.Body
import retrofit2.http.GET
import retrofit2.http.Header
Expand All @@ -20,34 +22,45 @@ import java.util.*
interface ChargepriceApi {
@POST("charge_prices")
suspend fun getChargePrices(
@Body request: ChargepriceRequest,
@Body @jsonapi.retrofit.Document request: ChargepriceRequest,
@Header("Accept-Language") language: String
): ArrayDocument<ChargePrice>
): Document<List<ChargePrice>>

@GET("vehicles")
suspend fun getVehicles(): ArrayDocument<ChargepriceCar>
@jsonapi.retrofit.Document
suspend fun getVehicles(): List<ChargepriceCar>

@GET("tariffs")
suspend fun getTariffs(): ArrayDocument<ChargepriceTariff>
@jsonapi.retrofit.Document
suspend fun getTariffs(): List<ChargepriceTariff>

@POST("user_feedback")
suspend fun userFeedback(@Body @jsonapi.retrofit.Document feedback: ChargepriceUserFeedback)

companion object {
private val cacheSize = 1L * 1024 * 1024 // 1MB
val supportedLanguages = setOf("de", "en", "fr", "nl")

val DATA_SOURCE_GOINGELECTRIC = "going_electric"
val DATA_SOURCE_OPENCHARGEMAP = "open_charge_map"
private val DATA_SOURCE_GOINGELECTRIC = "going_electric"
private val DATA_SOURCE_OPENCHARGEMAP = "open_charge_map"

private val jsonApiAdapterFactory = ResourceAdapterFactory.builder()
.add(ChargepriceRequest::class.java)
.add(ChargepriceTariff::class.java)
.add(ChargepriceBrand::class.java)
.add(ChargePrice::class.java)
.add(ChargepriceCar::class.java)
private val jsonApiAdapterFactory = JsonApiFactory.Builder()
.addType(ChargepriceRequest::class.java)
.addType(ChargepriceTariff::class.java)
.addType(ChargepriceBrand::class.java)
.addType(ChargePrice::class.java)
.addType(ChargepriceCar::class.java)
.build()
val moshi = Moshi.Builder()
.add(jsonApiAdapterFactory)
.add(KotlinJsonAdapterFactory())
.add(
PolymorphicJsonAdapterFactory.of(ChargepriceUserFeedback::class.java, "type")
.withSubtype(ChargepriceMissingPriceFeedback::class.java, "missing_price")
.withSubtype(ChargepriceWrongPriceFeedback::class.java, "wrong_price")
.withSubtype(ChargepriceMissingVehicleFeedback::class.java, "missing_vehicle")
)
.build()

fun create(
apikey: String,
baseurl: String = "https://api.chargeprice.app/v1/",
Expand All @@ -73,7 +86,8 @@ interface ChargepriceApi {

val retrofit = Retrofit.Builder()
.baseUrl(baseurl)
.addConverterFactory(JsonApiConverterFactory.create(moshi))
.addConverterFactory(DocumentConverterFactory.create())
.addConverterFactory(MoshiConverterFactory.create(moshi))
.client(client)
.build()
return retrofit.create(ChargepriceApi::class.java)
Expand All @@ -89,6 +103,15 @@ interface ChargepriceApi {
}
}

fun getPoiUrl(charger: ChargeLocation) =
"https://www.chargeprice.app/?poi_id=${charger.id}&poi_source=${getDataAdapter(charger)}"

fun getDataAdapter(charger: ChargeLocation) = when (charger.dataSource) {
"goingelectric" -> DATA_SOURCE_GOINGELECTRIC
"openchargemap" -> DATA_SOURCE_OPENCHARGEMAP
else -> throw IllegalArgumentException()
}

@JvmStatic
fun isCountrySupported(country: String, dataSource: String): Boolean = when (dataSource) {
// list of countries updated 2021/08/24
Expand Down
Loading

0 comments on commit 19b87b7

Please sign in to comment.