Repository navigation
Log connection events and signal strength in the BLE envelope - #154
Merged
Merged
Conversation
Owner direction (2026-10-08): log the connection state as well, in the envelope, together with the RSSI. - BleRecord gains rssi_dbm (5, optional sint32): the phone's latest RSSI for the car when the record was acquired, absent when unknown. The controller passes the value it already holds for the car into every HistoryStore record call, so status, charge, drive and link records all carry it. - New payload kind link_event (6, first in the oneof): LinkEvent.State CONNECTED when a link becomes ready and LOST when a link that had become ready ends. They go to <vehicleId>.link.pblog through VehicleLogs, with acquired_at as the event time and rssi_dbm as the last RSSI before it. A connection attempt that never became ready logs nothing, so a car out of range does not spam the log. LOST is also written when the app itself closes a ready link (tracking switched off, a car that moved to a new address); a killed app writes nothing. Log only: no read model or UI. - The held-back status flush is gone: StatusLogGate, its test and HistoryStore.onLinkLost are removed. A LOST event marks when watching ended, and the last logged status holds until then. shouldLogStatus is unchanged; HistoryStore keeps a plain last-logged map, seeded on load as before. - HistoryStore reads the link files on load only to refresh the record counts its 20k cap trims by, as it does for the other kinds; without it the cap would not hold across restarts. - VehicleLink sits two lines under detekt's LargeClass cap, so the RSSI and link helpers live next to updateConnection in the controller, and the recordStatus call is a one-liner like the other two record calls. The wire-order test pins tags 5 and 6, a ProtoLog round trip covers link events with rssi_dbm, and a record without rssi_dbm reads it as absent. The newer-payload test moves to field 7, since field 5 is now taken. ADR-0008, PRIVACY.md and the master plan record the change. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0129RzhbEE2cboMcYyZMuxqX
Contributor
ScreenshotsCaptured from the demo build at a8b5abb. Debug APK: zip from Android CI (GitHub sign-in needed) |
Owner renames for #154, asked for on 2026-10-08 before it merges. Field numbers and types do not change, so the wire format is the same. - BleRecord.rssi_dbm becomes rssi (still field 5, optional sint32; the proto comment says the value is in dBm). The Kotlin parameters are rssi, and the controller helper is latestRssi(address). - "link" becomes "connection": LinkEvent is ConnectionEvent, link_event is connection_event (still field 6), <vehicleId>.link.pblog is <vehicleId>.connection.pblog, and recordLink is recordConnection in the controller and in HistoryStore. VehicleLink and ConnectionPhase keep their names. - LinkEvent.State.LOST becomes ConnectionEvent.State.DISCONNECTED (still 2): the event is also logged when the app closes the connection itself, so "lost" was the wrong word. CONNECTED is unchanged. The recordStatus call takes latestRssi(address) through a local, and the test fixtures share connected/disconnected values, so no line passes 140 columns. ADR-0008, PRIVACY.md and the master plan use the new names. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0129RzhbEE2cboMcYyZMuxqX
Contributor
ScreenshotsCaptured from the demo build at efacbeb. Debug APK: zip from Android CI (GitHub sign-in needed) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.


Summary
Follows #148 and #149 (the
BleRecordenvelope). Owner direction, 2026-10-08: "We should log connection state as well. Could be added to the envelope, together with RSSI?" No tracking issue.BleRecord.rssi(5,optional sint32, in dBm) is the phone's latest RSSI for the car when the record was acquired, absent when unknown. The controller passes the value it already holds for the car (latestRssi(address)) into eachHistoryStorecall: status, charge, drive and connection.connection_event(6, first in the oneof):ConnectionEvent.StateCONNECTEDwhen a connection becomes ready (wherefirstStatusAfterConnectresets) andDISCONNECTEDwhen a connection that had become ready ends. They go to<vehicleId>.connection.pblogthroughVehicleLogs;acquired_atis the event time andrssithe last RSSI before it. A connection attempt that never became ready logs nothing, so a car out of range does not spam the log. Log only: no read model or UI.StatusLogGate, its test andHistoryStore.onLinkLostare gone: DISCONNECTED marks when watching ended, and the last logged status holds until then.shouldLogStatusis unchanged;HistoryStorekeeps a plain last-logged map, seeded on load as before.PRIVACY.mdand the master plan are updated.Review notes:
VehicleLinksits 2 lines under detekt'sLargeClasscap (700), so the helpers (latestRssi,recordConnection) live next toupdateConnection, and therecordStatuscall stays compact.HistoryStorereads the connection files on load only to refresh the record counts its 20k cap trims by; without it the cap would not hold across restarts.rssinow owns; it uses field 7.rssi_dbmtorssi, link to connection,LOSTtoDISCONNECTED). Field numbers and types are unchanged, and a unit test pins the wire tags.Type
Testing
./gradlew :core:test(174 tests)./gradlew :app:testDebugUnitTest./gradlew :app:lintDebugAlso green:
:app:assembleDebug,ktlintCheck,detekt(one run of the full command on the final commit).New core tests in
BleRecordMappingTest: the wire tags for fields 5 and 6 plus theConnectionEventstate numbers; aProtoLoground trip with connection events andrssi; a record withoutrssireads it as absent (and 0 dBm stays 0).HistoryStoreand the controller wiring have no unit tests (they need an AndroidContext). I droveHistoryStorewith a throwaway JVM harness, not committed, run on the final code: connection and status records land in the right files with the right RSSI, the status policy holds across a restart, and the 20k cap holds across restarts (that test fails without the load-time count refresh). The controller change is read-reviewed only; there is no emulator or car here.Checklist
expected.txtregenerated, not hand-edited (n/a: our own log envelope, not Tesla's protocol; a unit test pins the wire tags)SPDX-License-Identifier: AGPL-3.0-only(no new source files)🤖 Generated with Claude Code
https://claude.ai/code/session_0129RzhbEE2cboMcYyZMuxqX