From 5f2dad82a129ca2d3ffe58502d5c2e2ab340f6ff Mon Sep 17 00:00:00 2001 From: firestar5683 <168790843+firestar5683@users.noreply.github.com> Date: Sun, 19 Apr 2026 16:33:22 -0500 Subject: [PATCH] more consistent param syncing --- .../ui/layouts/settings/starpilot/panel.py | 39 ++++++++++++++++++- .../components/tools/device_settings.js | 35 ++++++++++++++--- starpilot/system/the_pond/the_pond.py | 9 ++++- 3 files changed, 76 insertions(+), 7 deletions(-) diff --git a/selfdrive/ui/layouts/settings/starpilot/panel.py b/selfdrive/ui/layouts/settings/starpilot/panel.py index 9f16513e5..057f2f7fc 100644 --- a/selfdrive/ui/layouts/settings/starpilot/panel.py +++ b/selfdrive/ui/layouts/settings/starpilot/panel.py @@ -36,11 +36,48 @@ class StarPilotPanelInfo: instance: Widget +class StarPilotParamsProxy: + def __init__(self, params: Params, params_memory: Params): + self._params = params + self._params_memory = params_memory + + def _mark_updated(self): + self._params_memory.put_bool("StarPilotTogglesUpdated", True) + + def put(self, key, value): + result = self._params.put(key, value) + self._mark_updated() + return result + + def put_bool(self, key, value): + result = self._params.put_bool(key, value) + self._mark_updated() + return result + + def put_int(self, key, value): + result = self._params.put_int(key, value) + self._mark_updated() + return result + + def put_float(self, key, value): + result = self._params.put_float(key, value) + self._mark_updated() + return result + + def remove(self, key): + result = self._params.remove(key) + self._mark_updated() + return result + + def __getattr__(self, name): + return getattr(self._params, name) + + class StarPilotPanel(Widget): def __init__(self): super().__init__() - self._params = Params() self._params_memory = Params(memory=True) + self._params = StarPilotParamsProxy(Params(), self._params_memory) self._navigate_callback: Callable | None = None self._back_callback: Callable | None = None self._current_sub_panel = "" diff --git a/starpilot/system/the_pond/assets/components/tools/device_settings.js b/starpilot/system/the_pond/assets/components/tools/device_settings.js index 20438227c..5372bd228 100644 --- a/starpilot/system/the_pond/assets/components/tools/device_settings.js +++ b/starpilot/system/the_pond/assets/components/tools/device_settings.js @@ -68,11 +68,34 @@ function applySelectOptions(el, options) { } } +function syncSelectValue(el, key) { + const targetValue = toSelectValue(state.values[key]) + if (!targetValue) { + el.value = "" + return + } + + if (key === "CarModel") { + const targetLabel = toSelectValue(state.values.CarModelName) + const options = Array.from(el.options) + const matchingIndex = options.findIndex(opt => { + if (opt.value !== targetValue) return false + return !targetLabel || opt.textContent === targetLabel + }) + if (matchingIndex !== -1) { + el.selectedIndex = matchingIndex + return + } + } + + el.value = targetValue +} + async function hydrateEndpointOptions(el, key, endpoint) { if (endpointOptionsCache[endpoint]) { applySelectOptions(el, endpointOptionsCache[endpoint]) el.dataset.hydrated = "1" - el.value = toSelectValue(state.values[key]) + syncSelectValue(el, key) return } @@ -94,7 +117,7 @@ async function hydrateEndpointOptions(el, key, endpoint) { applySelectOptions(el, options) el.dataset.hydrated = "1" - el.value = toSelectValue(state.values[key]) + syncSelectValue(el, key) } function syncInputs() { @@ -115,7 +138,7 @@ function syncInputs() { el.dataset.endpoint = endpoint hydrateEndpointOptions(el, key, endpoint) } else { - el.value = toSelectValue(state.values[key]) + syncSelectValue(el, key) } continue } @@ -125,7 +148,7 @@ function syncInputs() { applySelectOptions(el, inlineOptions) el.dataset.hydrated = "1" } - el.value = toSelectValue(state.values[key]) + syncSelectValue(el, key) } } } @@ -513,12 +536,14 @@ async function updateParam(key, elType) { if (!el) return const param = state.paramMetaByKey[key] || {} + let selectedLabel = "" let formattedVal if (elType === "checkbox") { formattedVal = !!el.checked } else if (elType === "dropdown") { formattedVal = coerceValueByType(el.value, param.data_type) + selectedLabel = el.options?.[el.selectedIndex]?.textContent || "" } else { formattedVal = coerceValueByType(el.value, param.data_type) } @@ -527,7 +552,7 @@ async function updateParam(key, elType) { const res = await fetch("/api/params", { method: "PUT", headers: { "Content-Type": "application/json" }, - body: JSON.stringify({ key, value: formattedVal }), + body: JSON.stringify({ key, value: formattedVal, label: selectedLabel }), }) const data = await res.json() diff --git a/starpilot/system/the_pond/the_pond.py b/starpilot/system/the_pond/the_pond.py index 5c36c6365..263f1485d 100644 --- a/starpilot/system/the_pond/the_pond.py +++ b/starpilot/system/the_pond/the_pond.py @@ -3638,6 +3638,7 @@ def setup(app): "drivingmodelversion": "DrivingModelVersion", }.get(key.lower(), key) val = data["value"] + selected_label_input = str(data.get("label") or "").strip() # Python json parses true/false as boolean if isinstance(val, bool): @@ -3730,7 +3731,13 @@ def setup(app): return jsonify({"error": "Car model cannot be empty."}), 400 catalog = _get_fingerprint_catalog() - model_label = catalog["model_to_label"].get(selected_model) + if selected_label_input and any( + entry["value"] == selected_model and entry["label"] == selected_label_input + for entry in catalog["all_models"] + ): + model_label = selected_label_input + else: + model_label = catalog["model_to_label"].get(selected_model) make_label = catalog["model_to_make"].get(selected_model) params.put("CarModel", selected_model)