f8e13417f2
date: 2026-08-15T14:20:10 master commit: d48cfa730bf21593b684efeaf3fd8940695e1dea
107 lines
5.4 KiB
Python
107 lines
5.4 KiB
Python
"""
|
|
Copyright (c) 2021-, Haibin Wen, sunnypilot, and a number of other contributors.
|
|
|
|
This file is part of sunnypilot and is licensed under the MIT License.
|
|
See the LICENSE.md file in the root directory for more details.
|
|
"""
|
|
import datetime
|
|
import os
|
|
from pathlib import Path
|
|
|
|
from openpilot.selfdrive.ui.ui_state import ui_state
|
|
from openpilot.selfdrive.ui.layouts.settings.developer import DeveloperLayout
|
|
from openpilot.common.hardware import PC
|
|
from openpilot.common.hardware.hw import Paths
|
|
from openpilot.system.ui.lib.application import gui_app
|
|
from openpilot.system.ui.lib.multilang import tr
|
|
from openpilot.system.ui.widgets import DialogResult
|
|
from openpilot.system.ui.widgets.confirm_dialog import ConfirmDialog
|
|
from openpilot.system.ui.widgets.list_view import button_item
|
|
|
|
from openpilot.system.ui.sunnypilot.widgets.html_render import HtmlModalSP
|
|
from openpilot.system.ui.sunnypilot.widgets.list_view import toggle_item_sp
|
|
|
|
PREBUILT_PATH = os.path.join(Paths.comma_home(), "prebuilt") if PC else "/data/openpilot/prebuilt"
|
|
|
|
|
|
class DeveloperLayoutSP(DeveloperLayout):
|
|
def __init__(self):
|
|
super().__init__()
|
|
self.error_log_path = os.path.join(Paths.crash_log_root(), "error.log")
|
|
self._is_release_branch: bool = self._is_release or ui_state.params.get_bool("IsReleaseSpBranch")
|
|
self._is_development_branch: bool = ui_state.params.get_bool("IsTestedBranch") or ui_state.params.get_bool("IsDevelopmentBranch")
|
|
self._initialize_items()
|
|
|
|
for item in self.items:
|
|
self._scroller.add_widget(item)
|
|
|
|
def _initialize_items(self):
|
|
self.show_advanced_controls = toggle_item_sp(tr("Show Advanced Controls"),
|
|
tr("Toggle visibility of advanced sunnypilot controls.<br>This only changes the visibility of the toggles; " +
|
|
"it does not change the actual enabled/disabled state."), param="ShowAdvancedControls")
|
|
|
|
self.enable_github_runner_toggle = toggle_item_sp(tr("GitHub Runner Service"), tr("Enables or disables the GitHub runner service."),
|
|
param="EnableGithubRunner")
|
|
|
|
self.enable_copyparty_toggle = toggle_item_sp(tr("copyparty Service"),
|
|
tr("copyparty is a very capable file server, you can use it to download your routes, view your logs " +
|
|
"and even make some edits on some files from your browser. " +
|
|
"Requires you to connect to your comma locally via its IP address."), param="EnableCopyparty")
|
|
|
|
self.prebuilt_toggle = toggle_item_sp(tr("Quickboot Mode"), "", param="QuickBootToggle", callback=self._on_prebuilt_toggled)
|
|
|
|
self.error_log_btn = button_item(tr("Error Log"), tr("VIEW"), tr("View the error log for sunnypilot crashes."), callback=self._on_error_log_clicked)
|
|
|
|
self.items: list = [self.show_advanced_controls, self.enable_github_runner_toggle, self.enable_copyparty_toggle, self.prebuilt_toggle, self.error_log_btn,]
|
|
|
|
@staticmethod
|
|
def _on_prebuilt_toggled(state):
|
|
if state:
|
|
Path(PREBUILT_PATH).touch(exist_ok=True)
|
|
else:
|
|
os.remove(PREBUILT_PATH)
|
|
ui_state.params.put_bool("QuickBootToggle", state)
|
|
|
|
def _on_delete_confirm(self, result):
|
|
if result == DialogResult.CONFIRM:
|
|
if os.path.exists(self.error_log_path):
|
|
os.remove(self.error_log_path)
|
|
|
|
def _on_error_log_closed(self, result, log_exists):
|
|
if result == DialogResult.CONFIRM and log_exists:
|
|
dialog2 = ConfirmDialog(tr("Would you like to delete this log?"), tr("Yes"), tr("No"), rich=False, callback=self._on_delete_confirm)
|
|
gui_app.push_widget(dialog2)
|
|
|
|
def _on_error_log_clicked(self):
|
|
text = ""
|
|
if os.path.exists(self.error_log_path):
|
|
text = f"<b>{datetime.datetime.fromtimestamp(os.path.getmtime(self.error_log_path)).strftime('%d-%b-%Y %H:%M:%S').upper()}</b><br><br>"
|
|
try:
|
|
with open(self.error_log_path) as file:
|
|
text += file.read()
|
|
except Exception:
|
|
pass
|
|
dialog = HtmlModalSP(text=text, callback=lambda result: self._on_error_log_closed(result, os.path.exists(self.error_log_path)))
|
|
gui_app.push_widget(dialog)
|
|
|
|
def _update_state(self):
|
|
disable_updates = ui_state.params.get_bool("DisableUpdates")
|
|
show_advanced = ui_state.params.get_bool("ShowAdvancedControls")
|
|
|
|
if (prebuilt_file := os.path.exists(PREBUILT_PATH)) != ui_state.params.get_bool("QuickBootToggle"):
|
|
ui_state.params.put_bool("QuickBootToggle", prebuilt_file)
|
|
self.prebuilt_toggle.action_item.set_state(prebuilt_file)
|
|
|
|
self.prebuilt_toggle.set_visible(show_advanced and not (self._is_release_branch or self._is_development_branch))
|
|
self.prebuilt_toggle.action_item.set_enabled(disable_updates)
|
|
|
|
if disable_updates:
|
|
self.prebuilt_toggle.set_description(tr("When toggled on, this creates a prebuilt file to allow accelerated boot times. When toggled off, it " +
|
|
"removes the prebuilt file so compilation of locally edited cpp files can be made."))
|
|
else:
|
|
self.prebuilt_toggle.set_description(tr("Quickboot mode requires updates to be disabled.<br>Enable 'Disable Updates' in the Software panel first."))
|
|
|
|
self.enable_copyparty_toggle.set_visible(show_advanced)
|
|
self.enable_github_runner_toggle.set_visible(show_advanced and not self._is_release_branch)
|
|
self.error_log_btn.set_visible(not self._is_release_branch)
|