fix(ble): correct climate command protobuf payloads - #51
Merged
Conversation
added 2 commits
July 9, 2026 20:35
Live-verified snapshot->act->verify->restore->confirm against the test car for auto_conditioning_start/stop, set_temps, set_climate_keeper_mode, and set_cabin_overheat_protection. Live-attempted the remaining commands and documented two real vehicle-side constraints discovered in the process (not library bugs): set_cop_temp is rejected "not_supported" on this car, and every remote seat/steering-wheel comfort command is gated by the read-only remote_heater_control_enabled flag. set_bioweapon_mode, remote_seat_cooler_request (no HW on this Model 3), set_preconditioning_max, and set_recirculation (no observable ClimateState field) ship with mocked-transport tests only. Also fixes a real bug found live: remote_seat_heater_request built the proto field name "SEAT_HEATER_MEDIUM" for level=2, but the proto's actual field is "SEAT_HEATER_MED" - medium seat heat has been broken since inception. Locked with a regression test.
Bre77
force-pushed
the
fm/tfa-ble-pr4-climate-m6
branch
from
July 9, 2026 10:36
2344ad6 to
9bb02f5
Compare
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
PR-4 of the BLE production-readiness program: live-verify the CLIMATE command group over BLE against the real test car (m5-btproxy, VIN LRW3F7EK4NC716336), per the master plan report.md PR-4 entry and the resolved decisions in decisions-resolved.md. Climate commands are all INFO-domain, all classified AUTO (snapshot->restore, no physical/mechanical risk) in the plan's safety matrix - this PR is the deliberate 'safest actuation' batch, classified HOLD-FOR-CAPTAIN only because it is the first real live actuation of this command group (same pattern as PR-3 for closures/locks).
Scope: all 15 climate commands listed in the plan's climate table (auto_conditioning_start/stop, set_temps, set_climate_keeper_mode, set_preconditioning_max, set_bioweapon_mode, set_cabin_overheat_protection, set_cop_temp, set_recirculation, remote_seat_heater_request, remote_seat_cooler_request, remote_auto_seat_climate_request, remote_steering_wheel_heater_request, remote_steering_wheel_heat_level_request, remote_auto_steering_wheel_heat_climate_request).
Deliberate per-command outcomes (all discovered live, not code changes I chose arbitrarily):
Bug found and fixed live: remote_seat_heater_request's medium level (seat_heater_level=2) built the protobuf field name 'SEAT_HEATER_MEDIUM', but the proto's actual oneof field is 'SEAT_HEATER_MED' (proto/car_server.proto) - this raised AttributeError at call time (not caught by pyright, since it's a dict-of-string-keys-expanded-as-kwargs pattern) and has been broken since the method was first written. Fixed the string and the misleading comment above it (which incorrectly documented HvacSeatCoolerLevel enum values instead of the actual SEAT_HEATER_* names used), and added a dedicated regression test (test_medium_level_regression) locking the correct proto field name via WhichOneof.
Also documented in AGENTS.md: the remote_heater_control_enabled gate discovery, and a general caution about the dict-of-string-kwargs pattern used for HvacSeatHeaterAction/HvacSeatCoolerAction construction bypassing pyright's static checking (explains why the medium-level bug went unnoticed).
Added tests/test_ble_climate_commands.py: 18 new mocked-transport regression tests covering proto construction and reply/rejection decoding for all 15 climate commands (including the deferred-live ones, per the existing PR-CT precedent of shipping mocked-transport-only coverage for commands that can't be live-verified on this rig). Full test suite (109 tests) passes, ruff clean, pyright strict clean. The car was left in its exact original climate state, confirmed via a final full climate_state() read before disconnecting.
What Changed
SEAT_HEATER_MEDoneof field, with regression coverage for the generated climate action payload.remote_heater_control_enabledgate for remote comfort commands.Risk Assessment
✅ Low: The branch makes a narrow protobuf field-name correction and adds focused mocked BLE coverage without changing broader command flow or public API behavior.
Testing
Inspected the PR-4 climate diff, ran the focused BLE climate suite and the full test suite successfully, then generated reviewer-visible JSON evidence showing the public
VehicleBluetoothclimate calls produce encrypted INFO-domain protobuf actions, decode vehicle-style rejections, and map seat-heater level 2 toSEAT_HEATER_MED; transientuv/pytest artifacts were removed from the worktree.Evidence: BLE climate command evidence
Pipeline
Updates from git push no-mistakes
✅ **intent** - passed
✅ No issues found.
✅ **Rebase** - passed
✅ No issues found.
✅ **Review** - passed
✅ No issues found.
✅ **Test** - passed
✅ No issues found.
uv run pytest tests/test_ble_climate_commands.pyuv run pytest testsGenerated/tmp/no-mistakes-evidence/01KX36CNX8N4J2MQXBV2T4E4HY/ble_climate_command_evidence.jsonby invokingVehicleBluetoothpublic climate methods overtests/ble_mocked_transport.pyand decrypting each sentRoutableMessage.✅ **Document** - passed
✅ No issues found.
✅ **Lint** - passed
✅ No issues found.
✅ **Push** - passed
✅ No issues found.