From ac47a9b73b27e1c6d4447416dff6dcc563306cd8 Mon Sep 17 00:00:00 2001 From: firestar5683 <168790843+firestar5683@users.noreply.github.com> Date: Mon, 30 Mar 2026 13:01:41 -0500 Subject: [PATCH] troubleshoot --- .../assets/components/tools/troubleshoot.css | 58 +++++++++++++ .../assets/components/tools/troubleshoot.js | 43 ++++++++++ starpilot/system/the_pond/the_pond.py | 86 +++++++++++++++++++ 3 files changed, 187 insertions(+) diff --git a/starpilot/system/the_pond/assets/components/tools/troubleshoot.css b/starpilot/system/the_pond/assets/components/tools/troubleshoot.css index 9cbf5cc1..c6e68f42 100644 --- a/starpilot/system/the_pond/assets/components/tools/troubleshoot.css +++ b/starpilot/system/the_pond/assets/components/tools/troubleshoot.css @@ -67,6 +67,64 @@ margin: 6px 0 0; } +.troubleshootFaultSummary { + margin: 0 0 12px; + opacity: 0.92; +} + +.troubleshootFaultGrid { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); + gap: 10px; +} + +.troubleshootFaultItem { + display: flex; + flex-direction: column; + gap: 8px; + padding: 12px; + border: 1px solid var(--sidebar-border-color); + border-radius: var(--border-radius-md); + background: rgba(255, 255, 255, 0.03); +} + +.troubleshootFaultLabel { + font-weight: 700; +} + +.troubleshootStatusBadge { + display: inline-flex; + align-items: center; + justify-content: center; + width: fit-content; + border-radius: 999px; + padding: 4px 10px; + font-size: 0.8rem; + font-weight: 800; + letter-spacing: 0.02em; + text-transform: uppercase; +} + +.troubleshootStatusBadgeOk { + background: rgba(64, 201, 124, 0.18); + color: #b8ffd4; +} + +.troubleshootStatusBadgeWarn { + background: rgba(245, 188, 87, 0.18); + color: #ffe2a3; +} + +.troubleshootStatusBadgeFault { + background: rgba(217, 90, 123, 0.2); + color: #ffd7e2; +} + +.troubleshootStatusBadgeNeutral { + background: rgba(255, 255, 255, 0.08); + color: rgba(255, 255, 255, 0.88); +} + .troubleshootSectionHeader { display: flex; align-items: center; diff --git a/starpilot/system/the_pond/assets/components/tools/troubleshoot.js b/starpilot/system/the_pond/assets/components/tools/troubleshoot.js index 5769805b..4d92c3c4 100644 --- a/starpilot/system/the_pond/assets/components/tools/troubleshoot.js +++ b/starpilot/system/the_pond/assets/components/tools/troubleshoot.js @@ -3,6 +3,12 @@ import { html, reactive } from "/assets/vendor/arrow-core.js" const state = reactive({ loading: true, error: "", + vehicleStatus: { + available: false, + summary: "", + summarySeverity: "neutral", + items: [], + }, snapshot: [], sections: [], isOnroad: false, @@ -74,12 +80,25 @@ function countNonDefaultItems() { }, 0) } +function statusBadgeClass(severity) { + const safeSeverity = String(severity || "neutral").trim().toLowerCase() + return `troubleshootStatusBadge troubleshootStatusBadge${safeSeverity.charAt(0).toUpperCase()}${safeSeverity.slice(1)}` +} + function buildReportText() { const lines = [] lines.push("StarPilot Troubleshoot Report") lines.push(`Generated: ${new Date().toISOString()}`) lines.push(`Onroad: ${state.isOnroad ? "Yes" : "No"}`) lines.push(`Only non-default values: ${state.showNonDefaultOnly ? "Yes" : "No"}`) + if (state.vehicleStatus?.summary) { + lines.push("") + lines.push("Vehicle Fault Status") + lines.push(`Summary: ${state.vehicleStatus.summary}`) + for (const item of state.vehicleStatus.items || []) { + lines.push(`- ${item.label}: ${formatValue(item.value)}`) + } + } lines.push("") lines.push("Snapshot") for (const item of state.snapshot) { @@ -133,6 +152,12 @@ async function fetchTroubleshoot(showToast = false) { state.snapshot = Array.isArray(payload.snapshot) ? payload.snapshot : [] state.sections = Array.isArray(payload.sections) ? payload.sections : [] + state.vehicleStatus = { + available: !!payload.vehicleStatus?.available, + summary: String(payload.vehicleStatus?.summary || ""), + summarySeverity: String(payload.vehicleStatus?.summarySeverity || "neutral"), + items: Array.isArray(payload.vehicleStatus?.items) ? payload.vehicleStatus.items : [], + } state.isOnroad = !!payload.isOnroad state.error = "" @@ -234,6 +259,24 @@ export function Troubleshoot() {

Changed Settings: ${() => countNonDefaultItems()}

+
+
+

Vehicle Fault Status

+ + ${() => state.vehicleStatus?.available ? "Live" : "Unavailable"} + +
+

${() => state.vehicleStatus?.summary || "Vehicle fault status unavailable."}

+
+ ${() => (state.vehicleStatus?.items || []).map((item) => html` +
+
${item.label}
+
${formatValue(item.value)}
+
+ `)} +
+
+

Snapshot

diff --git a/starpilot/system/the_pond/the_pond.py b/starpilot/system/the_pond/the_pond.py index c044395d..df533bbc 100644 --- a/starpilot/system/the_pond/the_pond.py +++ b/starpilot/system/the_pond/the_pond.py @@ -2077,6 +2077,91 @@ def _snapshot_bool_text(value): return "No" return "Unavailable" +def _build_vehicle_fault_status(): + unavailable_items = [ + {"label": "Cruise Fault", "value": "Unavailable", "severity": "neutral"}, + {"label": "LKAS Fault", "value": "Unavailable", "severity": "neutral"}, + {"label": "CAN Valid", "value": "Unavailable", "severity": "neutral"}, + {"label": "Cruise Available", "value": "Unavailable", "severity": "neutral"}, + {"label": "Cruise Engaged", "value": "Unavailable", "severity": "neutral"}, + ] + + is_onroad = params.get_bool("IsOnroad") + unavailable_summary = "Vehicle fault status is unavailable while offroad." + unavailable_severity = "neutral" + if is_onroad: + unavailable_summary = "Waiting for live vehicle fault status..." + unavailable_severity = "warn" + + try: + sm = messaging.SubMaster(["carState"], poll="carState") + sm.update(100) + has_live_car_state = sm.seen["carState"] and sm.alive["carState"] and sm.valid["carState"] + if not has_live_car_state: + return { + "available": False, + "summary": unavailable_summary, + "summarySeverity": unavailable_severity, + "items": unavailable_items, + } + + car_state = sm["carState"] + cruise_state = getattr(car_state, "cruiseState", None) + + cruise_faulted = bool(getattr(car_state, "accFaulted", False)) + steer_fault_temporary = bool(getattr(car_state, "steerFaultTemporary", False)) + steer_fault_permanent = bool(getattr(car_state, "steerFaultPermanent", False)) + can_valid = bool(getattr(car_state, "canValid", False)) + cruise_available = bool(getattr(cruise_state, "available", False)) if cruise_state is not None else None + cruise_enabled = bool(getattr(cruise_state, "enabled", False)) if cruise_state is not None else None + + if steer_fault_permanent: + lkas_fault_value = "Permanent" + lkas_fault_severity = "fault" + elif steer_fault_temporary: + lkas_fault_value = "Temporary" + lkas_fault_severity = "warn" + else: + lkas_fault_value = "Clear" + lkas_fault_severity = "ok" + + active_statuses = [] + if cruise_faulted: + active_statuses.append("cruise fault") + if steer_fault_permanent: + active_statuses.append("permanent LKAS fault") + elif steer_fault_temporary: + active_statuses.append("temporary LKAS fault") + if not can_valid: + active_statuses.append("CAN invalid") + + if active_statuses: + summary = "Active status: " + ", ".join(active_statuses) + "." + summary_severity = "fault" if ("cruise fault" in active_statuses or "permanent LKAS fault" in active_statuses or "CAN invalid" in active_statuses) else "warn" + else: + summary = "No active cruise or LKAS faults detected." + summary_severity = "ok" + + return { + "available": True, + "summary": summary, + "summarySeverity": summary_severity, + "items": [ + {"label": "Cruise Fault", "value": "Faulted" if cruise_faulted else "Clear", "severity": "fault" if cruise_faulted else "ok"}, + {"label": "LKAS Fault", "value": lkas_fault_value, "severity": lkas_fault_severity}, + {"label": "CAN Valid", "value": "Yes" if can_valid else "No", "severity": "ok" if can_valid else "fault"}, + {"label": "Cruise Available", "value": "Yes" if cruise_available else "No", "severity": "ok" if cruise_available else "neutral"}, + {"label": "Cruise Engaged", "value": "Yes" if cruise_enabled else "No", "severity": "ok" if cruise_enabled else "neutral"}, + ], + } + except Exception: + return { + "available": False, + "summary": unavailable_summary, + "summarySeverity": unavailable_severity, + "items": unavailable_items, + } + def _get_starpilot_toggles_snapshot(): raw_toggles = _safe_params_get_live_raw("StarPilotToggles") if not raw_toggles: @@ -2260,6 +2345,7 @@ def _build_troubleshoot_payload(): ] return { + "vehicleStatus": _build_vehicle_fault_status(), "snapshot": snapshot_items, "sections": sections, "isOnroad": params.get_bool("IsOnroad"),