Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions common/params_keys.h
Original file line number Diff line number Diff line change
Expand Up @@ -321,6 +321,9 @@ inline static std::unordered_map<std::string, ParamKeyAttributes> 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}},

Expand Down
12 changes: 12 additions & 0 deletions launch_env.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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
11 changes: 11 additions & 0 deletions selfdrive/ui/bp/layouts/settings/bluepilot.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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"),
Expand Down Expand Up @@ -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,
Expand Down
3 changes: 3 additions & 0 deletions selfdrive/ui/bp/mici/layouts/settings/bluepilot.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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)
Expand Down
13 changes: 11 additions & 2 deletions selfdrive/ui/mici/widgets/pairing_dialog.py
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand All @@ -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:
Expand Down
16 changes: 13 additions & 3 deletions selfdrive/ui/widgets/pairing_dialog.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,23 @@ 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 ""
token = Api(dongle_id).get_token({'pair': True})
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:
Expand Down Expand Up @@ -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)
Expand Down