Add persistent consumption and charging dashboards

This commit is contained in:
TCFDONMEZ
2026-09-30 11:17:54 +03:00
parent 69ef0eeef6
commit 25abf0da5b
18 changed files with 323 additions and 84 deletions
@@ -584,6 +584,21 @@ object EVHardware {
return volts * amps / 1_000f
}
/** Raw pack voltage/current used by the OEM charging screen; read-only, SWI68/69. */
fun getVendorBatteryVoltageV(): Float? {
val gen = FirmwareInfo.getGeneration()
if (gen != FirmwareInfo.Gen.SWI68 && gen != FirmwareInfo.Gen.SWI69) return null
return getFloatPropertyCPM(PROP_BMS_PACK_VOLT_SWI68, AREA_GLOBAL)
?.takeIf { it.isFinite() && it in PACK_VOLTAGE_RANGE }
}
fun getVendorBatteryCurrentA(): Float? {
val gen = FirmwareInfo.getGeneration()
if (gen != FirmwareInfo.Gen.SWI68 && gen != FirmwareInfo.Gen.SWI69) return null
return getFloatPropertyCPM(PROP_BMS_PACK_CURRENT_SWI68, AREA_GLOBAL)
?.takeIf { it.isFinite() && kotlin.math.abs(it) <= MAX_PACK_CURRENT_A }
}
/** Vendor range fallback; SWI68 and SWI69 both publish it on the same id. */
fun getVendorRangeKm(): Int? =
if (FirmwareInfo.getGeneration() == FirmwareInfo.Gen.SWI68 ||
@@ -31,6 +31,8 @@ data class EnergySnapshot(
val parked: Boolean?,
val climate: ClimateSnapshot,
val tirePressures: TirePressureSnapshot,
val batteryVoltageV: Float? = null,
val batteryCurrentA: Float? = null,
) {
val hasVehicleData: Boolean
get() = socPercent != null || rangeKm != null || speedKmh != null ||
@@ -26,6 +26,8 @@ interface EnergySignalSource {
fun vehicleConsumedKwh(): Float? = null
fun vehicleRegeneratedKwh(): Float? = null
fun parked(): Boolean?
fun batteryVoltageV(): Float? = null
fun batteryCurrentA(): Float? = null
fun climate(): ClimateSnapshot
fun tirePressures(): TirePressureSnapshot
/** Probe-only values excluded from [EnergySnapshot] and normal consumers. */
@@ -66,6 +68,8 @@ class EvHardwareEnergySignalSource(context: Context) : EnergySignalSource {
override fun vehicleConsumedKwh() = SaicCharging.consumedKwhSinceCharge()
override fun vehicleRegeneratedKwh() = SaicCharging.regeneratedKwhSinceCharge()
override fun parked() = EVHardware.isVehicleInPark()
override fun batteryVoltageV() = EVHardware.getVendorBatteryVoltageV()
override fun batteryCurrentA() = EVHardware.getVendorBatteryCurrentA()
override fun tirePressures() = TirePressureSnapshot(
frontLeftKpa = EVHardware.getTirePressureKpa(EVHardware.Wheel.FRONT_LEFT),
frontRightKpa = EVHardware.getTirePressureKpa(EVHardware.Wheel.FRONT_RIGHT),
@@ -122,6 +126,8 @@ class EnergyTelemetryReader(private val source: EnergySignalSource) {
parked = source.parked(),
climate = source.climate(),
tirePressures = source.tirePressures(),
batteryVoltageV = source.batteryVoltageV()?.takeIf { it.isFinite() },
batteryCurrentA = source.batteryCurrentA()?.takeIf { it.isFinite() },
)
/** Reads CP-004 candidates only when an unstable evidence capture explicitly requests them. */