diff --git a/app/release/app-release.apk b/app/release/app-release.apk new file mode 100644 index 00000000..1051febf Binary files /dev/null and b/app/release/app-release.apk differ diff --git a/app/release/baselineProfiles/0/app-release.dm b/app/release/baselineProfiles/0/app-release.dm new file mode 100644 index 00000000..737a1116 Binary files /dev/null and b/app/release/baselineProfiles/0/app-release.dm differ diff --git a/app/release/baselineProfiles/1/app-release.dm b/app/release/baselineProfiles/1/app-release.dm new file mode 100644 index 00000000..4e403706 Binary files /dev/null and b/app/release/baselineProfiles/1/app-release.dm differ diff --git a/app/release/output-metadata.json b/app/release/output-metadata.json new file mode 100644 index 00000000..868e696e --- /dev/null +++ b/app/release/output-metadata.json @@ -0,0 +1,37 @@ +{ + "version": 3, + "artifactType": { + "type": "APK", + "kind": "Directory" + }, + "applicationId": "com.openvehicles.OVMS", + "variantName": "release", + "elements": [ + { + "type": "SINGLE", + "filters": [], + "attributes": [], + "versionCode": 2024091401, + "versionName": "4.7.1", + "outputFile": "app-release.apk" + } + ], + "elementType": "File", + "baselineProfiles": [ + { + "minApi": 28, + "maxApi": 30, + "baselineProfiles": [ + "baselineProfiles/1/app-release.dm" + ] + }, + { + "minApi": 31, + "maxApi": 2147483647, + "baselineProfiles": [ + "baselineProfiles/0/app-release.dm" + ] + } + ], + "minSdkVersionForDexing": 19 +} \ No newline at end of file diff --git a/app/src/main/java/com/openvehicles/OVMS/api/ApiService.kt b/app/src/main/java/com/openvehicles/OVMS/api/ApiService.kt index ded45b6d..070d602f 100644 --- a/app/src/main/java/com/openvehicles/OVMS/api/ApiService.kt +++ b/app/src/main/java/com/openvehicles/OVMS/api/ApiService.kt @@ -29,9 +29,9 @@ import com.openvehicles.OVMS.api.ApiObservable.deleteObserver import com.openvehicles.OVMS.api.ApiObservable.notifyLoggedIn import com.openvehicles.OVMS.api.ApiObservable.notifyUpdate import com.openvehicles.OVMS.entities.CarData -import com.openvehicles.OVMS.utils.AppPrefs import com.openvehicles.OVMS.ui.MainActivity import com.openvehicles.OVMS.ui.utils.Database +import com.openvehicles.OVMS.utils.AppPrefs import com.openvehicles.OVMS.utils.CarsStorage import com.openvehicles.OVMS.utils.Sys import java.io.Serializable @@ -485,6 +485,29 @@ class ApiService : Service(), ApiTask.ApiTaskListener, ApiObserver { override fun onPushNotification(msgClass: Char, msgText: String?) { // This callback only receives MP push notifications for the currently selected vehicle. // See MyFirebaseMessagingService for system notification broadcasting. + if(appPrefs!!.getData("option_notification_enabled_" + carData!!.sel_vehicleid,"0") == "1"){ + val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager + createNotificationChannel() + // Define the notification channel (required for Android O and above) + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + val channelName = getString(R.string.app_name) + val channelDescription = "OVMS" + val channel = NotificationChannel("your_channel_id", channelName, NotificationManager.IMPORTANCE_DEFAULT).apply { + description = channelDescription + } + notificationManager.createNotificationChannel(channel) + } + // Create the notification + val notificationBuilder = NotificationCompat.Builder(this, "your_channel_id") + .setSmallIcon(R.drawable.ic_service) + .setContentTitle("OVMS") + .setContentText(msgText ?: msgText) + .setPriority(NotificationCompat.PRIORITY_DEFAULT) + .setAutoCancel(true) + + // Show the notification + notificationManager.notify(1, notificationBuilder.build()) + } } // ApiObserver interface: diff --git a/app/src/main/java/com/openvehicles/OVMS/api/ApiTask.kt b/app/src/main/java/com/openvehicles/OVMS/api/ApiTask.kt index 70fbdf71..c2ea82f3 100644 --- a/app/src/main/java/com/openvehicles/OVMS/api/ApiTask.kt +++ b/app/src/main/java/com/openvehicles/OVMS/api/ApiTask.kt @@ -537,6 +537,12 @@ class ApiTask( msgData ) else Log.w(TAG, "W MSG Invalid") + 'X' -> if (carData.processGen(msgData)) publishProgress( + MsgType.UPDATE, + msgCode, + msgData + ) else Log.w(TAG, "X MSG Invalid") + 'Y' -> if (carData.processNewTPMS(msgData)) publishProgress( MsgType.UPDATE, msgCode, diff --git a/app/src/main/java/com/openvehicles/OVMS/entities/CarData.kt b/app/src/main/java/com/openvehicles/OVMS/entities/CarData.kt index f8bcee8f..03fd0f77 100644 --- a/app/src/main/java/com/openvehicles/OVMS/entities/CarData.kt +++ b/app/src/main/java/com/openvehicles/OVMS/entities/CarData.kt @@ -9,7 +9,11 @@ import com.openvehicles.OVMS.utils.AppPrefs import java.io.Serializable import java.text.DecimalFormat import java.text.SimpleDateFormat +import java.time.format.DateTimeFormatter import java.util.Date +import java.time.Instant +import java.time.ZoneId +import kotlin.text.format class CarData : Serializable { @@ -110,7 +114,9 @@ class CarData : Serializable { var car_type = "" var car_canwrite_raw = 0 var car_canwrite = false - var car_gsmlock = "" + var car_gsm_provider = "" + var car_mdm_mode = "" + @JvmField var car_gsm_signal = "" var car_gsm_dbm = 0 @@ -156,6 +162,7 @@ class CarData : Serializable { var car_speed_units = "" var car_chargelimit_rangelimit = "" var car_max_idealrange = "" + var car_charge_timestamp = "" var stale_chargetimer = DataStale.NoValue var stale_status = DataStale.NoValue @@ -276,6 +283,9 @@ class CarData : Serializable { var car_charge_plugtype = 0 var car_charge_power_kw_raw = 0.0 var car_charge_power_kw = "" + var car_charge_kwh_grid = 0f + var car_charge_kwh_grid_total = 0f + var car_battery_capacity = 0f @JvmField var car_battery_voltage = 0.0 var car_battery_current_raw = 0.0 @@ -351,6 +361,33 @@ class CarData : Serializable { @JvmField var car_energyrecd = 0f + // Car Gen Message "X" + // not implemented yet? + var car_gen_inprogress = false + var car_gen_pilot = false + var car_gen_voltage = 0 + var car_gen_current = 0f + var car_gen_power = 0f + var car_gen_efficiency = 0f + var car_gen_type = "" + var car_gen_state = "" + var car_gen_substate = "" + var car_gen_mode = "" + var car_gen_climit = 0f + var car_gen_limit_range = 0f + var car_gen_limit_soc = 0 + var car_gen_kwh = 0f + var car_gen_kwh_grid = 0f + var car_gen_kwh_grid_total = 0f + var car_gen_time = 0 + var car_gen_timermode = 0 + var car_gen_timerstart = 0 + var car_gen_duration_empty = 0 + var car_gen_duration_range = 0 + var car_gen_duration_soc = 0 + var car_gen_temp = 0f + var car_gen_timestamp = "" + // // Renault Twizy specific // @@ -693,6 +730,20 @@ class CarData : Serializable { } else { "" } + car_charge_kwh_grid = dataParts[38].toFloat() + car_charge_kwh_grid_total = dataParts[39].toFloat() + car_battery_capacity = dataParts[40].toFloat() + } + + if (dataParts.size >= 42) { + val dateFormat = appPrefs!!.getData("option_date_format", "0") == "1" + val charge_timestamp_raw = dataParts[41].toInt() + val timestamp_formater = if(dateFormat) { + DateTimeFormatter.ofPattern("dd.MM.yy HH:mm").withZone(ZoneId.systemDefault()) + } else { + DateTimeFormatter.ofPattern("MM/dd yy hh:mm").withZone(ZoneId.systemDefault()) + } + car_charge_timestamp = timestamp_formater.format(Instant.ofEpochSecond(charge_timestamp_raw.toLong())) } } catch (e: Exception) { Log.e(TAG, "processStatus: ERROR", e) @@ -818,7 +869,7 @@ class CarData : Serializable { car_type = dataParts[4] } if (dataParts.size >= 6) { - car_gsmlock = dataParts[5] + car_gsm_provider = dataParts[5] } if (dataParts.size >= 8) { car_servicerange = if (dataParts[6] != "") { @@ -834,6 +885,10 @@ class CarData : Serializable { } if (dataParts.size >= 9) { car_hardware = dataParts[8] + + } + if (dataParts.size >= 10) { + car_mdm_mode = dataParts[9].split(";")[0].toString() } } catch (e: Exception) { Log.e(TAG, "processFirmware: ERROR", e) @@ -985,6 +1040,18 @@ class CarData : Serializable { end = i + cnt while (i < end) { ival = dataParts[i].toInt() + if (car_type == "SQ") { + // orange alert + if ((j == 0) && ((car_tpms_pressure_raw!![j] < 210) || (car_tpms_pressure_raw!![j] > 240))) ival =1 + if ((j == 1) && ((car_tpms_pressure_raw!![j] < 210) || (car_tpms_pressure_raw!![j] > 240))) ival =1 + if ((j == 2) && ((car_tpms_pressure_raw!![j] < 240) || (car_tpms_pressure_raw!![j] > 270))) ival =1 + if ((j == 3) && ((car_tpms_pressure_raw!![j] < 240) || (car_tpms_pressure_raw!![j] > 270))) ival =1 + // red alert + if ((j == 0) && ((car_tpms_pressure_raw!![j] < 190) || (car_tpms_pressure_raw!![j] > 260))) ival =2 + if ((j == 1) && ((car_tpms_pressure_raw!![j] < 190) || (car_tpms_pressure_raw!![j] > 260))) ival =2 + if ((j == 2) && ((car_tpms_pressure_raw!![j] < 220) || (car_tpms_pressure_raw!![j] > 290))) ival =2 + if ((j == 3) && ((car_tpms_pressure_raw!![j] < 220) || (car_tpms_pressure_raw!![j] > 290))) ival =2 + } if (ival > 2) ival = 2 else if (ival < 0) ival = 0 sval = if (ival == 0) "✔" else if (ival == 1) "⛛" else "⚠" car_tpms_alert_raw!![j] = ival @@ -1013,6 +1080,58 @@ class CarData : Serializable { return true } + /** + * Process GEN message ("X") + * not implemented yet? + */ + fun processGen(msgdata: String): Boolean { + init() + Log.d(TAG, "processGen: $msgdata") + try { + val dataParts = + msgdata.split(",\\s*".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray() + if (dataParts.size >= 9) { + car_gen_inprogress = dataParts[0].toBoolean() + car_gen_pilot = dataParts[1].toBoolean() + car_gen_voltage = dataParts[2].toInt() + car_gen_current = dataParts[3].toFloat() + car_gen_power = dataParts[4].toFloat() + car_gen_efficiency = dataParts[5].toFloat() + car_gen_type = dataParts[6] + car_gen_state = dataParts[7] + car_gen_substate = dataParts[8] + car_gen_mode = dataParts[9] + car_gen_climit = dataParts[10].toFloat() + car_gen_limit_range = dataParts[11].toFloat() + car_gen_limit_soc = dataParts[12].toInt() + car_gen_kwh = dataParts[13].toFloat() + car_gen_kwh_grid = dataParts[14].toFloat() + car_gen_kwh_grid_total = dataParts[15].toFloat() + car_gen_time = dataParts[16].toInt() + car_gen_timermode = dataParts[17].toInt() + car_gen_timerstart = dataParts[18].toInt() + car_gen_duration_empty = dataParts[19].toInt() + car_gen_duration_range = dataParts[20].toInt() + car_gen_duration_soc = dataParts[21].toInt() + car_gen_temp = dataParts[22].toFloat() + if (dataParts.size >= 23) { + val dateFormat = appPrefs!!.getData("option_date_format", "0") == "1" + val charge_timestamp_raw = dataParts[23].toInt() + val timestamp_formater = if(dateFormat) { + DateTimeFormatter.ofPattern("dd.MM.yy HH:mm").withZone(ZoneId.systemDefault()) + } else { + DateTimeFormatter.ofPattern("MM/dd yy hh:mm").withZone(ZoneId.systemDefault()) + } + car_charge_timestamp = timestamp_formater.format(Instant.ofEpochSecond(charge_timestamp_raw.toLong())) + } + } + } catch (e: Exception) { + Log.e(TAG, "processGen: ERROR", e) + return false + } + recalc() + return true + } /** * Get data extract suitable for system broadcast. * @@ -1080,7 +1199,10 @@ class CarData : Serializable { b.putInt("car_chargelimit_minsremaining_range", car_chargelimit_minsremaining_range) b.putInt("car_chargelimit_soclimit", car_chargelimit_soclimit) b.putInt("car_chargelimit_minsremaining_soc", car_chargelimit_minsremaining_soc) - + b.putFloat("car_charge_kwh_grid", car_charge_kwh_grid) + b.putFloat("car_charge_kwh_grid_total", car_charge_kwh_grid_total) + b.putFloat("car_battery_capacity", car_battery_capacity) + b.putString("car_charge_timestamp", car_charge_timestamp) // // Location (msgCode 'L') @@ -1157,10 +1279,11 @@ class CarData : Serializable { b.putString("car_vin", car_vin) b.putInt("car_gsm_dbm", car_gsm_dbm) b.putInt("car_gsm_bars", car_gsm_bars) - b.putString("car_gsm_lock", car_gsmlock) + b.putString("car_gsm_provider", car_gsm_provider) b.putInt("car_canwrite", car_canwrite_raw) b.putInt("car_servicedays", car_servicetime) b.putInt("car_servicedist", car_servicerange) + b.putString("car_mdm_mode", car_mdm_mode) // // TPMS new flexible wheel layout (msgCode 'Y') @@ -1200,6 +1323,35 @@ class CarData : Serializable { // Capabilities (msgCode 'V') // b.putString("car_capabilities", car_capabilities) + + // + // Gen (msgCode 'X') + // + // not implemented yet? + b.putBoolean("car_gen_inprogress", car_gen_inprogress) + b.putBoolean("car_gen_pilot", car_gen_pilot) + b.putInt("car_gen_voltage", car_gen_voltage) + b.putFloat("car_gen_current", car_gen_current) + b.putFloat("car_gen_power", car_gen_power) + b.putFloat("car_gen_efficiency", car_gen_efficiency) + b.putString("car_gen_type", car_gen_type) + b.putString("car_gen_state", car_gen_state) + b.putString("car_gen_substate", car_gen_substate) + b.putString("car_gen_mode", car_gen_mode) + b.putFloat("car_gen_climit", car_gen_climit) + b.putFloat("car_gen_limit_range", car_gen_limit_range) + b.putInt("car_gen_limit_soc", car_gen_limit_soc) + b.putFloat("car_gen_kwh", car_gen_kwh) + b.putFloat("car_gen_kwh_grid", car_gen_kwh_grid) + b.putFloat("car_gen_kwh_grid_total", car_gen_kwh_grid_total) + b.putInt("car_gen_time", car_gen_time) + b.putInt("car_gen_timermode", car_gen_timermode) + b.putInt("car_gen_timerstart", car_gen_timerstart) + b.putInt("car_gen_duration_empty", car_gen_duration_empty) + b.putInt("car_gen_duration_range", car_gen_duration_range) + b.putInt("car_gen_duration_soc", car_gen_duration_soc) + b.putFloat("car_gen_temp", car_gen_temp) + b.putString("car_gen_timestamp", car_gen_timestamp) } catch (e: Exception) { e.printStackTrace() } diff --git a/app/src/main/java/com/openvehicles/OVMS/ui/CarFragment.kt b/app/src/main/java/com/openvehicles/OVMS/ui/CarFragment.kt index f960f8c2..c94b2c1c 100644 --- a/app/src/main/java/com/openvehicles/OVMS/ui/CarFragment.kt +++ b/app/src/main/java/com/openvehicles/OVMS/ui/CarFragment.kt @@ -17,6 +17,8 @@ import android.view.ViewGroup import android.widget.ImageView import android.widget.TextView import android.widget.Toast +import androidx.appcompat.app.AlertDialog +import androidx.appcompat.app.AppCompatDialog import com.openvehicles.OVMS.R import com.openvehicles.OVMS.api.OnResultCommandListener import com.openvehicles.OVMS.entities.CarData @@ -29,6 +31,8 @@ import com.openvehicles.OVMS.ui.settings.LogsFragment import com.openvehicles.OVMS.ui.utils.Ui import com.openvehicles.OVMS.ui.utils.Ui.getDrawableIdentifier import com.openvehicles.OVMS.ui.utils.Ui.showPinDialog +import com.openvehicles.OVMS.ui.witdet.SlideNumericView +import com.openvehicles.OVMS.ui.witdet.SwitcherView import com.openvehicles.OVMS.utils.AppPrefs import com.openvehicles.OVMS.utils.CarsStorage.getSelectedCarData import kotlin.math.floor @@ -70,6 +74,7 @@ class CarFragment : BaseFragment(), View.OnClickListener, OnResultCommandListene * * @param carData */ + private fun setupCarType(carData: CarData?) { Log.d(TAG, "updateCarType: old=" + uiCarType + ", new=" + carData!!.car_type) if (uiCarType == carData.car_type) { @@ -97,10 +102,14 @@ class CarFragment : BaseFragment(), View.OnClickListener, OnResultCommandListene } "SQ" -> { // UI changes for Smart EQ: + val eqBoxes: ImageView = findViewById(R.id.tabCarImageCarTempsBoxes) as ImageView + eqBoxes.setImageResource(R.drawable.motortemp_letterbox_2) + findViewById(R.id.btn_valet_mode).visibility = View.INVISIBLE findViewById(R.id.btn_lock_car).visibility = View.INVISIBLE //findViewById(R.id.tabCarImageCarLocked).visibility = View.INVISIBLE //findViewById(R.id.tabCarImageCarValetMode).visibility = View.INVISIBLE + // change "Homelink" image: tabCarImageHomeLink.setImageResource(R.drawable.ic_home_link) } @@ -137,8 +146,8 @@ class CarFragment : BaseFragment(), View.OnClickListener, OnResultCommandListene || carData.car_type == "VWUP" || carData.car_type == "VWUP.T26") { // enable - tabCarImageCarACBoxes.setVisibility(View.VISIBLE) - tabCarImageAC.setVisibility(View.VISIBLE) + tabCarImageCarACBoxes.visibility = View.VISIBLE + tabCarImageAC.visibility = View.VISIBLE if (carData.car_hvac_on) { tabCarImageAC.setImageResource(R.drawable.ic_ac_on) } else { @@ -146,8 +155,8 @@ class CarFragment : BaseFragment(), View.OnClickListener, OnResultCommandListene } } else { // disable - tabCarImageCarACBoxes.setVisibility(View.INVISIBLE) - tabCarImageAC.setVisibility(View.INVISIBLE) + tabCarImageCarACBoxes.visibility = View.INVISIBLE + tabCarImageAC.visibility = View.INVISIBLE } uiCarType = carData.car_type @@ -268,6 +277,8 @@ class CarFragment : BaseFragment(), View.OnClickListener, OnResultCommandListene updateCarBodyView(carData) } + @Deprecated("Deprecated in Java") + @Suppress("DEPRECATION") override fun onActivityCreated(savedInstanceState: Bundle?) { super.onActivityCreated(savedInstanceState) registerForContextMenu(findViewById(R.id.btn_wakeup)) @@ -278,6 +289,10 @@ class CarFragment : BaseFragment(), View.OnClickListener, OnResultCommandListene findViewById(R.id.btn_valet_mode).setOnClickListener(this) findViewById(R.id.tabCarText12V).setOnClickListener(this) findViewById(R.id.tabCarText12VLabel).setOnClickListener(this) + findViewById(R.id.textFLWheelVal).setOnClickListener(this) + findViewById(R.id.textFRWheelVal).setOnClickListener(this) + findViewById(R.id.textRLWheelVal).setOnClickListener(this) + findViewById(R.id.textRRWheelVal).setOnClickListener(this) } override fun registerForContextMenu(view: View) { @@ -293,6 +308,7 @@ class CarFragment : BaseFragment(), View.OnClickListener, OnResultCommandListene val dialogButton: Int val isPinEntry: Boolean val id = v.id + val app_Car_ID = carData!!.sel_vehicleid when (id) { R.id.btn_lock_car -> { // get dialog mode & labels: if (carData!!.car_type == "RT") { @@ -404,6 +420,98 @@ class CarFragment : BaseFragment(), View.OnClickListener, OnResultCommandListene Configuration.ORIENTATION_UNDEFINED ) } + R.id.textFLWheelVal -> { + val tpms_fl = getString(R.string.tpms_fl) + val tpms_fr = getString(R.string.tpms_fr) + val tpms_rl = getString(R.string.tpms_rl) + val tpms_rr = getString(R.string.tpms_rr) + val options = arrayOf("$tpms_fl", "$tpms_fr", "$tpms_rl", "$tpms_rr") + var checkedItem = (appPrefs.getData("tpms_fl_$app_Car_ID", 0.toString()))!!.toInt() // To store the index of the selected item tpms + AlertDialog.Builder(requireActivity()) + .setTitle(R.string.fl_get_tpms) + .setSingleChoiceItems(options, checkedItem) { _, which -> + checkedItem = which // Update the selected item index + } + .setNegativeButton(R.string.Close, null) + .setPositiveButton(R.string.fl_set_tpms) { _, _ -> + when (checkedItem) { + 0 -> appPrefs.saveData("tpms_fl_$app_Car_ID", "0") + 1 -> appPrefs.saveData("tpms_fl_$app_Car_ID", "1") + 2 -> appPrefs.saveData("tpms_fl_$app_Car_ID", "2") + 3 -> appPrefs.saveData("tpms_fl_$app_Car_ID", "3") + } + } + .show() + } + R.id.textFRWheelVal -> { + val tpms_fl = getString(R.string.tpms_fl) + val tpms_fr = getString(R.string.tpms_fr) + val tpms_rl = getString(R.string.tpms_rl) + val tpms_rr = getString(R.string.tpms_rr) + val options = arrayOf("$tpms_fl", "$tpms_fr", "$tpms_rl", "$tpms_rr") + var checkedItem = (appPrefs.getData("tpms_fr_$app_Car_ID", 1.toString()))!!.toInt() // To store the index of the selected item tpms + AlertDialog.Builder(requireActivity()) + .setTitle(R.string.fr_get_tpms) + .setSingleChoiceItems(options, checkedItem) { _, which -> + checkedItem = which // Update the selected item index + } + .setNegativeButton(R.string.Close, null) + .setPositiveButton(R.string.fr_set_tpms) { _, _ -> + when (checkedItem) { + 0 -> appPrefs.saveData("tpms_fr_$app_Car_ID", "0") + 1 -> appPrefs.saveData("tpms_fr_$app_Car_ID", "1") + 2 -> appPrefs.saveData("tpms_fr_$app_Car_ID", "2") + 3 -> appPrefs.saveData("tpms_fr_$app_Car_ID", "3") + } + } + .show() + } + R.id.textRLWheelVal -> { + val tpms_fl = getString(R.string.tpms_fl) + val tpms_fr = getString(R.string.tpms_fr) + val tpms_rl = getString(R.string.tpms_rl) + val tpms_rr = getString(R.string.tpms_rr) + val options = arrayOf("$tpms_fl", "$tpms_fr", "$tpms_rl", "$tpms_rr") + var checkedItem = (appPrefs.getData("tpms_rl_$app_Car_ID", 2.toString()))!!.toInt() // To store the index of the selected item tpms + AlertDialog.Builder(requireActivity()) + .setTitle(R.string.rl_get_tpms) + .setSingleChoiceItems(options, checkedItem) { _, which -> + checkedItem = which // Update the selected item index + } + .setNegativeButton(R.string.Close, null) + .setPositiveButton(R.string.rl_set_tpms) { _, _ -> + when (checkedItem) { + 0 -> appPrefs.saveData("tpms_rl_$app_Car_ID", "0") + 1 -> appPrefs.saveData("tpms_rl_$app_Car_ID", "1") + 2 -> appPrefs.saveData("tpms_rl_$app_Car_ID", "2") + 3 -> appPrefs.saveData("tpms_rl_$app_Car_ID", "3") + } + } + .show() + } + R.id.textRRWheelVal -> { + val tpms_fl = getString(R.string.tpms_fl) + val tpms_fr = getString(R.string.tpms_fr) + val tpms_rl = getString(R.string.tpms_rl) + val tpms_rr = getString(R.string.tpms_rr) + val options = arrayOf("$tpms_fl", "$tpms_fr", "$tpms_rl", "$tpms_rr") + var checkedItem = (appPrefs.getData("tpms_rr_$app_Car_ID", 3.toString()))!!.toInt() // To store the index of the selected item tpms + AlertDialog.Builder(requireActivity()) + .setTitle(R.string.rr_get_tpms) + .setSingleChoiceItems(options, checkedItem) { _, which -> + checkedItem = which // Update the selected item index + } + .setNegativeButton(R.string.Close, null) + .setPositiveButton(R.string.rr_set_tpms) { _, _ -> + when (checkedItem) { + 0 -> appPrefs.saveData("tpms_rr_$app_Car_ID", "0") + 1 -> appPrefs.saveData("tpms_rr_$app_Car_ID", "1") + 2 -> appPrefs.saveData("tpms_rr_$app_Car_ID", "2") + 3 -> appPrefs.saveData("tpms_rr_$app_Car_ID", "3") + } + } + .show() + } else -> { v.performLongClick() } @@ -413,6 +521,7 @@ class CarFragment : BaseFragment(), View.OnClickListener, OnResultCommandListene override fun onCreateContextMenu(menu: ContextMenu, v: View, menuInfo: ContextMenuInfo?) { super.onCreateContextMenu(menu, v, menuInfo) val id = v.id + val app_Car_ID = carData!!.sel_vehicleid when (id) { R.id.btn_wakeup -> { if (carData!!.car_type == "RT") { @@ -421,6 +530,11 @@ class CarFragment : BaseFragment(), View.OnClickListener, OnResultCommandListene } menu.setHeaderTitle(R.string.lb_wakeup_car) menu.add(0, MI_WAKEUP, 0, R.string.Wakeup) + /* + if (carData!!.car_type == "SQ") { + menu.add(0, MI_WAKEUP_2, 0, "reset Trip") + } + */ menu.add(R.string.Cancel) } R.id.tabCarImageHomelink, R.id.txt_homelink -> { @@ -431,33 +545,78 @@ class CarFragment : BaseFragment(), View.OnClickListener, OnResultCommandListene } else { menu.setHeaderTitle(R.string.textHOMELINK) } - if (carData!!.car_type == "SQ") { - menu.add(0, MI_HL_01, 0, "Booster") - menu.add(0, MI_HL_02, 0, "2") - menu.add(0, MI_HL_03, 0, "3") - menu.add(R.string.Cancel) + if (appPrefs.getData("plugin_2_$app_Car_ID") == "on") { + menu.add(0, MI_HL_01, 0, R.string.mi_ac_on) } else { menu.add(0, MI_HL_01, 0, "1") + } + // not needed/working btn for SmartEQ + if (carData!!.car_type != "SQ") { menu.add(0, MI_HL_02, 0, "2") menu.add(0, MI_HL_03, 0, "3") - menu.add(R.string.Cancel) } + if (appPrefs.getData("plugin_2_$app_Car_ID") == "on") { + menu.add(0, MI_HL_BTR, 0, R.string.lb_booster_ctrl_reset) + } + if(appPrefs.getData("option_firmware_enabled_$app_Car_ID") == "1") { + menu.add(0, MI_HL_FW, 0, R.string.lb_options_firmware_update) + } + if(appPrefs.getData("option_plugin_ovms_$app_Car_ID") == "1") { + menu.add(0, MI_HL_PLUGIN_OVMS, 0, R.string.lb_options_plugin_ovms) + } + if(appPrefs.getData("option_plugin_eq_$app_Car_ID") == "1") { + menu.add(0, MI_HL_PLUGIN_EQ, 0, R.string.lb_options_plugin_eq) + } + menu.add(R.string.Close) } R.id.tabCarImageAC -> { menu.setHeaderTitle(R.string.textAC) - menu.add(0, MI_AC_ON, 0, R.string.mi_ac_on) - menu.add(0, MI_AC_OFF, 0, R.string.mi_ac_off) - menu.add(R.string.Cancel) + if (appPrefs.getData("plugin_2_$app_Car_ID") == "on") { + menu.add(0, MI_AC_ON, 0, R.string.mi_ac_on) + // not needed/working btn for SmartEQ + if (carData!!.car_type != "SQ") { + menu.add(0, MI_AC_OFF, 0, R.string.mi_ac_off) + } + menu.add(0, MI_AC_BON, 0, if(appPrefs.getData("booster_on_$app_Car_ID") == "on") R.string.lb_booster_off else R.string.lb_booster_on) + menu.add(0, MI_AC_BT, 0, R.string.lb_booster_time) + menu.add(0, MI_AC_BW, 0, if(appPrefs.getData("booster_weekly_on_$app_Car_ID") == "on") R.string.lb_booster_weekly_off else R.string.lb_booster_weekly_on) + menu.add(0, MI_AC_BDS, 0, R.string.lb_booster_day_sel) + menu.add(0, MI_AC_BTD, 0, if(appPrefs.getData("booster_btd_$app_Car_ID") == "1") R.string.lb_booster_doubler_off else R.string.lb_booster_doubler_on) + } else { + menu.add(0, MI_AC_ON, 0, R.string.mi_ac_on) + // not needed/working btn for SmartEQ + if (carData!!.car_type != "SQ") { + menu.add(0, MI_AC_OFF, 0, R.string.mi_ac_off) + } + } + menu.add(R.string.Close) } + } } - + override fun onContextItemSelected(item: MenuItem): Boolean { + // "Booster" box: + val app_Car_ID = carData!!.sel_vehicleid + val tabCarImageBooster = findViewById(R.id.tabCarImageBooster) as ImageView + val tabCarImageCalendar = findViewById(R.id.tabCarImageCalendar) as ImageView + val tabInfoTextBoostertime = findViewById(R.id.tabInfoTextBoostertime) as TextView + if(appPrefs.getData("booster_btd_$app_Car_ID") == "1") tabCarImageBooster.setImageResource(R.drawable.heat_cool_2) else tabCarImageBooster.setImageResource(R.drawable.heat_cool) + tabCarImageBooster.visibility = if (appPrefs.getData("booster_on_$app_Car_ID") == "on") View.VISIBLE else View.INVISIBLE + tabInfoTextBoostertime.visibility = if (appPrefs.getData("booster_on_$app_Car_ID") == "on") View.VISIBLE else View.INVISIBLE + tabInfoTextBoostertime.text = appPrefs.getData("booster_time_$app_Car_ID") + tabCarImageCalendar.visibility = if (appPrefs.getData("booster_weekly_on_$app_Car_ID") == "on") View.VISIBLE else View.INVISIBLE return when (item.itemId) { MI_WAKEUP -> { sendCommand(R.string.msg_wakeup_car, "18", this) true } + MI_WAKEUP_2 -> { + sendCommand(R.string.msg_wakeup_reset, "7,me set v.b.energy.recd 0", this) + sendCommand(R.string.msg_wakeup_reset, "7,me set v.b.energy.used 0", this) + sendCommand(R.string.msg_wakeup_reset, "7,me set v.p.trip 0", this) + true + } MI_HL_01 -> { sendCommand(R.string.msg_issuing_homelink, "24,0", this) true @@ -474,6 +633,283 @@ class CarFragment : BaseFragment(), View.OnClickListener, OnResultCommandListene sendCommand(R.string.msg_issuing_homelink, "24", this) true } + MI_HL_BTR -> { + appPrefs.saveData("booster_on_$app_Car_ID", "off") + appPrefs.saveData("booster_time_$app_Car_ID", "05:15") + appPrefs.saveData("booster_weekly_on_$app_Car_ID", "off") + appPrefs.saveData("booster_btd_$app_Car_ID", "0") + appPrefs.saveData("booster_time_h_$app_Car_ID", "5") + appPrefs.saveData("booster_time_m_$app_Car_ID", "15") + tabCarImageBooster.visibility = View.INVISIBLE + tabInfoTextBoostertime.visibility = View.INVISIBLE + tabCarImageCalendar.visibility = View.INVISIBLE + sendCommand(R.string.msg_issuing_homelink, "7,config set usr b.init no", this) + sendCommand(R.string.msg_issuing_homelink, "7,module reset", this) + true + } + MI_HL_FW -> { + var options = arrayOf("Edge - nightly Developer", "Eap - stable Developer", "Main - @PlayStore") + var checkedItem = -1 // To store the index of the selected item + AlertDialog.Builder(requireActivity()) + .setTitle(R.string.lb_plugin_firmware) + .setSingleChoiceItems(options, checkedItem) { _, which -> + checkedItem = which // Update the selected item index + } + .setNegativeButton(R.string.Close, null) + .setPositiveButton(R.string.lb_firmware_update) { _, _ -> + when (checkedItem) { + 0 -> sendCommand(R.string.lb_firmware_update, "7,ota flash http ovms.dexters-web.de/firmware/ota/v3.3/edge/ovms3.bin", this) + 1 -> sendCommand(R.string.lb_firmware_update, "7,ota flash http ovms.dexters-web.de/firmware/ota/v3.3/eap/ovms3.bin", this) + 2 -> sendCommand(R.string.lb_firmware_update, "7,ota flash http ovms.dexters-web.de/firmware/ota/v3.3/main/ovms3.bin", this) + } + } + .show() + true + } + MI_HL_PLUGIN_OVMS -> { + val plugin_update = getString(R.string.lb_plugin_update) + val plugin_script_reload = getString(R.string.lb_plugin_script_reload) + val plugin_1 = if (appPrefs.getData("plugin_ovms_1_$app_Car_ID") == "on") getString(R.string.lb_plugin_ovms_1_off) else getString(R.string.lb_plugin_ovms_1_on) + val plugin_2 = if (appPrefs.getData("plugin_ovms_2_$app_Car_ID") == "on") getString(R.string.lb_plugin_ovms_2_off) else getString(R.string.lb_plugin_ovms_2_on) + val plugin_3 = if (appPrefs.getData("plugin_ovms_3_$app_Car_ID") == "on") getString(R.string.lb_plugin_ovms_3_off) else getString(R.string.lb_plugin_ovms_3_on) + val plugin_4 = if (appPrefs.getData("plugin_ovms_4_$app_Car_ID") == "on") getString(R.string.lb_plugin_ovms_4_off) else getString(R.string.lb_plugin_ovms_4_on) + val plugin_5 = if (appPrefs.getData("plugin_ovms_5_$app_Car_ID") == "on") getString(R.string.lb_plugin_ovms_5_off) else getString(R.string.lb_plugin_ovms_5_on) + + var options = arrayOf( + "$plugin_update", + "$plugin_script_reload", + "$plugin_1", + "$plugin_2", + "$plugin_3", + "$plugin_4", + "$plugin_5" + ) + var checkedItem = -1 // To store the index of the selected item + AlertDialog.Builder(requireActivity()) + .setTitle(R.string.lb_options_plugin_ovms) + .setSingleChoiceItems(options, checkedItem) { _, which -> + checkedItem = which // Update the selected item index + } + .setNegativeButton(R.string.Close, null) + .setPositiveButton(R.string.execute) { _, _ -> + when (checkedItem) { + // plugin update + 0 -> { + sendCommand(R.string.lb_plugin_update, "7,plugin update", this) + } + // script reload + 1 -> { + sendCommand(R.string.lb_plugin_script_reload, "7,script reload", this) + } + // plugin 1 auxbatmon + 2 -> { + if (appPrefs.getData("plugin_ovms_1_$app_Car_ID") == "on") { + appPrefs.saveData("plugin_ovms_1_$app_Car_ID", "off") + sendCommand(R.string.lb_plugin_ovms_1_off, "7,plugin disable auxbatmon", this) + } else { + if (appPrefs.getData("plugin_ovms_1_$app_Car_ID") == "off") { + appPrefs.saveData("plugin_ovms_1_$app_Car_ID", "on") + sendCommand(R.string.lb_plugin_ovms_1_on, "7,plugin enable auxbatmon", this) + } else { + appPrefs.saveData("plugin_ovms_1_$app_Car_ID", "on") + sendCommand(R.string.lb_plugin_ovms_1_on,"7,plugin install auxbatmon",this) + } + } + } + // plugin 2 pwrmon + 3 -> { + if (appPrefs.getData("plugin_ovms_2_$app_Car_ID") == "on") { + appPrefs.saveData("plugin_ovms_2_$app_Car_ID", "off") + sendCommand(R.string.lb_plugin_ovms_2_off, "7,plugin disable pwrmon", this) + } else { + if (appPrefs.getData("plugin_ovms_2_$app_Car_ID") == "off") { + appPrefs.saveData("plugin_ovms_2_$app_Car_ID", "on") + sendCommand(R.string.lb_plugin_ovms_2_on, "7,plugin enable pwrmon", this) + } else { + appPrefs.saveData("plugin_ovms_2_$app_Car_ID", "on") + sendCommand(R.string.lb_plugin_ovms_2_on, "7,plugin install pwrmon", this) + } + } + } + // plugin 3 regenmon + 4 -> { + if (appPrefs.getData("plugin_ovms_3_$app_Car_ID") == "on") { + appPrefs.saveData("plugin_ovms_3_$app_Car_ID", "off") + sendCommand(R.string.lb_plugin_ovms_3_off, "7,plugin disable regenmon", this) + } else { + if (appPrefs.getData("plugin_ovms_3_$app_Car_ID") == "off") { + appPrefs.saveData("plugin_ovms_3_$app_Car_ID", "on") + sendCommand(R.string.lb_plugin_ovms_3_on, "7,plugin enable regenmon", this) + } else { + appPrefs.saveData("plugin_ovms_3_$app_Car_ID", "on") + sendCommand(R.string.lb_plugin_ovms_3_on, "7,plugin install regenmon", this) + } + } + } + // plugin 4 repidscan + 5 -> { + if (appPrefs.getData("plugin_ovms_4_$app_Car_ID") == "on") { + appPrefs.saveData("plugin_ovms_4_$app_Car_ID", "off") + sendCommand(R.string.lb_plugin_ovms_4_off, "7,plugin disable repidscan", this) + } else { + if (appPrefs.getData("plugin_ovms_4_$app_Car_ID") == "off") { + appPrefs.saveData("plugin_ovms_4_$app_Car_ID", "on") + sendCommand(R.string.lb_plugin_ovms_4_on, "7,plugin enable repidscan", this) + } else { + appPrefs.saveData("plugin_ovms_4_$app_Car_ID", "on") + sendCommand(R.string.lb_plugin_ovms_4_on, "7,plugin install repidscan", this) + } + } + } + // plugin 5 retools + 6 -> { + if (appPrefs.getData("plugin_ovms_5_$app_Car_ID") == "on") { + appPrefs.saveData("plugin_ovms_5_$app_Car_ID", "off") + sendCommand(R.string.lb_plugin_ovms_5_off, "7,plugin disable retools", this) + } else { + if (appPrefs.getData("plugin_ovms_5_$app_Car_ID") == "off") { + appPrefs.saveData("plugin_ovms_5_$app_Car_ID", "on") + sendCommand(R.string.lb_plugin_ovms_5_on, "7,plugin enable retools", this) + } else { + appPrefs.saveData("plugin_ovms_5_$app_Car_ID", "on") + sendCommand(R.string.lb_plugin_ovms_5_on, "7,plugin install retools", this) + } + } + } + } + } + .show() + true + } + MI_HL_PLUGIN_EQ -> { + val plugin_inst = if (appPrefs.getData("plugin_repo_smarteq_$app_Car_ID") == "on") getString(R.string.lb_options_plugin_deinst) else getString(R.string.lb_options_plugin_inst) + val plugin_update = getString(R.string.lb_plugin_update) + val plugin_script_reload = getString(R.string.lb_plugin_script_reload) + val plugin_1 = if (appPrefs.getData("plugin_1_$app_Car_ID") == "on") getString(R.string.lb_plugin_eq_1_off) else getString(R.string.lb_plugin_eq_1_on) + val plugin_2 = if (appPrefs.getData("plugin_2_$app_Car_ID") == "on") getString(R.string.lb_plugin_eq_2_off) else getString(R.string.lb_plugin_eq_2_on) + val plugin_3 = if (appPrefs.getData("plugin_3_$app_Car_ID") == "on") getString(R.string.lb_plugin_eq_3_off) else getString(R.string.lb_plugin_eq_3_on) + val plugin_4 = if (appPrefs.getData("plugin_4_$app_Car_ID") == "on") getString(R.string.lb_plugin_eq_4_off) else getString(R.string.lb_plugin_eq_4_on) + val plugin_5 = if (appPrefs.getData("plugin_5_$app_Car_ID") == "on") getString(R.string.lb_plugin_eq_5_off) else getString(R.string.lb_plugin_eq_5_on) + + var options = arrayOf( + "$plugin_inst", + "$plugin_update", + "$plugin_script_reload", + "$plugin_1", + "$plugin_2", + "$plugin_3", + "$plugin_4", + "$plugin_5" + ) + var checkedItem = -1 // To store the index of the selected item + AlertDialog.Builder(requireActivity()) + .setTitle(R.string.lb_options_plugin_eq) + .setSingleChoiceItems(options, checkedItem) { _, which -> + checkedItem = which // Update the selected item index + } + .setNegativeButton(R.string.Close, null) + .setPositiveButton(R.string.execute) { _, _ -> + when (checkedItem) { + // plugin installation SmartEQ + 0 -> { + if (appPrefs.getData("plugin_repo_smarteq_$app_Car_ID") == "on") { + appPrefs.saveData("plugin_repo_smarteq_$app_Car_ID", "off") + sendCommand(R.string.lb_options_plugin_deinst, "7,plugin repo remove SmartEQ", this) + } else { + appPrefs.saveData("plugin_repo_smarteq_$app_Car_ID", "on") + sendCommand(R.string.lb_options_plugin_inst, "7,plugin repo install SmartEQ https://ovms.dimitrie.eu/plugins/", this) + } + } + // plugin update + 1 -> { + sendCommand(R.string.lb_plugin_update, "7,plugin update", this) + } + // script reload + 2 -> { + sendCommand(R.string.lb_plugin_script_reload, "7,script reload", this) + } + // plugin 1 xsq_v2data + 3 -> { + if (appPrefs.getData("plugin_1_$app_Car_ID") == "on") { + appPrefs.saveData("plugin_1_$app_Car_ID", "off") + sendCommand(R.string.lb_plugin_eq_1_off, "7,plugin disable xsq_v2data", this) + } else { + //appPrefs.saveData("plugin_1_$app_Car_ID", "on") + /* disable plugin 1 activation it will replaced // to do + if (appPrefs.getData("plugin_1_$app_Car_ID") == "off") { + appPrefs.saveData("plugin_1_$app_Car_ID", "on") + sendCommand(R.string.lb_plugin_eq_1_on, "7,plugin enable xsq_v2data", this) + } else { + appPrefs.saveData("plugin_1_$app_Car_ID", "on") + sendCommand(R.string.lb_plugin_eq_1_on,"7,plugin install xsq_v2data",this) + }*/ + } + } + // plugin 2 scheduled_booster + 4 -> { + if (appPrefs.getData("plugin_2_$app_Car_ID") == "on") { + appPrefs.saveData("plugin_2_$app_Car_ID", "off") + sendCommand(R.string.lb_plugin_eq_2_off, "7,plugin disable scheduled_booster", this) + } else { + if (appPrefs.getData("plugin_2_$app_Car_ID") == "off") { + appPrefs.saveData("plugin_2_$app_Car_ID", "on") + sendCommand(R.string.lb_plugin_eq_2_on, "7,plugin enable scheduled_booster", this) + } else { + appPrefs.saveData("plugin_2_$app_Car_ID", "on") + sendCommand(R.string.lb_plugin_eq_2_on, "7,plugin install scheduled_booster", this) + } + } + } + // plugin 3 gps_onoff + 5 -> { + if (appPrefs.getData("plugin_3_$app_Car_ID") == "on") { + appPrefs.saveData("plugin_3_$app_Car_ID", "off") + sendCommand(R.string.lb_plugin_eq_3_off, "7,plugin disable gps_onoff", this) + } else { + if (appPrefs.getData("plugin_3_$app_Car_ID") == "off") { + appPrefs.saveData("plugin_3_$app_Car_ID", "on") + sendCommand(R.string.lb_plugin_eq_3_on, "7,plugin enable gps_onoff", this) + } else { + appPrefs.saveData("plugin_3_$app_Car_ID", "on") + sendCommand(R.string.lb_plugin_eq_3_on, "7,plugin install gps_onoff", this) + } + } + } + // plugin 4 booster_12V + 6 -> { + if (appPrefs.getData("plugin_4_$app_Car_ID") == "on") { + appPrefs.saveData("plugin_4_$app_Car_ID", "off") + sendCommand(R.string.lb_plugin_eq_4_off, "7,plugin disable booster_12V", this) + } else { + if (appPrefs.getData("plugin_4_$app_Car_ID") == "off") { + appPrefs.saveData("plugin_4_$app_Car_ID", "on") + sendCommand(R.string.lb_plugin_eq_4_on, "7,plugin enable booster_12V", this) + } else { + appPrefs.saveData("plugin_4_$app_Car_ID", "on") + sendCommand(R.string.lb_plugin_eq_4_on, "7,plugin install booster_12V", this) + } + } + } + // plugin 5 modem_lte + 7 -> { + if (appPrefs.getData("plugin_5_$app_Car_ID") == "on") { + appPrefs.saveData("plugin_5_$app_Car_ID", "off") + sendCommand(R.string.lb_plugin_eq_5_off, "7,plugin disable modem_lte", this) + } else { + if (appPrefs.getData("plugin_5_$app_Car_ID") == "off") { + appPrefs.saveData("plugin_5_$app_Car_ID", "on") + sendCommand(R.string.lb_plugin_eq_5_on, "7,plugin enable modem_lte", this) + } else { + appPrefs.saveData("plugin_5_$app_Car_ID", "on") + sendCommand(R.string.lb_plugin_eq_5_on, "7,plugin install modem_lte", this) + } + } + } + } + } + .show() + true + } MI_AC_ON -> { sendCommand(R.string.msg_issuing_climatecontrol, "26,1", this) true @@ -482,6 +918,171 @@ class CarFragment : BaseFragment(), View.OnClickListener, OnResultCommandListene sendCommand(R.string.msg_issuing_climatecontrol, "26,0", this) true } + MI_AC_BON -> { + val state = appPrefs.getData("booster_on_$app_Car_ID") + val newState = if (state == "on") "off" else "on" + tabCarImageBooster.visibility = if (newState == "on") View.VISIBLE else View.INVISIBLE + tabInfoTextBoostertime.visibility = if (newState == "on") View.VISIBLE else View.INVISIBLE + appPrefs.saveData("booster_on_$app_Car_ID", newState) + if (newState == "off") { + tabCarImageCalendar.visibility = View.INVISIBLE + appPrefs.saveData("booster_on_$app_Car_ID", "off") + appPrefs.saveData("booster_weekly_on_$app_Car_ID", "off") + sendCommand( + R.string.msg_issuing_climatecontrol, + "7,config set usr b.data 1,2,2,0,-1,-1,-1", + this + ) + } else { + appPrefs.saveData("booster_on_$app_Car_ID", "on") + sendCommand( + R.string.msg_issuing_climatecontrol, + "7,config set usr b.data 1,1,0,0,-1,-1,-1", + this + ) + } + true + } + MI_AC_BT -> { + // create booster timer dialog: + val dialogView = LayoutInflater.from(activity).inflate( + R.layout.dlg_booster_time, null + ) + + val booster_h = dialogView.findViewById(R.id.booster_time_hour) as SlideNumericView? + val booster_m = dialogView.findViewById(R.id.booster_time_min) as SlideNumericView? + val booster_sel = dialogView.findViewById(R.id.booster_SwitcherView) as SwitcherView? + if(appPrefs.getData("booster_time_h_$app_Car_ID") != "") { + booster_h!!.value = appPrefs.getData("booster_time_h_$app_Car_ID").toInt() + booster_m!!.value = appPrefs.getData("booster_time_m_$app_Car_ID").toInt() + } + if(appPrefs.getData("booster_btd_$app_Car_ID") != "") booster_sel!!.selected = appPrefs.getData("booster_btd_$app_Car_ID").toInt() + + AlertDialog.Builder(requireActivity()) + .setTitle(R.string.lb_booster_time) + .setView(dialogView) + .setNegativeButton(R.string.Cancel, null) + .setPositiveButton( + R.string.Set + ) { dlg, _ -> + appPrefs.saveData("booster_on_$app_Car_ID", "on") + tabCarImageBooster.visibility = View.VISIBLE + tabInfoTextBoostertime.visibility = View.VISIBLE + val appCompatDialog = dlg as AppCompatDialog + val booster_hd = appCompatDialog + .findViewById(R.id.booster_time_hour) as SlideNumericView? + val booster_md = appCompatDialog + .findViewById(R.id.booster_time_min) as SlideNumericView? + val booster_h = if(booster_hd!!.value < 10) String.format("0%d", booster_hd.value) else booster_hd.value + val booster_m = if(booster_md!!.value < 10) String.format("0%d", booster_md.value) else booster_md.value + val booster_sel = appCompatDialog + .findViewById(R.id.booster_SwitcherView) as SwitcherView? + val booster_btd = booster_sel!!.selected + val time = "$booster_h:$booster_m" + val cmd = "7,config set usr b.data 1,1,0,$booster_h$booster_m,-1,-1,$booster_btd" + appPrefs.saveData("booster_time_$app_Car_ID", time) + appPrefs.saveData("booster_time_h_$app_Car_ID", "$booster_h") + appPrefs.saveData("booster_time_m_$app_Car_ID", "$booster_m") + appPrefs.saveData("booster_btd_$app_Car_ID", "$booster_btd") + tabInfoTextBoostertime.text = time + if("$booster_btd" == "1") tabCarImageBooster.setImageResource(R.drawable.heat_cool_2) else tabCarImageBooster.setImageResource(R.drawable.heat_cool) + sendCommand( + R.string.msg_issuing_climatecontrol, cmd, + this@CarFragment) + } + .show() + true + } + MI_AC_BW -> { + val state_weekly = appPrefs.getData("booster_weekly_on_$app_Car_ID") + val newState = if (state_weekly == "on") "off" else "on" + if (newState == "off") { + appPrefs.saveData("booster_on_$app_Car_ID", "off") + appPrefs.saveData("booster_weekly_on_$app_Car_ID", "off") + tabCarImageBooster.visibility = View.INVISIBLE + tabInfoTextBoostertime.visibility = View.INVISIBLE + tabCarImageCalendar.visibility = View.INVISIBLE + sendCommand( + R.string.msg_issuing_climatecontrol, + "7,config set usr b.data 1,2,2,0,-1,-1,-1", + this + ) + } else { + appPrefs.saveData("booster_on_$app_Car_ID", "on") + appPrefs.saveData("booster_weekly_on_$app_Car_ID", "on") + tabCarImageBooster.visibility = View.VISIBLE + tabInfoTextBoostertime.visibility = View.VISIBLE + tabCarImageCalendar.visibility = View.VISIBLE + sendCommand( + R.string.msg_issuing_climatecontrol, + "7,config set usr b.data 1,1,1,0,-1,-1,-1", + this + ) + } + true + } + MI_AC_BDS -> { + // show booster start Day dialog: + val dialogView = LayoutInflater.from(activity).inflate( + R.layout.dlg_booster_days, null + ) + + val booster_sel_s = dialogView.findViewById(R.id.booster_DayViewStart) as SwitcherView? + val booster_sel_e = dialogView.findViewById(R.id.booster_DayViewEnd) as SwitcherView? + if(appPrefs.getData("booster_day_start_$app_Car_ID") != "") booster_sel_s!!.selected = appPrefs.getData("booster_day_start_$app_Car_ID").toInt() + if(appPrefs.getData("booster_day_end_$app_Car_ID") != "") booster_sel_e!!.selected = appPrefs.getData("booster_day_end_$app_Car_ID").toInt() + + AlertDialog.Builder(requireActivity()) + .setTitle(R.string.lb_booster_day_sel) + .setView(dialogView) + .setNegativeButton(R.string.Cancel, null) + .setPositiveButton( + R.string.Set + ) { dlg, _ -> + appPrefs.saveData("booster_on_$app_Car_ID", "on") + appPrefs.saveData("booster_weekly_on_$app_Car_ID", "on") + tabCarImageBooster.visibility = View.VISIBLE + tabInfoTextBoostertime.visibility = View.VISIBLE + tabCarImageCalendar.visibility = View.VISIBLE + val appCompatDialog = dlg as AppCompatDialog + val booster_sel_s = appCompatDialog + .findViewById(R.id.booster_DayViewStart) as SwitcherView? + val booster_sel_e = appCompatDialog + .findViewById(R.id.booster_DayViewEnd) as SwitcherView? + val booster_start = booster_sel_s!!.selected + val booster_end = booster_sel_e!!.selected + val cmd = "7,config set usr b.data 1,1,1,0,$booster_start,$booster_end,-1" + appPrefs.saveData("booster_day_start_$app_Car_ID", "$booster_start") + appPrefs.saveData("booster_day_end_$app_Car_ID", "$booster_end") + sendCommand( + R.string.msg_issuing_climatecontrol, cmd, + this@CarFragment) + } + .show() + true + } + MI_AC_BTD -> { + val state = appPrefs.getData("booster_btd_$app_Car_ID") + val newState = if (state == "1") "0" else "1" + if (newState == "0") { + appPrefs.saveData("booster_btd_$app_Car_ID", "0") + tabCarImageBooster.setImageResource(R.drawable.heat_cool) + sendCommand( + R.string.msg_issuing_climatecontrol, + "7,config set usr b.data 1,0,0,0,-1,-1,-1", + this + ) + } else { + appPrefs.saveData("booster_btd_$app_Car_ID", "1") + tabCarImageBooster.setImageResource(R.drawable.heat_cool_2) + sendCommand( + R.string.msg_issuing_climatecontrol, + "7,config set usr b.data 1,0,0,0,-1,-1,1", + this + ) + } + true + } else -> false } } @@ -491,7 +1092,7 @@ class CarFragment : BaseFragment(), View.OnClickListener, OnResultCommandListene return } - val command = result[0].toInt() + //val command = result[0].toInt() val resCode = result[1].toInt() val resText = if (result.size > 2) result[2] else "" val cmdMessage = getSentCommandMessage(result[0]) @@ -569,7 +1170,7 @@ class CarFragment : BaseFragment(), View.OnClickListener, OnResultCommandListene if (minutes == 0L) { tv.text = getText(R.string.justnow) } else if (minutes == 1L) { - tv.text = "1 min" + tv.text = getText(R.string.min1) } else if (days > 1) { tv.text = String.format(getText(R.string.ndays).toString(), days) } else if (hours > 1) { @@ -608,6 +1209,9 @@ class CarFragment : BaseFragment(), View.OnClickListener, OnResultCommandListene } else if (carData.sel_vehicle_image.startsWith("car_i3_")) { // BMW i3: one ol image for all colors since roof is same: iv.setImageResource(R.drawable.ol_car_i3) + } else if (carData.sel_vehicle_image.startsWith("car_smart_44")) { + // smart ED: one ol image for all colors: + iv.setImageResource(R.drawable.ol_car_vwup_black) } else if (carData.sel_vehicle_image.startsWith("car_smart_")) { // smart ED: one ol image for all colors: iv.setImageResource(R.drawable.ol_car_smart) @@ -636,7 +1240,7 @@ class CarFragment : BaseFragment(), View.OnClickListener, OnResultCommandListene // "12V" box: //label = (TextView) findViewById(R.id.tabCarText12VLabel); var tv: TextView = findViewById(R.id.tabCarText12V) as TextView - tv.text = String.format("%.1fV", this.carData!!.car_12vline_voltage) + tv.text = String.format("%.2fV", this.carData!!.car_12vline_voltage) if (this.carData!!.car_12vline_ref <= 1.5 || this.carData!!.car_charging_12v) { // charging / calmdown tv.setTextColor(-0x565601) @@ -657,20 +1261,20 @@ class CarFragment : BaseFragment(), View.OnClickListener, OnResultCommandListene tv = findViewById(R.id.tabCarTextAmbient) as TextView when (carData.stale_ambient_temp) { DataStale.NoValue -> { - iv.setVisibility(View.INVISIBLE) + iv.visibility = View.INVISIBLE label.visibility = View.INVISIBLE tv.text = null } DataStale.Stale -> { - iv.setVisibility(View.VISIBLE) + iv.visibility = View.VISIBLE label.visibility = View.VISIBLE - tv.text = carData.car_temp_ambient + tv.text = String.format("%.0f°C", carData.car_temp_ambient_raw) tv.setTextColor(-0x7f7f80) } else -> { - iv.setVisibility(View.VISIBLE) + iv.visibility = View.VISIBLE label.visibility = View.VISIBLE - tv.text = carData.car_temp_ambient + tv.text = String.format("%.0f°C", carData.car_temp_ambient_raw) tv.setTextColor(-0x1) } } @@ -751,7 +1355,7 @@ class CarFragment : BaseFragment(), View.OnClickListener, OnResultCommandListene // Update display: if (stale1 == DataStale.NoValue) { - iv.setVisibility(View.INVISIBLE) + iv.visibility = View.INVISIBLE fltv.text = null frtv.text = null rltv.text = null @@ -761,31 +1365,59 @@ class CarFragment : BaseFragment(), View.OnClickListener, OnResultCommandListene rltvv.text = null rrtvv.text = null } else { - iv.setVisibility(View.VISIBLE) - fltv.text = val1!![0] - frtv.text = val1[1] - rltv.text = val1[2] - rrtv.text = val1[3] - fltvv.text = val2!![0] - frtvv.text = val2[1] - rltvv.text = val2[2] - rrtvv.text = val2[3] - val trans1 = if (stale1 == DataStale.Stale) -0x80000000 else -0x1000000 - val trans2 = if (stale2 == DataStale.Stale) -0x80000000 else -0x1000000 + iv.visibility = View.VISIBLE + + val tpms_fl = (appPrefs.getData("tpms_fl_" + carData.sel_vehicleid, 0.toString()))!!.toInt() + val tpms_fr = (appPrefs.getData("tpms_fr_" + carData.sel_vehicleid, 1.toString()))!!.toInt() + val tpms_rl = (appPrefs.getData("tpms_rl_" + carData.sel_vehicleid, 2.toString()))!!.toInt() + val tpms_rr = (appPrefs.getData("tpms_rr_" + carData.sel_vehicleid, 3.toString()))!!.toInt() + + if ((carData.car_type == "SQ")&&(val1!![0]=="FL")&&(val2!![0]!="FL")) { + // fix the wrong side of the tires + fltv.text = getString(R.string.fl_tpms) + frtv.text = getString(R.string.fr_tpms) + rltv.text = getString(R.string.rl_tpms) + rrtv.text = getString(R.string.rr_tpms) + fltvv.text = val2[tpms_fl] + frtvv.text = val2[tpms_fr] + rltvv.text = val2[tpms_rl] + rrtvv.text = val2[tpms_rr] + }else if ((carData.car_type == "SQ")&&(val1!![0]!="FL")) { + // fix the wrong side of the tires + fltv.text = getString(R.string.fl_tpms) + frtv.text = getString(R.string.fr_tpms) + rltv.text = getString(R.string.rl_tpms) + rrtv.text = getString(R.string.rr_tpms) + fltvv.text = val1[tpms_fl] + frtvv.text = val1[tpms_fr] + rltvv.text = val1[tpms_rl] + rrtvv.text = val1[tpms_rr] + }else { + fltv.text = val1!![0] + frtv.text = val1[1] + rltv.text = val1[2] + rrtv.text = val1[3] + fltvv.text = val2!![0] + frtvv.text = val2[1] + rltvv.text = val2[2] + rrtvv.text = val2[3] + } + + val trans1 = if ((carData.car_type != "SQ")&&(stale1 == DataStale.Stale)) -0x80000000 else -0x1000000 + val trans2 = if ((carData.car_type != "SQ")&&(stale1 == DataStale.Stale)) -0x80000000 else -0x1000000 val alertcol = intArrayOf(0xFFFFFF, 0xFFAA44, 0xFF4444) - fltv.setTextColor(trans1 or alertcol[alert!![0]]) - frtv.setTextColor(trans1 or alertcol[alert[1]]) - rltv.setTextColor(trans1 or alertcol[alert[2]]) - rrtv.setTextColor(trans1 or alertcol[alert[3]]) - // Display alert state "OK" icons in green: + fltv.setTextColor(trans1 or alertcol[alert!![tpms_fl]]) + frtv.setTextColor(trans1 or alertcol[alert[tpms_fr]]) + rltv.setTextColor(trans1 or alertcol[alert[tpms_rl]]) + rrtv.setTextColor(trans1 or alertcol[alert[tpms_rr]]) if (val2.contentEquals(carData.car_tpms_alert)) { alertcol[0] = 0x44FF44 } - fltvv.setTextColor(trans2 or alertcol[alert[0]]) - frtvv.setTextColor(trans2 or alertcol[alert[1]]) - rltvv.setTextColor(trans2 or alertcol[alert[2]]) - rrtvv.setTextColor(trans2 or alertcol[alert[3]]) + frtvv.setTextColor(trans2 or alertcol[alert[tpms_fl]]) + fltvv.setTextColor(trans2 or alertcol[alert[tpms_fr]]) + rrtvv.setTextColor(trans2 or alertcol[alert[tpms_rl]]) + rltvv.setTextColor(trans2 or alertcol[alert[tpms_rr]]) } // "Temp PEM" box: @@ -798,7 +1430,6 @@ class CarFragment : BaseFragment(), View.OnClickListener, OnResultCommandListene || carData.car_type.startsWith("VA") || carData.car_type == "MI" || carData.car_type == "SE" - || carData.car_type == "SQ" || carData.car_type == "NL") { pemtvl.setText(R.string.textCAB) if (carData.stale_car_temps == DataStale.NoValue) { @@ -811,6 +1442,19 @@ class CarFragment : BaseFragment(), View.OnClickListener, OnResultCommandListene pemtv.setTextColor(-0x1) } } + } else if (carData.car_type == "SQ"){ + // switches the box from PEM to Battery energy + pemtvl.setText(R.string.textEnergy) + if (carData.stale_car_temps == DataStale.NoValue) { + pemtv.text = "" + } else { + pemtv.text = String.format("%.1fkWh",carData.car_battery_capacity) + if (carData.stale_car_temps == DataStale.Stale) { + pemtv.setTextColor(-0x7f7f80) + } else { + pemtv.setTextColor(-0x1) + } + } } else { pemtvl.setText(R.string.textPEM) if (carData.stale_car_temps == DataStale.NoValue) { @@ -836,7 +1480,7 @@ class CarFragment : BaseFragment(), View.OnClickListener, OnResultCommandListene || this.carData!!.car_type == "NL" || this.carData!!.car_type == "MGEV") { motortvl.setText(R.string.textHVBATT) - motortv.text = String.format("%.1fV", this.carData!!.car_battery_voltage) + motortv.text = String.format("%.0fV", this.carData!!.car_battery_voltage) if (carData.stale_car_temps == DataStale.Stale) { motortv.setTextColor(-0x7f7f80) } else { @@ -857,46 +1501,121 @@ class CarFragment : BaseFragment(), View.OnClickListener, OnResultCommandListene } } + // "Booster" box: + val tabCarImageBooster = findViewById(R.id.tabCarImageBooster) as ImageView + val tabCarImageCalendar = findViewById(R.id.tabCarImageCalendar) as ImageView + val tabInfoTextBoostertime = findViewById(R.id.tabInfoTextBoostertime) as TextView + val app_Car_ID = carData.sel_vehicleid + if(appPrefs.getData("booster_btd_" + carData.sel_vehicleid) == "1") tabCarImageBooster.setImageResource(R.drawable.heat_cool_2) else tabCarImageBooster.setImageResource(R.drawable.heat_cool) + tabCarImageBooster.visibility = if (appPrefs.getData("booster_on_$app_Car_ID") == "on") View.VISIBLE else View.INVISIBLE + tabInfoTextBoostertime.visibility = if (appPrefs.getData("booster_on_$app_Car_ID") == "on") View.VISIBLE else View.INVISIBLE + tabInfoTextBoostertime.text = appPrefs.getData("booster_time_$app_Car_ID") + tabCarImageCalendar.visibility = if (appPrefs.getData("booster_weekly_on_$app_Car_ID") == "on") View.VISIBLE else View.INVISIBLE + + + // "SoC" box: + val soctvl = findViewById(R.id.tabCarTextSoCLabel) as TextView + val soctv =findViewById(R.id.tabCarTextSoC) as TextView + if (carData.car_type == "SQ"){ + soctvl.visibility = View.VISIBLE + soctv.visibility = View.VISIBLE + + if (carData.stale_status == DataStale.NoValue) { + soctv.text = "" + } else { + soctv.text = String.format("%.0f%%", carData.car_soc_raw) + if (carData.stale_car_temps == DataStale.Stale) { + soctv.setTextColor(-0x7f7f80) + } else { + soctv.setTextColor(-0x1) + } + } + } + + // "SoH" box: + val sohtvl = findViewById(R.id.tabCarTextSoHLabel) as TextView + val sohtv =findViewById(R.id.tabCarTextSoH) as TextView + if (carData.car_type == "SQ"){ + sohtvl.visibility = View.VISIBLE + sohtv.visibility = View.VISIBLE + + if (carData.stale_status == DataStale.NoValue) { + sohtv.text = "" + } else { + sohtv.text = String.format("%.0f%%", carData.car_soh) + if (carData.stale_car_temps == DataStale.Stale) { + sohtv.setTextColor(-0x7f7f80) + } else { + sohtv.setTextColor(-0x1) + } + } + } + // Temperatures + val batterytvl = findViewById(R.id.tabCarTextChargerLabel) as TextView val batterytv = findViewById(R.id.tabCarTextBattery) as TextView val chargertv = findViewById(R.id.tabCarTextCharger) as TextView - if (carData.stale_car_temps == DataStale.NoValue) { - batterytv.text = "" - chargertv.text = "" + if (carData.car_type == "SQ") { + // switches the box from battery to cabin + batterytvl.setText(R.string.textCAB) + if (carData.stale_car_temps == DataStale.NoValue) { + + batterytv.text = "" + chargertv.text = "" + } else { + batterytv.text = String.format("%.0f°C", carData.car_temp_battery_raw) + chargertv.text = String.format("%.0f°C", carData.car_temp_cabin_raw) + if (carData.stale_car_temps == DataStale.Stale) { + batterytv.setTextColor(-0x7f7f80) + chargertv.setTextColor(-0x7f7f80) + } else { + batterytv.setTextColor(-0x1) + chargertv.setTextColor(-0x1) + } + } } else { - batterytv.text = carData.car_temp_battery - chargertv.text = carData.car_temp_charger - if (carData.stale_car_temps == DataStale.Stale) { - batterytv.setTextColor(-0x7f7f80) - chargertv.setTextColor(-0x7f7f80) + if (carData.stale_car_temps == DataStale.NoValue) { + batterytv.text = "" + chargertv.text = "" } else { - batterytv.setTextColor(-0x1) - chargertv.setTextColor(-0x1) + batterytv.text = carData.car_temp_battery + chargertv.text = carData.car_temp_charger + if (carData.stale_car_temps == DataStale.Stale) { + batterytv.setTextColor(-0x7f7f80) + chargertv.setTextColor(-0x7f7f80) + } else { + batterytv.setTextColor(-0x1) + chargertv.setTextColor(-0x1) + } } } var st: String var ss: SpannableString // Odometer - st = String.format("%.1f%s", carData.car_odometer_raw / 10, carData.car_distance_units) + st = String.format("⏲ %.1f %s", carData.car_odometer_raw / 10, carData.car_distance_units) ss = SpannableString(st) ss.setSpan(RelativeSizeSpan(0.67f), st.indexOf(carData.car_distance_units), st.length, 0) tv = findViewById(R.id.tabCarTextOdometer) as TextView tv.text = ss + // move the Odometer text to the right position + if (carData.car_type == "SQ") { + tv.translationY = "-165".toFloat() + } // Speed tv = findViewById(R.id.tabCarTextSpeed) as TextView if (!carData.car_started) { tv.text = "" } else { - st = String.format("%.1f%s", carData.car_speed_raw, carData.car_speed_units) + st = String.format("%.0f %s", carData.car_speed_raw, carData.car_speed_units) ss = SpannableString(st) ss.setSpan(RelativeSizeSpan(0.67f), st.indexOf(carData.car_speed_units), st.length, 0) tv.text = ss } // Trip - st = String.format("➟%.1f%s", carData.car_tripmeter_raw / 10, carData.car_distance_units) + st = String.format("➟ %.1f %s", carData.car_tripmeter_raw / 10, carData.car_distance_units) ss = SpannableString(st) ss.setSpan(RelativeSizeSpan(0.67f), st.indexOf(carData.car_distance_units), st.length, 0) tv = findViewById(R.id.tabCarTextTrip) as TextView @@ -904,7 +1623,7 @@ class CarFragment : BaseFragment(), View.OnClickListener, OnResultCommandListene // Energy st = String.format( - "▴%.1f ▾%.1f kWh", + "▴ %.1f ▾ %.1f kWh", floor((carData.car_energyused * 10).toDouble()) / 10, floor((carData.car_energyrecd * 10).toDouble()) / 10 ) @@ -913,9 +1632,16 @@ class CarFragment : BaseFragment(), View.OnClickListener, OnResultCommandListene tv = findViewById(R.id.tabCarTextEnergy) as TextView tv.text = ss + // Energy consume + st = String.format("▴▾ %.1f kW",carData.car_power) + ss = SpannableString(st) + ss.setSpan(RelativeSizeSpan(0.67f), st.indexOf("kW"), st.length, 0) + tv = findViewById(R.id.tabCarTextConsumeEnergy) as TextView + tv.text = ss + // Car Hood iv = findViewById(R.id.tabCarImageCarHoodOpen) as ImageView - iv.setVisibility(if (carData.car_bonnet_open) View.VISIBLE else View.INVISIBLE) + iv.visibility = if (carData.car_bonnet_open) View.VISIBLE else View.INVISIBLE if (carData.car_type.startsWith("VA")) { // Volt, Ampera iv.setImageResource(R.drawable.voltampera_outline_hd) @@ -925,222 +1651,222 @@ class CarFragment : BaseFragment(), View.OnClickListener, OnResultCommandListene if (carData.sel_vehicle_image.startsWith("car_zoe_")) { // Left Door Zoe iv = findViewById(R.id.tabCarImageCarLeftDoorOpen) as ImageView - iv.setVisibility(if (carData.car_frontleftdoor_open) View.VISIBLE else View.INVISIBLE) + iv.visibility = if (carData.car_frontleftdoor_open) View.VISIBLE else View.INVISIBLE iv.setImageResource(R.drawable.zoe_outline_ld) // Right Door Zoe iv = findViewById(R.id.tabCarImageCarRightDoorOpen) as ImageView - iv.setVisibility(if (carData.car_frontrightdoor_open) View.VISIBLE else View.INVISIBLE) + iv.visibility = if (carData.car_frontrightdoor_open) View.VISIBLE else View.INVISIBLE iv.setImageResource(R.drawable.zoe_outline_rd) // Rear Left Door Zoe iv = findViewById(R.id.tabCarImageCarRearLeftDoorOpen) as ImageView - iv.setVisibility(if (carData.car_rearleftdoor_open) View.VISIBLE else View.INVISIBLE) + iv.visibility = if (carData.car_rearleftdoor_open) View.VISIBLE else View.INVISIBLE iv.setImageResource(R.drawable.zoe_outline_rld) // Rear Right Door Zoe iv = findViewById(R.id.tabCarImageCarRearRightDoorOpen) as ImageView - iv.setVisibility(if (carData.car_rearrightdoor_open) View.VISIBLE else View.INVISIBLE) + iv.visibility = if (carData.car_rearrightdoor_open) View.VISIBLE else View.INVISIBLE iv.setImageResource(R.drawable.zoe_outline_rrd) // Trunk Zoe iv = findViewById(R.id.tabCarImageCarTrunkOpen) as ImageView - iv.setVisibility(if (carData.car_trunk_open) View.VISIBLE else View.INVISIBLE) + iv.visibility = if (carData.car_trunk_open) View.VISIBLE else View.INVISIBLE iv.setImageResource(R.drawable.zoe_outline_tr) // Headlights Zoe iv = findViewById(R.id.tabCarImageCarHeadlightsON) as ImageView - iv.setVisibility(if (carData.car_headlights_on) View.VISIBLE else View.INVISIBLE) + iv.visibility = if (carData.car_headlights_on) View.VISIBLE else View.INVISIBLE iv.setImageResource(R.drawable.zoe_carlights) } else if (carData.sel_vehicle_image.startsWith("car_mgzs_")) { // Left Door MGZS iv = findViewById(R.id.tabCarImageCarLeftDoorOpen) as ImageView - iv.setVisibility(if (carData.car_frontleftdoor_open) View.VISIBLE else View.INVISIBLE) + iv.visibility = if (carData.car_frontleftdoor_open) View.VISIBLE else View.INVISIBLE iv.setImageResource(R.drawable.mgzs_outline_ld) // Right Door MGZS iv = findViewById(R.id.tabCarImageCarRightDoorOpen) as ImageView - iv.setVisibility(if (carData.car_frontrightdoor_open) View.VISIBLE else View.INVISIBLE) + iv.visibility = if (carData.car_frontrightdoor_open) View.VISIBLE else View.INVISIBLE iv.setImageResource(R.drawable.mgzs_outline_rd) // Rear Left Door MGZS iv = findViewById(R.id.tabCarImageCarRearLeftDoorOpen) as ImageView - iv.setVisibility(if (carData.car_rearleftdoor_open) View.VISIBLE else View.INVISIBLE) + iv.visibility = if (carData.car_rearleftdoor_open) View.VISIBLE else View.INVISIBLE iv.setImageResource(R.drawable.mgzs_outline_rld) // Rear Right Door MGZS iv = findViewById(R.id.tabCarImageCarRearRightDoorOpen) as ImageView - iv.setVisibility(if (carData.car_rearrightdoor_open) View.VISIBLE else View.INVISIBLE) + iv.visibility = if (carData.car_rearrightdoor_open) View.VISIBLE else View.INVISIBLE iv.setImageResource(R.drawable.mgzs_outline_rrd) // Trunk MGZS iv = findViewById(R.id.tabCarImageCarTrunkOpen) as ImageView - iv.setVisibility(if (carData.car_trunk_open) View.VISIBLE else View.INVISIBLE) + iv.visibility = if (carData.car_trunk_open) View.VISIBLE else View.INVISIBLE iv.setImageResource(R.drawable.mgzs_outline_tr) // Headlights MGZS iv = findViewById(R.id.tabCarImageCarHeadlightsON) as ImageView - iv.setVisibility(if (carData.car_headlights_on) View.VISIBLE else View.INVISIBLE) + iv.visibility = if (carData.car_headlights_on) View.VISIBLE else View.INVISIBLE iv.setImageResource(R.drawable.mgzs_carlights) - } else if (carData.sel_vehicle_image.startsWith("car_smart_")) { + } else if ((carData.sel_vehicle_image.startsWith("car_smart_"))||(!carData.sel_vehicle_image.startsWith("car_smart_44_"))) { // Left Door Smart iv = findViewById(R.id.tabCarImageCarLeftDoorOpen) as ImageView - iv.setVisibility(if (carData.car_frontleftdoor_open) View.VISIBLE else View.INVISIBLE) + iv.visibility = if (carData.car_frontleftdoor_open) View.VISIBLE else View.INVISIBLE iv.setImageResource(R.drawable.smart_outline_ld) // Right Door Smart iv = findViewById(R.id.tabCarImageCarRightDoorOpen) as ImageView - iv.setVisibility(if (carData.car_frontrightdoor_open) View.VISIBLE else View.INVISIBLE) + iv.visibility = if (carData.car_frontrightdoor_open) View.VISIBLE else View.INVISIBLE iv.setImageResource(R.drawable.smart_outline_rd) // Trunk Smart iv = findViewById(R.id.tabCarImageCarTrunkOpen) as ImageView - iv.setVisibility(if (carData.car_trunk_open) View.VISIBLE else View.INVISIBLE) + iv.visibility = if (carData.car_trunk_open) View.VISIBLE else View.INVISIBLE iv.setImageResource(R.drawable.smart_outline_tr) // Headlights Smart iv = findViewById(R.id.tabCarImageCarHeadlightsON) as ImageView - iv.setVisibility(if (carData.car_headlights_on) View.VISIBLE else View.INVISIBLE) + iv.visibility = if (carData.car_headlights_on) View.VISIBLE else View.INVISIBLE iv.setImageResource(R.drawable.smart_carlights) } else if (carData.sel_vehicle_image.startsWith("car_leaf")) { // Left Door Leaf iv = findViewById(R.id.tabCarImageCarLeftDoorOpen) as ImageView - iv.setVisibility(if (carData.car_frontleftdoor_open) View.VISIBLE else View.INVISIBLE) + iv.visibility = if (carData.car_frontleftdoor_open) View.VISIBLE else View.INVISIBLE iv.setImageResource(R.drawable.leaf_outline_ld) // Right Door Leaf iv = findViewById(R.id.tabCarImageCarRightDoorOpen) as ImageView - iv.setVisibility(if (carData.car_frontrightdoor_open) View.VISIBLE else View.INVISIBLE) + iv.visibility = if (carData.car_frontrightdoor_open) View.VISIBLE else View.INVISIBLE iv.setImageResource(R.drawable.leaf_outline_rd) // Rear Left Door Leaf iv = findViewById(R.id.tabCarImageCarRearLeftDoorOpen) as ImageView - iv.setVisibility(if (carData.car_rearleftdoor_open) View.VISIBLE else View.INVISIBLE) + iv.visibility = if (carData.car_rearleftdoor_open) View.VISIBLE else View.INVISIBLE iv.setImageResource(R.drawable.leaf_outline_rld) // Rear Right Door Leaf iv = findViewById(R.id.tabCarImageCarRearRightDoorOpen) as ImageView - iv.setVisibility(if (carData.car_rearrightdoor_open) View.VISIBLE else View.INVISIBLE) + iv.visibility = if (carData.car_rearrightdoor_open) View.VISIBLE else View.INVISIBLE iv.setImageResource(R.drawable.leaf_outline_rrd) // Trunk Leaf iv = findViewById(R.id.tabCarImageCarTrunkOpen) as ImageView - iv.setVisibility(if (carData.car_trunk_open) View.VISIBLE else View.INVISIBLE) + iv.visibility = if (carData.car_trunk_open) View.VISIBLE else View.INVISIBLE iv.setImageResource(R.drawable.leaf_outline_tr) // Headlights Leaf iv = findViewById(R.id.tabCarImageCarHeadlightsON) as ImageView - iv.setVisibility(if (carData.car_headlights_on) View.VISIBLE else View.INVISIBLE) + iv.visibility = if (carData.car_headlights_on) View.VISIBLE else View.INVISIBLE if (carData.sel_vehicle_image.startsWith("car_leaf2")) { iv.setImageResource(R.drawable.leaf2_carlights) } else iv.setImageResource(R.drawable.leaf_carlights) - } else if (carData.sel_vehicle_image.startsWith("car_vwup_")) { + } else if ((carData.sel_vehicle_image.startsWith("car_vwup_"))||(carData.sel_vehicle_image.startsWith("car_smart_44_"))) { // Left Door VW e-Up iv = findViewById(R.id.tabCarImageCarLeftDoorOpen) as ImageView - iv.setVisibility(if (carData.car_frontleftdoor_open) View.VISIBLE else View.INVISIBLE) + iv.visibility = if (carData.car_frontleftdoor_open) View.VISIBLE else View.INVISIBLE iv.setImageResource(R.drawable.vwup_outline_ld) // Right Door VW e-Up iv = findViewById(R.id.tabCarImageCarRightDoorOpen) as ImageView - iv.setVisibility(if (carData.car_frontrightdoor_open) View.VISIBLE else View.INVISIBLE) + iv.visibility = if (carData.car_frontrightdoor_open) View.VISIBLE else View.INVISIBLE iv.setImageResource(R.drawable.vwup_outline_rd) // Rear Left Door VW e-Up iv = findViewById(R.id.tabCarImageCarRearLeftDoorOpen) as ImageView - iv.setVisibility(if (carData.car_rearleftdoor_open) View.VISIBLE else View.INVISIBLE) + iv.visibility = if (carData.car_rearleftdoor_open) View.VISIBLE else View.INVISIBLE iv.setImageResource(R.drawable.vwup_outline_rld) // Rear Right Door VW e-Up iv = findViewById(R.id.tabCarImageCarRearRightDoorOpen) as ImageView - iv.setVisibility(if (carData.car_rearrightdoor_open) View.VISIBLE else View.INVISIBLE) + iv.visibility = if (carData.car_rearrightdoor_open) View.VISIBLE else View.INVISIBLE iv.setImageResource(R.drawable.vwup_outline_rrd) // Trunk VW e-Up iv = findViewById(R.id.tabCarImageCarTrunkOpen) as ImageView - iv.setVisibility(if (carData.car_trunk_open) View.VISIBLE else View.INVISIBLE) + iv.visibility = if (carData.car_trunk_open) View.VISIBLE else View.INVISIBLE iv.setImageResource(R.drawable.vwup_outline_tr) // Headlights VW e-Up iv = findViewById(R.id.tabCarImageCarHeadlightsON) as ImageView - iv.setVisibility(if (carData.car_headlights_on) View.VISIBLE else View.INVISIBLE) + iv.visibility = if (carData.car_headlights_on) View.VISIBLE else View.INVISIBLE iv.setImageResource(R.drawable.vwup_carlights) } else if (carData.sel_vehicle_image.startsWith("car_ampera_") || carData.sel_vehicle_image.startsWith("car_holdenvolt_")) { // Left Door Volt, Ampera iv = findViewById(R.id.tabCarImageCarLeftDoorOpen) as ImageView - iv.setVisibility(if (carData.car_frontleftdoor_open) View.VISIBLE else View.INVISIBLE) + iv.visibility = if (carData.car_frontleftdoor_open) View.VISIBLE else View.INVISIBLE iv.setImageResource(R.drawable.voltampera_outline_ld) // Right Door Volt, Ampera iv = findViewById(R.id.tabCarImageCarRightDoorOpen) as ImageView - iv.setVisibility(if (carData.car_frontrightdoor_open) View.VISIBLE else View.INVISIBLE) + iv.visibility = if (carData.car_frontrightdoor_open) View.VISIBLE else View.INVISIBLE iv.setImageResource(R.drawable.voltampera_outline_rd) // Rear Left Door Volt, Ampera iv = findViewById(R.id.tabCarImageCarRearLeftDoorOpen) as ImageView - iv.setVisibility(if (carData.car_rearleftdoor_open) View.VISIBLE else View.INVISIBLE) + iv.visibility = if (carData.car_rearleftdoor_open) View.VISIBLE else View.INVISIBLE iv.setImageResource(R.drawable.voltampera_outline_rld) // Rear Right Door Volt, Ampera iv = findViewById(R.id.tabCarImageCarRearRightDoorOpen) as ImageView - iv.setVisibility(if (carData.car_rearrightdoor_open) View.VISIBLE else View.INVISIBLE) + iv.visibility = if (carData.car_rearrightdoor_open) View.VISIBLE else View.INVISIBLE iv.setImageResource(R.drawable.voltampera_outline_rrd) // Trunk Volt, Ampera iv = findViewById(R.id.tabCarImageCarTrunkOpen) as ImageView - iv.setVisibility(if (carData.car_trunk_open) View.VISIBLE else View.INVISIBLE) + iv.visibility = if (carData.car_trunk_open) View.VISIBLE else View.INVISIBLE iv.setImageResource(R.drawable.voltampera_outline_tr) // Headlights Volt, Ampera iv = findViewById(R.id.tabCarImageCarHeadlightsON) as ImageView - iv.setVisibility(if (carData.car_headlights_on) View.VISIBLE else View.INVISIBLE) + iv.visibility = if (carData.car_headlights_on) View.VISIBLE else View.INVISIBLE iv.setImageResource(R.drawable.voltampera_carlights) } else if (carData.sel_vehicle_image.startsWith("car_kangoo_")) { // Left Door Kangoo iv = findViewById(R.id.tabCarImageCarLeftDoorOpen) as ImageView - iv.setVisibility(if (carData.car_frontleftdoor_open) View.VISIBLE else View.INVISIBLE) + iv.visibility = if (carData.car_frontleftdoor_open) View.VISIBLE else View.INVISIBLE iv.setImageResource(R.drawable.kangoo_outline_ld) // Right Door Kangoo iv = findViewById(R.id.tabCarImageCarRightDoorOpen) as ImageView - iv.setVisibility(if (carData.car_frontrightdoor_open) View.VISIBLE else View.INVISIBLE) + iv.visibility = if (carData.car_frontrightdoor_open) View.VISIBLE else View.INVISIBLE iv.setImageResource(R.drawable.kangoo_outline_rd) // Rear Left Door Kangoo iv = findViewById(R.id.tabCarImageCarRearLeftDoorOpen) as ImageView - iv.setVisibility(if (carData.car_rearleftdoor_open) View.VISIBLE else View.INVISIBLE) + iv.visibility = if (carData.car_rearleftdoor_open) View.VISIBLE else View.INVISIBLE iv.setImageResource(R.drawable.kangoo_outline_rld) // Rear Right Door Kangoo iv = findViewById(R.id.tabCarImageCarRearRightDoorOpen) as ImageView - iv.setVisibility(if (carData.car_rearrightdoor_open) View.VISIBLE else View.INVISIBLE) + iv.visibility = if (carData.car_rearrightdoor_open) View.VISIBLE else View.INVISIBLE iv.setImageResource(R.drawable.kangoo_outline_rrd) // Trunk Kangoo iv = findViewById(R.id.tabCarImageCarTrunkOpen) as ImageView - iv.setVisibility(if (carData.car_trunk_open) View.VISIBLE else View.INVISIBLE) + iv.visibility = if (carData.car_trunk_open) View.VISIBLE else View.INVISIBLE iv.setImageResource(R.drawable.kangoo_outline_tr) // Headlights Kangoo iv = findViewById(R.id.tabCarImageCarHeadlightsON) as ImageView - iv.setVisibility(if (carData.car_headlights_on) View.VISIBLE else View.INVISIBLE) + iv.visibility = if (carData.car_headlights_on) View.VISIBLE else View.INVISIBLE iv.setImageResource(R.drawable.kangoo_carlights) } else { // Left Door iv = findViewById(R.id.tabCarImageCarLeftDoorOpen) as ImageView - iv.setVisibility(if (carData.car_frontleftdoor_open) View.VISIBLE else View.INVISIBLE) + iv.visibility = if (carData.car_frontleftdoor_open) View.VISIBLE else View.INVISIBLE // Right Door iv = findViewById(R.id.tabCarImageCarRightDoorOpen) as ImageView - iv.setVisibility(if (carData.car_frontrightdoor_open) View.VISIBLE else View.INVISIBLE) + iv.visibility = if (carData.car_frontrightdoor_open) View.VISIBLE else View.INVISIBLE // Trunk iv = findViewById(R.id.tabCarImageCarTrunkOpen) as ImageView - iv.setVisibility(if (carData.car_trunk_open) View.VISIBLE else View.INVISIBLE) + iv.visibility = if (carData.car_trunk_open) View.VISIBLE else View.INVISIBLE // Headlights iv = findViewById(R.id.tabCarImageCarHeadlightsON) as ImageView - iv.setVisibility(if (carData.car_headlights_on) View.VISIBLE else View.INVISIBLE) + iv.visibility = if (carData.car_headlights_on) View.VISIBLE else View.INVISIBLE } // Car locked @@ -1189,9 +1915,9 @@ class CarFragment : BaseFragment(), View.OnClickListener, OnResultCommandListene // Charge Port iv = findViewById(R.id.tabCarImageCarChargePortOpen) as ImageView if (!carData.car_chargeport_open) { - iv.setVisibility(View.INVISIBLE) + iv.visibility = View.INVISIBLE } else { - iv.setVisibility(View.VISIBLE) + iv.visibility = View.VISIBLE if (carData.sel_vehicle_image.startsWith("car_twizy_")) { // Renault Twizy: iv.setImageResource(R.drawable.ol_car_twizy_chargeport) @@ -1270,7 +1996,7 @@ class CarFragment : BaseFragment(), View.OnClickListener, OnResultCommandListene } else if (carData.car_charge_state_i_raw == 0x04) { // Charging done iv.setImageResource(R.drawable.roadster_outline_cd) - } else if (carData.car_charge_state_i_raw >= 0x15 && carData.car_charge_state_i_raw <= 0x19) { + } else if (carData.car_charge_state_i_raw in 0x15..0x19) { // Stopped iv.setImageResource(R.drawable.roadster_outline_cs) } else { @@ -1298,7 +2024,17 @@ class CarFragment : BaseFragment(), View.OnClickListener, OnResultCommandListene private const val MI_HL_02 = Menu.FIRST + 2 private const val MI_HL_03 = Menu.FIRST + 3 private const val MI_HL_DEFAULT = Menu.FIRST + 4 - private const val MI_AC_ON = Menu.FIRST + 5 - private const val MI_AC_OFF = Menu.FIRST + 6 + private const val MI_HL_BTR = Menu.FIRST + 5 + private const val MI_HL_FW = Menu.FIRST + 6 + private const val MI_HL_PLUGIN_EQ = Menu.FIRST + 7 + private const val MI_HL_PLUGIN_OVMS = Menu.FIRST + 8 + private const val MI_AC_ON = Menu.FIRST + 9 + private const val MI_AC_OFF = Menu.FIRST + 10 + private const val MI_AC_BON = Menu.FIRST + 11 + private const val MI_AC_BT = Menu.FIRST + 12 + private const val MI_AC_BW = Menu.FIRST + 13 + private const val MI_AC_BDS = Menu.FIRST + 14 + private const val MI_AC_BTD = Menu.FIRST + 15 + private const val MI_WAKEUP_2 = Menu.FIRST + 16 } } diff --git a/app/src/main/java/com/openvehicles/OVMS/ui/InfoFragment.kt b/app/src/main/java/com/openvehicles/OVMS/ui/InfoFragment.kt index e209220f..bb634c22 100644 --- a/app/src/main/java/com/openvehicles/OVMS/ui/InfoFragment.kt +++ b/app/src/main/java/com/openvehicles/OVMS/ui/InfoFragment.kt @@ -1,5 +1,8 @@ +@file:Suppress("DEPRECATION") + package com.openvehicles.OVMS.ui +import android.animation.ObjectAnimator import android.content.Context import android.content.res.Configuration import android.graphics.Bitmap @@ -40,7 +43,9 @@ import com.openvehicles.OVMS.ui.witdet.ReversedSeekBar import com.openvehicles.OVMS.ui.witdet.ScaleLayout import com.openvehicles.OVMS.ui.witdet.SlideNumericView import com.openvehicles.OVMS.ui.witdet.SwitcherView +import com.openvehicles.OVMS.utils.AppPrefs import com.openvehicles.OVMS.utils.CarsStorage +import com.openvehicles.OVMS.utils.CarsStorage.getSelectedCarData import java.util.Locale import kotlin.math.max import kotlin.math.min @@ -53,6 +58,7 @@ class InfoFragment : BaseFragment(), View.OnClickListener, OnResultCommandListen private var carSelectPos = 0 private lateinit var handler: Handler private var carChanger: Runnable? = null + lateinit var appPrefs: AppPrefs override fun onCreateView( inflater: LayoutInflater, @@ -62,6 +68,9 @@ class InfoFragment : BaseFragment(), View.OnClickListener, OnResultCommandListen // init car data: carsStorage = CarsStorage carData = carsStorage.getSelectedCarData() + // init car data: + carData = getSelectedCarData() + appPrefs = AppPrefs(requireActivity(), "ovms") // inflate layout: val rootView = inflater.inflate(R.layout.fragment_info, null) @@ -111,6 +120,66 @@ class InfoFragment : BaseFragment(), View.OnClickListener, OnResultCommandListen // nop } } + val app_Car_ID = carData!!.sel_vehicleid + val booster_on_btn = rootView.findViewById(R.id.tabCarImageBooster) + booster_on_btn.setOnClickListener { + AlertDialog.Builder(requireActivity()) + .setTitle(R.string.lb_booster_off) + .setNegativeButton(R.string.Cancel, null) + .setPositiveButton(android.R.string.ok) { _, + _ -> + appPrefs.saveData("booster_on_$app_Car_ID", "off") + appPrefs.saveData("booster_weekly_on_$app_Car_ID", "off") + val tabCarImageBooster = findViewById(R.id.tabCarImageBooster) as ImageView + if(appPrefs.getData("booster_btd_$app_Car_ID") == "1") tabCarImageBooster.setImageResource(R.drawable.heat_cool_2) else tabCarImageBooster.setImageResource(R.drawable.heat_cool) + val tabInfoTextBoostertime = + findViewById(R.id.tabInfoTextBoostertime) as TextView + val tabCarImageCalendar = findViewById(R.id.tabCarImageCalendar) as ImageView + tabCarImageBooster.visibility = View.INVISIBLE + tabInfoTextBoostertime.visibility = View.INVISIBLE + tabCarImageCalendar.visibility = View.INVISIBLE + sendCommand( + R.string.msg_issuing_climatecontrol, + "7,config set usr b.data 1,2,2,0,-1,-1,0", + this@InfoFragment + ) + } + .show() + } + + val booster_weekly_btn = rootView.findViewById(R.id.tabCarImageCalendar) + booster_weekly_btn.setOnClickListener { + AlertDialog.Builder(requireActivity()) + .setTitle(R.string.lb_booster_weekly_off) + .setNegativeButton(R.string.Cancel, null) + .setPositiveButton(android.R.string.ok) { _, + _ -> + appPrefs.saveData("booster_on_$app_Car_ID", "off") + appPrefs.saveData("booster_weekly_on_$app_Car_ID", "off") + val tabCarImageBooster = findViewById(R.id.tabCarImageBooster) as ImageView + if(appPrefs.getData("booster_btd_$app_Car_ID") == "1") tabCarImageBooster.setImageResource(R.drawable.heat_cool_2) else tabCarImageBooster.setImageResource(R.drawable.heat_cool) + val tabCarImageCalendar = findViewById(R.id.tabCarImageCalendar) as ImageView + val tabInfoTextBoostertime = findViewById(R.id.tabInfoTextBoostertime) as TextView + tabCarImageBooster.visibility = View.INVISIBLE + tabInfoTextBoostertime.visibility = View.INVISIBLE + tabCarImageCalendar.visibility = View.INVISIBLE + sendCommand( + R.string.msg_issuing_climatecontrol, + "7,config set usr b.data 1,2,2,0,-1,-1,0", + this@InfoFragment + ) + } + .show() + } + + val booster_ac_btn = rootView.findViewById(R.id.tabCarImageAC) + booster_ac_btn.setOnClickListener { + AlertDialog.Builder(requireActivity()) + .setTitle(R.string.lb_booster) + .setNegativeButton(R.string.Cancel, null) + .setPositiveButton(R.string.lb_booster_activate) { _, _ -> sendCommand(R.string.lb_booster, "26,1", this@InfoFragment ) } + .show() + } // init ScaleLayout: val scaleLayout = rootView.findViewById(R.id.scaleLayout) as ScaleLayout @@ -121,7 +190,7 @@ class InfoFragment : BaseFragment(), View.OnClickListener, OnResultCommandListen scaleLayout.context.resources, R.drawable.charger_button ) - var tw = (srcBmp.getWidth() * (lp.height / srcBmp.getHeight())) + var tw = (srcBmp.width * (lp.height / srcBmp.height)) var th = lp.height if (tw < 40) { tw = 61 @@ -138,7 +207,7 @@ class InfoFragment : BaseFragment(), View.OnClickListener, OnResultCommandListen scaleLayout .context.resources, dstBmp ) - sb.setThumb(drw) + sb.thumb = drw // sb.setThumbOffset(dstBmp.getWidth() / 9); } setHasOptionsMenu(true) @@ -164,7 +233,7 @@ class InfoFragment : BaseFragment(), View.OnClickListener, OnResultCommandListen override fun onResume() { super.onResume() - carSelect.setAdapter(CarSelectAdapter()) + carSelect.adapter = CarSelectAdapter() carSelectPos = carsStorage.getSelectedCarIndex() carSelect.setSelection(carSelectPos) Log.d(TAG, "onResume: pos=" + carSelectPos + ", id=" + carData!!.sel_vehicleid) @@ -195,6 +264,7 @@ class InfoFragment : BaseFragment(), View.OnClickListener, OnResultCommandListen findViewById(R.id.tabInfoTextSOC).setOnClickListener(this) findViewById(R.id.tabInfoTextChargeMode).setOnClickListener(this) findViewById(R.id.tabInfoImageBatteryChargingOverlay).setOnClickListener(this) + findViewById(R.id.tabInfoImageBatteryAnimation).setOnClickListener(this) findViewById(R.id.tabInfoImageBatteryOverlay).setOnClickListener(this) val bar = findViewById(R.id.tabInfoSliderChargerControl) as ReversedSeekBar @@ -228,6 +298,11 @@ class InfoFragment : BaseFragment(), View.OnClickListener, OnResultCommandListen } + override fun registerForContextMenu(view: View) { + super.registerForContextMenu(view) + view.setOnClickListener(this) + } + private fun chargerConfirmStart() { val bar = findViewById(R.id.tabInfoSliderChargerControl) as ReversedSeekBar // create & open dialog: @@ -380,7 +455,7 @@ class InfoFragment : BaseFragment(), View.OnClickListener, OnResultCommandListen chargerSettingVWUP() } "SQ" -> { - // nothing to do + // nothing todo! } else -> { chargerSettingDefault() @@ -584,7 +659,7 @@ class InfoFragment : BaseFragment(), View.OnClickListener, OnResultCommandListen val etrSuffSOC = carData!!.car_chargelimit_minsremaining_soc val suffRange = carData!!.car_chargelimit_rangelimit_raw val etrSuffRange = carData!!.car_chargelimit_minsremaining_range - if (etrSuffRange > 0) { + if ((etrSuffRange > 0) && (carData!!.car_type != "SQ")) { val infoEtrRange = getString( R.string.info_etr_suffrange, suffRange, @@ -596,7 +671,7 @@ class InfoFragment : BaseFragment(), View.OnClickListener, OnResultCommandListen } infoEtr += infoEtrRange } - if (etrSuffSOC > 0) { + if ((etrSuffSOC > 0) && (carData!!.car_type != "SQ")) { val infoEtrSOC = getString( R.string.info_etr_suffsoc, suffSOC, String.format("%02d:%02d", etrSuffSOC / 60, etrSuffSOC % 60) @@ -627,8 +702,9 @@ class InfoFragment : BaseFragment(), View.OnClickListener, OnResultCommandListen } infoEtr += infoEtrFull } + textView = findViewById(R.id.tabInfoTextChargeEtrFull) as TextView? - if (textView != null) { + if ((textView != null) && (carData!!.car_type != "SQ")){ textView.text = infoEtr if (infoEtr != "") { etrVisible = true @@ -637,10 +713,21 @@ class InfoFragment : BaseFragment(), View.OnClickListener, OnResultCommandListen textView.visibility = View.INVISIBLE } } + // Smart EQ (SQ) + val textViewEQ = findViewById(R.id.tabInfoTextChargeEtrFullEQ) as TextView? + if ((textViewEQ != null) && (carData!!.car_type == "SQ")) { + textViewEQ.text = infoEtr + if (infoEtr != "") { + etrVisible = false + textViewEQ.visibility = View.VISIBLE + } else { + textViewEQ.visibility = View.INVISIBLE + } + } // display background if any ETR visible: val bgImg = findViewById(R.id.tabInfoImageChargeEtr) as ImageView? - bgImg?.setVisibility(if (etrVisible) View.VISIBLE else View.INVISIBLE) + bgImg?.visibility = if (etrVisible) View.VISIBLE else View.INVISIBLE } // This updates the part of the view with times shown. @@ -700,7 +787,7 @@ class InfoFragment : BaseFragment(), View.OnClickListener, OnResultCommandListen hours = minutes / 60 days = minutes / (60 * 24) if (minutes == 0L) tv.text = getText(R.string.justnow) else if (minutes == 1L) tv.text = - "1 min" else if (days > 1) tv.text = String.format( + getText(R.string.min1) else if (days > 1) tv.text = String.format( getText(R.string.ndays).toString(), days ) else if (hours > 1) tv.text = String.format( @@ -730,16 +817,26 @@ class InfoFragment : BaseFragment(), View.OnClickListener, OnResultCommandListen // This updates the main informational part of the view. // It is called when the server gets new data. private fun updateCarInfoView(carData: CarData) { - var tv = findViewById(R.id.txt_title) as TextView - tv.text = carData.sel_vehicle_label + val headline = findViewById(R.id.txt_title) as TextView + val odometer = String.format("⏲ %.1f %s", carData.car_odometer_raw / 10, carData.car_distance_units) + val power = String.format("%.1f kWh/100 km", carData.car_charge_kwh_grid_total) + if(carData.car_type == "SQ") { + headline.text = carData.sel_vehicle_label + "\n" + power + "\n" + odometer + }else{ + headline.text = carData.sel_vehicle_label + "\n" + odometer + } + val carPos = carsStorage.getStoredCars().indexOf(carData) if (carPos != carSelectPos) { Log.d(TAG, "updateCarInfoView: id=" + carData.sel_vehicleid + " pos=" + carPos) carSelectPos = carPos carSelect.setSelection(carSelectPos) } - tv = findViewById(R.id.tabInfoTextSOC) as TextView - tv.text = carData.car_soc + val tv = findViewById(R.id.tabInfoTextSOC) as TextView + val tv_or = findViewById(R.id.tabInfoTextSOC_or) as TextView + val soc_str = carData.car_soc_raw + tv.text = String.format("%.0f%%", soc_str) + tv_or.text = String.format("%.0f%%", soc_str) val cmtv = findViewById(R.id.tabInfoTextChargeMode) as TextView val coiv = findViewById(R.id.tabInfoImageBatteryChargingOverlay) as ImageView val bar = findViewById(R.id.tabInfoSliderChargerControl) as ReversedSeekBar @@ -748,12 +845,15 @@ class InfoFragment : BaseFragment(), View.OnClickListener, OnResultCommandListen val tvf = findViewById(R.id.tabInfoTextChargeStatus) as TextView val tvPowerInput = findViewById(R.id.tabInfoTextChargePowerInput) as TextView val tvPowerLoss = findViewById(R.id.tabInfoTextChargePowerLoss) as TextView + if (!carData.car_chargeport_open || carData.car_charge_substate_i_raw == 0x07) { // Charge port is closed or car is not plugged in findViewById(R.id.tabInfoImageCharger).visibility = View.INVISIBLE bar.visibility = View.INVISIBLE cmtv.visibility = View.INVISIBLE - coiv.setVisibility(View.INVISIBLE) + coiv.visibility = View.INVISIBLE + tv.visibility = View.VISIBLE + tv_or.visibility = View.INVISIBLE tvl.visibility = View.INVISIBLE tvr.visibility = View.INVISIBLE tvf.visibility = View.INVISIBLE @@ -761,19 +861,24 @@ class InfoFragment : BaseFragment(), View.OnClickListener, OnResultCommandListen tvPowerLoss.visibility = View.INVISIBLE } else { // Car is plugged in - val cmst = if (carData.car_battery_rangespeed != "") { + tv.visibility = View.INVISIBLE + tv_or.visibility = View.VISIBLE + val cmst = if(carData.car_type == "SQ") { + val chargeduration = carData.car_charge_duration_raw / 60 String.format( - "%s ≤%s ⏲%s ▾%.1fkWh", - carData.car_charge_mode.uppercase(Locale.getDefault()), - carData.car_charge_currentlimit, - carData.car_battery_rangespeed, - carData.car_charge_kwhconsumed + "⏱ %02d:%02d ▾ %.1fkWh ⚡ %.1fkW", + chargeduration / 60, chargeduration % 60, + carData.car_charge_kwhconsumed, + carData.car_charge_power_input_kw_raw ) } else { - if(carData!!.car_type == "SQ") { + if (carData.car_battery_rangespeed != "") { String.format( - "SoH %.1f", - carData.car_soh + "%s ≤%s ⏲%s ▾%.1fkWh", + carData.car_charge_mode.uppercase(Locale.getDefault()), + carData.car_charge_currentlimit, + carData.car_battery_rangespeed, + carData.car_charge_kwhconsumed ) }else{ String.format( @@ -801,7 +906,7 @@ class InfoFragment : BaseFragment(), View.OnClickListener, OnResultCommandListen 4 -> chargeStateInfo = R.string.state_done 21 -> chargeStateInfo = R.string.state_stopped } - if (chargeStateInfo != 0) { + if ((this.carData!!.car_type != "SQ")&&(chargeStateInfo != 0)) { tvf.text = String.format( getText(chargeStateInfo).toString(), carData.car_charge_linevoltage, @@ -809,7 +914,24 @@ class InfoFragment : BaseFragment(), View.OnClickListener, OnResultCommandListen ) tvf.visibility = View.VISIBLE } - coiv.setVisibility(View.VISIBLE) + if ((this.carData!!.car_type == "SQ")) { + val timestamp_arr = (carData.car_charge_timestamp).split(" ") + tvPowerInput.text = String.format("%s %s",timestamp_arr[2],"h") + tvPowerInput.visibility = View.VISIBLE + tvPowerLoss.text = String.format("⚡ %s %%",carData.car_charger_efficiency) + tvPowerLoss.visibility = View.VISIBLE + if (chargeStateInfo != 0) { + val linevoltage = String.format("%.0f%s ", carData.car_charge_linevoltage_raw, "V") + val current = String.format(" %s%s",carData.car_battery_current_raw, "A") // car_charge_current + tvf.text = String.format( + getText(chargeStateInfo).toString(), + linevoltage, + current + ) + tvf.visibility = View.VISIBLE + } + } + coiv.visibility = View.VISIBLE } else { // Standard car: findViewById(R.id.tabInfoImageCharger).visibility = View.VISIBLE @@ -822,7 +944,7 @@ class InfoFragment : BaseFragment(), View.OnClickListener, OnResultCommandListen bar.progress = 100 tvl.text = null tvr.text = getText(R.string.slidetocharge) - coiv.setVisibility(View.INVISIBLE) + coiv.visibility = View.INVISIBLE tvPowerInput.visibility = View.INVISIBLE tvPowerLoss.visibility = View.INVISIBLE } @@ -832,7 +954,7 @@ class InfoFragment : BaseFragment(), View.OnClickListener, OnResultCommandListen bar.progress = 100 tvl.text = null tvr.text = getText(R.string.timedcharge) - coiv.setVisibility(View.INVISIBLE) + coiv.visibility = View.INVISIBLE tvPowerInput.visibility = View.INVISIBLE tvPowerLoss.visibility = View.INVISIBLE } @@ -846,7 +968,7 @@ class InfoFragment : BaseFragment(), View.OnClickListener, OnResultCommandListen carData.car_charge_current ) tvr.text = "" - coiv.setVisibility(View.VISIBLE) + coiv.visibility = View.VISIBLE if (carData.car_charge_power_input_kw_raw > 0) { tvPowerInput.text = carData.car_charge_power_input_kw tvPowerInput.visibility = View.VISIBLE @@ -866,23 +988,127 @@ class InfoFragment : BaseFragment(), View.OnClickListener, OnResultCommandListen bar.progress = 100 tvl.text = null tvr.text = null - coiv.setVisibility(View.INVISIBLE) + coiv.visibility = View.INVISIBLE tvPowerInput.visibility = View.INVISIBLE tvPowerLoss.visibility = View.INVISIBLE } } } } - tv = findViewById(R.id.tabInfoTextIdealRange) as TextView - tv.text = carData.car_range_ideal - tv = findViewById(R.id.tabInfoTextEstimatedRange) as TextView - tv.text = carData.car_range_estimated + + // ideal/est range + val ideallabel = findViewById(R.id.tabInfoTextIdealLabel) as TextView + val idealtv = findViewById(R.id.tabInfoTextIdealRange) as TextView + if (carData.car_type == "SQ") { + // calculate minimal range for SQ + ideallabel.text = getString(R.string.Idealminimal) + idealtv.text = String.format("%.0f %s", (carData.car_range_estimated_raw) * 0.835, carData.car_distance_units) + // ideallabel.textSize = 14F + }else{ + idealtv.text = carData.car_range_ideal + } + val esttv = findViewById(R.id.tabInfoTextEstimatedRange) as TextView + esttv.text = String.format("%.0f %s", carData.car_range_estimated_raw, carData.car_distance_units) + + // Smart EQ: cabin/ambient temperature A/C + val ambientiv = findViewById(R.id.tabInfoImageTemperatureText) as ImageView + val ambienttvl = findViewById(R.id.tabInfoTextAmbientLabel) as TextView + val ambienttv = findViewById(R.id.tabInfoTextAmbient) as TextView + val cabintvl = findViewById(R.id.tabInfoTextCabinLabel) as TextView + val cabintv = findViewById(R.id.tabInfoTextCabin) as TextView + + val tabCarImageCarACBoxes = findViewById(R.id.tabCarImageCarACBoxes) as ImageView + val tabCarImageAC = findViewById(R.id.tabCarImageAC) as ImageView + val tabInfoImageBattery = findViewById(R.id.tabInfoImageBattery) as ImageView + val tabInfoTextSOC = findViewById(R.id.tabInfoTextSOC) as TextView + val tabInfoTextChargeMode = findViewById(R.id.tabInfoTextChargeMode) as TextView + val tabInfoImageBatteryChargingOverlay = findViewById(R.id.tabInfoImageBatteryChargingOverlay) as ImageView + val tabInfoImageBatteryAnimation = findViewById(R.id.tabInfoImageBatteryAnimation) as ImageView + val tabInfoImageBatteryOverlay = findViewById(R.id.tabInfoImageBatteryOverlay) + val tabInfoImageChargeEtr = findViewById(R.id.tabInfoImageChargeEtr) as ImageView + val tabInfoTextChargeEtrSuff = findViewById(R.id.tabInfoTextChargeEtrSuff) as TextView + val tabInfoTextChargeEtrFull = findViewById(R.id.tabInfoTextChargeEtrFull) as TextView + val tabCarImageBooster = findViewById(R.id.tabCarImageBooster) as ImageView + if(appPrefs.getData("booster_btd_" + carData.sel_vehicleid) == "1") tabCarImageBooster.setImageResource(R.drawable.heat_cool_2) else tabCarImageBooster.setImageResource(R.drawable.heat_cool) + val tabCarImageCalendar = findViewById(R.id.tabCarImageCalendar) as ImageView + val tabInfoTextBoostertime = findViewById(R.id.tabInfoTextBoostertime) as TextView + + if (carData.car_type == "SQ") { + tabInfoImageBattery.isClickable = false + tabInfoTextSOC.isClickable = false + tabInfoTextChargeMode.isClickable = false + tabInfoImageBatteryChargingOverlay.isClickable = false + tabInfoImageBatteryAnimation.isClickable = false + tabInfoImageBatteryOverlay.isClickable = false + tabCarImageAC.isClickable = true + ambientiv.visibility = View.VISIBLE + ambienttvl.text = getString(R.string.textAMBIENT) + ambienttv.text = String.format("%.0f°C", carData.car_temp_ambient_raw) + cabintvl.text = getString(R.string.textCAB) + cabintv.text = String.format("%.0f°C", carData.car_temp_cabin_raw) + ambientiv.visibility = View.VISIBLE + ambienttvl.visibility = View.VISIBLE + ambienttv.visibility = View.VISIBLE + cabintvl.visibility = View.VISIBLE + cabintv.visibility = View.VISIBLE + tabCarImageCarACBoxes.visibility = View.VISIBLE + tabCarImageAC.visibility = View.VISIBLE + tabCarImageBooster.visibility = if (appPrefs.getData("booster_on_" + carData.sel_vehicleid) == "on") View.VISIBLE else View.INVISIBLE + tabInfoTextBoostertime.visibility = if (appPrefs.getData("booster_on_" + carData.sel_vehicleid) == "on") View.VISIBLE else View.INVISIBLE + tabInfoTextBoostertime.text = appPrefs.getData("booster_time_" + carData.sel_vehicleid) + tabCarImageCalendar.visibility = if (appPrefs.getData("booster_weekly_on_" + carData.sel_vehicleid) == "on") View.VISIBLE else View.INVISIBLE + + // AC on/off + if (carData.car_hvac_on) { + tabCarImageAC.setImageResource(R.drawable.ic_ac_on) + } else { + tabCarImageAC.setImageResource(R.drawable.ic_ac_off) + } + // move ETR image/text down + tabInfoImageChargeEtr.translationY = "250".toFloat() + tabInfoTextChargeEtrSuff.translationY = "170".toFloat() + tabInfoTextChargeEtrFull.translationY = "170".toFloat() + } + + // resize Battery image val maxWeight = (findViewById(R.id.tabInfoTextSOC) as TextView).layoutParams.width val realWeight = Math .round(maxWeight * carData.car_soc_raw / 100 * 1.1f) - val v = findViewById(R.id.tabInfoImageBatteryOverlay) - v.layoutParams.width = min(maxWeight.toDouble(), realWeight.toDouble()).toInt() - v.requestLayout() + val batt = findViewById(R.id.tabInfoImageBatteryOverlay) + batt.layoutParams.width = min(maxWeight.toDouble(), realWeight.toDouble()).toInt() + batt.requestLayout() + + // animated charging: Battery image + val battc = findViewById(R.id.tabInfoImageBatteryOverlayC) + battc.layoutParams.width = min(maxWeight.toDouble(), realWeight.toDouble()).toInt() + battc.requestLayout() + val animator = ObjectAnimator.ofFloat(battc, "alpha", 0.7F, 0F) + animator.repeatCount = ObjectAnimator.INFINITE + animator.duration = 1500 + animator.repeatMode = ObjectAnimator.REVERSE + animator.start() + + // animated charging: charge Battery image + val chargeing = findViewById(R.id.tabInfoImageBatteryAnimation) + chargeing.layoutParams.width = min(maxWeight.toDouble(), realWeight.toDouble()).toInt() + chargeing.requestLayout() + val animatorcharge = ObjectAnimator.ofFloat(chargeing, "alpha", 0.4F, 1F) + animatorcharge.repeatCount = ObjectAnimator.INFINITE + animatorcharge.duration = 1500 + animatorcharge.repeatMode = ObjectAnimator.REVERSE + animatorcharge.start() + + // switch animation on/off depending on charge power input + if ((carData.car_chargeport_open) && (carData.car_charge_power_input_kw_raw > 1.3)) { + batt.visibility = View.INVISIBLE + battc.visibility = View.VISIBLE + chargeing.visibility = View.VISIBLE + }else{ + batt.visibility = View.VISIBLE + battc.visibility = View.INVISIBLE + chargeing.visibility = View.INVISIBLE + } + val iv = findViewById(R.id.img_signal_rssi) as ImageView iv.setImageResource( getDrawableIdentifier( @@ -922,13 +1148,11 @@ class InfoFragment : BaseFragment(), View.OnClickListener, OnResultCommandListen } else { ImageView(parent.context) } - iv.setLayoutParams( - Gallery.LayoutParams( - ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT - ) + iv.layoutParams = Gallery.LayoutParams( + ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT ) - iv.setScaleType(ImageView.ScaleType.FIT_START) - iv.setAdjustViewBounds(true) + iv.scaleType = ImageView.ScaleType.FIT_START + iv.adjustViewBounds = true iv.setImageResource( getDrawableIdentifier( parent.context, diff --git a/app/src/main/java/com/openvehicles/OVMS/ui/MainActivity.kt b/app/src/main/java/com/openvehicles/OVMS/ui/MainActivity.kt index 278390fe..e757303a 100644 --- a/app/src/main/java/com/openvehicles/OVMS/ui/MainActivity.kt +++ b/app/src/main/java/com/openvehicles/OVMS/ui/MainActivity.kt @@ -195,6 +195,15 @@ class MainActivity : ApiActivity(), ActionBar.OnNavigationListener, GetMapDetail ConnectionList(this, this, true) } + // get/create Booster setting: + val boosterOn = appPrefs.getData("booster_on") + if (boosterOn.isEmpty()) { + appPrefs.saveData("booster_on", "no") + appPrefs.saveData("booster_weekly_on", "no") + appPrefs.saveData("booster_time", "0515") + Log.d(TAG, "onCreate: generated booster_on/weekly_on") + } + // Start background ApiService: Log.i(TAG, "onCreate: starting ApiService") try { diff --git a/app/src/main/java/com/openvehicles/OVMS/ui/MapFragment.kt b/app/src/main/java/com/openvehicles/OVMS/ui/MapFragment.kt index bcf6565f..17244cda 100644 --- a/app/src/main/java/com/openvehicles/OVMS/ui/MapFragment.kt +++ b/app/src/main/java/com/openvehicles/OVMS/ui/MapFragment.kt @@ -43,7 +43,6 @@ import com.openvehicles.OVMS.ui.utils.DemoClusterOptionsProvider import com.openvehicles.OVMS.ui.utils.MarkerGenerator.addMarkers import com.openvehicles.OVMS.ui.utils.Ui.getDrawableIdentifier import com.openvehicles.OVMS.utils.AppPrefs -import java.util.Arrays import kotlin.math.asin import kotlin.math.cos import kotlin.math.max @@ -234,7 +233,7 @@ class MapFragment : BaseFragment(), GoogleMap.OnInfoWindowClickListener, GetMapD } override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) { - inflater.inflate(R.menu.map_options, menu) + inflater.inflate(R.menu.map_options, menu) optionsMenu = menu // set checkboxes: @@ -253,39 +252,55 @@ class MapFragment : BaseFragment(), GoogleMap.OnInfoWindowClickListener, GetMapD optionsMenu.findItem(R.id.mi_map_filter_range) .setVisible(false) } + val packageInfo = this.requireContext().packageManager.getPackageInfo(this.requireContext().packageName, 0) + val versionName = packageInfo.versionName + if (versionName.contains("DEV", ignoreCase = true)){ + optionsMenu.findItem(R.id.mi_map_settings).setVisible(false) + appPrefs.saveData("maxresults", "250") + updateMap.clearCache() + } } override fun onOptionsItemSelected(item: MenuItem): Boolean { val menuId = item.itemId val newState = !item.isChecked - if (menuId == R.id.mi_map_autotrack) { - appPrefs.saveData("autotrack", if (newState) "on" else "off") - item.setChecked(newState) - autoTrack = newState - if (autoTrack) { - update() + when (menuId) { + R.id.mi_map_autotrack -> { + appPrefs.saveData("autotrack", if (newState) "on" else "off") + item.setChecked(newState) + autoTrack = newState + if (autoTrack) { + update() + } + if (map != null && map!!.isMyLocationEnabled) { + Log.d(TAG, "onOptionsItemSelected: MyLocation button = " + !autoTrack) + map!!.uiSettings.isMyLocationButtonEnabled = !autoTrack + } + return true } - if (map != null && map!!.isMyLocationEnabled) { - Log.d(TAG, "onOptionsItemSelected: MyLocation button = " + !autoTrack) - map!!.uiSettings.isMyLocationButtonEnabled = !autoTrack + R.id.mi_map_filter_range -> { + appPrefs.saveData("inrange", if (newState) "on" else "off") + item.setChecked(newState) + updateMapDetails(false) + return true } - } else if (menuId == R.id.mi_map_filter_connections) { - appPrefs.saveData("filter", if (newState) "on" else "off") - item.setChecked(newState) - updateMapDetails(false) - } else if (menuId == R.id.mi_map_filter_range) { - appPrefs.saveData("inrange", if (newState) "on" else "off") - item.setChecked(newState) - updateMapDetails(false) - } else if (menuId == R.id.mi_map_settings) { - show( - requireActivity(), - MapSettingsFragment::class.java, - Bundle(), - Configuration.ORIENTATION_UNDEFINED - ) + R.id.mi_map_filter_connections -> { + appPrefs.saveData("filter", if (newState) "on" else "off") + item.setChecked(newState) + updateMapDetails(false) + return true + } + R.id.mi_map_settings -> { + show( + requireActivity(), + MapSettingsFragment::class.java, + Bundle(), + Configuration.ORIENTATION_UNDEFINED + ) + return true + } + else -> return false } - return false } override fun updateClustering(clusterSizeIndex: Int, isEnabled: Boolean) { diff --git a/app/src/main/java/com/openvehicles/OVMS/ui/MapSettingsFragment.kt b/app/src/main/java/com/openvehicles/OVMS/ui/MapSettingsFragment.kt index b0a72cf2..25493101 100644 --- a/app/src/main/java/com/openvehicles/OVMS/ui/MapSettingsFragment.kt +++ b/app/src/main/java/com/openvehicles/OVMS/ui/MapSettingsFragment.kt @@ -62,7 +62,7 @@ class MapSettingsFragment : Fragment(), ConnectionsListener { // set maxresults spinner to current value: try { - val ocmMaxResultsValue = appPrefs.getData("maxresults") + val ocmMaxResultsValue = appPrefs.getData("maxresults", "100") val ocmMaxResultsOptions = resources.getStringArray(R.array.ocm_options_maxresults) var ocmMaxResultsIndex = 0 for (i in ocmMaxResultsOptions.indices) { @@ -101,7 +101,7 @@ class MapSettingsFragment : Fragment(), ConnectionsListener { maxResultsSpinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener { override fun onItemSelected(adapterView: AdapterView<*>, view: View, i: Int, l: Long) { val selected = adapterView.getItemAtPosition(i).toString() - if (appPrefs.getData("maxresults") != selected) { + if (appPrefs.getData("maxresults", "100") != selected) { appPrefs.saveData("maxresults", "" + selected) MapFragment.updateMap.clearCache() } diff --git a/app/src/main/java/com/openvehicles/OVMS/ui/settings/CarEditorFragment.kt b/app/src/main/java/com/openvehicles/OVMS/ui/settings/CarEditorFragment.kt index e6aa85e1..7de81a69 100644 --- a/app/src/main/java/com/openvehicles/OVMS/ui/settings/CarEditorFragment.kt +++ b/app/src/main/java/com/openvehicles/OVMS/ui/settings/CarEditorFragment.kt @@ -280,6 +280,20 @@ class CarEditorFragment : BaseFragment() { private const val TAG = "CarEditorFragment" private val availableColors = arrayOf( + "car_smart_ed_white", + "car_smart_eq_red", + "car_smart_eq_black", + "car_smart_eq_white", + "car_smart_eq_fl_black", + "car_smart_eq_fl_white", + "car_smart_eq_cabrio_black", + "car_smart_eq_cabrio_crystalwhite", + "car_smart_eq_cabrio_grey", + "car_smart_eq_cabrio_lavaorange", + "car_smart_eq_cabrio_lavaorange_nosignal", + "car_smart_44_black", + "car_smart_44_white_silver", + "car_smart_44_fl_black", "car_roadster_arcticwhite", "car_roadster_brilliantyellow", "car_roadster_electricblue", @@ -333,10 +347,6 @@ class CarEditorFragment : BaseFragment() { "car_leaf2_superblack", "car_leaf2_vividblue", "car_env200_white", - "car_smart_ed_white", - "car_smart_eq_red", - "car_smart_eq_black", - "car_smart_eq_white", "car_zoe_black", "car_vwup_black", "car_vwup_blue", diff --git a/app/src/main/java/com/openvehicles/OVMS/ui/settings/CarInfoFragment.kt b/app/src/main/java/com/openvehicles/OVMS/ui/settings/CarInfoFragment.kt index 7acf8a78..cb481feb 100644 --- a/app/src/main/java/com/openvehicles/OVMS/ui/settings/CarInfoFragment.kt +++ b/app/src/main/java/com/openvehicles/OVMS/ui/settings/CarInfoFragment.kt @@ -52,20 +52,29 @@ class CarInfoFragment : BaseFragment() { setValue(rootView, R.id.txt_server, carData!!.server_firmware) setValue(rootView, R.id.txt_car, carData!!.car_firmware) setValue(rootView, R.id.txt_hardware, carData!!.car_hardware) - setValue(rootView, R.id.txt_gsm, carData!!.car_gsm_signal) + setValue(rootView, + R.id.txt_gsm, + String.format( + "%s %s %s",carData!!.car_gsm_signal, carData!!.car_gsm_provider, carData!!.car_mdm_mode) + ) setValue( rootView, R.id.txt_cac, if (carData!!.car_CAC_percent > 0) String.format( - "%.2f Ah = %.1f%%", + "%.0f Ah = %.1f%%", carData!!.car_CAC, carData!!.car_CAC_percent - ) else String.format("%.2f Ah", carData!!.car_CAC) + ) else if (carData!!.car_type == "SQ") String.format( + "%.0f Ah SoC: %.0f%% %.1fkWh", + carData!!.car_CAC, + carData!!.car_soc_raw, + carData!!.car_battery_capacity + ) else String.format("%.0f Ah", carData!!.car_CAC) ) - setValue(rootView, R.id.txt_soh, String.format("%.1f%%", carData!!.car_soh)) + setValue(rootView, R.id.txt_soh, String.format("%.0f%%", carData!!.car_soh)) setValue( rootView, R.id.txt_12v_info, String.format( - "%.1fV (%s) %.1fA", + "%.2fV (%s) %.1fA", carData!!.car_12vline_voltage, if (carData!!.car_charging_12v) "charging" else if (carData!!.car_12vline_ref <= 1.5) String.format( "calmdown, %d min left", @@ -74,10 +83,18 @@ class CarInfoFragment : BaseFragment() { carData!!.car_12v_current ) ) + val defaulttime = (carData!!.car_charge_timestamp.startsWith("01.01.70") || carData!!.car_charge_timestamp.startsWith("01/01 70")) setValue( rootView, R.id.txt_charge_info, - String.format("%.1f kWh", carData!!.car_charge_kwhconsumed) + String.format("%.1f %s %s %s", + carData!!.car_charge_kwhconsumed, + "kWh", + if (defaulttime) + {""} else {carData!!.car_charge_timestamp}, + if (defaulttime) + {""} else {"h"} + ) ) // Show known car service interval info: diff --git a/app/src/main/java/com/openvehicles/OVMS/ui/settings/FeaturesFragment.kt b/app/src/main/java/com/openvehicles/OVMS/ui/settings/FeaturesFragment.kt index ea446967..4471bb60 100644 --- a/app/src/main/java/com/openvehicles/OVMS/ui/settings/FeaturesFragment.kt +++ b/app/src/main/java/com/openvehicles/OVMS/ui/settings/FeaturesFragment.kt @@ -194,8 +194,7 @@ class FeaturesFragment : BaseFragment(), OnResultCommandListener, OnItemClickLis // Renault Twizy: private const val FEATURE_GPSLOGINT = 0x00 // GPS log interval [seconds] private const val FEATURE_KICKDOWN_THRESHOLD = 0x01 // Kickdown threshold (pedal change) - private const val FEATURE_KICKDOWN_COMPZERO = - 0x02 // Kickdown pedal compensation zero point + private const val FEATURE_KICKDOWN_COMPZERO = 0x02 // Kickdown pedal compensation zero point private const val FEATURE_CHARGEMODE = 0x06 // Charge mode (0-1) private const val FEATURE_CHARGEPOWER = 0x07 // Charge power level (0-7) private const val FEATURE_SUFFSOC = 0x0A // Charge alert: sufficient SOC @@ -209,6 +208,11 @@ class FeaturesFragment : BaseFragment(), OnResultCommandListener, OnItemClickLis private const val FEATURE_REMOTE_AC_TEMP = 0x15 // temperature for remote AC private const val FEATURE_REMOTE_AC_ON_BAT = 0x16 // allow remote AC on battery power? + // Smart EQ: + private const val FEATURE_LED_STATE = 0x01 // LED Online State + private const val FEATURE_IOS_TPMS_FIX = 0x02 // iOS TPMS fix + private const val FEATURE_RESET_TRIP_CHARGE = 0x03 // reset trip at charge + // The FEATURE_CARBITS feature is a set of ON/OFF bits to control different // miscelaneous aspects of the system. The following bits are defined: //private static final int FEATURE_CB_2008 = 0x01; // Set to 1 to mark the car as 2008/2009 @@ -335,6 +339,25 @@ class FeaturesFragment : BaseFragment(), OnResultCommandListener, OnItemClickLis } } + // Smart EQ: + if (carData!!.car_type == "SQ") { + when (position) { + FEATURE_LED_STATE -> return context.getString( + R.string.lb_ft_sq_led_state, + position + ) + FEATURE_IOS_TPMS_FIX -> return context.getString( + R.string.lb_ft_sq_ios_tpms_fix, + position + ) + FEATURE_RESET_TRIP_CHARGE -> return context.getString( + R.string.lb_ft_sq_reset_trip_charge, + position + ) + else -> {} + } + } + return when (position) { FEATURE_SPEEDO -> context.getString( R.string.lb_ft_digital_speedo, diff --git a/app/src/main/java/com/openvehicles/OVMS/ui/settings/GlobalOptionsFragment.kt b/app/src/main/java/com/openvehicles/OVMS/ui/settings/GlobalOptionsFragment.kt index dae14a88..1af7be3a 100644 --- a/app/src/main/java/com/openvehicles/OVMS/ui/settings/GlobalOptionsFragment.kt +++ b/app/src/main/java/com/openvehicles/OVMS/ui/settings/GlobalOptionsFragment.kt @@ -1,5 +1,6 @@ package com.openvehicles.OVMS.ui.settings +import android.content.Context import android.content.DialogInterface import android.content.Intent import android.os.Bundle @@ -14,39 +15,55 @@ import android.widget.CheckBox import android.widget.EditText import android.widget.ImageButton import android.widget.TextView +import android.widget.Toast import androidx.appcompat.app.AlertDialog import com.openvehicles.OVMS.R import com.openvehicles.OVMS.api.ApiService +import com.openvehicles.OVMS.api.OnResultCommandListener import com.openvehicles.OVMS.ui.BaseFragment import com.openvehicles.OVMS.ui.utils.Ui.setOnClick import com.openvehicles.OVMS.ui.utils.Ui.setValue import com.openvehicles.OVMS.utils.AppPrefs +import com.openvehicles.OVMS.utils.CarsStorage.getSelectedCarData +import com.openvehicles.OVMS.utils.OVMSNotifications import com.openvehicles.OVMS.utils.Sys.getRandomString /** * Created by balzer on 03.12.16. */ -class GlobalOptionsFragment : BaseFragment(), View.OnClickListener, OnFocusChangeListener { +class GlobalOptionsFragment : BaseFragment(), View.OnClickListener, OnFocusChangeListener, OnResultCommandListener { + private val carData = getSelectedCarData() private var appPrefs: AppPrefs? = null private var txtCodes: EditText? = null private var btnRevert: ImageButton? = null private var serviceEnabled = false private var broadcastEnabled = false + private var ovmsNotifications: OVMSNotifications? = null // Currently unused, may be reused if single messages shall be sent private var broadcastCodes: String? = null private var commandsEnabled = false + private var notificationEnabled = false + private var pluginOVMS= false + private var pluginEQ = false + private var firmwareEnabled = false + private var dateFormat = false override fun onActivityCreated(savedInstanceState: Bundle?) { super.onActivityCreated(savedInstanceState) - compatActivity?.supportActionBar!!.setIcon(R.drawable.ic_action_settings) compatActivity?.setTitle(R.string.Options) appPrefs = AppPrefs(compatActivity!!, "ovms") + val app_Car_ID = carData!!.sel_vehicleid serviceEnabled = appPrefs!!.getData("option_service_enabled", "0") == "1" broadcastEnabled = appPrefs!!.getData("option_broadcast_enabled", "0") == "1" broadcastCodes = appPrefs!!.getData("option_broadcast_codes", DEFAULT_BROADCAST_CODES) commandsEnabled = appPrefs!!.getData("option_commands_enabled", "0") == "1" + notificationEnabled = appPrefs!!.getData("option_notification_enabled_$app_Car_ID", "0") == "1" + pluginOVMS = appPrefs!!.getData("option_plugin_ovms_$app_Car_ID", "0") == "1" + pluginEQ = appPrefs!!.getData("option_plugin_eq_$app_Car_ID", "0") == "1" + firmwareEnabled = appPrefs!!.getData("option_firmware_enabled_$app_Car_ID", "0") == "1" + dateFormat = appPrefs!!.getData("option_date_format", "0") == "1" var checkBox: CheckBox = findViewById(R.id.cb_options_service) as CheckBox checkBox.setChecked(serviceEnabled) checkBox.setOnClickListener(this) @@ -63,6 +80,22 @@ class GlobalOptionsFragment : BaseFragment(), View.OnClickListener, OnFocusChang checkBox = findViewById(R.id.cb_options_commands) as CheckBox checkBox.setChecked(commandsEnabled) checkBox.setOnClickListener(this) + checkBox = findViewById(R.id.cb_options_notification) as CheckBox + checkBox.setChecked(notificationEnabled) + checkBox.setOnClickListener(this) + checkBox = findViewById(R.id.cb_options_plugin_ovms) as CheckBox + checkBox.setChecked(pluginOVMS) + checkBox.setOnClickListener(this) + checkBox = findViewById(R.id.cb_options_plugin_eq) as CheckBox + checkBox.setChecked(pluginEQ) + checkBox.setOnClickListener(this) + checkBox = findViewById(R.id.cb_options_firmware) as CheckBox + checkBox.setChecked(firmwareEnabled) + checkBox.setOnClickListener(this) + checkBox = findViewById(R.id.cb_options_date_format) as CheckBox + checkBox.setChecked(dateFormat) + checkBox.setOnClickListener(this) + setOnClick(requireView(), R.id.cb_options_reboot, this) setOnClick(requireView(), R.id.cb_options_apikey_renew, this) setValue(requireView(), R.id.tv_options_apikey, appPrefs!!.getData("APIKey")) val info = findViewById(R.id.txt_options_broadcast_info) as TextView @@ -80,6 +113,7 @@ class GlobalOptionsFragment : BaseFragment(), View.OnClickListener, OnFocusChang override fun onClick(v: View) { val context = context ?: return val id = v.id + val app_Car_ID = carData!!.sel_vehicleid when (id) { R.id.cb_options_service -> { serviceEnabled = (v as CheckBox).isChecked @@ -99,10 +133,43 @@ class GlobalOptionsFragment : BaseFragment(), View.OnClickListener, OnFocusChang txtCodes!!.setText(broadcastCodes) appPrefs!!.saveData("option_broadcast_codes", broadcastCodes) } + R.id.cb_options_notification -> { + notificationEnabled = (v as CheckBox).isChecked + appPrefs!!.saveData("option_notification_enabled_$app_Car_ID", if (notificationEnabled) "1" else "0") + } R.id.cb_options_commands -> { commandsEnabled = (v as CheckBox).isChecked appPrefs!!.saveData("option_commands_enabled", if (commandsEnabled) "1" else "0") } + R.id.cb_options_plugin_ovms -> { + pluginOVMS = (v as CheckBox).isChecked + appPrefs!!.saveData("option_plugin_ovms_$app_Car_ID", if (pluginOVMS) "1" else "0") + } + R.id.cb_options_plugin_eq -> { + pluginEQ = (v as CheckBox).isChecked + appPrefs!!.saveData("option_plugin_eq_$app_Car_ID", if (pluginEQ) "1" else "0") + } + R.id.cb_options_firmware -> { + firmwareEnabled = (v as CheckBox).isChecked + appPrefs!!.saveData("option_firmware_enabled_$app_Car_ID", if (firmwareEnabled) "1" else "0") + } + R.id.cb_options_date_format -> { + dateFormat = (v as CheckBox).isChecked + appPrefs!!.saveData("option_date_format", if (dateFormat) "1" else "0") + } + R.id.cb_options_reboot -> { + AlertDialog.Builder(context) + .setMessage(R.string.lb_reset_ovms_module) + .setNegativeButton(R.string.Cancel, null) + .setPositiveButton(R.string.Yes) { dialog1: DialogInterface?, which: Int -> + sendCommand( + "reboot module activated", + "5", + this@GlobalOptionsFragment + ) + } + .create().show() + } R.id.cb_options_apikey_renew -> { AlertDialog.Builder(context) .setMessage(R.string.lb_options_apikey_renew_confirm) @@ -118,6 +185,39 @@ class GlobalOptionsFragment : BaseFragment(), View.OnClickListener, OnFocusChang } } + override fun onResultCommand(result: Array) { + if (result.size <= 1) return + val command = result[0].toInt() + val resCode = result[1].toInt() + val resText = if (result.size > 2) result[2] else "" + val cmdMessage = getSentCommandMessage(result[0]) + val context: Context? = activity + if (context != null) { + when (resCode) { + 0 -> Toast.makeText( + context, cmdMessage + " => " + getString(R.string.msg_ok), + Toast.LENGTH_SHORT + ).show() + + 1 -> Toast.makeText( + context, cmdMessage + " => " + getString(R.string.err_failed, resText), + Toast.LENGTH_SHORT + ).show() + + 2 -> Toast.makeText( + context, cmdMessage + " => " + getString(R.string.err_unsupported_operation), + Toast.LENGTH_SHORT + ).show() + + 3 -> Toast.makeText( + context, cmdMessage + " => " + getString(R.string.err_unimplemented_operation), + Toast.LENGTH_SHORT + ).show() + } + } + cancelCommand() + } + override fun onFocusChange(v: View, hasFocus: Boolean) { if (v.id == R.id.txt_options_broadcast_codes) { if (!hasFocus) { diff --git a/app/src/main/res/drawable-nodpi/battery_100_c.png b/app/src/main/res/drawable-nodpi/battery_100_c.png new file mode 100644 index 00000000..bf717403 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/battery_100_c.png differ diff --git a/app/src/main/res/drawable-nodpi/calendar.png b/app/src/main/res/drawable-nodpi/calendar.png new file mode 100644 index 00000000..25618a39 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/calendar.png differ diff --git a/app/src/main/res/drawable-nodpi/car_imiev_black.png b/app/src/main/res/drawable-nodpi/car_imiev_black.png index edebad4b..d438c384 100644 Binary files a/app/src/main/res/drawable-nodpi/car_imiev_black.png and b/app/src/main/res/drawable-nodpi/car_imiev_black.png differ diff --git a/app/src/main/res/drawable-nodpi/car_imiev_blue.png b/app/src/main/res/drawable-nodpi/car_imiev_blue.png index 87ce429e..40f7c6f1 100644 Binary files a/app/src/main/res/drawable-nodpi/car_imiev_blue.png and b/app/src/main/res/drawable-nodpi/car_imiev_blue.png differ diff --git a/app/src/main/res/drawable-nodpi/car_imiev_cherrybrown.png b/app/src/main/res/drawable-nodpi/car_imiev_cherrybrown.png index 75444787..fc2fe3aa 100644 Binary files a/app/src/main/res/drawable-nodpi/car_imiev_cherrybrown.png and b/app/src/main/res/drawable-nodpi/car_imiev_cherrybrown.png differ diff --git a/app/src/main/res/drawable-nodpi/car_imiev_coolsilver.png b/app/src/main/res/drawable-nodpi/car_imiev_coolsilver.png index d5e07e77..177b1eea 100644 Binary files a/app/src/main/res/drawable-nodpi/car_imiev_coolsilver.png and b/app/src/main/res/drawable-nodpi/car_imiev_coolsilver.png differ diff --git a/app/src/main/res/drawable-nodpi/car_imiev_white.png b/app/src/main/res/drawable-nodpi/car_imiev_white.png index 71c9dbbc..ff58f4d8 100644 Binary files a/app/src/main/res/drawable-nodpi/car_imiev_white.png and b/app/src/main/res/drawable-nodpi/car_imiev_white.png differ diff --git a/app/src/main/res/drawable-nodpi/car_imiev_whitered.png b/app/src/main/res/drawable-nodpi/car_imiev_whitered.png index 57af80da..cc43cdfb 100644 Binary files a/app/src/main/res/drawable-nodpi/car_imiev_whitered.png and b/app/src/main/res/drawable-nodpi/car_imiev_whitered.png differ diff --git a/app/src/main/res/drawable-nodpi/car_ioniq_polarwhite.PNG b/app/src/main/res/drawable-nodpi/car_ioniq_polarwhite.PNG index a3dcc226..8fc56f48 100644 Binary files a/app/src/main/res/drawable-nodpi/car_ioniq_polarwhite.PNG and b/app/src/main/res/drawable-nodpi/car_ioniq_polarwhite.PNG differ diff --git a/app/src/main/res/drawable-nodpi/car_kianiro_black.png b/app/src/main/res/drawable-nodpi/car_kianiro_black.png index d2d07598..5483aaca 100644 Binary files a/app/src/main/res/drawable-nodpi/car_kianiro_black.png and b/app/src/main/res/drawable-nodpi/car_kianiro_black.png differ diff --git a/app/src/main/res/drawable-nodpi/car_kianiro_blue.png b/app/src/main/res/drawable-nodpi/car_kianiro_blue.png index 8421f5c5..e4ec2e3a 100644 Binary files a/app/src/main/res/drawable-nodpi/car_kianiro_blue.png and b/app/src/main/res/drawable-nodpi/car_kianiro_blue.png differ diff --git a/app/src/main/res/drawable-nodpi/car_kianiro_grey.png b/app/src/main/res/drawable-nodpi/car_kianiro_grey.png index 9ee3faf0..41a08275 100644 Binary files a/app/src/main/res/drawable-nodpi/car_kianiro_grey.png and b/app/src/main/res/drawable-nodpi/car_kianiro_grey.png differ diff --git a/app/src/main/res/drawable-nodpi/car_kianiro_silver.png b/app/src/main/res/drawable-nodpi/car_kianiro_silver.png index 7f673dc8..823dec71 100644 Binary files a/app/src/main/res/drawable-nodpi/car_kianiro_silver.png and b/app/src/main/res/drawable-nodpi/car_kianiro_silver.png differ diff --git a/app/src/main/res/drawable-nodpi/car_kianiro_snowwhite.png b/app/src/main/res/drawable-nodpi/car_kianiro_snowwhite.png index 52ba8e2c..99576f9b 100644 Binary files a/app/src/main/res/drawable-nodpi/car_kianiro_snowwhite.png and b/app/src/main/res/drawable-nodpi/car_kianiro_snowwhite.png differ diff --git a/app/src/main/res/drawable-nodpi/car_leaf_coulisred.png b/app/src/main/res/drawable-nodpi/car_leaf_coulisred.png index 61f6a6fe..ff2d9c2c 100644 Binary files a/app/src/main/res/drawable-nodpi/car_leaf_coulisred.png and b/app/src/main/res/drawable-nodpi/car_leaf_coulisred.png differ diff --git a/app/src/main/res/drawable-nodpi/car_leaf_deepblue.png b/app/src/main/res/drawable-nodpi/car_leaf_deepblue.png index 5a5b925c..0956f504 100644 Binary files a/app/src/main/res/drawable-nodpi/car_leaf_deepblue.png and b/app/src/main/res/drawable-nodpi/car_leaf_deepblue.png differ diff --git a/app/src/main/res/drawable-nodpi/car_leaf_forgedbronze.png b/app/src/main/res/drawable-nodpi/car_leaf_forgedbronze.png index 68dbd080..c42af560 100644 Binary files a/app/src/main/res/drawable-nodpi/car_leaf_forgedbronze.png and b/app/src/main/res/drawable-nodpi/car_leaf_forgedbronze.png differ diff --git a/app/src/main/res/drawable-nodpi/car_leaf_gunmetallic.png b/app/src/main/res/drawable-nodpi/car_leaf_gunmetallic.png index a9c6703f..56541768 100644 Binary files a/app/src/main/res/drawable-nodpi/car_leaf_gunmetallic.png and b/app/src/main/res/drawable-nodpi/car_leaf_gunmetallic.png differ diff --git a/app/src/main/res/drawable-nodpi/car_leaf_pearlwhite.png b/app/src/main/res/drawable-nodpi/car_leaf_pearlwhite.png index 3939147d..290670eb 100644 Binary files a/app/src/main/res/drawable-nodpi/car_leaf_pearlwhite.png and b/app/src/main/res/drawable-nodpi/car_leaf_pearlwhite.png differ diff --git a/app/src/main/res/drawable-nodpi/car_leaf_planetblue.png b/app/src/main/res/drawable-nodpi/car_leaf_planetblue.png index c44f013b..e62454ec 100644 Binary files a/app/src/main/res/drawable-nodpi/car_leaf_planetblue.png and b/app/src/main/res/drawable-nodpi/car_leaf_planetblue.png differ diff --git a/app/src/main/res/drawable-nodpi/car_leaf_superblack.png b/app/src/main/res/drawable-nodpi/car_leaf_superblack.png index 2ee9e9c6..de2c7419 100644 Binary files a/app/src/main/res/drawable-nodpi/car_leaf_superblack.png and b/app/src/main/res/drawable-nodpi/car_leaf_superblack.png differ diff --git a/app/src/main/res/drawable-nodpi/car_mgzs_black.png b/app/src/main/res/drawable-nodpi/car_mgzs_black.png index 840f8fc1..74d4c581 100644 Binary files a/app/src/main/res/drawable-nodpi/car_mgzs_black.png and b/app/src/main/res/drawable-nodpi/car_mgzs_black.png differ diff --git a/app/src/main/res/drawable-nodpi/car_mgzs_blue.png b/app/src/main/res/drawable-nodpi/car_mgzs_blue.png index 6c925ad2..f4c3570a 100644 Binary files a/app/src/main/res/drawable-nodpi/car_mgzs_blue.png and b/app/src/main/res/drawable-nodpi/car_mgzs_blue.png differ diff --git a/app/src/main/res/drawable-nodpi/car_mgzs_lightblue.png b/app/src/main/res/drawable-nodpi/car_mgzs_lightblue.png index ea277536..49ab97ed 100644 Binary files a/app/src/main/res/drawable-nodpi/car_mgzs_lightblue.png and b/app/src/main/res/drawable-nodpi/car_mgzs_lightblue.png differ diff --git a/app/src/main/res/drawable-nodpi/car_mgzs_red.png b/app/src/main/res/drawable-nodpi/car_mgzs_red.png index 7cee3b9a..cfd446c9 100644 Binary files a/app/src/main/res/drawable-nodpi/car_mgzs_red.png and b/app/src/main/res/drawable-nodpi/car_mgzs_red.png differ diff --git a/app/src/main/res/drawable-nodpi/car_mgzs_white.png b/app/src/main/res/drawable-nodpi/car_mgzs_white.png index d38672a7..1ce185a2 100644 Binary files a/app/src/main/res/drawable-nodpi/car_mgzs_white.png and b/app/src/main/res/drawable-nodpi/car_mgzs_white.png differ diff --git a/app/src/main/res/drawable-nodpi/car_smart_44_black.png b/app/src/main/res/drawable-nodpi/car_smart_44_black.png new file mode 100644 index 00000000..71e15a0e Binary files /dev/null and b/app/src/main/res/drawable-nodpi/car_smart_44_black.png differ diff --git a/app/src/main/res/drawable-nodpi/car_smart_44_fl_black.png b/app/src/main/res/drawable-nodpi/car_smart_44_fl_black.png new file mode 100644 index 00000000..8b0b0592 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/car_smart_44_fl_black.png differ diff --git a/app/src/main/res/drawable-nodpi/car_smart_44_white_silver.png b/app/src/main/res/drawable-nodpi/car_smart_44_white_silver.png new file mode 100644 index 00000000..310c8a99 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/car_smart_44_white_silver.png differ diff --git a/app/src/main/res/drawable-nodpi/car_smart_ed_white.png b/app/src/main/res/drawable-nodpi/car_smart_ed_white.png index 5235a60c..724d2ea2 100644 Binary files a/app/src/main/res/drawable-nodpi/car_smart_ed_white.png and b/app/src/main/res/drawable-nodpi/car_smart_ed_white.png differ diff --git a/app/src/main/res/drawable-nodpi/car_smart_eq_black.png b/app/src/main/res/drawable-nodpi/car_smart_eq_black.png index 2d3c26ee..03704332 100644 Binary files a/app/src/main/res/drawable-nodpi/car_smart_eq_black.png and b/app/src/main/res/drawable-nodpi/car_smart_eq_black.png differ diff --git a/app/src/main/res/drawable-nodpi/car_smart_eq_cabrio_black.png b/app/src/main/res/drawable-nodpi/car_smart_eq_cabrio_black.png new file mode 100644 index 00000000..36ed893e Binary files /dev/null and b/app/src/main/res/drawable-nodpi/car_smart_eq_cabrio_black.png differ diff --git a/app/src/main/res/drawable-nodpi/car_smart_eq_cabrio_crystalwhite.png b/app/src/main/res/drawable-nodpi/car_smart_eq_cabrio_crystalwhite.png new file mode 100644 index 00000000..caf16674 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/car_smart_eq_cabrio_crystalwhite.png differ diff --git a/app/src/main/res/drawable-nodpi/car_smart_eq_cabrio_grey.png b/app/src/main/res/drawable-nodpi/car_smart_eq_cabrio_grey.png new file mode 100644 index 00000000..8cb78bbf Binary files /dev/null and b/app/src/main/res/drawable-nodpi/car_smart_eq_cabrio_grey.png differ diff --git a/app/src/main/res/drawable-nodpi/car_smart_eq_cabrio_lavaorange.png b/app/src/main/res/drawable-nodpi/car_smart_eq_cabrio_lavaorange.png new file mode 100644 index 00000000..2b1b741e Binary files /dev/null and b/app/src/main/res/drawable-nodpi/car_smart_eq_cabrio_lavaorange.png differ diff --git a/app/src/main/res/drawable-nodpi/car_smart_eq_cabrio_lavaorange_nosignal.png b/app/src/main/res/drawable-nodpi/car_smart_eq_cabrio_lavaorange_nosignal.png new file mode 100644 index 00000000..bd7dce79 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/car_smart_eq_cabrio_lavaorange_nosignal.png differ diff --git a/app/src/main/res/drawable-nodpi/car_smart_eq_fl_black.png b/app/src/main/res/drawable-nodpi/car_smart_eq_fl_black.png new file mode 100644 index 00000000..4615780f Binary files /dev/null and b/app/src/main/res/drawable-nodpi/car_smart_eq_fl_black.png differ diff --git a/app/src/main/res/drawable-nodpi/car_smart_eq_fl_white.png b/app/src/main/res/drawable-nodpi/car_smart_eq_fl_white.png new file mode 100644 index 00000000..c9699b3c Binary files /dev/null and b/app/src/main/res/drawable-nodpi/car_smart_eq_fl_white.png differ diff --git a/app/src/main/res/drawable-nodpi/car_smart_eq_red.png b/app/src/main/res/drawable-nodpi/car_smart_eq_red.png index 4674cd51..13a245bc 100644 Binary files a/app/src/main/res/drawable-nodpi/car_smart_eq_red.png and b/app/src/main/res/drawable-nodpi/car_smart_eq_red.png differ diff --git a/app/src/main/res/drawable-nodpi/car_smart_eq_white.png b/app/src/main/res/drawable-nodpi/car_smart_eq_white.png index e439ba93..0a39fa5b 100644 Binary files a/app/src/main/res/drawable-nodpi/car_smart_eq_white.png and b/app/src/main/res/drawable-nodpi/car_smart_eq_white.png differ diff --git a/app/src/main/res/drawable-nodpi/handbrake_on.png b/app/src/main/res/drawable-nodpi/handbrake_on.png index c1635fd3..f625dddf 100644 Binary files a/app/src/main/res/drawable-nodpi/handbrake_on.png and b/app/src/main/res/drawable-nodpi/handbrake_on.png differ diff --git a/app/src/main/res/drawable-nodpi/heat_cool.png b/app/src/main/res/drawable-nodpi/heat_cool.png new file mode 100644 index 00000000..42883ef5 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/heat_cool.png differ diff --git a/app/src/main/res/drawable-nodpi/heat_cool_2.png b/app/src/main/res/drawable-nodpi/heat_cool_2.png new file mode 100644 index 00000000..cc5258d8 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/heat_cool_2.png differ diff --git a/app/src/main/res/drawable-nodpi/letterbox.png b/app/src/main/res/drawable-nodpi/letterbox.png new file mode 100644 index 00000000..9ca2b428 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/letterbox.png differ diff --git a/app/src/main/res/drawable-nodpi/motortemp_letterbox_2.png b/app/src/main/res/drawable-nodpi/motortemp_letterbox_2.png new file mode 100644 index 00000000..bf9bdb92 Binary files /dev/null and b/app/src/main/res/drawable-nodpi/motortemp_letterbox_2.png differ diff --git a/app/src/main/res/drawable-nodpi/smart_off_l.png b/app/src/main/res/drawable-nodpi/smart_off_l.png index 6c366201..c7a1e7a1 100644 Binary files a/app/src/main/res/drawable-nodpi/smart_off_l.png and b/app/src/main/res/drawable-nodpi/smart_off_l.png differ diff --git a/app/src/main/res/layout/dlg_booster_days.xml b/app/src/main/res/layout/dlg_booster_days.xml new file mode 100644 index 00000000..11378fe5 --- /dev/null +++ b/app/src/main/res/layout/dlg_booster_days.xml @@ -0,0 +1,64 @@ + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/dlg_booster_time.xml b/app/src/main/res/layout/dlg_booster_time.xml new file mode 100644 index 00000000..68868b08 --- /dev/null +++ b/app/src/main/res/layout/dlg_booster_time.xml @@ -0,0 +1,76 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/fragment_car.xml b/app/src/main/res/layout/fragment_car.xml index d49e1781..c7b7b465 100644 --- a/app/src/main/res/layout/fragment_car.xml +++ b/app/src/main/res/layout/fragment_car.xml @@ -9,86 +9,107 @@ android:id="@+id/scaleLayout" android:layout_width="match_parent" android:layout_height="match_parent" - android:layout_margin="8dp" - > + android:layout_margin="8dp"> + android:src="@drawable/ol_car_default" /> + android:src="@drawable/roadster_outline_cp" /> + android:visibility="invisible" /> + android:visibility="invisible" /> + android:visibility="invisible" /> + android:visibility="invisible" /> + android:visibility="invisible" /> + android:visibility="invisible" /> + android:src="@drawable/carlock_roadster" /> + android:src="@drawable/carvaleton_roadster" /> + android:visibility="invisible" /> + android:src="@drawable/motortemp_letterbox" /> + android:src="@drawable/letterbox_ambient" /> + android:src="@drawable/tirepress_letterbox" /> + + + + + tools:ignore="PxUsage" /> + android:src="@drawable/letterbox_ac" /> + tools:ignore="PxUsage" /> + + + android:textStyle="bold" /> + android:textStyle="bold" + android:clickable="true" + android:focusable="true"/> + android:textStyle="bold" /> + android:textStyle="bold" + android:clickable="true" + android:focusable="true"/> + android:textStyle="bold" /> + android:textStyle="bold" + android:clickable="true" + android:focusable="true"/> + android:textStyle="bold" /> + android:textStyle="bold" + android:clickable="true" + android:focusable="true"/> + android:text="@string/textPEM" /> + android:textStyle="bold" /> + + + + + android:text="@string/textSoH" + android:visibility="invisible"/> + + + + + android:textStyle="bold" /> + android:text="@string/textMOTOR" /> + android:textStyle="bold" /> + android:textSize="18px" /> + android:focusable="true" + android:text="@string/text12VBATT" /> + android:textStyle="bold" /> + android:text="@string/textAMBIENT" /> + android:textStyle="bold" /> + android:text="@string/textCHARGER" /> + android:textStyle="bold" /> @@ -289,14 +368,15 @@ android:layout_width="232px" android:layout_height="44px" android:layout_x="152px" - android:layout_y="170px" + android:layout_y="150px" android:fontFamily="sans-serif-condensed" android:gravity="center" android:singleLine="false" android:text="123456.7km" android:textColor="@color/colorForeground" - android:textSize="25px" - android:typeface="monospace"/> + android:textSize="30px" + android:textStyle="bold" + android:typeface="monospace" /> + android:textSize="24px" + android:typeface="monospace" /> + + + android:textSize="24px" + android:typeface="monospace" /> + android:typeface="monospace" /> @@ -353,8 +448,10 @@ android:layout_width="200px" android:layout_height="120px" android:layout_x="166px" - android:layout_y="400px" - android:clickable="true"/> + android:layout_y="410px" + android:clickable="true" + android:focusable="true" + tools:ignore="PxUsage" /> + android:clickable="true" + android:focusable="true" /> + android:clickable="true" + android:focusable="true" /> \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_careditor.xml b/app/src/main/res/layout/fragment_careditor.xml index 02281ece..9340c8ab 100755 --- a/app/src/main/res/layout/fragment_careditor.xml +++ b/app/src/main/res/layout/fragment_careditor.xml @@ -1,8 +1,10 @@ + android:padding="16dp" + android:textAlignment="center"> @@ -22,24 +24,24 @@ @@ -54,15 +56,14 @@ android:id="@+id/select_server" style="@style/Widget.AppCompat.Spinner.Underlined" android:layout_width="match_parent" - android:layout_height="wrap_content" - android:layout_column="1" - android:background="@drawable/spinner_ab_focused_ovms" + android:layout_height="48dp" + android:background="@drawable/spinner_ab_focused_ovms" android:entries="@array/select_server_options" /> + + + + + + + + android:layout_gravity="center_vertical" + tools:ignore="DuplicateIds" /> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +