From eaae399c6e49b91993fa708f6911ccb740f3f178 Mon Sep 17 00:00:00 2001 From: Tomek Zebrowski Date: Sun, 21 Jul 2024 15:25:28 +0200 Subject: [PATCH] Add trip info screen --- app/src/main/res/values/strings.xml | 2 + app/src/main/res/xml/preferences.xml | 18 + .../java/org/obd/graphs/aa/CarSettings.kt | 7 + .../org/obd/graphs/aa/screen/CarScreen.kt | 25 +- .../aa/screen/nav/AvailableFeaturesScreen.kt | 8 + .../aa/screen/nav/NavTemplateCarScreen.kt | 2 +- .../graphs/aa/screen/nav/SurfaceController.kt | 13 +- .../obd/graphs/aa/screen/nav/SurfaceScreen.kt | 6 +- automotive/src/main/res/values/strings.xml | 2 + .../collector/InMemoryCarMetricsCollector.kt | 9 +- .../org/obd/graphs/bl/collector/Metric.kt | 4 +- .../obd/graphs/bl/collector/MetricsBuilder.kt | 30 +- .../graphs/bl/collector/MetricsCollector.kt | 2 + .../graphs/bl/generator/MetricsGenerator.kt | 9 +- .../org/obd/graphs/bl/query/ObdMetricExt.kt | 44 +- .../bl/query/QueryStrategyOrchestrator.kt | 1 + .../obd/graphs/bl/query/QueryStrategyType.kt | 1 + .../graphs/bl/query/TripInfoQueryStrategy.kt | 45 +++ .../org/obd/graphs/renderer/AbstractDrawer.kt | 26 +- .../renderer/AbstractSurfaceRenderer.kt | 12 + .../org/obd/graphs/renderer/ScreenSettings.kt | 8 + .../obd/graphs/renderer/SurfaceRenderer.kt | 5 +- .../graphs/renderer/drag/DragRacingDrawer.kt | 2 +- .../drag/DragRacingSurfaceRenderer.kt | 22 +- .../obd/graphs/renderer/trip/TripDrawer.kt | 378 ++++++++++++++++++ .../graphs/renderer/trip/TripInfoDetails.kt | 22 + .../renderer/trip/TripSurfaceRenderer.kt | 100 +++++ 27 files changed, 745 insertions(+), 58 deletions(-) create mode 100644 datalogger/src/main/java/org/obd/graphs/bl/query/TripInfoQueryStrategy.kt create mode 100644 screen_renderer/src/main/java/org/obd/graphs/renderer/trip/TripDrawer.kt create mode 100644 screen_renderer/src/main/java/org/obd/graphs/renderer/trip/TripInfoDetails.kt create mode 100644 screen_renderer/src/main/java/org/obd/graphs/renderer/trip/TripSurfaceRenderer.kt 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