fix(ble): drop scan-time service UUID filter from find_vehicle - #45
Merged
Conversation
added 2 commits
July 9, 2026 16:10
The vehicle advertises no 128-bit service UUID in its advertisement or scan response - only its VIN-derived name (in the scan response). SERVICE_UUID only exists as a GATT service after connecting. Filtering BleakScanner discovery by service_uuids therefore hides the vehicle entirely on a direct BlueZ adapter; this was masked in testing because an ESPHome bluetooth proxy doesn't enforce that filter the same way. Scan unfiltered and match by name instead, with active scanning required so the scan response (which carries the name) is captured. Post-connect GATT use of SERVICE_UUID is untouched.
Durable knowledge from the find_vehicle scan-filter fix: the vehicle advertises no service UUID pre-connect, so a BleakScanner service_uuids filter hides it on a direct BlueZ adapter.
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
find_vehiclescan-time filter hides the vehicle on a direct BlueZ adapterADV_INDor its scan response - only its VIN-derived local name (^S[a-f0-9]{16}[CDRP]$) is advertised, and only in the SCAN_RSP.SERVICE_UUIDonly exists as a GATT service after connecting.find_vehiclescanned withBleakScanner(service_uuids=[SERVICE_UUID]), a discovery-time filter. Since the car never advertises that UUID, a directbleak/BlueZ adapter returns zero devices and the vehicle is never found.service_uuidsfilter; scan unfiltered and match by the existing VIN-derived name lookup (find_device_by_name), which is the actual discriminator the car exposes pre-connect.scanning_mode="active") so the scan response - which carries the name - is captured. This matches bleak's own default, but makes the requirement explicit rather than incidental.SERVICE_UUIDitself and its post-connect GATT uses (establish_connection(..., services=[SERVICE_UUID])) are untouched - it's still correct there, only the scan-time filter use was wrong.What Changed
tesla_fleet_api/tesla/vehicle/bluetooth.py:find_vehicle's defaultBleakScannerno longer passesservice_uuids=[SERVICE_UUID]; it now passesscanning_mode="active"instead.tests/test_find_vehicle_scan_filter.py(new): asserts the default scanner is constructed without aservice_uuidsfilter and with active scanning, and that name-based matching still works end to end.Risk Assessment
Low, and safe by construction: removing a discovery filter can only surface more devices to the name-match step, never hide the target vehicle. Post-connect GATT behavior (
SERVICE_UUIDusage inconnect()) is unchanged.Testing
uv run pytest tests- 58 passed, 8 subtests passed.uv run ruff check/uv run ruff format --checkon touched files - clean.uv run pyright tesla_fleet_api- 0 errors.Full narrative / original brief
find_vehiclescans withBleakScanner(service_uuids=[SERVICE_UUID])(the Tesla vehicle BLE service UUID) as a discovery-time filter. But a Tesla vehicle does not advertise that 128-bit service UUID in its advertisement or scan-response - it advertises only its VIN-derived local name (^S[a-f0-9]{16}[CDRP]$) in the scan response, plus a nameless iBeacon ADV_IND. The service UUID only exists as a GATT service after you connect. So filtering the scan by that UUID means a direct BlueZ/bleak adapter returns zero devices andfind_vehiclenever sees the car.This was masked in testing because discovery went through an ESPHome bluetooth proxy (bleak-esphome/habluetooth), whose scanner does not enforce the service-UUID filter the same way - so the car was still found. On a direct local adapter it would not be.
Fix: drop the scan-time
service_uuidsfilter, scan unfiltered, match by the existing VIN-derived local name, and require active scanning so the scan response (which carries the name) is captured. Keep all post-connectSERVICE_UUIDGATT usage intact.