mirror of
https://github.com/firestar5683/StarPilot.git
synced 2026-07-07 22:52:06 +08:00
Kachow 2
This commit is contained in:
@@ -1,33 +1,91 @@
|
||||
#!/usr/bin/env python3
|
||||
import dataclasses
|
||||
import json
|
||||
import requests
|
||||
import os
|
||||
import threading
|
||||
import time
|
||||
|
||||
from pathlib import Path
|
||||
from types import SimpleNamespace
|
||||
|
||||
from cereal import messaging
|
||||
from openpilot.common.basedir import BASEDIR
|
||||
from openpilot.common.params import Params
|
||||
from openpilot.common.time_helpers import system_time_valid
|
||||
from openpilot.system.hardware import HARDWARE
|
||||
from openpilot.system.version import get_build_metadata
|
||||
|
||||
from openpilot.starpilot.assets.theme_manager import ThemeManager
|
||||
from openpilot.starpilot.common.starpilot_backups import backup_starpilot
|
||||
from openpilot.starpilot.common.connect_server import sync_konik_dongle_id
|
||||
from openpilot.starpilot.common.maps_catalog import normalize_schedule_value, sanitize_selected_locations_csv
|
||||
from openpilot.starpilot.common.theme_asset_names import find_matching_theme_asset_file
|
||||
from openpilot.starpilot.common.starpilot_utilities import get_starpilot_api_info, is_FrogsGoMoo, is_url_pingable, run_cmd
|
||||
from openpilot.starpilot.common.starpilot_variables import (
|
||||
ERROR_LOGS_PATH, STARPILOT_API, FROGS_GO_MOO_PATH, HD_LOGS_PATH, KONIK_LOGS_PATH, MAPS_PATH, THEME_SAVE_PATH,
|
||||
StarPilotVariables, get_starpilot_toggles
|
||||
)
|
||||
STARPILOT_API = os.getenv("STARPILOT_API", "https://frogpilot.com/api")
|
||||
BOOT_LOGO_STATE_PATH = Path("/cache/starpilot_boot_logo_state_v1")
|
||||
|
||||
|
||||
def _starpilot_data_root():
|
||||
if HARDWARE.get_device_type() == "pc":
|
||||
from openpilot.system.hardware.hw import Paths
|
||||
|
||||
return Path(Paths.comma_home()) / "starpilot" / "data"
|
||||
return Path("/data")
|
||||
|
||||
|
||||
def _starpilot_persist_root():
|
||||
if HARDWARE.get_device_type() == "pc":
|
||||
from openpilot.system.hardware.hw import Paths
|
||||
|
||||
return Path(Paths.persist_root())
|
||||
return Path("/persist")
|
||||
|
||||
|
||||
def _theme_save_path():
|
||||
return _starpilot_data_root() / "themes"
|
||||
|
||||
|
||||
def _maps_path():
|
||||
return _starpilot_data_root() / "media/0/osm/offline"
|
||||
|
||||
|
||||
def _run_cmd(*args, **kwargs):
|
||||
from openpilot.starpilot.common.starpilot_utilities import run_cmd
|
||||
|
||||
return run_cmd(*args, **kwargs)
|
||||
|
||||
|
||||
def _boot_logo_cache_key(selected_logo, source_logo):
|
||||
try:
|
||||
source_stat = source_logo.stat()
|
||||
source_path = source_logo.resolve()
|
||||
except OSError:
|
||||
return None
|
||||
|
||||
selected = selected_logo.decode("utf-8", "ignore") if isinstance(selected_logo, (bytes, bytearray)) else str(selected_logo or "")
|
||||
return "\n".join([
|
||||
selected.strip().lower(),
|
||||
str(source_path),
|
||||
str(source_stat.st_mtime_ns),
|
||||
str(source_stat.st_size),
|
||||
"",
|
||||
])
|
||||
|
||||
|
||||
def _boot_logo_cache_matches(cache_key):
|
||||
if cache_key is None:
|
||||
return False
|
||||
try:
|
||||
return BOOT_LOGO_STATE_PATH.read_text() == cache_key
|
||||
except OSError:
|
||||
return False
|
||||
|
||||
|
||||
def _write_boot_logo_cache(cache_key):
|
||||
if cache_key is None:
|
||||
return
|
||||
try:
|
||||
BOOT_LOGO_STATE_PATH.parent.mkdir(parents=True, exist_ok=True)
|
||||
BOOT_LOGO_STATE_PATH.write_text(cache_key)
|
||||
except OSError:
|
||||
pass
|
||||
|
||||
|
||||
def seed_desktop_theme_assets():
|
||||
from openpilot.starpilot.assets.theme_manager import ThemeManager
|
||||
|
||||
params = Params()
|
||||
params_memory = Params(memory=True)
|
||||
params_defaults = Params(return_defaults=True)
|
||||
@@ -59,6 +117,11 @@ def seed_desktop_theme_assets():
|
||||
|
||||
|
||||
def starpilot_boot_functions(build_metadata, 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)
|
||||
|
||||
maps_selected_raw = params.get("MapsSelected")
|
||||
@@ -70,12 +133,14 @@ def starpilot_boot_functions(build_metadata, params):
|
||||
|
||||
params.put("BuildMetadata", json.dumps(dataclasses.asdict(build_metadata)))
|
||||
|
||||
StarPilotVariables()
|
||||
ThemeManager(params, params_memory, boot_run=True).update_active_theme(time_validated=system_time_valid(), starpilot_toggles=get_starpilot_toggles(), boot_run=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)
|
||||
|
||||
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)
|
||||
@@ -86,12 +151,13 @@ def starpilot_boot_functions(build_metadata, params):
|
||||
|
||||
|
||||
def install_starpilot(build_metadata, params):
|
||||
data_root = _starpilot_data_root()
|
||||
paths = [
|
||||
ERROR_LOGS_PATH,
|
||||
HD_LOGS_PATH,
|
||||
KONIK_LOGS_PATH,
|
||||
MAPS_PATH,
|
||||
THEME_SAVE_PATH
|
||||
data_root / "error_logs",
|
||||
data_root / "media/0/realdata_HD",
|
||||
data_root / "media/0/realdata_konik",
|
||||
data_root / "media/0/osm/offline",
|
||||
_theme_save_path()
|
||||
]
|
||||
for path in paths:
|
||||
path.mkdir(parents=True, exist_ok=True)
|
||||
@@ -100,15 +166,27 @@ def install_starpilot(build_metadata, params):
|
||||
|
||||
update_boot_logo(starpilot=True, selected_logo=params.get("BootLogo"))
|
||||
|
||||
if is_FrogsGoMoo():
|
||||
mount_options = run_cmd(["findmnt", "-n", "-o", "OPTIONS", "/persist"], "Successfully retrieved mount options", "Failed to retrieve mount options")
|
||||
run_cmd(["sudo", "mount", "-o", "remount,rw", "/persist"], "Successfully remounted /persist as read-write", "Failed to remount /persist")
|
||||
run_cmd(["sudo", "python3", FROGS_GO_MOO_PATH], "Successfully ran frogsgomoo.py", "Failed to run frogsgomoo.py")
|
||||
run_cmd(["sudo", "mount", "-o", f"remount,{mount_options}", "/persist"], "Successfully restored /persist mount options", "Failed to restore /persist mount options")
|
||||
frogs_go_moo_path = _starpilot_persist_root() / "frogsgomoo.py"
|
||||
if frogs_go_moo_path.is_file():
|
||||
mount_options = _run_cmd(["findmnt", "-n", "-o", "OPTIONS", "/persist"], "Successfully retrieved mount options", "Failed to retrieve mount options")
|
||||
_run_cmd(["sudo", "mount", "-o", "remount,rw", "/persist"], "Successfully remounted /persist as read-write", "Failed to remount /persist")
|
||||
_run_cmd(["sudo", "python3", frogs_go_moo_path], "Successfully ran frogsgomoo.py", "Failed to run frogsgomoo.py")
|
||||
_run_cmd(["sudo", "mount", "-o", f"remount,{mount_options}", "/persist"], "Successfully restored /persist mount options", "Failed to restore /persist mount options")
|
||||
|
||||
|
||||
def register_device(build_metadata, params):
|
||||
def register_thread():
|
||||
import requests
|
||||
|
||||
def is_url_pingable(url):
|
||||
if not url:
|
||||
return False
|
||||
try:
|
||||
response = requests.head(url, timeout=10, allow_redirects=True, headers={"User-Agent": "starpilot-ping-test/1.0 (https://github.com/FrogAi/StarPilot)"})
|
||||
return response.ok
|
||||
except Exception:
|
||||
return False
|
||||
|
||||
dongle_id = params.get("DongleId")
|
||||
if isinstance(dongle_id, bytes):
|
||||
dongle_id = dongle_id.decode("utf-8", errors="ignore")
|
||||
@@ -163,7 +241,9 @@ def update_boot_logo(starpilot=False, stock=False, selected_logo=None):
|
||||
selected = selected_logo.decode("utf-8", "ignore") if isinstance(selected_logo, (bytes, bytearray)) else str(selected_logo)
|
||||
selected = selected.strip()
|
||||
if selected.lower() not in {"", "stock", "default"}:
|
||||
matched_logo = find_matching_theme_asset_file(THEME_SAVE_PATH / "bootlogos", selected)
|
||||
from openpilot.starpilot.common.theme_asset_names import find_matching_theme_asset_file
|
||||
|
||||
matched_logo = find_matching_theme_asset_file(_theme_save_path() / "bootlogos", selected)
|
||||
if matched_logo is not None:
|
||||
target_logo = matched_logo
|
||||
elif stock:
|
||||
@@ -176,6 +256,10 @@ def update_boot_logo(starpilot=False, stock=False, selected_logo=None):
|
||||
print(f"Error: Target logo file not found at {target_logo}")
|
||||
return
|
||||
|
||||
cache_key = _boot_logo_cache_key(selected_logo, target_logo)
|
||||
if boot_logo_location.is_file() and _boot_logo_cache_matches(cache_key):
|
||||
return
|
||||
|
||||
source_logo = target_logo
|
||||
staged_logo = Path("/tmp/starpilot_boot_logo.jpg")
|
||||
try:
|
||||
@@ -196,13 +280,18 @@ def update_boot_logo(starpilot=False, stock=False, selected_logo=None):
|
||||
current_logo = boot_logo_location.read_bytes() if boot_logo_location.is_file() else b""
|
||||
desired_logo = source_logo.read_bytes()
|
||||
if current_logo != desired_logo:
|
||||
mount_options = run_cmd(["findmnt", "-n", "-o", "OPTIONS", "/"], "Successfully retrieved mount options", "Failed to retrieve mount options")
|
||||
run_cmd(["sudo", "mount", "-o", "remount,rw", "/"], "Successfully remounted / as read-write", "Failed to remount /")
|
||||
run_cmd(["sudo", "cp", source_logo, boot_logo_location], "Successfully replaced boot logo", "Failed to replace boot logo")
|
||||
run_cmd(["sudo", "mount", "-o", f"remount,{mount_options}", "/"], "Successfully restored / mount options", "Failed to restore / mount options")
|
||||
mount_options = _run_cmd(["findmnt", "-n", "-o", "OPTIONS", "/"], "Successfully retrieved mount options", "Failed to retrieve mount options")
|
||||
_run_cmd(["sudo", "mount", "-o", "remount,rw", "/"], "Successfully remounted / as read-write", "Failed to remount /")
|
||||
if _run_cmd(["sudo", "cp", source_logo, boot_logo_location], "Successfully replaced boot logo", "Failed to replace boot logo") is None:
|
||||
return
|
||||
_run_cmd(["sudo", "mount", "-o", f"remount,{mount_options}", "/"], "Successfully restored / mount options", "Failed to restore / mount options")
|
||||
_write_boot_logo_cache(cache_key)
|
||||
|
||||
|
||||
def update_maps(now, params, params_memory, manual_update=False):
|
||||
from cereal import messaging
|
||||
from openpilot.starpilot.common.maps_catalog import normalize_schedule_value, sanitize_selected_locations_csv
|
||||
|
||||
maps_selected_raw = params.get("MapsSelected")
|
||||
maps_selected = sanitize_selected_locations_csv(maps_selected_raw)
|
||||
if not maps_selected:
|
||||
@@ -217,7 +306,8 @@ def update_maps(now, params, params_memory, manual_update=False):
|
||||
is_sunday = now.weekday() == 6
|
||||
schedule = normalize_schedule_value(params.get("PreferredSchedule"))
|
||||
|
||||
maps_downloaded = MAPS_PATH.exists() and any(path.is_file() for path in MAPS_PATH.rglob("*"))
|
||||
maps_path = _maps_path()
|
||||
maps_downloaded = maps_path.exists() and any(path.is_file() for path in maps_path.rglob("*"))
|
||||
if maps_downloaded and (schedule == 0 or (schedule == 1 and not is_sunday) or (schedule == 2 and not is_first)) and not manual_update:
|
||||
return
|
||||
|
||||
@@ -265,7 +355,7 @@ def update_maps(now, params, params_memory, manual_update=False):
|
||||
|
||||
def update_openpilot(thread_manager, params):
|
||||
def update_available():
|
||||
run_cmd(["pkill", "-SIGUSR1", "-f", "system.updated.updated"], "Checking for updates...", "Failed to check for update...", report=False)
|
||||
_run_cmd(["pkill", "-SIGUSR1", "-f", "system.updated.updated"], "Checking for updates...", "Failed to check for update...", report=False)
|
||||
|
||||
while params.get("UpdaterState") != "checking...":
|
||||
time.sleep(1)
|
||||
@@ -279,7 +369,7 @@ def update_openpilot(thread_manager, params):
|
||||
while params.get_bool("IsOnroad") or thread_manager.is_thread_alive("lock_doors"):
|
||||
time.sleep(60)
|
||||
|
||||
run_cmd(["pkill", "-SIGHUP", "-f", "system.updated.updated"], "Update available, downloading...", "Failed to download update...", report=False)
|
||||
_run_cmd(["pkill", "-SIGHUP", "-f", "system.updated.updated"], "Update available, downloading...", "Failed to download update...", report=False)
|
||||
|
||||
while not params.get_bool("UpdateAvailable"):
|
||||
time.sleep(60)
|
||||
|
||||
@@ -316,7 +316,12 @@ def default_ev_tuning_enabled(CP):
|
||||
ev_vehicle |= getattr(CP, "transmissionType", None) == car.CarParams.TransmissionType.direct
|
||||
return bool(ev_vehicle)
|
||||
|
||||
def get_starpilot_toggles(sm=messaging.SubMaster(["starpilotPlan"])):
|
||||
def get_starpilot_toggles(sm=None):
|
||||
if sm is None:
|
||||
if not hasattr(get_starpilot_toggles, "_sm"):
|
||||
get_starpilot_toggles._sm = messaging.SubMaster(["starpilotPlan"])
|
||||
sm = get_starpilot_toggles._sm
|
||||
|
||||
toggles_text = sm["starpilotPlan"].starpilotToggles
|
||||
if toggles_text:
|
||||
get_starpilot_toggles._last_toggles_text = toggles_text
|
||||
|
||||
@@ -1,29 +1,57 @@
|
||||
#!/usr/bin/env python3
|
||||
import time
|
||||
import json
|
||||
import jwt
|
||||
import random
|
||||
import string
|
||||
from typing import cast
|
||||
from pathlib import Path
|
||||
|
||||
from datetime import datetime, timedelta, UTC
|
||||
from openpilot.common.api import api_get, get_key_pair
|
||||
from openpilot.common.params import Params
|
||||
from openpilot.common.spinner import Spinner
|
||||
from openpilot.selfdrive.selfdrived.alertmanager import set_offroad_alert
|
||||
from openpilot.system.hardware import HARDWARE, PC
|
||||
from openpilot.system.hardware.hw import Paths
|
||||
from openpilot.common.swaglog import cloudlog
|
||||
|
||||
|
||||
UNREGISTERED_DONGLE_ID = "UnregisteredDevice"
|
||||
OFFROAD_UNREGISTERED_ALERT = "Offroad_UnregisteredHardware"
|
||||
KEYS = {"id_rsa": "RS256",
|
||||
"id_ecdsa": "ES256"}
|
||||
|
||||
|
||||
def api_get(*args, **kwargs):
|
||||
from openpilot.common.api import api_get as api_get_impl
|
||||
|
||||
return api_get_impl(*args, **kwargs)
|
||||
|
||||
|
||||
def get_key_pair() -> tuple[str, str, str] | tuple[None, None, None]:
|
||||
for key, algorithm in KEYS.items():
|
||||
private_path = Path(Paths.persist_root()) / "comma" / key
|
||||
public_path = Path(Paths.persist_root()) / "comma" / f"{key}.pub"
|
||||
if private_path.is_file() and public_path.is_file():
|
||||
return algorithm, private_path.read_text(), public_path.read_text()
|
||||
return None, None, None
|
||||
|
||||
|
||||
def _has_key_pair() -> bool:
|
||||
for key in KEYS:
|
||||
private_path = Path(Paths.persist_root()) / "comma" / key
|
||||
public_path = Path(Paths.persist_root()) / "comma" / f"{key}.pub"
|
||||
if private_path.is_file() and public_path.is_file():
|
||||
return True
|
||||
return False
|
||||
|
||||
def is_registered_device() -> bool:
|
||||
dongle = Params().get("DongleId")
|
||||
return dongle not in (None, UNREGISTERED_DONGLE_ID)
|
||||
|
||||
|
||||
def _set_registration_alert(params: Params, dongle_id: str | None) -> None:
|
||||
show_alert = (dongle_id == UNREGISTERED_DONGLE_ID) and not PC
|
||||
if show_alert:
|
||||
from openpilot.selfdrive.selfdrived.alertmanager import set_offroad_alert
|
||||
|
||||
set_offroad_alert(OFFROAD_UNREGISTERED_ALERT, True)
|
||||
else:
|
||||
params.remove(OFFROAD_UNREGISTERED_ALERT)
|
||||
|
||||
|
||||
def register(show_spinner=False, register_konik=False) -> str | None:
|
||||
"""
|
||||
All devices built since March 2024 come with all
|
||||
@@ -42,13 +70,18 @@ def register(show_spinner=False, register_konik=False) -> str | None:
|
||||
with open(Paths.persist_root()+"/comma/dongle_id") as f:
|
||||
dongle_id = f.read().strip()
|
||||
|
||||
# Create registration token, in the future, this key will make JWTs directly
|
||||
jwt_algo, private_key, public_key = get_key_pair()
|
||||
|
||||
if not public_key and not register_konik:
|
||||
if not _has_key_pair() and not register_konik:
|
||||
dongle_id = UNREGISTERED_DONGLE_ID
|
||||
cloudlog.warning("missing public key")
|
||||
elif dongle_id is None or register_konik:
|
||||
import json
|
||||
import jwt
|
||||
from datetime import datetime, timedelta, UTC
|
||||
from openpilot.common.spinner import Spinner
|
||||
|
||||
# Create registration token, in the future, this key will make JWTs directly
|
||||
jwt_algo, private_key, public_key = get_key_pair()
|
||||
|
||||
if show_spinner:
|
||||
spinner = Spinner()
|
||||
spinner.update("registering device")
|
||||
@@ -73,14 +106,14 @@ def register(show_spinner=False, register_konik=False) -> str | None:
|
||||
while True:
|
||||
try:
|
||||
register_token = jwt.encode({'register': True, 'exp': datetime.now(UTC).replace(tzinfo=None) + timedelta(hours=1)},
|
||||
cast(str, private_key), algorithm=jwt_algo)
|
||||
private_key, algorithm=jwt_algo)
|
||||
cloudlog.info("getting pilotauth")
|
||||
resp = api_get("v2/pilotauth/", method='POST', timeout=15,
|
||||
imei=imei1, imei2=imei2, serial=serial, public_key=public_key, register_token=register_token)
|
||||
|
||||
if resp.status_code in (402, 403):
|
||||
cloudlog.info(f"Unable to register device, got {resp.status_code}")
|
||||
dongle_id = ''.join(random.choices(string.ascii_lowercase + string.digits, k=16))
|
||||
dongle_id = UNREGISTERED_DONGLE_ID
|
||||
else:
|
||||
dongleauth = json.loads(resp.text)
|
||||
dongle_id = dongleauth["dongle_id"]
|
||||
@@ -99,7 +132,7 @@ def register(show_spinner=False, register_konik=False) -> str | None:
|
||||
if not register_konik and dongle_id != params.get("KonikDongleId"):
|
||||
params.put("DongleId", dongle_id)
|
||||
params.put("StockDongleId", dongle_id)
|
||||
set_offroad_alert("Offroad_UnregisteredHardware", (dongle_id == UNREGISTERED_DONGLE_ID) and not PC)
|
||||
_set_registration_alert(params, dongle_id)
|
||||
return dongle_id
|
||||
|
||||
|
||||
|
||||
+15
-12
@@ -1,18 +1,11 @@
|
||||
import errno
|
||||
import fcntl
|
||||
import os
|
||||
import sys
|
||||
import pathlib
|
||||
import shutil
|
||||
import signal
|
||||
import subprocess
|
||||
import tempfile
|
||||
import threading
|
||||
|
||||
from openpilot.common.basedir import BASEDIR
|
||||
from openpilot.common.params import Params
|
||||
|
||||
def unblock_stdout() -> None:
|
||||
import errno
|
||||
import fcntl
|
||||
import signal
|
||||
import sys
|
||||
|
||||
# get a non-blocking stdout
|
||||
child_pid, child_pty = os.forkpty()
|
||||
if child_pid != 0: # parent
|
||||
@@ -51,7 +44,17 @@ def write_onroad_params(started, params):
|
||||
|
||||
|
||||
def save_bootlog():
|
||||
import threading
|
||||
|
||||
def fn():
|
||||
import pathlib
|
||||
import shutil
|
||||
import subprocess
|
||||
import tempfile
|
||||
|
||||
from openpilot.common.basedir import BASEDIR
|
||||
from openpilot.common.params import Params
|
||||
|
||||
tmpdir = tempfile.mkdtemp()
|
||||
env = os.environ.copy()
|
||||
env['PARAMS_COPY_PATH'] = tmpdir
|
||||
|
||||
+52
-15
@@ -2,7 +2,6 @@
|
||||
import datetime
|
||||
import json
|
||||
import os
|
||||
import shutil
|
||||
from pathlib import Path
|
||||
import signal
|
||||
import sys
|
||||
@@ -24,26 +23,18 @@ def _append_boot_timing_line(line: str) -> None:
|
||||
|
||||
from cereal import car, log
|
||||
import cereal.messaging as messaging
|
||||
from openpilot.common.utils import atomic_write
|
||||
from openpilot.common.params import Params, ParamKeyFlag, ParamKeyType
|
||||
from openpilot.common.text_window import TextWindow
|
||||
from openpilot.system.hardware import HARDWARE
|
||||
from openpilot.system.manager.helpers import unblock_stdout, write_onroad_params, save_bootlog
|
||||
from openpilot.system.manager.process import ensure_running
|
||||
from openpilot.system.manager.process_config import managed_processes
|
||||
from openpilot.system.athena.registration import register, UNREGISTERED_DONGLE_ID
|
||||
from openpilot.common.swaglog import cloudlog, add_file_handler
|
||||
from openpilot.common.swaglog import cloudlog
|
||||
from openpilot.system.version import get_build_metadata, terms_version, training_version
|
||||
from openpilot.system.hardware.hw import Paths
|
||||
|
||||
_MANAGER_CORE_IMPORT_DONE = time.monotonic()
|
||||
|
||||
from openpilot.starpilot.common.starpilot_functions import starpilot_boot_functions, install_starpilot, uninstall_starpilot
|
||||
from openpilot.starpilot.common.starpilot_variables import (
|
||||
LEGACY_STARPILOT_PARAM_RENAMES,
|
||||
LEGACY_STARPILOT_STATS_KEY_RENAMES,
|
||||
get_starpilot_toggles,
|
||||
)
|
||||
|
||||
_MANAGER_IMPORT_DONE = time.monotonic()
|
||||
_manager_import_timing_line = (
|
||||
@@ -67,9 +58,23 @@ STARPILOT_PC_ROOT_MIGRATION_FLAG = Path("/data") / "starpilot_pc_root_v1"
|
||||
STARPILOT_PARAMS_CACHE_MIGRATION_FLAG = Path("/data") / "starpilot_params_cache_v1"
|
||||
STARPILOT_LEGACY_CACHE_MARKER_KEYS = ("RemapCancelToDistance",)
|
||||
STARPILOT_REMOVED_PARAM_KEYS = ("HumanFollowing",)
|
||||
UNREGISTERED_DONGLE_ID = "UnregisteredDevice"
|
||||
POWER_WATCHDOG_PATH = "/var/tmp/power_watchdog"
|
||||
LEGACY_CARMODEL_MIGRATIONS = {
|
||||
"CHEVROLET_BOLT_CC_2019_2021": "CHEVROLET_BOLT_CC_2018_2021",
|
||||
}
|
||||
LEGACY_STARPILOT_PARAM_RENAMES = {
|
||||
"FrogPilotApiToken": "StarPilotApiToken",
|
||||
"FrogPilotCarParams": "StarPilotCarParams",
|
||||
"FrogPilotCarParamsPersistent": "StarPilotCarParamsPersistent",
|
||||
"FrogPilotDongleId": "StarPilotDongleId",
|
||||
"FrogPilotStats": "StarPilotStats",
|
||||
}
|
||||
LEGACY_STARPILOT_STATS_KEY_RENAMES = {
|
||||
"FrogPilotDrives": "StarPilotDrives",
|
||||
"FrogPilotMeters": "StarPilotMeters",
|
||||
"FrogPilotSeconds": "StarPilotSeconds",
|
||||
}
|
||||
STARPILOT_STATS_DROP_KEYS = {"CurrentMonthsKilometers", "ResetStats"}
|
||||
STARPILOT_STATS_MAX_KEYS = {"LongestDistanceWithoutOverride", "MaxAcceleration"}
|
||||
|
||||
@@ -114,6 +119,30 @@ def _capture_manager_exception() -> None:
|
||||
cloudlog.exception("failed to capture manager exception")
|
||||
|
||||
|
||||
def _write_power_watchdog(timestamp: float) -> None:
|
||||
import tempfile
|
||||
|
||||
tmp_file_name = None
|
||||
try:
|
||||
with tempfile.NamedTemporaryFile("w", dir=os.path.dirname(POWER_WATCHDOG_PATH), delete=False) as f:
|
||||
tmp_file_name = f.name
|
||||
f.write(str(timestamp))
|
||||
os.replace(tmp_file_name, POWER_WATCHDOG_PATH)
|
||||
tmp_file_name = None
|
||||
finally:
|
||||
if tmp_file_name is not None:
|
||||
try:
|
||||
os.unlink(tmp_file_name)
|
||||
except FileNotFoundError:
|
||||
pass
|
||||
|
||||
|
||||
def _get_starpilot_toggles(sm=None):
|
||||
from openpilot.starpilot.common.starpilot_variables import get_starpilot_toggles
|
||||
|
||||
return get_starpilot_toggles(sm)
|
||||
|
||||
|
||||
def _to_text(value):
|
||||
if value is None:
|
||||
return None
|
||||
@@ -285,6 +314,8 @@ def _copy_param_store_without_overwrite(source: Path, destination: Path) -> int:
|
||||
if not source.is_dir():
|
||||
return 0
|
||||
|
||||
import shutil
|
||||
|
||||
destination.mkdir(parents=True, exist_ok=True)
|
||||
copied_entries = 0
|
||||
for path in source.iterdir():
|
||||
@@ -402,6 +433,8 @@ def _merge_tree_without_overwrite(source: Path, destination: Path) -> int:
|
||||
if not source.exists():
|
||||
return moved_entries
|
||||
|
||||
import shutil
|
||||
|
||||
if not destination.exists():
|
||||
destination.parent.mkdir(parents=True, exist_ok=True)
|
||||
shutil.move(str(source), str(destination))
|
||||
@@ -881,6 +914,8 @@ def manager_init() -> None:
|
||||
last_timing = _log_boot_timing("manager_init", "version_params", manager_init_start, last_timing)
|
||||
|
||||
# set dongle id
|
||||
from openpilot.system.athena.registration import register
|
||||
|
||||
reg_res = register(show_spinner=True)
|
||||
if reg_res:
|
||||
dongle_id = reg_res
|
||||
@@ -958,7 +993,7 @@ def manager_thread() -> None:
|
||||
last_timing = _log_boot_timing("manager_thread", "messaging", manager_thread_start, last_timing)
|
||||
|
||||
write_onroad_params(False, params)
|
||||
initial_toggles = get_starpilot_toggles()
|
||||
initial_toggles = _get_starpilot_toggles()
|
||||
last_timing = _log_boot_timing("manager_thread", "initial_toggles", manager_thread_start, last_timing)
|
||||
ensure_running(managed_processes.values(), False, params=params, CP=sm['carParams'], not_run=ignore, starpilot_toggles=initial_toggles)
|
||||
last_timing = _log_boot_timing("manager_thread", "initial_ensure_running", manager_thread_start, last_timing)
|
||||
@@ -974,7 +1009,7 @@ def manager_thread() -> None:
|
||||
|
||||
params_memory = Params(memory=True)
|
||||
|
||||
starpilot_toggles = get_starpilot_toggles()
|
||||
starpilot_toggles = _get_starpilot_toggles()
|
||||
last_timing = _log_boot_timing("manager_thread", "loop_toggles", manager_thread_start, last_timing)
|
||||
_log_boot_timing("manager_thread", "loop_ready", manager_thread_start, last_timing)
|
||||
|
||||
@@ -1024,8 +1059,7 @@ def manager_thread() -> None:
|
||||
# kick AGNOS power monitoring watchdog
|
||||
try:
|
||||
if sm.all_checks(['deviceState']):
|
||||
with atomic_write("/var/tmp/power_watchdog", "w", overwrite=True) as f:
|
||||
f.write(str(time.monotonic()))
|
||||
_write_power_watchdog(time.monotonic())
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
@@ -1048,7 +1082,7 @@ def manager_thread() -> None:
|
||||
break
|
||||
|
||||
# StarPilot variables
|
||||
starpilot_toggles = get_starpilot_toggles(sm)
|
||||
starpilot_toggles = _get_starpilot_toggles(sm)
|
||||
|
||||
|
||||
def main() -> None:
|
||||
@@ -1087,6 +1121,9 @@ if __name__ == "__main__":
|
||||
except KeyboardInterrupt:
|
||||
print("got CTRL-C, exiting")
|
||||
except Exception:
|
||||
from openpilot.common.swaglog import add_file_handler
|
||||
from openpilot.common.text_window import TextWindow
|
||||
|
||||
add_file_handler(cloudlog)
|
||||
cloudlog.exception("Manager failed to start")
|
||||
|
||||
|
||||
Reference in New Issue
Block a user