mirror of
https://github.com/ev-map/EVMap.git
synced 2026-04-21 22:58:50 -04:00
make plugs filter use the plug list from GE API
This commit is contained in:
@@ -29,6 +29,15 @@ interface GoingElectricApi {
|
||||
@GET("chargepoints/")
|
||||
fun getChargepointDetail(@Query("ge_id") id: Long): Call<ChargepointList>
|
||||
|
||||
@GET("chargepoints/pluglist/")
|
||||
suspend fun getPlugs(): Response<StringList>
|
||||
|
||||
@GET("chargepoints/networklist/")
|
||||
suspend fun getNetworks(): Response<StringList>
|
||||
|
||||
@GET("chargepoints/chargecardlist/")
|
||||
suspend fun getChargeCards(): Response<StringList>
|
||||
|
||||
companion object {
|
||||
private val cacheSize = 10L * 1024 * 1024; // 10MB
|
||||
|
||||
|
||||
@@ -24,6 +24,12 @@ data class ChargepointList(
|
||||
val chargelocations: List<ChargepointListItem>
|
||||
)
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class StringList(
|
||||
val status: String,
|
||||
val result: List<String>
|
||||
)
|
||||
|
||||
sealed class ChargepointListItem
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
|
||||
@@ -17,19 +17,21 @@ import net.vonforst.evmap.viewmodel.SliderFilterValue
|
||||
ChargeLocation::class,
|
||||
BooleanFilterValue::class,
|
||||
MultipleChoiceFilterValue::class,
|
||||
SliderFilterValue::class
|
||||
], version = 3
|
||||
SliderFilterValue::class,
|
||||
Plug::class
|
||||
], version = 4
|
||||
)
|
||||
@TypeConverters(Converters::class)
|
||||
abstract class AppDatabase : RoomDatabase() {
|
||||
abstract fun chargeLocationsDao(): ChargeLocationsDao
|
||||
abstract fun filterValueDao(): FilterValueDao
|
||||
abstract fun plugDao(): PlugDao
|
||||
|
||||
companion object {
|
||||
private lateinit var context: Context
|
||||
private val database: AppDatabase by lazy(LazyThreadSafetyMode.SYNCHRONIZED) {
|
||||
Room.databaseBuilder(context, AppDatabase::class.java, "evmap.db")
|
||||
.addMigrations(MIGRATION_2, MIGRATION_3)
|
||||
.addMigrations(MIGRATION_2, MIGRATION_3, MIGRATION_4)
|
||||
.build()
|
||||
}
|
||||
|
||||
@@ -58,5 +60,12 @@ abstract class AppDatabase : RoomDatabase() {
|
||||
db.endTransaction()
|
||||
}
|
||||
}
|
||||
|
||||
private val MIGRATION_4 = object : Migration(3, 4) {
|
||||
override fun migrate(db: SupportSQLiteDatabase) {
|
||||
db.execSQL("CREATE TABLE IF NOT EXISTS `Plug` (`name` TEXT NOT NULL, PRIMARY KEY(`name`))")
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
49
app/src/main/java/net/vonforst/evmap/storage/PlugDao.kt
Normal file
49
app/src/main/java/net/vonforst/evmap/storage/PlugDao.kt
Normal file
@@ -0,0 +1,49 @@
|
||||
package net.vonforst.evmap.storage
|
||||
|
||||
import androidx.lifecycle.LiveData
|
||||
import androidx.room.*
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.launch
|
||||
import net.vonforst.evmap.api.goingelectric.GoingElectricApi
|
||||
import java.time.Duration
|
||||
import java.time.Instant
|
||||
|
||||
@Entity
|
||||
data class Plug(@PrimaryKey val name: String)
|
||||
|
||||
@Dao
|
||||
interface PlugDao {
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||
suspend fun insert(vararg plugs: Plug)
|
||||
|
||||
@Delete
|
||||
suspend fun delete(vararg plugs: Plug)
|
||||
|
||||
@Query("SELECT * FROM plug")
|
||||
fun getAllPlugs(): LiveData<List<Plug>>
|
||||
}
|
||||
|
||||
class PlugRepository(
|
||||
private val api: GoingElectricApi, private val scope: CoroutineScope,
|
||||
private val dao: PlugDao, private val prefs: PreferenceDataSource
|
||||
) {
|
||||
fun getPlugs(): LiveData<List<Plug>> {
|
||||
scope.launch {
|
||||
updatePlugs()
|
||||
}
|
||||
return dao.getAllPlugs()
|
||||
}
|
||||
|
||||
private suspend fun updatePlugs() {
|
||||
if (Duration.between(prefs.lastPlugUpdate, Instant.now()) < Duration.ofDays(1)) return
|
||||
|
||||
val response = api.getPlugs()
|
||||
if (!response.isSuccessful) return
|
||||
|
||||
for (name in response.body()!!.result) {
|
||||
dao.insert(Plug(name))
|
||||
}
|
||||
|
||||
prefs.lastPlugUpdate = Instant.now()
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,7 @@ package net.vonforst.evmap.storage
|
||||
|
||||
import android.content.Context
|
||||
import androidx.preference.PreferenceManager
|
||||
import java.time.Instant
|
||||
|
||||
class PreferenceDataSource(context: Context) {
|
||||
val sp = PreferenceManager.getDefaultSharedPreferences(context)
|
||||
@@ -11,4 +12,10 @@ class PreferenceDataSource(context: Context) {
|
||||
set(value) {
|
||||
sp.edit().putBoolean("navigate_use_maps", value).apply()
|
||||
}
|
||||
|
||||
var lastPlugUpdate: Instant
|
||||
get() = Instant.ofEpochMilli(sp.getLong("last_plug_update", 0L))
|
||||
set(value) {
|
||||
sp.edit().putLong("last_plug_update", value.toEpochMilli()).apply()
|
||||
}
|
||||
}
|
||||
@@ -5,7 +5,7 @@ import androidx.databinding.BaseObservable
|
||||
import androidx.lifecycle.AndroidViewModel
|
||||
import androidx.lifecycle.LiveData
|
||||
import androidx.lifecycle.MediatorLiveData
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import androidx.room.Entity
|
||||
import androidx.room.PrimaryKey
|
||||
import net.vonforst.evmap.R
|
||||
@@ -13,6 +13,9 @@ import net.vonforst.evmap.adapter.Equatable
|
||||
import net.vonforst.evmap.api.goingelectric.Chargepoint
|
||||
import net.vonforst.evmap.api.goingelectric.GoingElectricApi
|
||||
import net.vonforst.evmap.storage.AppDatabase
|
||||
import net.vonforst.evmap.storage.Plug
|
||||
import net.vonforst.evmap.storage.PlugRepository
|
||||
import net.vonforst.evmap.storage.PreferenceDataSource
|
||||
import kotlin.math.abs
|
||||
import kotlin.reflect.KClass
|
||||
import kotlin.reflect.full.cast
|
||||
@@ -24,41 +27,47 @@ internal fun mapPowerInverse(power: Int) = powerSteps
|
||||
.minBy { it.first }?.second ?: 0
|
||||
|
||||
internal fun getFilters(
|
||||
api: GoingElectricApi,
|
||||
application: Application
|
||||
application: Application,
|
||||
plugs: LiveData<List<Plug>>
|
||||
): LiveData<List<Filter<FilterValue>>> {
|
||||
val liveData = MutableLiveData<List<Filter<FilterValue>>>()
|
||||
liveData.value = listOf(
|
||||
BooleanFilter(application.getString(R.string.filter_free), "freecharging"),
|
||||
BooleanFilter(application.getString(R.string.filter_free_parking), "freeparking"),
|
||||
SliderFilter(
|
||||
application.getString(R.string.filter_min_power), "min_power",
|
||||
powerSteps.size - 1,
|
||||
mapping = ::mapPower,
|
||||
inverseMapping = ::mapPowerInverse,
|
||||
unit = "kW"
|
||||
),
|
||||
MultipleChoiceFilter(
|
||||
application.getString(R.string.filter_connectors), "connectors",
|
||||
mapOf(
|
||||
Chargepoint.TYPE_1 to application.getString(R.string.plug_type_1),
|
||||
Chargepoint.TYPE_2 to application.getString(R.string.plug_type_2),
|
||||
Chargepoint.TYPE_3 to application.getString(R.string.plug_type_3),
|
||||
Chargepoint.CCS to application.getString(R.string.plug_ccs),
|
||||
Chargepoint.SCHUKO to application.getString(R.string.plug_schuko),
|
||||
Chargepoint.CHADEMO to application.getString(R.string.plug_chademo),
|
||||
Chargepoint.SUPERCHARGER to application.getString(R.string.plug_supercharger),
|
||||
Chargepoint.CEE_BLAU to application.getString(R.string.plug_cee_blau),
|
||||
Chargepoint.CEE_ROT to application.getString(R.string.plug_cee_rot)
|
||||
)
|
||||
),
|
||||
SliderFilter(
|
||||
application.getString(R.string.filter_min_connectors),
|
||||
"min_connectors",
|
||||
10
|
||||
return MediatorLiveData<List<Filter<FilterValue>>>().apply {
|
||||
val plugNames = mapOf(
|
||||
Chargepoint.TYPE_1 to application.getString(R.string.plug_type_1),
|
||||
Chargepoint.TYPE_2 to application.getString(R.string.plug_type_2),
|
||||
Chargepoint.TYPE_3 to application.getString(R.string.plug_type_3),
|
||||
Chargepoint.CCS to application.getString(R.string.plug_ccs),
|
||||
Chargepoint.SCHUKO to application.getString(R.string.plug_schuko),
|
||||
Chargepoint.CHADEMO to application.getString(R.string.plug_chademo),
|
||||
Chargepoint.SUPERCHARGER to application.getString(R.string.plug_supercharger),
|
||||
Chargepoint.CEE_BLAU to application.getString(R.string.plug_cee_blau),
|
||||
Chargepoint.CEE_ROT to application.getString(R.string.plug_cee_rot)
|
||||
)
|
||||
)
|
||||
return liveData
|
||||
addSource(plugs) { plugs ->
|
||||
val plugMap = plugs.map { plug ->
|
||||
plug.name to (plugNames[plug.name] ?: plug.name)
|
||||
}.toMap()
|
||||
value = listOf(
|
||||
BooleanFilter(application.getString(R.string.filter_free), "freecharging"),
|
||||
BooleanFilter(application.getString(R.string.filter_free_parking), "freeparking"),
|
||||
SliderFilter(
|
||||
application.getString(R.string.filter_min_power), "min_power",
|
||||
powerSteps.size - 1,
|
||||
mapping = ::mapPower,
|
||||
inverseMapping = ::mapPowerInverse,
|
||||
unit = "kW"
|
||||
),
|
||||
MultipleChoiceFilter(
|
||||
application.getString(R.string.filter_connectors), "connectors",
|
||||
plugMap
|
||||
),
|
||||
SliderFilter(
|
||||
application.getString(R.string.filter_min_connectors),
|
||||
"min_connectors",
|
||||
10
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -84,9 +93,14 @@ class FilterViewModel(application: Application, geApiKey: String) :
|
||||
AndroidViewModel(application) {
|
||||
private var api = GoingElectricApi.create(geApiKey, context = application)
|
||||
private var db = AppDatabase.getInstance(application)
|
||||
private var prefs = PreferenceDataSource(application)
|
||||
|
||||
private val plugs: LiveData<List<Plug>> by lazy {
|
||||
PlugRepository(api, viewModelScope, db.plugDao(), prefs).getPlugs()
|
||||
}
|
||||
|
||||
private val filters: LiveData<List<Filter<FilterValue>>> by lazy {
|
||||
getFilters(api, application)
|
||||
getFilters(application, plugs)
|
||||
}
|
||||
|
||||
private val filterValues: LiveData<List<FilterValue>> by lazy {
|
||||
|
||||
@@ -11,6 +11,9 @@ import net.vonforst.evmap.api.goingelectric.ChargepointList
|
||||
import net.vonforst.evmap.api.goingelectric.ChargepointListItem
|
||||
import net.vonforst.evmap.api.goingelectric.GoingElectricApi
|
||||
import net.vonforst.evmap.storage.AppDatabase
|
||||
import net.vonforst.evmap.storage.Plug
|
||||
import net.vonforst.evmap.storage.PlugRepository
|
||||
import net.vonforst.evmap.storage.PreferenceDataSource
|
||||
import retrofit2.Call
|
||||
import retrofit2.Callback
|
||||
import retrofit2.Response
|
||||
@@ -20,6 +23,7 @@ data class MapPosition(val bounds: LatLngBounds, val zoom: Float)
|
||||
class MapViewModel(application: Application, geApiKey: String) : AndroidViewModel(application) {
|
||||
private var api = GoingElectricApi.create(geApiKey, context = application)
|
||||
private var db = AppDatabase.getInstance(application)
|
||||
private var prefs = PreferenceDataSource(application)
|
||||
|
||||
val bottomSheetState: MutableLiveData<Int> by lazy {
|
||||
MutableLiveData<Int>()
|
||||
@@ -31,7 +35,10 @@ class MapViewModel(application: Application, geApiKey: String) : AndroidViewMode
|
||||
private val filterValues: LiveData<List<FilterValue>> by lazy {
|
||||
db.filterValueDao().getFilterValues()
|
||||
}
|
||||
private val filters = getFilters(api, application)
|
||||
private val plugs: LiveData<List<Plug>> by lazy {
|
||||
PlugRepository(api, viewModelScope, db.plugDao(), prefs).getPlugs()
|
||||
}
|
||||
private val filters = getFilters(application, plugs)
|
||||
|
||||
private val filtersWithValue: LiveData<List<FilterWithValue<out FilterValue>>> by lazy {
|
||||
filtersWithValue(filters, filterValues)
|
||||
|
||||
Reference in New Issue
Block a user