Report the chosen setup, the car's offered video modes and the working strategy

Reports could not tell a built-in unit from a dongle, and offers and
handshakes were only visible in failure text, so there was nothing to
compare working pairings against.

session_start now records the setup type (builtin/adapter/usb/app), the
resolved profile and whether it was chosen or detected. Session reports
carry every video mode the head unit offered, whether the comma's address
reached the car in the pairing request, and, for streaming sessions, the
strategy that worked (window, reply style, Wi-Fi channel type). The drive
report gains low-cardinality tags (aa.setup_type, aa.adapter_model,
aa.profile_source, aa.phone_address_sent); long values stay in contexts.
Old logs without these fields still report. aa.schema is now 3.
This commit is contained in:
dirwin31
2026-11-01 13:29:15 -08:00
committed by Danny
parent 745b1e94de
commit fd660ef6f7
4 changed files with 126 additions and 2 deletions
@@ -161,6 +161,61 @@ def bounded_trace(trace: list[dict], limit: int) -> dict:
return {"events": kept, "omitted": len(trace) - len(kept)}
MAX_OFFERED_MODES = 16
SETUP_TYPES = ("builtin", "adapter", "usb", "app")
def offered_modes(events: list[dict]) -> list[str]:
"""Every video mode the head unit offered, e.g. "1280x720 H.264 margins 0x240", from its service discovery.
Kept for working pairings too, so the choice of mode can later be replayed against real cars."""
from openpilot.starpilot.system.starport.session import CODEC_H264_BP, CODEC_NAMES, RESOLUTION_NAMES
found = next((event for event in events if event["event"] == "discovered"), {})
modes: list[str] = []
for channel in found.get("channels") or []:
for config in (channel.get("video_configs") or []) if isinstance(channel, dict) else []:
if not isinstance(config, dict):
continue
def field(number, default=None):
values = config.get(str(number), config.get(number))
return values[0] if isinstance(values, list) and values and isinstance(values[0], int) else default
resolution, codec = field(1), field(10, CODEC_H264_BP)
text = f"{RESOLUTION_NAMES.get(resolution, f'resolution {resolution}')} {CODEC_NAMES.get(codec, f'codec {codec}')}"
if field(3, 0) or field(4, 0):
text += f" margins {field(3, 0)}x{field(4, 0)}"
modes.append(text)
return modes[:MAX_OFFERED_MODES]
def session_setup(events: list[dict]) -> dict:
"""The setup type and profile the owner chose, as recorded when the session started."""
start = next((event for event in events if event["event"] == "session_start"), {})
setup = start.get("setup") if isinstance(start.get("setup"), dict) else {}
kind = setup.get("type")
return {key: value for key, value in (
("type", kind if kind in SETUP_TYPES else None),
("profile", scrub(setup.get("profile", ""), 40) or None),
("profile_source", setup.get("profile_source") if setup.get("profile_source") in ("override", "detected", "standard") else None),
) if value}
def session_strategy(events: list[dict], setup: dict) -> dict:
"""What a streaming session ran with; the raw material for "this head unit usually likes this profile"."""
if not any(event["event"] == "video_acknowledged" for event in events):
return {}
ready = next((event for event in reversed(events) if event["event"] == "video_setup"), {})
reply = next((event for event in events if event["event"] == "bootstrap_version_reply"), {})
mode = ready.get("mode") if isinstance(ready.get("mode"), dict) else {}
# Only a wireless bootstrap has a version reply; the modern one is logged, the standard one is its absence.
style = reply.get("style") or ("standard" if any(event["event"] == "bootstrap_start_response" for event in events) else None)
strategy = {"profile": setup.get("profile"), "window_offered": ready.get("window"), "window_used": ready.get("used_window"),
"reply_style": style, "channel_type": reply.get("channel_type"),
"config_index": mode.get("config_index")}
return {key: value for key, value in strategy.items() if value is not None}
def session_record(path: Path) -> dict:
"""One finished session log reduced to its outcome, stage timings, video and the car it talked to."""
from openpilot.starpilot.system.starport import compat_report
@@ -184,7 +239,14 @@ def session_record(path: Path) -> dict:
car = report["car"]
start = next((e for e in events if e["event"] == "session_start"), {})
software, settings = start.get("software", {}), start.get("settings")
setup = session_setup(events)
opened = next((e for e in events if e["event"] == "bluetooth_opened"), None)
record = {
"setup": setup,
"offered_modes": offered_modes(events),
# True when the comma's address went to the car in the pairing request; None when the car never opened that channel.
"phone_address_sent": bool(opened.get("phone_address")) if opened is not None else None,
"strategy": session_strategy(events, setup),
"software": {key: str(software.get(key) or "unknown") for key in ("commit", "branch")} if isinstance(software, dict) else {},
"settings": settings if isinstance(settings, dict) else {},
"seq": _session_number(path),
@@ -395,6 +457,8 @@ def drive_event(sessions: list[dict]) -> dict:
head_unit = next((s["head_unit"] for s in reversed(sessions) if s["head_unit"]), {})
video = next((s["video"] for s in reversed(sessions) if s["video"].get("resolution")), {})
label = _head_unit_label(head_unit)
setup = next((s["setup"] for s in reversed(sessions) if s.get("setup")), {})
sent = next((s["phone_address_sent"] for s in reversed(sessions) if s.get("phone_address_sent") is not None), None)
failures = [failure_detail(failure) for failure in drive_failures(sessions)]
failed = [session for session in sessions if session["seq"] in {failure["session"] for failure in failures}]
heading = "failures" if failures else "sessions"
@@ -425,6 +489,11 @@ def drive_event(sessions: list[dict]) -> dict:
"aa.encoder": video.get("encoder", "unknown"),
"aa.fps": str(summary["fps_avg"]) if summary["fps_avg"] is not None else "none",
"aa.failures": str(len(failures)),
# Low-cardinality choices only; long values (offered modes, strategy) live in the contexts below.
**({"aa.setup_type": setup["type"]} if setup.get("type") else {}),
**({"aa.adapter_model": setup["profile"]} if setup.get("profile") else {}),
**({"aa.profile_source": setup["profile_source"]} if setup.get("profile_source") else {}),
**({"aa.phone_address_sent": "yes" if sent else "no"} if sent is not None else {}),
**({"aa.attention": ",".join(reasons)[:190]} if reasons else {}),
**({"aa.cause": latest["cause"], "aa.stage": latest["stage"], "aa.error_kind": latest["error_kind"]} if latest else {})},
"breadcrumbs": {"values": attempt_breadcrumbs(sessions)},
@@ -38,7 +38,7 @@ class Sender:
self.opener = opener or urllib.request.build_opener(NoRedirect())
self.active = active
self.logger, self.client = logger, client
self.schema_tags = {"aa.schema": "2"} if schema_tags is None else schema_tags
self.schema_tags = {"aa.schema": "3"} if schema_tags is None else schema_tags
def __call__(self, **event) -> bool:
if not self.active():
@@ -1134,9 +1134,13 @@ class Supervisor:
receiver = {"wired": "usb", "headunitpad": "headunitpad", "openheadunit": "openheadunit"}.get(connection, self.config["receiver_name"])
from openpilot.starpilot.system.starport.bugsink_transport import device_metadata
software = device_metadata()
profile, profile_source = car_profiles.resolve(self.config)
self.log("session_start", receiver=receiver, generation=generation, trigger=trigger,
software={key: software.get(key, "unknown") for key in ("commit", "branch")},
settings={key: self.config.get(key) for key in REPORTED_SETTINGS})
settings={key: self.config.get(key) for key in REPORTED_SETTINGS},
# What the owner chose, so a report can tell a built-in unit from a dongle and say which profile applied.
setup={"type": {"wired": "usb", "headunitpad": "app", "openheadunit": "app"}.get(connection) or self.car_type(),
"profile": profile, "profile_source": profile_source})
lease = self._lease() if wireless else NoLease()
attempt = 0
car_first = trigger == "onroad" and wireless
@@ -441,3 +441,54 @@ def test_pairing_that_failed_carries_a_device_slice_but_success_does_not(tmp_pat
assert event["contexts"]["starport_pairing_system"]["bluetooth"]["lines"] == ["bt '<name>' up"]
assert calls[0][1] - calls[0][0] == 30
assert "starport_pairing_system" not in br.pairing_event({**record, "result": "paired"}, collector)["contexts"]
OFFER = {"channels": [{"id": 3, "video_configs": [
{"1": [2], "10": [3], "3": [0], "4": [240]},
{"1": [8], "10": [7], "3": [288], "4": [1378]},
{"1": [7], "10": [7], "3": [0], "4": [811]}]}], "head_unit": {"2": ["Honda"]}}
def adapter_session():
events = [list(item) for item in STREAMED]
events[0] = (0, 0, "session_start", {"receiver": "AAWireless", "trigger": "auto",
"setup": {"type": "adapter", "profile": "aawireless", "profile_source": "override"}})
events[5] = (0, 10, "discovered", {**OFFER, "head_unit": STREAMED[5][3]["head_unit"]})
events.insert(6, (0, 10, "bootstrap_start_response", {}))
events.insert(7, (0, 10, "bootstrap_version_reply", {"style": "modern", "channel_type": 1}))
events.insert(8, (0, 10, "bluetooth_opened", {"channel": 6, "phone_address": "39:90:21:64:07:00"}))
events.insert(9, (0, 11, "video_setup", {"mode": {"config_index": 0}, "window": 30, "used_window": 30}))
return events
def test_report_keeps_setup_offered_modes_and_the_working_strategy(tmp_path):
record = br.session_record(write_session(tmp_path, 1, adapter_session()))
assert record["setup"] == {"type": "adapter", "profile": "aawireless", "profile_source": "override"}
assert record["offered_modes"] == ["1280x720 H.264 margins 0x240", "1440x2560 H.265 margins 288x1378", "1080x1920 H.265 margins 0x811"]
assert record["phone_address_sent"] is True
assert record["strategy"] == {"profile": "aawireless", "window_offered": 30, "window_used": 30,
"reply_style": "modern", "channel_type": 1, "config_index": 0}
event = br.drive_event([record])
tags = event["tags"]
assert (tags["aa.setup_type"], tags["aa.adapter_model"], tags["aa.profile_source"], tags["aa.phone_address_sent"]) == (
"adapter", "aawireless", "override", "yes")
context = event["contexts"]["starport_session_1"]
assert context["offered_modes"] == record["offered_modes"] and context["strategy"]["reply_style"] == "modern"
assert "39:90:21:64:07:00" not in json.dumps(event) # the comma's own address is sanitized from every field
def test_report_records_that_the_address_was_not_sent_and_old_logs_still_report(tmp_path):
events = [list(item) for item in STREAMED]
events.insert(6, (0, 10, "bluetooth_opened", {"channel": 6, "phone_address": ""}))
assert br.drive_event([br.session_record(write_session(tmp_path, 1, events))])["tags"]["aa.phone_address_sent"] == "no"
old = br.session_record(write_session(tmp_path, 2, STREAMED)) # a log written before these fields existed
assert old["setup"] == {} and old["offered_modes"] == [] and old["phone_address_sent"] is None and old["strategy"] == {}
tags = br.drive_event([old])["tags"]
assert not any(key in tags for key in ("aa.setup_type", "aa.adapter_model", "aa.profile_source", "aa.phone_address_sent"))
def test_unknown_setup_values_are_dropped(tmp_path):
events = [list(item) for item in STREAMED]
events[0] = (0, 0, "session_start", {"setup": {"type": "<script>", "profile": "x" * 90, "profile_source": "guess"}})
setup = br.session_record(write_session(tmp_path, 1, events))["setup"]
assert "type" not in setup and "profile_source" not in setup and len(setup["profile"]) <= 40