diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index dc083390..7d0480e7 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -180,6 +180,8 @@
Debug
General
+ Trip Info
+
Routines
Enable routines screen
It enables routines screen which let you to execute different ECU functions. This feature is very risky, and you use it on your own risk
diff --git a/app/src/main/res/xml/preferences.xml b/app/src/main/res/xml/preferences.xml
index b0f909b9..acdffe39 100644
--- a/app/src/main/res/xml/preferences.xml
+++ b/app/src/main/res/xml/preferences.xml
@@ -1335,6 +1335,24 @@
+
+
+
+
+
+
+
diff --git a/automotive/src/main/java/org/obd/graphs/aa/CarSettings.kt b/automotive/src/main/java/org/obd/graphs/aa/CarSettings.kt
index ff8acdce..4b6e517e 100644
--- a/automotive/src/main/java/org/obd/graphs/aa/CarSettings.kt
+++ b/automotive/src/main/java/org/obd/graphs/aa/CarSettings.kt
@@ -66,6 +66,7 @@ class CarSettings(private val carContext: CarContext) : ScreenSettings {
private val dragRacingSettings = DragRacingSettings()
private val colorTheme = ColorTheme()
private val gaugeRendererSettings = GaugeRendererSettings()
+ private val tripInfoSettings = TripInfoSettings()
override fun getDragRacingSettings(): DragRacingSettings = dragRacingSettings.apply {
vehicleSpeedFrequencyReadEnabled = Prefs.getBoolean("pref.aa.drag_race.debug.display_frequency", true)
@@ -77,6 +78,12 @@ class CarSettings(private val carContext: CarContext) : ScreenSettings {
fontSize = Prefs.getS("pref.aa.drag_race.font_size", "30").toInt()
}
+ override fun getTripInfoSettings(): TripInfoSettings = tripInfoSettings.apply {
+ fontSize = Prefs.getS("pref.aa.trip_info.font_size", "24").toInt()
+ }
+
+
+
override fun getColorTheme(): ColorTheme = colorTheme.apply {
progressColor = Prefs.getInt(PREF_THEME_PROGRESS_BAR_COLOR, COLOR_DYNAMIC_SELECTOR_SPORT)
dividerColor = Prefs.getInt(PREF_THEME_DIVIDER_COLOR, Color.WHITE)
diff --git a/automotive/src/main/java/org/obd/graphs/aa/screen/CarScreen.kt b/automotive/src/main/java/org/obd/graphs/aa/screen/CarScreen.kt
index 4c292746..e6f540e8 100644
--- a/automotive/src/main/java/org/obd/graphs/aa/screen/CarScreen.kt
+++ b/automotive/src/main/java/org/obd/graphs/aa/screen/CarScreen.kt
@@ -29,10 +29,7 @@ import org.obd.graphs.AA_EDIT_PREF_SCREEN
import org.obd.graphs.RenderingThread
import org.obd.graphs.aa.*
import org.obd.graphs.aa.mapColor
-import org.obd.graphs.aa.screen.nav.CHANGE_SCREEN_EVENT
-import org.obd.graphs.aa.screen.nav.DRAG_RACING_SCREEN_ID
-import org.obd.graphs.aa.screen.nav.GIULIA_SCREEN_ID
-import org.obd.graphs.aa.screen.nav.ROUTINES_SCREEN_ID
+import org.obd.graphs.aa.screen.nav.*
import org.obd.graphs.aa.toast
import org.obd.graphs.bl.collector.MetricsCollector
import org.obd.graphs.bl.datalogger.WorkflowStatus
@@ -102,13 +99,21 @@ internal abstract class CarScreen(
}
dataLogger.start(query)
}
- DRAG_RACING_SCREEN_ID -> {
- query.setStrategy(QueryStrategyType.DRAG_RACING_QUERY)
- dataLogger.start(query)
- }
+
+ DRAG_RACING_SCREEN_ID ->
+ dataLogger.start(query.apply{
+ setStrategy(QueryStrategyType.DRAG_RACING_QUERY)
+ })
+
+ TRIP_INFO_SCREEN_ID ->
+ dataLogger.start(query.apply{
+ setStrategy(QueryStrategyType.TRIP_INFO_QUERY)
+ })
+
ROUTINES_SCREEN_ID -> {
- query.setStrategy(QueryStrategyType.ROUTINES_QUERY)
- dataLogger.start(query)
+ dataLogger.start(query.apply{
+ setStrategy(QueryStrategyType.ROUTINES_QUERY)
+ })
}
}
})
diff --git a/automotive/src/main/java/org/obd/graphs/aa/screen/nav/AvailableFeaturesScreen.kt b/automotive/src/main/java/org/obd/graphs/aa/screen/nav/AvailableFeaturesScreen.kt
index b215c885..ff1421c6 100644
--- a/automotive/src/main/java/org/obd/graphs/aa/screen/nav/AvailableFeaturesScreen.kt
+++ b/automotive/src/main/java/org/obd/graphs/aa/screen/nav/AvailableFeaturesScreen.kt
@@ -31,6 +31,7 @@ import org.obd.graphs.bl.datalogger.*
const val GIULIA_SCREEN_ID = 0
const val DRAG_RACING_SCREEN_ID = 1
const val ROUTINES_SCREEN_ID = 2
+const val TRIP_INFO_SCREEN_ID = 3
internal class AvailableFeaturesScreen(
carContext: CarContext,
@@ -59,6 +60,13 @@ internal class AvailableFeaturesScreen(
val items = ItemList.Builder().apply {
+ addItem(
+ row(
+ TRIP_INFO_SCREEN_ID, R.drawable.action_giulia,
+ carContext.getString(R.string.available_features_trip_info_screen_title)
+ )
+ )
+
addItem(
row(
DRAG_RACING_SCREEN_ID, R.drawable.action_drag_race_screen,
diff --git a/automotive/src/main/java/org/obd/graphs/aa/screen/nav/NavTemplateCarScreen.kt b/automotive/src/main/java/org/obd/graphs/aa/screen/nav/NavTemplateCarScreen.kt
index 684fba91..00eb14ad 100644
--- a/automotive/src/main/java/org/obd/graphs/aa/screen/nav/NavTemplateCarScreen.kt
+++ b/automotive/src/main/java/org/obd/graphs/aa/screen/nav/NavTemplateCarScreen.kt
@@ -72,7 +72,7 @@ internal class NavTemplateCarScreen(
Log.d(LOG_KEY, "Selected new screen id=$it")
it?.let {
val newScreen = it.toString().toInt()
- if (newScreen == GIULIA_SCREEN_ID || newScreen == DRAG_RACING_SCREEN_ID) {
+ if (newScreen == GIULIA_SCREEN_ID || newScreen == DRAG_RACING_SCREEN_ID || newScreen == TRIP_INFO_SCREEN_ID) {
surfaceScreen.toggleSurfaceRenderer(newScreen)
invalidate()
} else {
diff --git a/automotive/src/main/java/org/obd/graphs/aa/screen/nav/SurfaceController.kt b/automotive/src/main/java/org/obd/graphs/aa/screen/nav/SurfaceController.kt
index fb42eff4..ae2f0a44 100644
--- a/automotive/src/main/java/org/obd/graphs/aa/screen/nav/SurfaceController.kt
+++ b/automotive/src/main/java/org/obd/graphs/aa/screen/nav/SurfaceController.kt
@@ -151,10 +151,19 @@ class SurfaceController(
}
DRAG_RACING_SCREEN_ID -> {
- query.setStrategy(QueryStrategyType.DRAG_RACING_QUERY)
- dataLogger.updateQuery(query = query)
+ dataLogger.updateQuery(query = query.apply {
+ setStrategy(QueryStrategyType.DRAG_RACING_QUERY)
+ })
+
surfaceRenderer = SurfaceRenderer.allocate(carContext, settings, metricsCollector, fps, surfaceRendererType = SurfaceRendererType.DRAG_RACING)
}
+
+ TRIP_INFO_SCREEN_ID -> {
+ dataLogger.updateQuery(query = query.apply {
+ setStrategy(QueryStrategyType.TRIP_INFO_QUERY)
+ })
+ surfaceRenderer = SurfaceRenderer.allocate(carContext, settings, metricsCollector, fps, surfaceRendererType = SurfaceRendererType.TRIP_INFO)
+ }
}
surfaceRenderer.applyMetricsFilter(query)
diff --git a/automotive/src/main/java/org/obd/graphs/aa/screen/nav/SurfaceScreen.kt b/automotive/src/main/java/org/obd/graphs/aa/screen/nav/SurfaceScreen.kt
index 6e1ef2d3..8410b54d 100644
--- a/automotive/src/main/java/org/obd/graphs/aa/screen/nav/SurfaceScreen.kt
+++ b/automotive/src/main/java/org/obd/graphs/aa/screen/nav/SurfaceScreen.kt
@@ -130,7 +130,7 @@ internal class SurfaceScreen(
}
fun renderFrame() {
- if (isAllowedFrameRendering()) {
+ if (isScreenAllowedForFrameRendering(screenId)) {
surfaceController.renderFrame()
}
}
@@ -258,6 +258,6 @@ internal class SurfaceScreen(
mapColor(settings.getColorTheme().actionsBtnVirtualScreensColor)
}
- private fun isAllowedFrameRendering() = screenId == GIULIA_SCREEN_ID ||
- screenId == DRAG_RACING_SCREEN_ID
+ private fun isScreenAllowedForFrameRendering(screenId: Int) = screenId == GIULIA_SCREEN_ID ||
+ screenId == DRAG_RACING_SCREEN_ID || screenId == TRIP_INFO_SCREEN_ID
}
\ No newline at end of file
diff --git a/automotive/src/main/res/values/strings.xml b/automotive/src/main/res/values/strings.xml
index d746f9e0..2770b951 100644
--- a/automotive/src/main/res/values/strings.xml
+++ b/automotive/src/main/res/values/strings.xml
@@ -17,4 +17,6 @@
Routines
Drag Racing
Metrics
+ Trip Info
+
\ No newline at end of file
diff --git a/datalogger/src/main/java/org/obd/graphs/bl/collector/InMemoryCarMetricsCollector.kt b/datalogger/src/main/java/org/obd/graphs/bl/collector/InMemoryCarMetricsCollector.kt
index 6b070355..49db6fd9 100644
--- a/datalogger/src/main/java/org/obd/graphs/bl/collector/InMemoryCarMetricsCollector.kt
+++ b/datalogger/src/main/java/org/obd/graphs/bl/collector/InMemoryCarMetricsCollector.kt
@@ -29,9 +29,12 @@ private const val LOG_KEY = "InMemoryCollector"
internal class InMemoryCarMetricsCollector : MetricsCollector {
private var metrics: SortedMap = TreeMap()
+ private val metricBuilder = MetricsBuilder()
override fun getMetrics(enabled: Boolean): List = metrics.values.filter { it.enabled == enabled }
+ override fun getMetric(id: Long): Metric? = metrics[id]
+
override fun applyFilter(enabled: Set, order: Map?) {
Log.i(LOG_KEY, "Updating visible PIDs=$enabled with order=$order")
@@ -40,7 +43,7 @@ internal class InMemoryCarMetricsCollector : MetricsCollector {
if (Log.isLoggable(LOG_KEY, Log.DEBUG)) {
Log.d(LOG_KEY, "Rebuilding metrics configuration for: $enabled != ${metrics.keys}")
}
- MetricsBuilder().buildFor(enabled).forEach {
+ metricBuilder.buildFor(enabled).forEach {
val key = it.source.command.pid.id
if (metrics.keys.indexOf(key) ==-1) {
@@ -67,6 +70,10 @@ internal class InMemoryCarMetricsCollector : MetricsCollector {
override fun append(input: ObdMetric?) {
input?.let { metric ->
+ if (!metrics.containsKey(metric.command.pid.id)) {
+ metrics[metric.command.pid.id] = metricBuilder.buildFor(metric)
+ }
+
metrics[metric.command.pid.id]?.let {
it.source = metric
diff --git a/datalogger/src/main/java/org/obd/graphs/bl/collector/Metric.kt b/datalogger/src/main/java/org/obd/graphs/bl/collector/Metric.kt
index f46ee6cc..09fd5cd1 100644
--- a/datalogger/src/main/java/org/obd/graphs/bl/collector/Metric.kt
+++ b/datalogger/src/main/java/org/obd/graphs/bl/collector/Metric.kt
@@ -23,6 +23,8 @@ import org.obd.metrics.api.model.ObdMetric
import org.obd.metrics.pid.PidDefinition
import org.obd.metrics.pid.ValueType
+private const val NO_DATA = "----"
+
data class Metric(
var source: ObdMetric,
var value: Number?,
@@ -46,7 +48,7 @@ data class Metric(
fun valueToString(): String =
if (source.value == null) {
- "----"
+ NO_DATA
} else {
toNumber(source.valueToDouble())
}
diff --git a/datalogger/src/main/java/org/obd/graphs/bl/collector/MetricsBuilder.kt b/datalogger/src/main/java/org/obd/graphs/bl/collector/MetricsBuilder.kt
index a2bb6d31..2ff0645b 100644
--- a/datalogger/src/main/java/org/obd/graphs/bl/collector/MetricsBuilder.kt
+++ b/datalogger/src/main/java/org/obd/graphs/bl/collector/MetricsBuilder.kt
@@ -25,6 +25,20 @@ import org.obd.metrics.command.obd.ObdCommand
import org.obd.metrics.pid.PidDefinitionRegistry
class MetricsBuilder {
+
+ fun buildFor(obdMetric: ObdMetric): Metric {
+ val histogramSupplier = dataLogger.getDiagnostics().histogram()
+ val histogram = histogramSupplier.findBy(obdMetric.command.pid)
+ return Metric
+ .newInstance(
+ min = histogram?.min ?: 0.0,
+ max = histogram?.max ?: 0.0,
+ mean = histogram?.mean ?: 0.0,
+ value = histogram?.latestValue ?: 0,
+ source = obdMetric
+ )
+ }
+
fun buildFor(ids: Set) = buildFor(ids, emptyMap())
fun buildFor(ids: Set, sortOrder: Map?): MutableList {
@@ -46,6 +60,7 @@ class MetricsBuilder {
return metrics
}
+
private fun buildMetrics(ids: Set): MutableList {
val pidRegistry: PidDefinitionRegistry = dataLogger.getPidDefinitionRegistry()
val histogramSupplier = dataLogger.getDiagnostics().histogram()
@@ -55,13 +70,14 @@ class MetricsBuilder {
val histogram = histogramSupplier.findBy(pid)
Metric
.newInstance(
- min = histogram?.min?:0.0,
- max = histogram?.max?:0.0,
- mean = histogram?.mean?:0.0,
- value = histogram?.latestValue?:0,
- source=ObdMetric.builder()
- .command(ObdCommand(pid))
- .value(histogram?.latestValue).build())
+ min = histogram?.min ?: 0.0,
+ max = histogram?.max ?: 0.0,
+ mean = histogram?.mean ?: 0.0,
+ value = histogram?.latestValue ?: 0,
+ source = ObdMetric.builder()
+ .command(ObdCommand(pid))
+ .value(histogram?.latestValue).build()
+ )
}
}.toMutableList()
}
diff --git a/datalogger/src/main/java/org/obd/graphs/bl/collector/MetricsCollector.kt b/datalogger/src/main/java/org/obd/graphs/bl/collector/MetricsCollector.kt
index cc862096..8d7b0197 100644
--- a/datalogger/src/main/java/org/obd/graphs/bl/collector/MetricsCollector.kt
+++ b/datalogger/src/main/java/org/obd/graphs/bl/collector/MetricsCollector.kt
@@ -22,6 +22,8 @@ import org.obd.metrics.api.model.ObdMetric
interface MetricsCollector {
+ fun getMetric(id: Long): Metric?
+
fun getMetrics(enabled: Boolean = true): List
fun applyFilter(enabled: Set, order: Map? = null)
diff --git a/datalogger/src/main/java/org/obd/graphs/bl/generator/MetricsGenerator.kt b/datalogger/src/main/java/org/obd/graphs/bl/generator/MetricsGenerator.kt
index 4d9cf7ae..4dff7129 100644
--- a/datalogger/src/main/java/org/obd/graphs/bl/generator/MetricsGenerator.kt
+++ b/datalogger/src/main/java/org/obd/graphs/bl/generator/MetricsGenerator.kt
@@ -2,6 +2,7 @@ package org.obd.graphs.bl.generator
import android.os.Handler
import android.os.Looper
+import android.util.Log
import org.obd.graphs.bl.datalogger.MetricsProcessor
import org.obd.graphs.bl.datalogger.dataLogger
import org.obd.graphs.bl.query.Query
@@ -86,19 +87,19 @@ class MetricsGenerator(private val debugBuild: Boolean) : MetricsProcessor {
private fun generateSequenceFor(pid: PidDefinition) =
mutableListOf().apply {
- if (pid.type == ValueType.DOUBLE) {
- var step = 1.0
+ if (pid.type == ValueType.DOUBLE || pid.type == null) {
+ var step = 1.55
if (pid.max.toInt() < 15) {
step = 0.1
}
if (pid.max.toInt() > 1000) {
- step = 5.0
+ step = 5.22
}
if (pid.max.toInt() > 5000) {
- step = 10.0
+ step = 10.33
}
(pid.min.toDouble()..pid.max.toDouble() step step).forEach {
diff --git a/datalogger/src/main/java/org/obd/graphs/bl/query/ObdMetricExt.kt b/datalogger/src/main/java/org/obd/graphs/bl/query/ObdMetricExt.kt
index 172e62a8..dec3615e 100644
--- a/datalogger/src/main/java/org/obd/graphs/bl/query/ObdMetricExt.kt
+++ b/datalogger/src/main/java/org/obd/graphs/bl/query/ObdMetricExt.kt
@@ -26,8 +26,51 @@ private const val VEHICLE_SPEED_PID_ID = 14L
private const val EXT_ENGINE_RPM_PID_ID = 7008L
private const val ENGINE_RPM_PID_ID = 13L
+private const val FUEL_CONSUMPTION_PID_ID = 7035L
+private const val FUEL_LEVEL_PID_ID = 7037L
+private const val GEARBOX_OIL_TEMP_PID_ID = 7025L
+private const val GEARBOX_ENGAGED_PID_ID = 7029L
+private const val OIL_TEMP_PID_ID = 7003L
+private const val COOLANT_TEMP_PID_ID = 7009L
+private const val EXHAUST_TEMP_PID_ID = 7016L
+private const val AIR_TEMP_PID_ID = 7002L
+private const val TOTAL_MISFIRES_PID_ID = 17078L
+private const val OIL_LEVEL_PID_ID = 7014L
+
+private const val ENGINE_TORQUE_PID_ID = 7028L
+private const val INTAKE_PRESSURE_PID_ID = 7005L
+private const val DISTANCE_PID_ID = 7076L
+private const val FUEL_CONSUMED_PID_ID = 7077L
+
+
+
class PIDsNamesRegistry {
+ fun getTotalMisfiresPID(): Long = TOTAL_MISFIRES_PID_ID
+ fun getOilLevelPID(): Long = OIL_LEVEL_PID_ID
+
+ fun getTorquePID(): Long = ENGINE_TORQUE_PID_ID
+
+ fun getIntakePressurePID(): Long = INTAKE_PRESSURE_PID_ID
+
+ fun getDistancePID(): Long = DISTANCE_PID_ID
+
+ fun getFuelConsumedPID(): Long = FUEL_CONSUMED_PID_ID
+
+ fun getFuelConsumptionPID(): Long = FUEL_CONSUMPTION_PID_ID
+ fun getFuelLevelPID(): Long = FUEL_LEVEL_PID_ID
+ fun getGearboxOilTempPID(): Long = GEARBOX_OIL_TEMP_PID_ID
+
+ fun getGearboxEngagedPID(): Long = GEARBOX_ENGAGED_PID_ID
+
+ fun getOilTempPID(): Long = OIL_TEMP_PID_ID
+
+ fun getCoolantTempPID(): Long = COOLANT_TEMP_PID_ID
+
+ fun getExhaustTempPID(): Long = EXHAUST_TEMP_PID_ID
+
+ fun getAirTempPID(): Long = AIR_TEMP_PID_ID
+
fun getAtmPressurePID(): Long = EXT_ATM_PRESSURE_PID_ID
fun getAmbientTempPID(): Long = EXT_AMBIENT_TEMP_PID_ID
fun getMeasuredIntakePressurePID (): Long = EXT_MEASURED_INTAKE_PRESSURE_PID_ID
@@ -38,5 +81,4 @@ class PIDsNamesRegistry {
fun getDynamicSelectorPID(): Long = EXT_DYNAMIC_SELECTOR_PID_ID
private fun isProfileExtensionsEnabled() = Prefs.getBoolean(PREF_PROFILE_2_0_GME_EXTENSION_ENABLED, false)
-
}
\ No newline at end of file
diff --git a/datalogger/src/main/java/org/obd/graphs/bl/query/QueryStrategyOrchestrator.kt b/datalogger/src/main/java/org/obd/graphs/bl/query/QueryStrategyOrchestrator.kt
index fe72f794..42bfceee 100644
--- a/datalogger/src/main/java/org/obd/graphs/bl/query/QueryStrategyOrchestrator.kt
+++ b/datalogger/src/main/java/org/obd/graphs/bl/query/QueryStrategyOrchestrator.kt
@@ -16,6 +16,7 @@ internal class QueryStrategyOrchestrator : java.io.Serializable, Query {
this[QueryStrategyType.DRAG_RACING_QUERY] = DragRacingQueryStrategy()
this[QueryStrategyType.INDIVIDUAL_QUERY_FOR_EACH_VIEW] = IndividualQueryStrategy()
this[QueryStrategyType.ROUTINES_QUERY] = RoutinesQueryStrategy()
+ this[QueryStrategyType.TRIP_INFO_QUERY] = TripInfoQueryStrategy()
}
}
diff --git a/datalogger/src/main/java/org/obd/graphs/bl/query/QueryStrategyType.kt b/datalogger/src/main/java/org/obd/graphs/bl/query/QueryStrategyType.kt
index da775ce0..c75525c3 100644
--- a/datalogger/src/main/java/org/obd/graphs/bl/query/QueryStrategyType.kt
+++ b/datalogger/src/main/java/org/obd/graphs/bl/query/QueryStrategyType.kt
@@ -20,6 +20,7 @@ package org.obd.graphs.bl.query
enum class QueryStrategyType {
ROUTINES_QUERY,
DRAG_RACING_QUERY,
+ TRIP_INFO_QUERY,
SHARED_QUERY,
INDIVIDUAL_QUERY_FOR_EACH_VIEW
}
\ No newline at end of file
diff --git a/datalogger/src/main/java/org/obd/graphs/bl/query/TripInfoQueryStrategy.kt b/datalogger/src/main/java/org/obd/graphs/bl/query/TripInfoQueryStrategy.kt
new file mode 100644
index 00000000..b105bed1
--- /dev/null
+++ b/datalogger/src/main/java/org/obd/graphs/bl/query/TripInfoQueryStrategy.kt
@@ -0,0 +1,45 @@
+/**
+ * Copyright 2019-2024, Tomasz Żebrowski
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ **/
+package org.obd.graphs.bl.query
+
+
+internal class TripInfoQueryStrategy : QueryStrategy() {
+ override fun getPIDs(): MutableSet =
+ mutableSetOf(
+ namesRegistry.getVehicleSpeedPID(),
+ namesRegistry.getFuelConsumptionPID(),
+ namesRegistry.getFuelLevelPID(),
+ namesRegistry.getAtmPressurePID(),
+ namesRegistry.getAmbientTempPID(),
+ namesRegistry.getGearboxEngagedPID(),
+ namesRegistry.getGearboxOilTempPID(),
+ namesRegistry.getOilTempPID(),
+ namesRegistry.getCoolantTempPID(),
+ namesRegistry.getExhaustTempPID(),
+ namesRegistry.getAirTempPID(),
+ namesRegistry.getTotalMisfiresPID(),
+ namesRegistry.getOilLevelPID(),
+ namesRegistry.getTorquePID(),
+ namesRegistry.getIntakePressurePID(),
+ namesRegistry.getDynamicSelectorPID(),
+ namesRegistry.getDistancePID(),
+ namesRegistry.getFuelConsumedPID()
+ )
+}
+
diff --git a/screen_renderer/src/main/java/org/obd/graphs/renderer/AbstractDrawer.kt b/screen_renderer/src/main/java/org/obd/graphs/renderer/AbstractDrawer.kt
index b5988e43..71f6c9c3 100644
--- a/screen_renderer/src/main/java/org/obd/graphs/renderer/AbstractDrawer.kt
+++ b/screen_renderer/src/main/java/org/obd/graphs/renderer/AbstractDrawer.kt
@@ -26,6 +26,7 @@ import org.obd.graphs.bl.datalogger.WorkflowStatus
import org.obd.graphs.bl.datalogger.dataLogger
import org.obd.graphs.bl.query.isAmbientTemp
import org.obd.graphs.bl.query.isAtmPressure
+import org.obd.graphs.bl.query.namesRegistry
import org.obd.graphs.commons.R
import org.obd.graphs.profile.profile
import org.obd.graphs.renderer.drag.MARGIN_END
@@ -33,7 +34,7 @@ import org.obd.graphs.renderer.drag.MARGIN_END
private const val STATUS_KEY_FONT_SIZE = 12f
private const val STATUS_VALUE_FONT_SIZE = 18f
-internal abstract class AbstractDrawer (context: Context, protected val settings: ScreenSettings) {
+internal abstract class AbstractDrawer(context: Context, protected val settings: ScreenSettings) {
protected val valueScaler: ValueScaler = ValueScaler()
@@ -121,7 +122,10 @@ internal abstract class AbstractDrawer (context: Context, protected val settings
}
}
- fun drawStatusPanel(canvas: Canvas, top: Float, left: Float, fps: Fps, metricsCollector: MetricsCollector? = null){
+ fun drawStatusPanel(
+ canvas: Canvas, top: Float, left: Float, fps: Fps, metricsCollector: MetricsCollector? = null,
+ drawContextInfo: Boolean = false
+ ) {
var text = statusLabel
var marginLeft = left
@@ -221,9 +225,11 @@ internal abstract class AbstractDrawer (context: Context, protected val settings
)
}
- metricsCollector?.let {
- if (settings.getDragRacingSettings().contextInfoEnabled) {
- metricsCollector.getMetrics().firstOrNull { it.source.isAmbientTemp() }?.let {
+
+ if (drawContextInfo) {
+ metricsCollector?.let {
+
+ metricsCollector.getMetric(namesRegistry.getAmbientTempPID())?.let {
marginLeft += getTextWidth(text, statusPaint) + 12F
text = ambientTempLabel
drawText(
@@ -231,7 +237,7 @@ internal abstract class AbstractDrawer (context: Context, protected val settings
text,
marginLeft,
top,
- Color.WHITE,
+ Color.LTGRAY,
STATUS_KEY_FONT_SIZE,
statusPaint
)
@@ -242,13 +248,13 @@ internal abstract class AbstractDrawer (context: Context, protected val settings
"${it.valueToString()}${it.source.command.pid.units}",
marginLeft,
top,
- Color.YELLOW,
+ Color.WHITE,
STATUS_VALUE_FONT_SIZE,
statusPaint
)
}
- metricsCollector.getMetrics().firstOrNull { it.source.isAtmPressure() }?.let {
+ metricsCollector.getMetric(namesRegistry.getAtmPressurePID())?.let {
marginLeft += getTextWidth(text, statusPaint) + 12F
text = atmPressureLabel
drawText(
@@ -256,7 +262,7 @@ internal abstract class AbstractDrawer (context: Context, protected val settings
text,
marginLeft,
top,
- Color.WHITE,
+ Color.LTGRAY,
STATUS_KEY_FONT_SIZE,
statusPaint
)
@@ -267,7 +273,7 @@ internal abstract class AbstractDrawer (context: Context, protected val settings
"${it.valueToString()}${it.source.command.pid.units}",
marginLeft,
top,
- Color.YELLOW,
+ Color.WHITE,
STATUS_VALUE_FONT_SIZE,
statusPaint
)
diff --git a/screen_renderer/src/main/java/org/obd/graphs/renderer/AbstractSurfaceRenderer.kt b/screen_renderer/src/main/java/org/obd/graphs/renderer/AbstractSurfaceRenderer.kt
index 6dd4bb65..d4bb43e1 100644
--- a/screen_renderer/src/main/java/org/obd/graphs/renderer/AbstractSurfaceRenderer.kt
+++ b/screen_renderer/src/main/java/org/obd/graphs/renderer/AbstractSurfaceRenderer.kt
@@ -19,6 +19,7 @@
package org.obd.graphs.renderer
import android.content.Context
+import android.graphics.Canvas
import android.graphics.Rect
import org.obd.graphs.bl.collector.MetricsCollector
import org.obd.graphs.bl.datalogger.dataLoggerPreferences
@@ -49,6 +50,17 @@ internal abstract class AbstractSurfaceRenderer(
}
}
+ protected fun getArea(area: Rect, canvas: Canvas, margin: Int): Rect {
+ val newArea = Rect()
+ if (area.isEmpty) {
+ newArea[0 + margin, viewSettings.marginTop, canvas.width - 1 - margin] = canvas.height - 1
+ } else {
+ val width = canvas.width - 1 - (margin)
+ newArea[area.left + margin, area.top + viewSettings.marginTop, width] = canvas.height
+ }
+ return newArea
+ }
+
protected fun metrics() = metricsCollector.getMetrics().subList(
0, min(
metricsCollector.getMetrics().size,
diff --git a/screen_renderer/src/main/java/org/obd/graphs/renderer/ScreenSettings.kt b/screen_renderer/src/main/java/org/obd/graphs/renderer/ScreenSettings.kt
index bf56b3f5..2fbc5108 100644
--- a/screen_renderer/src/main/java/org/obd/graphs/renderer/ScreenSettings.kt
+++ b/screen_renderer/src/main/java/org/obd/graphs/renderer/ScreenSettings.kt
@@ -60,6 +60,11 @@ data class DragRacingSettings(
var fontSize: Int = 32
)
+
+data class TripInfoSettings(
+ var fontSize: Int = 24
+)
+
interface ScreenSettings {
fun isPIDsSortOrderEnabled(): Boolean = false
@@ -68,6 +73,9 @@ interface ScreenSettings {
fun getDragRacingSettings(): DragRacingSettings = DragRacingSettings()
+ fun getTripInfoSettings(): TripInfoSettings = TripInfoSettings()
+
+
fun getMaxItems (): Int = 6
fun getGaugeRendererSetting(): GaugeRendererSettings = GaugeRendererSettings()
diff --git a/screen_renderer/src/main/java/org/obd/graphs/renderer/SurfaceRenderer.kt b/screen_renderer/src/main/java/org/obd/graphs/renderer/SurfaceRenderer.kt
index c50f13d3..a66b4863 100644
--- a/screen_renderer/src/main/java/org/obd/graphs/renderer/SurfaceRenderer.kt
+++ b/screen_renderer/src/main/java/org/obd/graphs/renderer/SurfaceRenderer.kt
@@ -26,9 +26,10 @@ import org.obd.graphs.bl.query.Query
import org.obd.graphs.renderer.drag.DragRacingSurfaceRenderer
import org.obd.graphs.renderer.gauge.GaugeSurfaceRenderer
import org.obd.graphs.renderer.giulia.GiuliaSurfaceRenderer
+import org.obd.graphs.renderer.trip.TripSurfaceRenderer
enum class SurfaceRendererType {
- GIULIA, GAUGE, DRAG_RACING
+ GIULIA, GAUGE, DRAG_RACING, TRIP_INFO
}
data class ViewSettings(var marginTop: Int = 0)
@@ -37,6 +38,7 @@ interface SurfaceRenderer {
fun applyMetricsFilter(query: Query)
fun onDraw(canvas: Canvas, drawArea: Rect?)
fun recycle()
+
companion object {
fun allocate(
context: Context,
@@ -50,6 +52,7 @@ interface SurfaceRenderer {
SurfaceRendererType.GAUGE -> GaugeSurfaceRenderer(context, settings, metricsCollector, fps, viewSettings)
SurfaceRendererType.GIULIA -> GiuliaSurfaceRenderer(context, settings, metricsCollector, fps, viewSettings)
SurfaceRendererType.DRAG_RACING -> DragRacingSurfaceRenderer(context, settings, metricsCollector, fps, viewSettings)
+ SurfaceRendererType.TRIP_INFO -> TripSurfaceRenderer(context, settings, metricsCollector, fps, viewSettings)
}
}
}
\ No newline at end of file
diff --git a/screen_renderer/src/main/java/org/obd/graphs/renderer/drag/DragRacingDrawer.kt b/screen_renderer/src/main/java/org/obd/graphs/renderer/drag/DragRacingDrawer.kt
index 0ae366ff..27f41901 100644
--- a/screen_renderer/src/main/java/org/obd/graphs/renderer/drag/DragRacingDrawer.kt
+++ b/screen_renderer/src/main/java/org/obd/graphs/renderer/drag/DragRacingDrawer.kt
@@ -139,7 +139,7 @@ internal class DragRacingDrawer(context: Context, settings: ScreenSettings) : Ab
drawDragRacingEntry(area, dragRacingResults._100_200, "100-200 km/h", rowTop, left, canvas, textSizeBase)
}
- inline fun drawMetric(
+ inline fun drawVehicleSpeed(
canvas: Canvas,
area: Rect,
metric: Metric,
diff --git a/screen_renderer/src/main/java/org/obd/graphs/renderer/drag/DragRacingSurfaceRenderer.kt b/screen_renderer/src/main/java/org/obd/graphs/renderer/drag/DragRacingSurfaceRenderer.kt
index 10bcfc2d..0239f161 100644
--- a/screen_renderer/src/main/java/org/obd/graphs/renderer/drag/DragRacingSurfaceRenderer.kt
+++ b/screen_renderer/src/main/java/org/obd/graphs/renderer/drag/DragRacingSurfaceRenderer.kt
@@ -54,13 +54,14 @@ internal class DragRacingSurfaceRenderer(
val dragRaceResults = dragRacingResultRegistry.getResult()
dragRacingDrawer.drawBackground(canvas, it)
- val margin = if (settings.getDragRacingSettings().shiftLightsEnabled || dragRaceResults.readyToRace) SHIFT_LIGHTS_WIDTH else 0
+ val dragRacingSettings = settings.getDragRacingSettings()
+ val margin = if (dragRacingSettings.shiftLightsEnabled || dragRaceResults.readyToRace) SHIFT_LIGHTS_WIDTH else 0
val area = getArea(it, canvas, margin)
var top = getDrawTop(area)
var left = dragRacingDrawer.getMarginLeft(area.left.toFloat())
- if (settings.getDragRacingSettings().shiftLightsEnabled) {
- dragRacingResultRegistry.setShiftLightsRevThreshold(settings.getDragRacingSettings().shiftLightsRevThreshold)
+ if (dragRacingSettings.shiftLightsEnabled) {
+ dragRacingResultRegistry.setShiftLightsRevThreshold(dragRacingSettings.shiftLightsRevThreshold)
// permanent white boxes
dragRacingDrawer.drawShiftLights(canvas, area, blinking = false)
}
@@ -76,14 +77,14 @@ internal class DragRacingSurfaceRenderer(
left += 5
if (settings.isStatusPanelEnabled()) {
- dragRacingDrawer.drawStatusPanel(canvas, top, left, fps, metricsCollector)
+ dragRacingDrawer.drawStatusPanel(canvas, top, left, fps, metricsCollector, drawContextInfo = settings.getDragRacingSettings().contextInfoEnabled)
top += 4
dragRacingDrawer.drawDivider(canvas, left, area.width().toFloat(), top, Color.DKGRAY)
top += 40
}
metricsCollector.getMetrics().firstOrNull { it.source.isVehicleSpeed() }?.let {
- top = dragRacingDrawer.drawMetric(
+ top = dragRacingDrawer.drawVehicleSpeed(
canvas = canvas,
area = area,
metric = it,
@@ -101,17 +102,6 @@ internal class DragRacingSurfaceRenderer(
}
}
- private fun getArea(area: Rect, canvas: Canvas, margin: Int) : Rect {
- val newArea = Rect()
- if (area.isEmpty) {
- newArea[0 + margin, viewSettings.marginTop, canvas.width - 1 - margin] = canvas.height - 1
- } else {
- val width = canvas.width - 1 - (margin)
- newArea[area.left + margin, area.top + viewSettings.marginTop, width] = canvas.height
- }
- return newArea
- }
-
private fun isShiftLight(dragRaceResults: DragRacingResults) =
settings.getDragRacingSettings().shiftLightsEnabled && dragRaceResults.enableShiftLights
diff --git a/screen_renderer/src/main/java/org/obd/graphs/renderer/trip/TripDrawer.kt b/screen_renderer/src/main/java/org/obd/graphs/renderer/trip/TripDrawer.kt
new file mode 100644
index 00000000..cf1546ad
--- /dev/null
+++ b/screen_renderer/src/main/java/org/obd/graphs/renderer/trip/TripDrawer.kt
@@ -0,0 +1,378 @@
+/**
+ * Copyright 2019-2024, Tomasz Żebrowski
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ **/
+package org.obd.graphs.renderer.trip
+
+import android.content.Context
+import android.graphics.*
+import org.obd.graphs.bl.collector.Metric
+import org.obd.graphs.bl.collector.MetricsBuilder
+import org.obd.graphs.renderer.AbstractDrawer
+import org.obd.graphs.renderer.ScreenSettings
+import org.obd.graphs.renderer.drag.MARGIN_END
+import org.obd.metrics.api.model.ObdMetric
+
+private const val CURRENT_MIN = 22f
+private const val CURRENT_MAX = 72f
+private const val NEW_MAX = 1.6f
+private const val NEW_MIN = 0.6f
+
+@Suppress("NOTHING_TO_INLINE")
+internal class TripDrawer(context: Context, settings: ScreenSettings) : AbstractDrawer(context, settings) {
+
+ private val metricBuilder = MetricsBuilder()
+
+ inline fun drawScreen(
+ canvas: Canvas,
+ area: Rect,
+ left: Float,
+ top: Float,
+ tripInfo: TripInfoDetails
+ ) {
+
+ val (textSizeBase) = calculateFontSize(area)
+
+ val x = 135
+ var rowTop = top + 12f
+ drawMetric(tripInfo.airTemp!!, top = rowTop, left = left, canvas, textSizeBase, statsEnabled = true)
+ drawMetric(tripInfo.coolantTemp!!, rowTop, left + 1 * x, canvas, textSizeBase, statsEnabled = true)
+ drawMetric(tripInfo.oilTemp!!, rowTop, left + 2 * x, canvas, textSizeBase, statsEnabled = true)
+ drawMetric(tripInfo.exhaustTemp!!, rowTop, left + 3 * x, canvas, textSizeBase, statsEnabled = true)
+ drawMetric(tripInfo.gearboxOilTemp!!, rowTop, left + 4 * x, canvas, textSizeBase, statsEnabled = true)
+ drawMetric(diff(tripInfo.distance!!), rowTop, left + 5 * x, canvas, textSizeBase)
+
+ //second row
+ rowTop = top + (textSizeBase) + 52f
+ drawMetric(tripInfo.fuellevel!!, rowTop, left, canvas, textSizeBase)
+ drawMetric(diff(tripInfo.fuelConsumed!!), rowTop, left + 1 * x, canvas, textSizeBase)
+ drawMetric(tripInfo.fuelConsumption!!, rowTop, left + 2 * x, canvas, textSizeBase, statsEnabled = true, unitEnabled = false)
+ drawMetric(tripInfo.gearboxEngaged!!, rowTop, left + 3 * x, canvas, textSizeBase)
+ drawMetric(tripInfo.oilLevel!!, rowTop, left + 4 * x, canvas, textSizeBase, statsEnabled = true)
+ drawMetric(tripInfo.totalMisfires!!, rowTop, left + 5 * x, canvas, textSizeBase, unitEnabled = false)
+
+ drawDivider(canvas, left, area.width().toFloat(), rowTop + textSizeBase + 2, Color.DKGRAY)
+
+ //metrics
+ rowTop += 2.2f * textSizeBase
+ drawMetric(canvas, area, tripInfo.intakePressure!!, left, rowTop)
+ drawMetric(canvas, area, tripInfo.torque!!, left + getAreaWidth(area) + 10, rowTop)
+ }
+
+ private fun diff(metric: Metric) : Metric {
+ val value: Number? = if (metric.source.value == null){
+ null
+ } else {
+ metric.max - metric.min
+ }
+
+ return metricBuilder.buildFor(ObdMetric.builder()
+ .command(metric.source.command)
+ .value(value).build())
+ }
+
+ private inline fun calculateFontSize(
+ area: Rect
+ ): Pair {
+
+ val scaleRatio = valueScaler.scaleToNewRange(
+ settings.getTripInfoSettings().fontSize.toFloat(),
+ CURRENT_MIN,
+ CURRENT_MAX,
+ NEW_MIN,
+ NEW_MAX
+ )
+
+ val areaWidth = area.width()
+ val valueTextSize = (areaWidth / 17f) * scaleRatio
+ val textSizeBase = (areaWidth / 22f) * scaleRatio
+ return Pair(valueTextSize, textSizeBase)
+ }
+
+ private inline fun drawMetric(
+ canvas: Canvas,
+ area: Rect,
+ metric: Metric,
+ left: Float,
+ top: Float
+ ): Float {
+
+ val (valueTextSize, textSizeBase) = calculateFontSize(area)
+
+ var top1 = top
+ var left1 = left
+
+ drawTitle(
+ canvas,
+ metric,
+ left1,
+ top1,
+ textSizeBase
+ )
+
+
+ drawValue(
+ canvas,
+ metric,
+ top1 + 44,
+ valueTextSize,
+ left = left + getAreaWidth(area) - 50f
+ )
+
+ top1 += 52f
+
+ if (settings.isStatisticsEnabled()) {
+ val tt = textSizeBase * 0.6f
+ if (metric.source.command.pid.historgam.isMinEnabled) {
+ left1 = drawText(
+ canvas,
+ "min",
+ left,
+ top1,
+ Color.LTGRAY,
+ tt * 0.8f,
+ valuePaint
+ )
+ left1 = drawText(
+ canvas,
+ metric.toNumber(metric.min),
+ left1,
+ top1,
+ Color.LTGRAY,
+ tt,
+ valuePaint
+ )
+ }
+ if (metric.source.command.pid.historgam.isMaxEnabled) {
+ left1 = drawText(
+ canvas,
+ "max",
+ left1,
+ top1,
+ Color.LTGRAY,
+ tt * 0.8f,
+ valuePaint
+ )
+ drawText(
+ canvas,
+ metric.toNumber(metric.max),
+ left1,
+ top1,
+ Color.LTGRAY,
+ tt,
+ valuePaint
+ )
+ }
+
+
+ top1 += getTextHeight("min", paint) / 2
+ }
+
+ top1 += 4f
+
+ drawProgressBar(
+ canvas,
+ left,
+ getAreaWidth(area), top1, metric,
+ color = settings.getColorTheme().progressColor
+ )
+
+ top1 += calculateDividerSpacing()
+
+ drawDivider(
+ canvas,
+ left, getAreaWidth(area), top1,
+ color = settings.getColorTheme().dividerColor
+ )
+
+ top1 += 10f + (textSizeBase).toInt()
+ return top1
+ }
+
+ private inline fun calculateDividerSpacing(): Int = 14
+ private inline fun getAreaWidth(area: Rect): Float = area.width().toFloat() / 2
+
+ private fun drawProgressBar(
+ canvas: Canvas,
+ left: Float,
+ width: Float,
+ top: Float,
+ it: Metric,
+ color: Int
+ ) {
+ paint.color = color
+
+ val progress = valueScaler.scaleToNewRange(
+ it.source.value?.toFloat() ?: it.source.command.pid.min.toFloat(),
+ it.source.command.pid.min.toFloat(), it.source.command.pid.max.toFloat(), left, left + width - MARGIN_END
+ )
+
+ canvas.drawRect(
+ left - 6,
+ top + 4,
+ progress,
+ top + calculateProgressBarHeight(),
+ paint
+ )
+ }
+
+ private fun drawValue(
+ canvas: Canvas,
+ metric: Metric,
+ top: Float,
+ textSize: Float,
+ left: Float,
+ ) {
+
+ valuePaint.typeface = Typeface.create(Typeface.DEFAULT, Typeface.NORMAL)
+ valuePaint.color = Color.WHITE
+
+ valuePaint.setShadowLayer(80f, 0f, 0f, Color.WHITE)
+ valuePaint.textSize = textSize
+ valuePaint.textAlign = Paint.Align.RIGHT
+ val text = metric.source.valueToString()
+ canvas.drawText(text, left, top, valuePaint)
+
+ valuePaint.color = Color.LTGRAY
+ valuePaint.textAlign = Paint.Align.LEFT
+ valuePaint.textSize = (textSize * 0.4).toFloat()
+ canvas.drawText(metric.source.command.pid.units, (left + 2), top, valuePaint)
+ }
+
+ private fun drawValue(
+ canvas: Canvas,
+ metric: Metric,
+ top: Float,
+ textSize: Float,
+ left: Float,
+ typeface: Typeface = Typeface.create(Typeface.DEFAULT, Typeface.NORMAL),
+ color: Int = Color.WHITE,
+ statsEnabled: Boolean,
+ unitEnabled: Boolean
+
+ ) {
+
+ valuePaint.typeface = typeface
+ valuePaint.color = color
+
+ valuePaint.setShadowLayer(80f, 0f, 0f, Color.WHITE)
+ valuePaint.textSize = textSize
+ val text = metric.source.valueToString()
+ canvas.drawText(text, left, top, valuePaint)
+ var textWidth = getTextWidth(text, valuePaint) + 2
+
+ if (unitEnabled) {
+ valuePaint.color = Color.LTGRAY
+ valuePaint.textSize = (textSize * 0.4).toFloat()
+ canvas.drawText(metric.source.command.pid.units, (left + textWidth), top, valuePaint)
+ textWidth += getTextWidth(metric.source.command.pid.units, valuePaint) + 2
+
+ }
+
+ if (settings.isStatisticsEnabled() && statsEnabled) {
+ valuePaint.color = Color.LTGRAY
+ valuePaint.textSize = (textSize * 0.65).toFloat()
+ canvas.drawText(metric.toNumber(metric.min), (left + textWidth), top, valuePaint)
+ canvas.drawText(metric.toNumber(metric.max), (left + textWidth), top - 20, valuePaint)
+ }
+ }
+
+ private fun calculateProgressBarHeight() = 16
+
+ private inline fun drawMetric(
+ metric: Metric,
+ top: Float,
+ left: Float,
+ canvas: Canvas,
+ textSizeBase: Float,
+ statsEnabled: Boolean = false,
+ unitEnabled: Boolean = true
+ ) {
+
+ drawValue(
+ canvas,
+ metric,
+ top = top,
+ textSize = textSizeBase * 0.8f,
+ left = left,
+ color = Color.WHITE,
+ typeface = Typeface.create(Typeface.DEFAULT, Typeface.NORMAL),
+ statsEnabled = statsEnabled,
+ unitEnabled = unitEnabled
+
+ )
+
+ drawTitle(canvas, metric, left, top + 24, textSizeBase * 0.35F)
+ }
+
+ private fun drawTitle(
+ canvas: Canvas,
+ metric: Metric,
+ left: Float,
+ top: Float,
+ textSize: Float
+ ) {
+
+ var top1 = top
+ titlePaint.textSize = textSize
+ titlePaint.typeface = Typeface.create(Typeface.DEFAULT, Typeface.NORMAL)
+
+ val description = if (metric.source.command.pid.longDescription == null || metric.source.command.pid.longDescription.isEmpty()) {
+ metric.source.command.pid.description
+ } else {
+ metric.source.command.pid.longDescription
+ }
+
+ if (settings.isBreakLabelTextEnabled()) {
+
+ val text = description.split("\n")
+ if (text.size == 1) {
+ canvas.drawText(
+ text[0],
+ left,
+ top,
+ titlePaint
+ )
+
+ } else {
+ titlePaint.textSize = textSize
+ var vPos = top
+ text.forEach {
+ canvas.drawText(
+ it,
+ left,
+ vPos,
+ titlePaint
+ )
+ vPos += titlePaint.textSize
+
+ }
+ top1 += titlePaint.textSize
+
+ }
+
+ } else {
+ val text = description.replace("\n", " ")
+ canvas.drawText(
+ text,
+ left,
+ top,
+ titlePaint
+ )
+ }
+ }
+}
\ No newline at end of file
diff --git a/screen_renderer/src/main/java/org/obd/graphs/renderer/trip/TripInfoDetails.kt b/screen_renderer/src/main/java/org/obd/graphs/renderer/trip/TripInfoDetails.kt
new file mode 100644
index 00000000..0c731df2
--- /dev/null
+++ b/screen_renderer/src/main/java/org/obd/graphs/renderer/trip/TripInfoDetails.kt
@@ -0,0 +1,22 @@
+package org.obd.graphs.renderer.trip
+
+import org.obd.graphs.bl.collector.Metric
+
+data class TripInfoDetails(
+ var ambientTemp: Metric? = null,
+ var atmPressure: Metric? = null,
+ var totalMisfires: Metric? = null,
+ var fuellevel: Metric? = null,
+ var fuelConsumption: Metric? = null,
+ var oilTemp: Metric? = null,
+ var coolantTemp: Metric? = null,
+ var airTemp: Metric? = null,
+ var exhaustTemp: Metric? = null,
+ var gearboxOilTemp: Metric? = null,
+ var gearboxEngaged: Metric? = null,
+ var oilLevel: Metric? = null,
+ var intakePressure: Metric? = null,
+ var torque: Metric? = null,
+ var distance: Metric? = null,
+ var fuelConsumed: Metric? = null
+)
\ No newline at end of file
diff --git a/screen_renderer/src/main/java/org/obd/graphs/renderer/trip/TripSurfaceRenderer.kt b/screen_renderer/src/main/java/org/obd/graphs/renderer/trip/TripSurfaceRenderer.kt
new file mode 100644
index 00000000..32500112
--- /dev/null
+++ b/screen_renderer/src/main/java/org/obd/graphs/renderer/trip/TripSurfaceRenderer.kt
@@ -0,0 +1,100 @@
+/**
+ * Copyright 2019-2024, Tomasz Żebrowski
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ **/
+package org.obd.graphs.renderer.trip
+
+import android.content.Context
+import android.graphics.Canvas
+import android.graphics.Color
+import android.graphics.Rect
+import org.obd.graphs.bl.collector.MetricsCollector
+import org.obd.graphs.bl.query.*
+import org.obd.graphs.renderer.*
+
+
+@Suppress("NOTHING_TO_INLINE")
+internal class TripSurfaceRenderer(
+ context: Context,
+ settings: ScreenSettings,
+ metricsCollector: MetricsCollector,
+ fps: Fps,
+ viewSettings: ViewSettings
+) : AbstractSurfaceRenderer(settings, context, fps, metricsCollector, viewSettings) {
+ private val tripInfo = TripInfoDetails()
+ private val tripDrawer = TripDrawer(context, settings)
+ override fun applyMetricsFilter(query: Query) {
+ metricsCollector.applyFilter(
+ enabled = query.getIDs()
+ )
+ }
+
+ override fun onDraw(canvas: Canvas, drawArea: Rect?) {
+
+ drawArea?.let { it ->
+
+ tripDrawer.drawBackground(canvas, it)
+
+ val margin = 0
+ val area = getArea(it, canvas, margin)
+ var top = getDrawTop(area)
+ var left = tripDrawer.getMarginLeft(area.left.toFloat())
+
+ left += 5
+
+ if (settings.isStatusPanelEnabled()) {
+ tripDrawer.drawStatusPanel(canvas, top, left, fps, metricsCollector, drawContextInfo = true)
+ top += 4
+ tripDrawer.drawDivider(canvas, left, area.width().toFloat(), top, Color.DKGRAY)
+ top += 40
+ }
+
+ tripDrawer.drawScreen(
+ canvas = canvas,
+ area = area,
+ left = left,
+ top = top,
+ tripInfo = tripInfo.apply {
+ airTemp = metricsCollector.getMetric(namesRegistry.getAirTempPID())
+ totalMisfires = metricsCollector.getMetric(namesRegistry.getTotalMisfiresPID())
+ ambientTemp = metricsCollector.getMetric(namesRegistry.getAmbientTempPID())
+ atmPressure = metricsCollector.getMetric(namesRegistry.getAtmPressurePID())
+ fuellevel = metricsCollector.getMetric(namesRegistry.getFuelLevelPID())
+ fuelConsumption = metricsCollector.getMetric(namesRegistry.getFuelConsumptionPID())
+ coolantTemp = metricsCollector.getMetric(namesRegistry.getCoolantTempPID())
+ exhaustTemp = metricsCollector.getMetric(namesRegistry.getExhaustTempPID())
+ oilTemp = metricsCollector.getMetric(namesRegistry.getOilTempPID())
+ gearboxOilTemp = metricsCollector.getMetric(namesRegistry.getGearboxOilTempPID())
+ gearboxEngaged = metricsCollector.getMetric(namesRegistry.getGearboxEngagedPID())
+ oilLevel = metricsCollector.getMetric(namesRegistry.getOilLevelPID())
+ torque = metricsCollector.getMetric(namesRegistry.getTorquePID())
+ intakePressure = metricsCollector.getMetric(namesRegistry.getIntakePressurePID())
+ distance = metricsCollector.getMetric(namesRegistry.getDistancePID())
+ fuelConsumed = metricsCollector.getMetric(namesRegistry.getFuelConsumedPID())
+ }
+ )
+ }
+ }
+
+ override fun recycle() {
+ tripDrawer.recycle()
+ }
+
+ init {
+ applyMetricsFilter(Query.instance(QueryStrategyType.TRIP_INFO_QUERY))
+ }
+}
\ No newline at end of file