From fc7e5f712c7db3fc366086ed7c7f3dcdc9c95c87 Mon Sep 17 00:00:00 2001 From: Dirk Petersen Date: Tue, 14 Jul 2026 22:05:36 -0700 Subject: [PATCH] Add "Use Konik instead of comma connect" toggle New optional toggle (BPUseKonik, default OFF) that points the device's backend at Konik (stable.konik.ai) instead of comma connect. When enabled, launch_env.sh exports API_HOST=https://api.konik.ai and ATHENA_HOST=wss://athena.konik.ai; openpilot already reads these env vars everywhere it talks to the backend (common/api/comma_connect.py, system/athena/athenad.py, registration, uploader), so no other code changes are needed. Unset/OFF keeps the stock comma defaults exactly byte-for-byte. The pairing dialog (both comma 3X / TICI and comma 4 / mici) also points its QR code and on-screen instructions at stable.konik.ai when the toggle is on, so users pair on the right site. Takes effect after a reboot; the user then re-pairs at stable.konik.ai. The toggle is added to both the TICI and mici BluePilot settings. Registration / DongleId is intentionally left untouched so the switch stays reversible. --- common/params_keys.h | 3 +++ launch_env.sh | 12 ++++++++++++ selfdrive/ui/bp/layouts/settings/bluepilot.py | 11 +++++++++++ .../ui/bp/mici/layouts/settings/bluepilot.py | 3 +++ selfdrive/ui/mici/widgets/pairing_dialog.py | 13 +++++++++++-- selfdrive/ui/widgets/pairing_dialog.py | 16 +++++++++++++--- 6 files changed, 53 insertions(+), 5 deletions(-) diff --git a/common/params_keys.h b/common/params_keys.h index e3d369cc37..b5c5228543 100644 --- a/common/params_keys.h +++ b/common/params_keys.h @@ -321,6 +321,9 @@ inline static std::unordered_map keys = { {"EnableWebRoutesServer", {PERSISTENT | BACKUP, BOOL, "0"}}, {"BPPortalPort", {PERSISTENT | BACKUP, INT, "8088"}}, + // BluePilot: Konik backend (route connectivity to stable.konik.ai instead of comma connect) + {"BPUseKonik", {PERSISTENT | BACKUP, BOOL, "0"}}, + // BluePilot: UI params {"BPLastSeenVersion", {PERSISTENT, STRING}}, diff --git a/launch_env.sh b/launch_env.sh index d71a5c2767..f252013d1b 100755 --- a/launch_env.sh +++ b/launch_env.sh @@ -20,3 +20,15 @@ if [ -z "$AGNOS_VERSION" ]; then fi export STAGING_ROOT="/data/safe_staging" + +# BluePilot: when the "Use Konik instead of comma connect" toggle (BPUseKonik) is on, point the +# device's connectivity at Konik (stable.konik.ai) instead of comma connect. openpilot already +# reads API_HOST / ATHENA_HOST everywhere it talks to the backend (common/api/comma_connect.py, +# system/athena/athenad.py, registration and the uploader), so setting them here redirects all of +# it with no other code changes. Only applied when the toggle is set; unset -> comma defaults. +# Takes effect on reboot; the user must re-pair the device at https://stable.konik.ai once enabled. +if [ "$(cat /data/params/d/BPUseKonik 2>/dev/null)" = "1" ]; then + export API_HOST="https://api.konik.ai" + export ATHENA_HOST="wss://athena.konik.ai" +fi +# End BluePilot diff --git a/selfdrive/ui/bp/layouts/settings/bluepilot.py b/selfdrive/ui/bp/layouts/settings/bluepilot.py index a16f4153f2..999d57cc46 100644 --- a/selfdrive/ui/bp/layouts/settings/bluepilot.py +++ b/selfdrive/ui/bp/layouts/settings/bluepilot.py @@ -74,6 +74,7 @@ def __init__(self): ("disable_BP_long_UI", self._disable_BP_long), ("disable_downhill_comp_UI", self._disable_dowhill_comp), ("BPUIDebugLog", self._ui_debug_log), + ("BPUseKonik", self._use_konik), ) ui_state.add_offroad_transition_callback(self._update_toggles) @@ -362,6 +363,15 @@ def _initialize_items(self): icon="warning.png" ) + # Use Konik instead of comma connect toggle + self._use_konik = toggle_item( + lambda: tr("Use Konik instead of comma connect"), + lambda: tr("Send routes, location & telemetry to Konik (stable.konik.ai) instead of comma connect. Reboot to apply, then re-pair at stable.konik.ai."), + initial_state=self._safe_get_bool(self._params, "BPUseKonik"), + callback=lambda state: self._toggle_callback(state, "BPUseKonik"), + icon="warning.png" + ) + # Disable BP lateral control toggle self._disable_BP_lat = toggle_item( lambda: tr("Disable BP Lateral Control"), @@ -413,6 +423,7 @@ def _initialize_items(self): self._preferred_network_btn, self._clear_model_cache_btn, self._ui_debug_log, + self._use_konik, SectionHeader(tr("Vehicle")), self._show_hands_free_ui, self._vbatt_pause_charging, diff --git a/selfdrive/ui/bp/mici/layouts/settings/bluepilot.py b/selfdrive/ui/bp/mici/layouts/settings/bluepilot.py index 341e57655c..0f4f1b17f6 100644 --- a/selfdrive/ui/bp/mici/layouts/settings/bluepilot.py +++ b/selfdrive/ui/bp/mici/layouts/settings/bluepilot.py @@ -72,6 +72,7 @@ def __init__(self, back_callback: Callable): self.clear_model_cache = BigButtonBP("clear crashed model", "", "icons_mici/settings/device/reboot.png") self.clear_model_cache.set_click_callback(self._clear_model_cache) self.ui_debug_log = BigParamControlBP("ui debug logging", "BPUIDebugLog") + self.use_konik = BigParamControlBP("use Konik instead of comma connect", "BPUseKonik") self.vbatt_pause_charging = BigParamFloatControl("12V battery limit", "vbatt_pause_charging", min=11.0, max=14.0, step=0.1) # Hybrid/EV power flow: enable toggle (like C3X) + style dropdown Flat/Round (C4), same pattern as Lower Right Display @@ -118,6 +119,7 @@ def __init__(self, back_callback: Callable): self.disable_dowhill_comp, self.clear_model_cache, self.ui_debug_log, + self.use_konik, ]) # Toggle lists @@ -140,6 +142,7 @@ def __init__(self, back_callback: Callable): ("BPUIDebugLog", self.ui_debug_log), ("mici_hide_onroad_fade", self.hide_fade), ("BPHideOnroadBorder", self.hide_border), + ("BPUseKonik", self.use_konik), ) ui_state.add_offroad_transition_callback(self._update_toggles) diff --git a/selfdrive/ui/mici/widgets/pairing_dialog.py b/selfdrive/ui/mici/widgets/pairing_dialog.py index a18b26ec02..d3639a5f8d 100644 --- a/selfdrive/ui/mici/widgets/pairing_dialog.py +++ b/selfdrive/ui/mici/widgets/pairing_dialog.py @@ -24,7 +24,15 @@ def __init__(self): self._last_qr_generation = float("-inf") self._txt_pair = gui_app.texture("icons_mici/settings/device/pair.png", 33, 60) - self._pair_label = UnifiedLabel("pair with comma connect", font_size=48, font_weight=FontWeight.BOLD, line_height=0.8) + # BluePilot: pair with Konik when the "Use Konik instead of comma connect" toggle is on + pair_with = "Konik" if self._use_konik() else "comma connect" + self._pair_label = UnifiedLabel(f"pair with {pair_with}", font_size=48, font_weight=FontWeight.BOLD, line_height=0.8) + + def _use_konik(self) -> bool: + try: + return self._params.get_bool("BPUseKonik") + except Exception: + return False def _get_pairing_url(self) -> str: try: @@ -33,7 +41,8 @@ def _get_pairing_url(self) -> str: except Exception as e: cloudlog.warning(f"Failed to get pairing token: {e}") token = "" - return f"https://connect.comma.ai/?pair={token}" + host = "stable.konik.ai" if self._use_konik() else "connect.comma.ai" + return f"https://{host}/?pair={token}" def _generate_qr_code(self) -> None: try: diff --git a/selfdrive/ui/widgets/pairing_dialog.py b/selfdrive/ui/widgets/pairing_dialog.py index 1ff550e4b6..181e5e24e7 100644 --- a/selfdrive/ui/widgets/pairing_dialog.py +++ b/selfdrive/ui/widgets/pairing_dialog.py @@ -28,6 +28,15 @@ def __init__(self): self._close_btn = IconButton(gui_app.texture("icons/close.png", 80, 80)) self._close_btn.set_click_callback(gui_app.pop_widget) + def _pairing_host(self) -> str: + # BluePilot: pair with Konik when the "Use Konik instead of comma connect" toggle is on + try: + if self.params.get_bool("BPUseKonik"): + return "stable.konik.ai" + except Exception: + pass + return "connect.comma.ai" + def _get_pairing_url(self) -> str: try: dongle_id = self.params.get("DongleId") or "" @@ -35,7 +44,7 @@ def _get_pairing_url(self) -> str: except Exception: cloudlog.exception("Failed to get pairing token") token = "" - return f"https://connect.comma.ai/?pair={token}" + return f"https://{self._pairing_host()}/?pair={token}" def _generate_qr_code(self) -> None: try: @@ -113,10 +122,11 @@ def _render(self, rect: rl.Rectangle) -> int: return -1 def _render_instructions(self, rect: rl.Rectangle) -> None: + host = self._pairing_host() instructions = [ - tr("Go to https://connect.comma.ai on your phone"), + tr("Go to https://connect.comma.ai on your phone").replace("connect.comma.ai", host), tr("Click \"add new device\" and scan the QR code on the right"), - tr("Bookmark connect.comma.ai to your home screen to use it like an app"), + tr("Bookmark connect.comma.ai to your home screen to use it like an app").replace("connect.comma.ai", host), ] font = gui_app.font(FontWeight.BOLD)