diff --git a/AGENTS.md b/AGENTS.md index 3ef26ce..ca065a1 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -74,7 +74,7 @@ Repository: `ssh://git@git.stinnesbeck.com:2222/nils/mg4.git` (remote `origin`), | Live data | on/off, ABRP API key and user token, upload frequency | | Server | URL, pairing by QR, ingest token, installation ID (read-only), config import | | Settings | full screen, voice key, Overview style with the accent colour beside it, the Mascot character (only for that style) (offered only for styles drawn in it, `OverviewStyle.usesAccent`; Retro and Terminal add "Original" for their own palette, `hasOriginal`), tyre unit, battery, charging price, version, update check, install from USB, About | -| Logs | ACC recorder (`AccRecorder`/`AccRecording`: every property and vendor getter via `VendorSurfaceProbe.capture`, again and again for 3 minutes, plus steering-wheel key broadcasts; lists what changed, rarest first; saved to the app and a USB stick), adaptive cruise control debug log (`CruiseLog`: the raw driver-assistance properties from `EVHardware.readAccDebug`, once a second; a line on change and every 2 s while driving; last 600 in a file), update log (every install step, with the platform's words), upload log | +| Logs | signal recorder (`SignalRecorder`/`SignalRecording`: every property and vendor getter via `VendorSurfaceProbe.capture`, again and again for 3 minutes, plus steering-wheel key broadcasts; lists what changed, rarest first; saved to the app and a USB stick; how to find where the car publishes something), update log (every install step, with the platform's words), upload log | Key classes (`app/src/main/java/com/evsuite/abrp/`): `AbrpUploadService` (foreground service, 15 s tick), `TelemetryUploader` (+ `TelemetryQueue`, persisted), `TelemetryPayload` (server diff --git a/EVHardware/lib/src/main/java/com/evsuite/hardware/CarPropertyEvidence.kt b/EVHardware/lib/src/main/java/com/evsuite/hardware/CarPropertyEvidence.kt index 7c57009..d894e51 100644 --- a/EVHardware/lib/src/main/java/com/evsuite/hardware/CarPropertyEvidence.kt +++ b/EVHardware/lib/src/main/java/com/evsuite/hardware/CarPropertyEvidence.kt @@ -172,9 +172,6 @@ object ReadFailureLog { lastReason.put(key, reason) != reason } - /** Why [key] last failed, or null when it answered (or was never read). */ - fun reason(key: String): String? = synchronized(lock) { lastReason[key] } - /** A property that starts answering again must not silence its next failure. */ fun clear(key: String) { synchronized(lock) { lastReason.remove(key) } diff --git a/EVHardware/lib/src/main/java/com/evsuite/hardware/EVHardware.kt b/EVHardware/lib/src/main/java/com/evsuite/hardware/EVHardware.kt index 0153836..90733a5 100644 --- a/EVHardware/lib/src/main/java/com/evsuite/hardware/EVHardware.kt +++ b/EVHardware/lib/src/main/java/com/evsuite/hardware/EVHardware.kt @@ -427,59 +427,6 @@ object EVHardware { private const val PROP_CCU_ONBD_PLUG = 0x2140F43E // vendor int, AC socket private const val PROP_CCU_OFFBD_PLUG = 0x2140F43F // vendor int, DC socket private const val PROP_ENERGY_SINCE_CHARGE = 0x2160A1BB // vendor float kWh - /** - * `AAD_EPTCCTRGTSPD` in the head unit's `CarAdvancedAssistedDrivingManager`: by its name the - * powertrain's cruise control target speed. Unit and the value while cruise control is off - * are not established; it is passed on raw. - */ - private const val PROP_CRUISE_TARGET_SPEED = 0x2160A15B // vendor float - - /** - * The other driver-assistance properties of `CarAdvancedAssistedDrivingManager` that may - * say what the adaptive cruise control is doing, read raw for the Logs tab while their - * meaning is established on the car: the operation mode of traffic-jam / intelligent - * cruise assist (`LANE_TJAICAOPMD`, by the manager 0 no request, 1 object following, - * 2 lane centre, 3 combined), the speed assist (`SPEED_ASST_SYS`, `SPEED_ASST_MODE`, by the - * manager 0 off, 2 manual limiter, 3 intelligent), the traffic-jam assist switch, and the - * object the ACC follows (`ACC_OBJ_*`: existence probability, longitudinal distance and - * relative speed). - */ - private val ACC_DEBUG_PROPS = listOf( - AccDebugProp("cc", PROP_CRUISE_TARGET_SPEED, float = true), - AccDebugProp("ica", 0x2140A12A, float = false), // AAD_LANE_TJAICAOPMD - AccDebugProp("tja", 0x2140A107, float = false), // AAD_TRAFFIC_JAM_ASST_SYS - AccDebugProp("sas", 0x2140A101, float = false), // AAD_SPEED_ASST_SYS - AccDebugProp("sam", 0x2140A102, float = false), // AAD_SPEED_ASST_MODE - AccDebugProp("obj", 0x2160A12F, float = true), // AAD_ACC_OBJ_EXIST_PRBLTY - AccDebugProp("dist", 0x2160A12C, float = true), // AAD_ACC_OBJ_LONG_RLTV_DIST - AccDebugProp("rel", 0x2160A12E, float = true), // AAD_ACC_OBJ_LONG_RLTV_SPD - ) - - private class AccDebugProp(val name: String, val id: Int, val float: Boolean) - - /** The cruise control target speed as the car reports it, unmapped; null when unread. */ - fun getCruiseTargetSpeedRaw(): Float? = supportedTelemetryRead { - getFloatPropertyCPM(PROP_CRUISE_TARGET_SPEED, AREA_GLOBAL)?.takeIf { it.isFinite() } - } - - /** - * The driver-assistance properties above, one raw reading each, for debugging the adaptive - * cruise control on the car: name to value (floats to two decimals), or to "unread" with - * the reason the car gave. Read only; about eight calls, so not on the main thread. - */ - fun readAccDebug(): List> = ACC_DEBUG_PROPS.map { prop -> - val value: Any? = supportedTelemetryRead { - if (prop.float) getFloatPropertyCPM(prop.id, AREA_GLOBAL)?.takeIf { it.isFinite() } - else readPropertyCPM(prop.id, AREA_GLOBAL, Int::class.javaObjectType) { sCpmGetIntMethod } as? Int - } - prop.name to when (value) { - is Float -> String.format(java.util.Locale.US, "%.2f", value) - null -> "unread" + (ReadFailureLog.reason( - "0x${Integer.toHexString(prop.id)}@0x${Integer.toHexString(AREA_GLOBAL)}") - ?.let { " ($it)" } ?: "") - else -> value.toString() - } - } /** * `HVAC_AMBIENT_TEMPERATURE`, the one in-car candidate left on this firmware. diff --git a/EVHardware/lib/src/main/java/com/evsuite/hardware/telemetry/EnergySnapshot.kt b/EVHardware/lib/src/main/java/com/evsuite/hardware/telemetry/EnergySnapshot.kt index c792730..7fd5cab 100644 --- a/EVHardware/lib/src/main/java/com/evsuite/hardware/telemetry/EnergySnapshot.kt +++ b/EVHardware/lib/src/main/java/com/evsuite/hardware/telemetry/EnergySnapshot.kt @@ -50,8 +50,6 @@ data class EnergySnapshot( val regenLevelRaw: Int? = null, /** The gear's raw code (MG4 SWI68: 1 P, 2 R, 3 N, 4 D); null where the car did not answer. */ val gearRaw: Int? = null, - /** Cruise control target speed as reported (`0x2160A15B`), unit not established; null unread. */ - val cruiseTargetSpeedRaw: Float? = null, ) { val hasVehicleData: Boolean get() = socPercent != null || rangeKm != null || speedKmh != null || @@ -61,7 +59,7 @@ data class EnergySnapshot( vehicleConsumedKwh != null || vehicleRegeneratedKwh != null || parked != null || climate.hasData || tirePressures.hasData || widestWindowPercent != null || driveModeRaw != null || regenLevelRaw != null || - gearRaw != null || cruiseTargetSpeedRaw != null + gearRaw != null } data class TirePressureSnapshot( diff --git a/EVHardware/lib/src/main/java/com/evsuite/hardware/telemetry/EnergyTelemetryReader.kt b/EVHardware/lib/src/main/java/com/evsuite/hardware/telemetry/EnergyTelemetryReader.kt index 0c70ba2..1ba47b7 100644 --- a/EVHardware/lib/src/main/java/com/evsuite/hardware/telemetry/EnergyTelemetryReader.kt +++ b/EVHardware/lib/src/main/java/com/evsuite/hardware/telemetry/EnergyTelemetryReader.kt @@ -29,8 +29,6 @@ interface EnergySignalSource { fun parked(): Boolean? /** The gear's raw code (MG4 SWI68: 1 P, 2 R, 3 N, 4 D). Null where unread. */ fun gearRaw(): Int? = null - /** The cruise control target speed, raw (unit not established). Null where unread. */ - fun cruiseTargetSpeedRaw(): Float? = null fun batteryVoltageV(): Float? = null fun batteryCurrentA(): Float? = null /** Widest window opening in percent; null where the firmware has no read. */ @@ -79,7 +77,6 @@ class EvHardwareEnergySignalSource(context: Context) : EnergySignalSource { override fun vehicleRegeneratedKwh() = SaicCharging.regeneratedKwhSinceCharge() override fun parked() = EVHardware.isVehicleInPark() override fun gearRaw() = EVHardware.getGearRaw() - override fun cruiseTargetSpeedRaw() = EVHardware.getCruiseTargetSpeedRaw() override fun batteryVoltageV() = EVHardware.getVendorBatteryVoltageV() override fun batteryCurrentA() = EVHardware.getVendorBatteryCurrentA() override fun widestWindowPercent() = SaicVehicleControl.widestWindowPercent() @@ -161,7 +158,6 @@ class EnergyTelemetryReader(private val source: EnergySignalSource) { driveModeRaw = source.driveModeRaw(), regenLevelRaw = source.regenLevelRaw(), gearRaw = source.gearRaw(), - cruiseTargetSpeedRaw = source.cruiseTargetSpeedRaw(), ) /** Reads CP-004 candidates only when an unstable evidence capture explicitly requests them. */ diff --git a/LICENSE.md b/LICENSE.md index a73c0c3..e3073fe 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -31,9 +31,7 @@ top. Those are Fatih's reads the car needs and upstream does not have — the ve ids `0x21401553`–`56`, the vendor mileage `0x21401566` for the odometer, the charging status from `0x2140F409`, SoC, range, power, pack voltage and current on SWI69 as on SWI68, and SWI69 speed already in km/h — plus translated comments and, from this fork, the gear's raw code -(`EVHardware.getGearRaw`, `EnergySnapshot.gearRaw`) and the cruise control target speed -(`getCruiseTargetSpeedRaw`, `EnergySnapshot.cruiseTargetSpeedRaw`) with the other driver-assistance -properties read raw for debugging (`readAccDebug`, `ReadFailureLog.reason`). To take upstream again, merge three ways with +(`EVHardware.getGearRaw`, `EnergySnapshot.gearRaw`). To take upstream again, merge three ways with `e4e1158` as the base. The car app links EVHardware into its APK, so the **built app** may only be used and passed on diff --git a/SPECS.md b/SPECS.md index cd8c5d1..be55c75 100644 --- a/SPECS.md +++ b/SPECS.md @@ -70,6 +70,13 @@ tyre pressures, GPS (lat, lon, elevation, heading) and the is_* flags. It does * - **Pack energy (`soe`) and capacity:** not published. The Live dashboard computes energy in pack as SOC × usable capacity, from the hidden dashboard constant `usableKwh` (50.8 kWh for the 51 kWh battery) in `k8s/grafana/dashboards/live.json`. +- **Adaptive cruise control (set speed, distance to the car ahead, ACC state):** the head unit gets + none of it (SWI68, checked 2026-10-25). The `AAD_*` properties of `CarAdvancedAssistedDrivingManager` + exist and answer, but stay at their defaults with ACC engaged behind another car + (`AAD_EPTCCTRGTSPD` `0x2160A15B` 0.0, `AAD_ACC_OBJ_*` 0.0 / -128.0, modes 0). A signal recording + of all 1,194 values while the set speed was 101, 90 and 80 km/h shows none of those numbers + (also tried as m/s, mph and ×2/×10/×16/×64) outside the actual speed, and the ACC buttons send + no key broadcast. Most likely only the instrument cluster has it. ## To do @@ -131,6 +138,18 @@ tyre pressures, GPS (lat, lon, elevation, heading) and the is_* flags. It does * confirmed car facts, app structure, UI conventions, build/test/ship, documents. It replaces upstream's EVABRPUploader text. The test emulator is now in the flake: `nix run .#car-emulator` (Android 9 AOSP at 1920×720, 160 dpi; the car build installs as the system user — checked). +- 2026-10-25 — App 2.32.1 (branch `styles-retro-future`): the cruise control work ends. The ACC + recording of 2.32.0 (ACC set to 101, 90 and 80 km/h, a car ahead) found nothing: see "Signals + the car does not provide". Removed: `CruiseLog` and its section on the Logs tab, and in + EVHardware the set-speed read (`getCruiseTargetSpeedRaw`, `EnergySnapshot.cruiseTargetSpeedRaw`), + `readAccDebug` and `ReadFailureLog.reason` — EVHardware is again as before 2.27.3. The old log + files are deleted on start. The recorder stays as a general tool, renamed **Signal recorder** + (`SignalRecorder`, `SignalRecording`, `signal-recording-