From 9ddf5d31b448431ccc3688c716de9b714b6b64dc Mon Sep 17 00:00:00 2001 From: firestar5683 <168790843+firestar5683@users.noreply.github.com> Date: Wed, 1 Jul 2026 13:41:33 -0500 Subject: [PATCH] kachow 3 --- starpilot/common/starpilot_functions.py | 121 ++++++++++++++++-- .../components/tools/device_settings.js | 2 +- .../tools/device_settings_layout.json | 4 +- starpilot/system/the_galaxy/the_galaxy.py | 2 +- 4 files changed, 111 insertions(+), 18 deletions(-) diff --git a/starpilot/common/starpilot_functions.py b/starpilot/common/starpilot_functions.py index eacd92039..c5625f6d5 100644 --- a/starpilot/common/starpilot_functions.py +++ b/starpilot/common/starpilot_functions.py @@ -15,6 +15,14 @@ from openpilot.system.hardware import HARDWARE STARPILOT_API = os.getenv("STARPILOT_API", "https://frogpilot.com/api") BOOT_LOGO_STATE_PATH = Path("/cache/starpilot_boot_logo_state_v1") +ACTIVE_THEME_PATH = Path(BASEDIR) / "starpilot/assets/active_theme" +ACTIVE_THEME_REQUIRED_PATHS = ( + ACTIVE_THEME_PATH / "colors/colors.json", + ACTIVE_THEME_PATH / "icons", + ACTIVE_THEME_PATH / "distance_icons", + ACTIVE_THEME_PATH / "signals", + ACTIVE_THEME_PATH / "sounds", +) def _starpilot_data_root(): @@ -47,6 +55,70 @@ def _run_cmd(*args, **kwargs): return run_cmd(*args, **kwargs) +def _path_has_content(path): + if path.is_symlink() and not path.exists(): + return False + if path.is_file(): + return True + if not path.is_dir(): + return False + try: + next(path.iterdir()) + return True + except (OSError, StopIteration): + return False + + +def _active_theme_ready(): + return all(_path_has_content(path) for path in ACTIVE_THEME_REQUIRED_PATHS) + + +def _normalize_dongle_id(value): + if isinstance(value, bytes): + value = value.decode("utf-8", errors="ignore") + if value is None: + return None + value = str(value).strip() + return value or None + + +def _read_persisted_stock_dongle_id(): + persisted_dongle_id_path = _starpilot_persist_root() / "comma" / "dongle_id" + if not persisted_dongle_id_path.is_file(): + return None + return _normalize_dongle_id(persisted_dongle_id_path.read_text()) + + +def _ensure_stock_dongle_id_fast(params): + current_dongle_id = _normalize_dongle_id(params.get("DongleId")) + konik_dongle_id = _normalize_dongle_id(params.get("KonikDongleId")) + stock_dongle_id = _normalize_dongle_id(params.get("StockDongleId")) + + if stock_dongle_id not in (None, konik_dongle_id): + return stock_dongle_id + + candidate = _read_persisted_stock_dongle_id() + if candidate in (None, konik_dongle_id): + candidate = current_dongle_id if current_dongle_id != konik_dongle_id else None + + if candidate is not None and candidate != stock_dongle_id: + params.put("StockDongleId", candidate) + + return candidate + + +def _sync_cached_konik_dongle_id(params): + current_dongle_id = _normalize_dongle_id(params.get("DongleId")) + konik_dongle_id = _normalize_dongle_id(params.get("KonikDongleId")) + stock_dongle_id = _ensure_stock_dongle_id_fast(params) + + if params.get_bool("UseKonikServer"): + if konik_dongle_id is not None and current_dongle_id != konik_dongle_id: + params.put("DongleId", konik_dongle_id) + elif current_dongle_id == konik_dongle_id and stock_dongle_id is not None: + params.put("DongleId", stock_dongle_id) + + def _boot_logo_cache_key(selected_logo, source_logo): try: source_stat = source_logo.stat() @@ -117,12 +189,40 @@ def seed_desktop_theme_assets(): def starpilot_boot_functions(build_metadata, params): + params.put("BuildMetadata", json.dumps(dataclasses.asdict(build_metadata))) + _sync_cached_konik_dongle_id(params) + + def boot_thread(): + try: + _finish_starpilot_boot(build_metadata) + except Exception as error: + print(f"StarPilot boot functions failed: {error}") + + if _active_theme_ready(): + threading.Thread(target=boot_thread, daemon=True).start() + return + + # Brand-new installs need active theme links before UI starts. Existing + # installs keep this off the manager hot path and refresh in the background. + _refresh_active_theme(Params()) + threading.Thread(target=boot_thread, daemon=True).start() + + +def _refresh_active_theme(params): from openpilot.starpilot.assets.theme_manager import ThemeManager - from openpilot.starpilot.common.connect_server import sync_konik_dongle_id - from openpilot.starpilot.common.maps_catalog import sanitize_selected_locations_csv from openpilot.starpilot.common.starpilot_variables import StarPilotVariables params_memory = Params(memory=True) + starpilot_toggles = StarPilotVariables().starpilot_toggles + ThemeManager(params, params_memory, boot_run=True).update_active_theme(time_validated=system_time_valid(), starpilot_toggles=starpilot_toggles, boot_run=True) + + +def _finish_starpilot_boot(build_metadata): + from openpilot.starpilot.common.connect_server import sync_konik_dongle_id + from openpilot.starpilot.common.maps_catalog import sanitize_selected_locations_csv + from openpilot.starpilot.common.starpilot_backups import backup_starpilot + + params = Params() maps_selected_raw = params.get("MapsSelected") maps_selected = sanitize_selected_locations_csv(maps_selected_raw) @@ -133,21 +233,14 @@ def starpilot_boot_functions(build_metadata, params): params.put("BuildMetadata", json.dumps(dataclasses.asdict(build_metadata))) - starpilot_toggles = StarPilotVariables().starpilot_toggles - ThemeManager(params, params_memory, boot_run=True).update_active_theme(time_validated=system_time_valid(), starpilot_toggles=starpilot_toggles, boot_run=True) - + _refresh_active_theme(params) sync_konik_dongle_id(params) - def boot_thread(): - from openpilot.starpilot.common.starpilot_backups import backup_starpilot + while not system_time_valid(): + print("Waiting for system time to become valid...") + time.sleep(1) - while not system_time_valid(): - print("Waiting for system time to become valid...") - time.sleep(1) - - backup_starpilot(build_metadata, params) - - threading.Thread(target=boot_thread, daemon=True).start() + backup_starpilot(build_metadata, params) def install_starpilot(build_metadata, params): diff --git a/starpilot/system/the_galaxy/assets/components/tools/device_settings.js b/starpilot/system/the_galaxy/assets/components/tools/device_settings.js index e1b575ce1..8d5764d24 100644 --- a/starpilot/system/the_galaxy/assets/components/tools/device_settings.js +++ b/starpilot/system/the_galaxy/assets/components/tools/device_settings.js @@ -13,7 +13,7 @@ const FAVORITE_OPTION_COLLATOR = new Intl.Collator(undefined, { numeric: true, s let syncScheduled = false let lastParams = null const DYNAMIC_DEFAULT_DEP_KEYS = new Set(["AccelerationProfile", "EVTuning", "TruckTuning"]) -const PANDA_FIRMWARE_TOGGLE_KEYS = new Set(["HKGRemoteStartBootsComma"]) +const PANDA_FIRMWARE_TOGGLE_KEYS = new Set(["IgnoreIgnitionLine", "RemoteStartBootsComma", "HKGRemoteStartBootsComma"]) // Module-level state (persists across route changes) const state = reactive({ diff --git a/starpilot/system/the_galaxy/assets/components/tools/device_settings_layout.json b/starpilot/system/the_galaxy/assets/components/tools/device_settings_layout.json index be9a3ce0d..a578ecc54 100644 --- a/starpilot/system/the_galaxy/assets/components/tools/device_settings_layout.json +++ b/starpilot/system/the_galaxy/assets/components/tools/device_settings_layout.json @@ -2515,14 +2515,14 @@ }, { "key": "RemoteStartBootsComma", - "label": "Remote Start Boots comma", + "label": "Remote Start Boots Comma (GM)", "description": "Use the remote-start GM panda firmware at boot.\n\nRequired for GM remote-start startup signal behavior.", "data_type": "bool", "ui_type": "toggle" }, { "key": "HKGRemoteStartBootsComma", - "label": "EV Remote Climate", + "label": "Remote Start Boots Comma (HKG)", "description": "Use the remote-climate Hyundai/Kia/Genesis CAN-FD panda firmware at boot.\n\nRequired for EV remote-climate startup signal behavior.", "data_type": "bool", "ui_type": "toggle" diff --git a/starpilot/system/the_galaxy/the_galaxy.py b/starpilot/system/the_galaxy/the_galaxy.py index ec8500b1d..17c54935b 100644 --- a/starpilot/system/the_galaxy/the_galaxy.py +++ b/starpilot/system/the_galaxy/the_galaxy.py @@ -113,7 +113,7 @@ _TESTING_GROUND_CUSTOM_RESERVED_INTERVAL_S = 15.0 _TESTING_GROUND_CUSTOM_RESERVED_PM = None _TESTING_GROUND_CUSTOM_RESERVED_LOCK = threading.Lock() _TESTING_GROUND_CUSTOM_RESERVED_LAST_PUBLISH_MONO = 0.0 -PANDA_FIRMWARE_TOGGLE_KEYS = {"HKGRemoteStartBootsComma"} +PANDA_FIRMWARE_TOGGLE_KEYS = {"IgnoreIgnitionLine", "RemoteStartBootsComma", "HKGRemoteStartBootsComma"} PANDA_FIRMWARE_CONFIRMATION_FIELD = "confirmedPandaFirmwareFlash" _PANDA_FLASH_REBOOT_LOCK = threading.Lock()