feat(vehicle): add signed vehicle image retrieval#100
Merged
Conversation
added 3 commits
July 23, 2026 20:56
Wraps the chunked vehicle-image (AP visualization/license-plate) read on Commands, so it works over both the BLE and Fleet API signed transports: one ID request to learn the total size, then paged DATA requests reassembled into the full image bytes.
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.
Intent
Add getVehicleImageState to python-tesla-fleet-api: wrap the chunked vehicle-image (AP visualization wrap / license-plate) read as vehicle_image_state() on the shared Commands class (not VehicleBluetooth-only), so it works over both the BLE and Fleet API signed transports since both VehicleBluetooth and VehicleSigned extend Commands. Design decisions: image metadata (total size) is fetched via one ID request first, then DATA requests page by chunk_size (default 16384) advancing by offset until all bytes are retrieved, reassembled in order and returned as bytes. Added VehicleImageType IntEnum (AUTOPILOT_VISUALIZATION_WRAP=1, LICENSE_PLATE=2) to const.py mirroring the proto VehicleImageStateType enum, since the codebase's convention is custom IntEnum/StrEnum rather than raw protobuf EnumTypeWrapper (which isn't callable, per an existing gotcha with navigation_gps_request). Updated tests/test_proto_coverage_lock.py's allowlist to drop getVehicleImageState now that it is wrapped, and widened that lock test to also check commands.py source (not just bluetooth.py) since this reader intentionally lives in commands.py to be shared across transports, unlike the other GetVehicleData sub-state readers which are BLE-only in bluetooth.py. Added tests/test_vehicle_image_state.py using the existing mocked-BLE-transport pattern, covering: multi-chunk paging and reassembly, a zero-size image making no DATA requests, and confirming VehicleSigned inherits the method. This was scoped as a small standalone PR (out of the earlier full-surface command rollout, where it was deliberately left as a chunking design spike).
What Changed
vehicle_image_state()to shared signed commands for paged vehicle-image retrieval over both BLE and Fleet API transports.VehicleImageTypeand validate chunk sizing, offsets, completeness, and declared image size during reassembly.Risk Assessment
✅ Low: The follow-up fully addresses the prior paging-integrity and chunk-size issues, and the complete change remains well-bounded with no additional material risks found.
Testing
The focused tests and all 449 repository tests passed; manual signed-transport verification captured the metadata-first paging sequence, correct byte reassembly, zero-size behavior, and shared BLE/Fleet API method surface in a reviewer-visible transcript. No screenshot was applicable because this is a Python library API with no rendered UI.
Evidence: Vehicle image state API transcript
vehicle_image_state end-user result: b'abcdefghij' request sequence: 1. ID image_type=1 offset=0 size=0 2. DATA image_type=1 offset=0 size=6 3. DATA image_type=1 offset=6 size=4 shared signed transport surface: VehicleBluetooth callable: True VehicleSigned inherits Commands: True VehicleSigned callable: True zero-size result: b'' requests: 1 (metadata only)Pipeline
Updates from git push no-mistakes
✅ **intent** - passed
✅ No issues found.
✅ **Rebase** - passed
✅ No issues found.
🔧 **Review** - 2 issues found → auto-fixed ✅
tesla_fleet_api/tesla/vehicle/commands.py:1051- An empty DATA response exits the loop and returns incomplete bytes as if retrieval succeeded, violating the method’s full-image contract. Raise an explicit error whenever fewer than total_size bytes are retrieved; also validate asset_data.start_offset (and final length) so missing, repeated, or out-of-order chunks cannot silently produce corrupt output.tesla_fleet_api/tesla/vehicle/commands.py:992- Validate chunk_size as a positive integer before the metadata request. A zero value sends zero-length DATA requests and can return a misleading empty/truncated result; a negative value fails later while constructing the protobuf uint32 field, after an unnecessary network request.🔧 Fix: Validate vehicle image paging and chunk integrity
✅ Re-checked - no issues remain.
✅ **Test** - passed
✅ No issues found.
Inspectedgit diff edc2faf2490f52d27c99a53da650f254b369f0bf..37b74f0bd8af182883c8826c77ab2f3f29751524 -- tesla_fleet_api testsagainst the authoritative intent.Ranuv run pytest tests/test_vehicle_image_state.py tests/test_proto_coverage_lock.py.Ran the complete suite withuv run pytest tests.Ran an end-user-style mocked signed-transport script that calledvehicle_image_state(), decoded the emitted protobuf requests, recorded ID → DATA(0,6) → DATA(6,4), confirmedb'abcdefghij'reassembly, verified the zero-size metadata-only path, and checked availability onVehicleBluetoothandVehicleSigned.Rangit status --shortafter testing to confirm no transient working-tree files remained.✅ **Document** - passed
✅ No issues found.
✅ **Lint** - passed
✅ No issues found.
✅ **Push** - passed
✅ No issues found.