From 5b1bfc26db49780666377dab694593cb178d62d7 Mon Sep 17 00:00:00 2001 From: DevTekVE Date: Sun, 5 Jan 2025 10:47:28 +0100 Subject: [PATCH] ui: add sunnylink settings and sidebar status (#503) * Add Sunnylink integration for improved device communication This commit introduces Sunnylink support, including modules for API interactions, device registration, logging, and uploader processes. Key changes involve adding Sunnylink-related components, such as sunnylinkd, manage_sunnylinkd, and associated utilities, along with seamless integration into process management. * Refactor Sunnylink modules and update import paths Standardize parameter handling in Sunnylink functions by initializing Params within functions as needed. Update imports to use fully-qualified paths for better clarity and consistency. Also, refactor logging messages for improved readability and maintainability. * Add Sunnylink support and improve log handling Introduced Sunnylink-specific functionality, including compression for oversized logs and platform-specific socket handling for macOS. Improved logging mechanisms, refactored log queue management, and fixed exception handling in sunnylinkd. * Refactor and fix minor coding style inconsistencies Remove unnecessary string concatenation, adjust spacing for better readability, and ensure cleaner code in `athenad.py` and `sunnylink.py`. Added a macOS-specific comment for TCP_KEEPALIVE configuration to improve code clarity. * Replace platform system check with sys platform in athenad.py To check for macOS platform, the code in athenad.py has been altered. Originally, the platform.system() function was used. However, the function has been replaced with sys.platform for a more consistent and preferable syntax. Particularly, this has been modified in the context of setting socket options. * Apply suggestions from code review Co-authored-by: sourcery-ai[bot] <58596630+sourcery-ai[bot]@users.noreply.github.com> * Simplify imports and reformat API function. Removed unused `platform` import for cleanup in `athenad.py`. Improved readability of `api_get` in `__init__.py` by reformatting the long return statement into multiple lines. * Adjust backoff logic and refactor API call formatting. Introduce randomness to backoff calculation in Sunnylink API to reduce synchronization issues. Minor code refactoring improves readability in the API call logic. * Refactor Sunnylink network check logic. Removed hardware-based network check due to performance concerns and replaced it with a real-time device state monitoring loop. This improves efficiency and ensures accurate online status before proceeding with Sunnylink registration. * Apply suggestions from code review * `Refactor saveParams error handling and simplify logic` Removed redundant try-except block wrapping the entire method for clarity. Moved error logging directly inside the loop to handle individual parameter exceptions more effectively. Simplified dictionary construction and improved error logging format. * Add BACKUP flag to select persistent parameters This commit introduces a new BACKUP flag and applies it to specific persistent parameters in `params.cc` and `params.h`. The BACKUP flag enhances data retention by designating parameters for inclusion in backups, ensuring crucial information is preserved across sessions. * Simplify Sunnypilot params formatting Removed unnecessary blank lines and adjusted the Sunnypilot comment format for better readability and consistency. No functional changes were made. * SP: Move Sunnypilot-related code to sunnypilot/sunnylink (#504) * Refactor and relocate sunnylink-related modules sunnylink components have been reorganized for better modularity and clarity, with files moved under `sunnypilot/sunnylink`. Unused code was removed, and reusable utilities were separated for easier maintenance. Adjusted references across the project to reflect these changes. * Permissions * adding init py * Add sunnylink toggle to developer panel and translations This commit introduces a new toggle for enabling or disabling sunnylink in the developer panel. Corresponding translation entries have been added for all supported languages to ensure compatibility across the UI. * Add SunnyLink integration and multi-language support updates Enhanced SidebarSP with SunnyLink connection status and temperature display. Extended translations for multiple languages, including new strings. Updated build scripts and added utility functions for SunnyPilot-specific features. * Need it this way as it's intentionally shortened. Sorry * format * only block drawing * format * format * fix path * cleanup translations * sunnylink panel * offroad transition * remove stretch * add panel to ui preview * Translating to spanish * just reorder params * Refactor sidebar drawing method names and remove unused code. Renamed `paintSidebar` to `drawSidebar` for better clarity across both `Sidebar` and `SidebarSP` classes. Removed unused utility functions `drawRoundedRect` and `interpColor` to streamline the codebase and improve maintainability. * Updating translations --------- Co-authored-by: sourcery-ai[bot] <58596630+sourcery-ai[bot]@users.noreply.github.com> Co-authored-by: Jason Wen --- .codespellignore | 1 + .github/workflows/ui_preview.yaml | 2 +- common/params.cc | 12 +++- selfdrive/ui/SConscript | 5 +- selfdrive/ui/qt/sidebar.cc | 6 +- selfdrive/ui/qt/sidebar.h | 2 +- selfdrive/ui/sunnypilot/SConscript | 8 ++- .../qt/offroad/settings/settings.cc | 2 + .../qt/offroad/settings/sunnylink_panel.cc | 72 +++++++++++++++++++ .../qt/offroad/settings/sunnylink_panel.h | 31 ++++++++ selfdrive/ui/sunnypilot/qt/sidebar.cc | 37 ++++++++-- selfdrive/ui/sunnypilot/qt/sidebar.h | 14 +++- selfdrive/ui/sunnypilot/qt/util.cc | 35 +++++++++ selfdrive/ui/sunnypilot/qt/util.h | 18 +++++ selfdrive/ui/tests/test_ui/run.py | 19 +++-- selfdrive/ui/translations/main_ar.ts | 58 +++++++++++++++ selfdrive/ui/translations/main_de.ts | 58 +++++++++++++++ selfdrive/ui/translations/main_es.ts | 58 +++++++++++++++ selfdrive/ui/translations/main_fr.ts | 58 +++++++++++++++ selfdrive/ui/translations/main_ja.ts | 58 +++++++++++++++ selfdrive/ui/translations/main_ko.ts | 58 +++++++++++++++ selfdrive/ui/translations/main_pt-BR.ts | 58 +++++++++++++++ selfdrive/ui/translations/main_th.ts | 58 +++++++++++++++ selfdrive/ui/translations/main_tr.ts | 58 +++++++++++++++ selfdrive/ui/translations/main_zh-CHS.ts | 58 +++++++++++++++ selfdrive/ui/translations/main_zh-CHT.ts | 58 +++++++++++++++ 26 files changed, 881 insertions(+), 21 deletions(-) create mode 100644 selfdrive/ui/sunnypilot/qt/offroad/settings/sunnylink_panel.cc create mode 100644 selfdrive/ui/sunnypilot/qt/offroad/settings/sunnylink_panel.h create mode 100644 selfdrive/ui/sunnypilot/qt/util.cc create mode 100644 selfdrive/ui/sunnypilot/qt/util.h diff --git a/.codespellignore b/.codespellignore index 916169347..ad053601e 100644 --- a/.codespellignore +++ b/.codespellignore @@ -1 +1,2 @@ Wen +REGIST diff --git a/.github/workflows/ui_preview.yaml b/.github/workflows/ui_preview.yaml index a91fba957..0df696fd4 100644 --- a/.github/workflows/ui_preview.yaml +++ b/.github/workflows/ui_preview.yaml @@ -86,7 +86,7 @@ jobs: run: >- sudo apt-get install -y imagemagick - scenes="homescreen settings_device settings_software settings_toggles settings_sunnypilot settings_sunnypilot_mads settings_developer offroad_alert update_available prime onroad onroad_disengaged onroad_override onroad_sidebar onroad_wide onroad_wide_sidebar onroad_alert_small onroad_alert_mid onroad_alert_full driver_camera body keyboard" + scenes="homescreen settings_device settings_software settings_sunnylink settings_toggles settings_sunnypilot settings_sunnypilot_mads settings_developer offroad_alert update_available prime onroad onroad_disengaged onroad_override onroad_sidebar onroad_wide onroad_wide_sidebar onroad_alert_small onroad_alert_mid onroad_alert_full driver_camera body keyboard" A=($scenes) DIFF="" diff --git a/common/params.cc b/common/params.cc index 85dc56463..edf002f10 100644 --- a/common/params.cc +++ b/common/params.cc @@ -201,18 +201,24 @@ std::unordered_map keys = { {"UpdaterLastFetchTime", PERSISTENT}, {"Version", PERSISTENT}, - // sunnypilot params + // --- sunnypilot params --- // {"EnableGithubRunner", PERSISTENT | BACKUP}, - {"EnableSunnylinkUploader", PERSISTENT | BACKUP}, - {"LastSunnylinkPingTime", CLEAR_ON_MANAGER_START}, + + // MADS params {"Mads", PERSISTENT | BACKUP}, {"MadsMainCruiseAllowed", PERSISTENT | BACKUP}, {"MadsPauseLateralOnBrake", PERSISTENT | BACKUP}, {"MadsUnifiedEngagementMode", PERSISTENT | BACKUP}, + + // Model Manager params {"ModelManager_ActiveBundle", PERSISTENT}, {"ModelManager_DownloadIndex", CLEAR_ON_MANAGER_START | CLEAR_ON_OFFROAD_TRANSITION | CLEAR_ON_ONROAD_TRANSITION}, {"ModelManager_LastSyncTime", CLEAR_ON_MANAGER_START | CLEAR_ON_OFFROAD_TRANSITION}, {"ModelManager_ModelsCache", PERSISTENT | BACKUP}, + + // sunnylink params + {"EnableSunnylinkUploader", PERSISTENT | BACKUP}, + {"LastSunnylinkPingTime", CLEAR_ON_MANAGER_START}, {"SunnylinkDongleId", PERSISTENT}, {"SunnylinkdPid", PERSISTENT}, {"SunnylinkEnabled", PERSISTENT}, diff --git a/selfdrive/ui/SConscript b/selfdrive/ui/SConscript index 47ad5bdef..fa2ff3bc7 100644 --- a/selfdrive/ui/SConscript +++ b/selfdrive/ui/SConscript @@ -14,14 +14,15 @@ if arch == "Darwin": sp_widgets_src = [] sp_qt_src = [] +sp_qt_util = [] if not GetOption('stock_ui'): SConscript(['sunnypilot/SConscript']) - Import('sp_widgets_src', 'sp_qt_src') + Import('sp_widgets_src', 'sp_qt_src', 'sp_qt_util') # FIXME: remove this once we're on 5.15 (24.04) qt_env['CXXFLAGS'] += ["-Wno-deprecated-declarations"] -qt_util = qt_env.Library("qt_util", ["#selfdrive/ui/qt/api.cc", "#selfdrive/ui/qt/util.cc"], LIBS=base_libs) +qt_util = qt_env.Library("qt_util", ["#selfdrive/ui/qt/api.cc", "#selfdrive/ui/qt/util.cc"] + sp_qt_util, LIBS=base_libs) widgets_src = ["qt/widgets/input.cc", "qt/widgets/wifi.cc", "qt/prime_state.cc", "qt/widgets/ssh_keys.cc", "qt/widgets/toggle.cc", "qt/widgets/controls.cc", "qt/widgets/offroad_alerts.cc", "qt/widgets/prime.cc", "qt/widgets/keyboard.cc", diff --git a/selfdrive/ui/qt/sidebar.cc b/selfdrive/ui/qt/sidebar.cc index 866a5b62d..fd8ea5bcf 100644 --- a/selfdrive/ui/qt/sidebar.cc +++ b/selfdrive/ui/qt/sidebar.cc @@ -110,10 +110,10 @@ void Sidebar::updateState(const UIState &s) { void Sidebar::paintEvent(QPaintEvent *event) { QPainter p(this); - paintSidebar(p); + drawSidebar(p); } -void Sidebar::paintSidebar(QPainter &p) { +void Sidebar::drawSidebar(QPainter &p) { p.setPen(Qt::NoPen); p.setRenderHint(QPainter::Antialiasing); @@ -140,8 +140,10 @@ void Sidebar::paintSidebar(QPainter &p) { const QRect r = QRect(58, 247, width() - 100, 50); p.drawText(r, Qt::AlignLeft | Qt::AlignVCenter, net_type); +#ifndef SUNNYPILOT // metrics drawMetric(p, temp_status.first, temp_status.second, 338); drawMetric(p, panda_status.first, panda_status.second, 496); drawMetric(p, connect_status.first, connect_status.second, 654); +#endif } diff --git a/selfdrive/ui/qt/sidebar.h b/selfdrive/ui/qt/sidebar.h index b1ce5887f..3c57d10a1 100644 --- a/selfdrive/ui/qt/sidebar.h +++ b/selfdrive/ui/qt/sidebar.h @@ -40,7 +40,7 @@ protected: void mousePressEvent(QMouseEvent *event) override; void mouseReleaseEvent(QMouseEvent *event) override; void drawMetric(QPainter &p, const QPair &label, QColor c, int y); - virtual void paintSidebar(QPainter &p); + virtual void drawSidebar(QPainter &p); QPixmap home_img, flag_img, settings_img; bool onroad, flag_pressed, settings_pressed; diff --git a/selfdrive/ui/sunnypilot/SConscript b/selfdrive/ui/sunnypilot/SConscript index 3e3bda6b6..0a5016d58 100644 --- a/selfdrive/ui/sunnypilot/SConscript +++ b/selfdrive/ui/sunnypilot/SConscript @@ -4,6 +4,10 @@ widgets_src = [ "sunnypilot/qt/widgets/scrollview.cc", ] +qt_util = [ + "sunnypilot/qt/util.cc", +] + qt_src = [ "sunnypilot/ui.cc", "sunnypilot/qt/sidebar.cc", @@ -11,6 +15,7 @@ qt_src = [ "sunnypilot/qt/home.cc", "sunnypilot/qt/offroad/settings/settings.cc", "sunnypilot/qt/offroad/settings/software_panel.cc", + "sunnypilot/qt/offroad/settings/sunnylink_panel.cc", "sunnypilot/qt/offroad/settings/sunnypilot_panel.cc", "sunnypilot/qt/onroad/onroad_home.cc", ] @@ -21,5 +26,6 @@ sunnypilot_panel_qt_src = [ sp_widgets_src = widgets_src sp_qt_src = qt_src + sunnypilot_panel_qt_src +sp_qt_util = qt_util -Export('sp_widgets_src', 'sp_qt_src') +Export('sp_widgets_src', 'sp_qt_src', "sp_qt_util") diff --git a/selfdrive/ui/sunnypilot/qt/offroad/settings/settings.cc b/selfdrive/ui/sunnypilot/qt/offroad/settings/settings.cc index cd7657e54..b5e87e47c 100644 --- a/selfdrive/ui/sunnypilot/qt/offroad/settings/settings.cc +++ b/selfdrive/ui/sunnypilot/qt/offroad/settings/settings.cc @@ -12,6 +12,7 @@ #include "selfdrive/ui/qt/offroad/developer_panel.h" #include "selfdrive/ui/sunnypilot/qt/offroad/settings/software_panel.h" +#include "selfdrive/ui/sunnypilot/qt/offroad/settings/sunnylink_panel.h" #include "selfdrive/ui/sunnypilot/qt/offroad/settings/sunnypilot_panel.h" TogglesPanelSP::TogglesPanelSP(SettingsWindow *parent) : TogglesPanel(parent) { @@ -69,6 +70,7 @@ SettingsWindowSP::SettingsWindowSP(QWidget *parent) : SettingsWindow(parent) { QList panels = { PanelInfo(" " + tr("Device"), device, "../../sunnypilot/selfdrive/assets/offroad/icon_home.svg"), PanelInfo(" " + tr("Network"), networking, "../assets/offroad/icon_network.png"), + PanelInfo(" " + tr("sunnylink"), new SunnylinkPanel(this), "../assets/offroad/icon_wifi_strength_full.svg"), PanelInfo(" " + tr("Toggles"), toggles, "../../sunnypilot/selfdrive/assets/offroad/icon_toggle.png"), PanelInfo(" " + tr("Software"), new SoftwarePanelSP(this), "../../sunnypilot/selfdrive/assets/offroad/icon_software.png"), PanelInfo(" " + tr("sunnypilot"), new SunnypilotPanel(this), "../assets/images/button_home.png"), diff --git a/selfdrive/ui/sunnypilot/qt/offroad/settings/sunnylink_panel.cc b/selfdrive/ui/sunnypilot/qt/offroad/settings/sunnylink_panel.cc new file mode 100644 index 000000000..12ae2209f --- /dev/null +++ b/selfdrive/ui/sunnypilot/qt/offroad/settings/sunnylink_panel.cc @@ -0,0 +1,72 @@ +/** + * 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. + */ + +#include "selfdrive/ui/sunnypilot/qt/offroad/settings/sunnylink_panel.h" + +#include "selfdrive/ui/sunnypilot/qt/util.h" +#include "selfdrive/ui/sunnypilot/qt/widgets/controls.h" + +SunnylinkPanel::SunnylinkPanel(QWidget *parent) : QFrame(parent) { + main_layout = new QStackedLayout(this); + ListWidget *list = new ListWidget(this, false); + + sunnylinkScreen = new QWidget(this); + QVBoxLayout *vlayout = new QVBoxLayout(sunnylinkScreen); + vlayout->setContentsMargins(50, 20, 50, 20); + + QString sunnylinkEnabledBtnDesc = tr("This is the master switch, it will allow you to cutoff any sunnylink requests should you want to do that."); + sunnylinkEnabledBtn = new ParamControl( + "SunnylinkEnabled", + tr("Enable sunnylink"), + sunnylinkEnabledBtnDesc, + ""); + list->addItem(sunnylinkEnabledBtn); + + connect(sunnylinkEnabledBtn, &ParamControl::showDescriptionEvent, [=]() { + // resets the description to the default one for the Easter egg + sunnylinkEnabledBtn->setDescription(sunnylinkEnabledBtnDesc); + }); + + connect(sunnylinkEnabledBtn, &ParamControl::toggleFlipped, [=](bool enabled) { + if (enabled) { + auto proud_description = ""+ tr("🎉Welcome back! We're excited to see you've enabled sunnylink again! 🚀")+ ""; + sunnylinkEnabledBtn->showDescription(); + sunnylinkEnabledBtn->setDescription(proud_description); + } else { + auto shame_description = ""+ tr("👋Not going to lie, it's sad to see you disabled sunnylink 😢, but we'll be here when you're ready to come back 🎉.")+ ""; + sunnylinkEnabledBtn->showDescription(); + sunnylinkEnabledBtn->setDescription(shame_description); + } + + updatePanel(offroad); + }); + + QObject::connect(uiState(), &UIState::offroadTransition, this, &SunnylinkPanel::updatePanel); + + sunnylinkScroller = new ScrollViewSP(list, this); + vlayout->addWidget(sunnylinkScroller); + + main_layout->addWidget(sunnylinkScreen); +} + +void SunnylinkPanel::showEvent(QShowEvent *event) { + updatePanel(offroad); +} + +void SunnylinkPanel::updatePanel(bool _offroad) { + QString sunnylink_device_id = tr("Device ID") + " " + getSunnylinkDongleId().value_or(tr("N/A")); + + sunnylinkEnabledBtn->setEnabled(_offroad); + + if (sunnylinkEnabledBtn->isToggled()) { + sunnylinkEnabledBtn->setValue(sunnylink_device_id); + } else { + sunnylinkEnabledBtn->setValue(""); + } + + offroad = _offroad; +} diff --git a/selfdrive/ui/sunnypilot/qt/offroad/settings/sunnylink_panel.h b/selfdrive/ui/sunnypilot/qt/offroad/settings/sunnylink_panel.h new file mode 100644 index 000000000..824a081af --- /dev/null +++ b/selfdrive/ui/sunnypilot/qt/offroad/settings/sunnylink_panel.h @@ -0,0 +1,31 @@ +/** + * 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. + */ + +#pragma once + +#include "selfdrive/ui/sunnypilot/qt/offroad/settings/settings.h" +#include "selfdrive/ui/sunnypilot/qt/widgets/scrollview.h" + +class SunnylinkPanel : public QFrame { + Q_OBJECT + +public: + explicit SunnylinkPanel(QWidget *parent = nullptr); + void showEvent(QShowEvent *event) override; + +public slots: + void updatePanel(bool _offroad); + +private: + Params params; + QStackedLayout *main_layout = nullptr; + QWidget *sunnylinkScreen = nullptr; + ScrollViewSP *sunnylinkScroller = nullptr; + bool offroad; + + ParamControl *sunnylinkEnabledBtn; +}; diff --git a/selfdrive/ui/sunnypilot/qt/sidebar.cc b/selfdrive/ui/sunnypilot/qt/sidebar.cc index af090e738..a4dc1d676 100644 --- a/selfdrive/ui/sunnypilot/qt/sidebar.cc +++ b/selfdrive/ui/sunnypilot/qt/sidebar.cc @@ -7,12 +7,12 @@ #include "selfdrive/ui/sunnypilot/qt/sidebar.h" -#include -#include - #include "selfdrive/ui/qt/util.h" +#include "selfdrive/ui/sunnypilot/qt/util.h" +#include "common/params.h" SidebarSP::SidebarSP(QWidget *parent) : Sidebar(parent) { + // Redirect uiUpdate signal to SidebarSP::updateState instead of Sidebar::updateState QObject::disconnect(uiState(), &UIState::uiUpdate, this, &Sidebar::updateState); QObject::connect(uiStateSP(), &UIStateSP::uiUpdate, this, &SidebarSP::updateState); } @@ -20,8 +20,35 @@ SidebarSP::SidebarSP(QWidget *parent) : Sidebar(parent) { void SidebarSP::updateState(const UIStateSP &s) { if (!isVisible()) return; Sidebar::updateState(s); + + ItemStatus sunnylinkStatus; + auto sl_dongle_id = getSunnylinkDongleId(); + auto last_sunnylink_ping_str = params.get("LastSunnylinkPingTime"); + auto last_sunnylink_ping = std::stoull(last_sunnylink_ping_str.empty() ? "0" : last_sunnylink_ping_str); + auto elapsed_sunnylink_ping = nanos_since_boot() - last_sunnylink_ping; + auto sunnylink_enabled = params.getBool("SunnylinkEnabled"); + + QString status = tr("DISABLED"); + QColor color = disabled_color; + + if (sunnylink_enabled && last_sunnylink_ping == 0) { + // If sunnylink is enabled, but we don't have a dongle id, and we haven't received a ping yet, we are registering + status = sl_dongle_id.has_value() ? tr("OFFLINE") : tr("REGIST..."); + color = sl_dongle_id.has_value() ? warning_color : progress_color; + } else if (sunnylink_enabled) { + // If sunnylink is enabled, we are considered online if we have received a ping in the last 80 seconds, else error. + status = elapsed_sunnylink_ping < 80000000000ULL ? tr("ONLINE") : tr("ERROR"); + color = elapsed_sunnylink_ping < 80000000000ULL ? good_color : danger_color; + } + sunnylinkStatus = ItemStatus{{tr("SUNNYLINK"), status}, color}; + setProperty("sunnylinkStatus", QVariant::fromValue(sunnylinkStatus)); } -void SidebarSP::paintSidebar(QPainter &p) { - Sidebar::paintSidebar(p); +void SidebarSP::drawSidebar(QPainter &p) { + Sidebar::drawSidebar(p); + // metrics + drawMetric(p, temp_status.first, temp_status.second, 310); + drawMetric(p, panda_status.first, panda_status.second, 440); + drawMetric(p, connect_status.first, connect_status.second, 570); + drawMetric(p, sunnylink_status.first, sunnylink_status.second, 700); } diff --git a/selfdrive/ui/sunnypilot/qt/sidebar.h b/selfdrive/ui/sunnypilot/qt/sidebar.h index ff9b78748..133106cfd 100644 --- a/selfdrive/ui/sunnypilot/qt/sidebar.h +++ b/selfdrive/ui/sunnypilot/qt/sidebar.h @@ -15,6 +15,8 @@ class SidebarSP : public Sidebar { Q_OBJECT + Q_PROPERTY(ItemStatus sunnylinkStatus MEMBER sunnylink_status NOTIFY valueChanged); + Q_PROPERTY(QString sidebarTemp MEMBER sidebar_temp_str NOTIFY valueChanged); public slots: void updateState(const UIStateSP &s); @@ -23,5 +25,15 @@ public: explicit SidebarSP(QWidget *parent = 0); private: - void paintSidebar(QPainter &p) override; + void drawSidebar(QPainter &p) override; + + Params params; + QString sidebar_temp = "0"; + QString sidebar_temp_str = "0"; + +protected: + const QColor progress_color = QColor(3, 132, 252); + const QColor disabled_color = QColor(128, 128, 128); + + ItemStatus sunnylink_status; }; diff --git a/selfdrive/ui/sunnypilot/qt/util.cc b/selfdrive/ui/sunnypilot/qt/util.cc new file mode 100644 index 000000000..a2bd7bde2 --- /dev/null +++ b/selfdrive/ui/sunnypilot/qt/util.cc @@ -0,0 +1,35 @@ +/** + * 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. + */ + +#include "selfdrive/ui/sunnypilot/qt/util.h" +#include "selfdrive/ui/qt/util.h" + +#include +#include + +#include +#include +#include + +#include "system/hardware/hw.h" + +std::optional getParamIgnoringDefault(const std::string ¶m_name, const std::string &default_value) { + std::string value = Params().get(param_name); + + if (!value.empty() && value != default_value) + return QString::fromStdString(value); + + return {}; +} + +QString getUserAgent(bool sunnylink) { + return (sunnylink ? "sunnypilot-" : "openpilot-") + getVersion(); +} + +std::optional getSunnylinkDongleId() { + return getParamIgnoringDefault("SunnylinkDongleId", "UnregisteredDevice"); +} diff --git a/selfdrive/ui/sunnypilot/qt/util.h b/selfdrive/ui/sunnypilot/qt/util.h new file mode 100644 index 000000000..a6c58eb06 --- /dev/null +++ b/selfdrive/ui/sunnypilot/qt/util.h @@ -0,0 +1,18 @@ +/** + * 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. + */ + +#pragma once + +#include +#include + +#include +#include + +QString getUserAgent(bool sunnylink = false); +std::optional getSunnylinkDongleId(); +std::optional getParamIgnoringDefault(const std::string ¶m_name, const std::string &default_value); diff --git a/selfdrive/ui/tests/test_ui/run.py b/selfdrive/ui/tests/test_ui/run.py index 847ebaf4e..d8694d174 100644 --- a/selfdrive/ui/tests/test_ui/run.py +++ b/selfdrive/ui/tests/test_ui/run.py @@ -42,17 +42,17 @@ def setup_settings_device(click, pm: PubMaster): def setup_settings_toggles(click, pm: PubMaster): setup_settings_device(click, pm) - click(278, 586) + click(278, 640) time.sleep(UI_DELAY) def setup_settings_software(click, pm: PubMaster): setup_settings_device(click, pm) - click(278, 716) + click(278, 750) time.sleep(UI_DELAY) def setup_settings_developer(click, pm: PubMaster): setup_settings_device(click, pm) - click(278, 976) + click(278, 970) time.sleep(UI_DELAY) def setup_onroad(click, pm: PubMaster): @@ -176,16 +176,23 @@ def setup_pair_device(click, pm: PubMaster): click(1950, 435) click(1800, 900) +def setup_settings_sunnylink(click, pm: PubMaster): + Params().put_bool("SunnylinkEnabled", True) + + setup_settings_device(click, pm) + click(278, 530) + time.sleep(UI_DELAY) + def setup_settings_sunnypilot(click, pm: PubMaster): setup_settings_device(click, pm) - click(278, 846) + click(278, 860) time.sleep(UI_DELAY) def setup_settings_sunnypilot_mads(click, pm: PubMaster): Params().put_bool("Mads", True) setup_settings_device(click, pm) - click(278, 846) + click(278, 860) click(970, 455) time.sleep(UI_DELAY) @@ -214,6 +221,7 @@ CASES = { } CASES.update({ + "settings_sunnylink": setup_settings_sunnylink, "settings_sunnypilot": setup_settings_sunnypilot, "settings_sunnypilot_mads": setup_settings_sunnypilot_mads, }) @@ -302,6 +310,7 @@ def create_screenshots(): with OpenpilotPrefix(): params = Params() params.put("DongleId", "123456789012345") + params.put("SunnylinkDongleId", "123456789012345") if name == 'prime': params.put('PrimeType', '1') elif name == 'pair_device': diff --git a/selfdrive/ui/translations/main_ar.ts b/selfdrive/ui/translations/main_ar.ts index 11bcb2155..244e96b42 100644 --- a/selfdrive/ui/translations/main_ar.ts +++ b/selfdrive/ui/translations/main_ar.ts @@ -725,6 +725,10 @@ This may take up to a minute. sunnypilot sunnypilot + + sunnylink + + Setup @@ -911,6 +915,33 @@ This may take up to a minute. 5G + + SidebarSP + + DISABLED + + + + OFFLINE + غير متصل + + + REGIST... + + + + ONLINE + متصل + + + ERROR + خطأ + + + SUNNYLINK + + + SoftwarePanel @@ -1107,6 +1138,33 @@ This may take up to a minute. تمكين SSH + + SunnylinkPanel + + This is the master switch, it will allow you to cutoff any sunnylink requests should you want to do that. + + + + Enable sunnylink + + + + N/A + غير متاح + + + 🎉Welcome back! We're excited to see you've enabled sunnylink again! 🚀 + + + + Device ID + + + + 👋Not going to lie, it's sad to see you disabled sunnylink 😢, but we'll be here when you're ready to come back 🎉. + + + SunnypilotPanel diff --git a/selfdrive/ui/translations/main_de.ts b/selfdrive/ui/translations/main_de.ts index 447246aad..a41205d6d 100644 --- a/selfdrive/ui/translations/main_de.ts +++ b/selfdrive/ui/translations/main_de.ts @@ -707,6 +707,10 @@ This may take up to a minute. sunnypilot sunnypilot + + sunnylink + + Setup @@ -894,6 +898,33 @@ This may take up to a minute. 5G + + SidebarSP + + DISABLED + + + + OFFLINE + OFFLINE + + + REGIST... + + + + ONLINE + ONLINE + + + ERROR + FEHLER + + + SUNNYLINK + + + SoftwarePanel @@ -1091,6 +1122,33 @@ This may take up to a minute. SSH aktivieren + + SunnylinkPanel + + This is the master switch, it will allow you to cutoff any sunnylink requests should you want to do that. + + + + Enable sunnylink + + + + N/A + Nicht verfügbar + + + 🎉Welcome back! We're excited to see you've enabled sunnylink again! 🚀 + + + + Device ID + + + + 👋Not going to lie, it's sad to see you disabled sunnylink 😢, but we'll be here when you're ready to come back 🎉. + + + SunnypilotPanel diff --git a/selfdrive/ui/translations/main_es.ts b/selfdrive/ui/translations/main_es.ts index 2c7eac570..f4780d717 100644 --- a/selfdrive/ui/translations/main_es.ts +++ b/selfdrive/ui/translations/main_es.ts @@ -709,6 +709,10 @@ Esto puede tardar un minuto. sunnypilot sunnypilot + + sunnylink + sunnylink + Setup @@ -895,6 +899,33 @@ Esto puede tardar un minuto. 5G + + SidebarSP + + DISABLED + DESHABILITADO + + + OFFLINE + OFFLINE + + + REGIST... + REGIST... + + + ONLINE + EN LÍNEA + + + ERROR + ERROR + + + SUNNYLINK + SUNNYLINK + + SoftwarePanel @@ -1091,6 +1122,33 @@ Esto puede tardar un minuto. Habilitar SSH + + SunnylinkPanel + + This is the master switch, it will allow you to cutoff any sunnylink requests should you want to do that. + Este es el interruptor principal; te permitirá desactivar completamente cualquier connectividad de sunnylink si así lo deseas. + + + Enable sunnylink + Habilitar sunnylink + + + N/A + N/A + + + 🎉Welcome back! We're excited to see you've enabled sunnylink again! 🚀 + 🎉¡Bienvenido de vuelta! Nos alegra que hayas reactivado sunnylink. 🚀 + + + Device ID + ID del dispositivo + + + 👋Not going to lie, it's sad to see you disabled sunnylink 😢, but we'll be here when you're ready to come back 🎉. + 👋No te mentiremos, nos entristece que hayas desactivado sunnylink 😢. Estaremos aquí cuando estes listo para volver 🎉. + + SunnypilotPanel diff --git a/selfdrive/ui/translations/main_fr.ts b/selfdrive/ui/translations/main_fr.ts index 351e684a2..5c2472904 100644 --- a/selfdrive/ui/translations/main_fr.ts +++ b/selfdrive/ui/translations/main_fr.ts @@ -709,6 +709,10 @@ Cela peut prendre jusqu'à une minute. sunnypilot sunnypilot + + sunnylink + + Setup @@ -895,6 +899,33 @@ Cela peut prendre jusqu'à une minute. 5G + + SidebarSP + + DISABLED + + + + OFFLINE + HORS LIGNE + + + REGIST... + + + + ONLINE + EN LIGNE + + + ERROR + ERREUR + + + SUNNYLINK + + + SoftwarePanel @@ -1091,6 +1122,33 @@ Cela peut prendre jusqu'à une minute. Activer SSH + + SunnylinkPanel + + This is the master switch, it will allow you to cutoff any sunnylink requests should you want to do that. + + + + Enable sunnylink + + + + N/A + N/A + + + 🎉Welcome back! We're excited to see you've enabled sunnylink again! 🚀 + + + + Device ID + + + + 👋Not going to lie, it's sad to see you disabled sunnylink 😢, but we'll be here when you're ready to come back 🎉. + + + SunnypilotPanel diff --git a/selfdrive/ui/translations/main_ja.ts b/selfdrive/ui/translations/main_ja.ts index f1690bb76..61fe372e3 100644 --- a/selfdrive/ui/translations/main_ja.ts +++ b/selfdrive/ui/translations/main_ja.ts @@ -703,6 +703,10 @@ This may take up to a minute. sunnypilot sunnypilot + + sunnylink + + Setup @@ -889,6 +893,33 @@ This may take up to a minute. 5G + + SidebarSP + + DISABLED + + + + OFFLINE + オフライン + + + REGIST... + + + + ONLINE + オンライン + + + ERROR + エラー + + + SUNNYLINK + + + SoftwarePanel @@ -1085,6 +1116,33 @@ This may take up to a minute. SSH を有効化 + + SunnylinkPanel + + This is the master switch, it will allow you to cutoff any sunnylink requests should you want to do that. + + + + Enable sunnylink + + + + N/A + N/A + + + 🎉Welcome back! We're excited to see you've enabled sunnylink again! 🚀 + + + + Device ID + + + + 👋Not going to lie, it's sad to see you disabled sunnylink 😢, but we'll be here when you're ready to come back 🎉. + + + SunnypilotPanel diff --git a/selfdrive/ui/translations/main_ko.ts b/selfdrive/ui/translations/main_ko.ts index 2dc036fee..6d6244fb7 100644 --- a/selfdrive/ui/translations/main_ko.ts +++ b/selfdrive/ui/translations/main_ko.ts @@ -705,6 +705,10 @@ This may take up to a minute. sunnypilot sunnypilot + + sunnylink + + Setup @@ -891,6 +895,33 @@ This may take up to a minute. 5G + + SidebarSP + + DISABLED + + + + OFFLINE + 연결 안됨 + + + REGIST... + + + + ONLINE + 온라인 + + + ERROR + 오류 + + + SUNNYLINK + + + SoftwarePanel @@ -1087,6 +1118,33 @@ This may take up to a minute. SSH 사용 + + SunnylinkPanel + + This is the master switch, it will allow you to cutoff any sunnylink requests should you want to do that. + + + + Enable sunnylink + + + + N/A + N/A + + + 🎉Welcome back! We're excited to see you've enabled sunnylink again! 🚀 + + + + Device ID + + + + 👋Not going to lie, it's sad to see you disabled sunnylink 😢, but we'll be here when you're ready to come back 🎉. + + + SunnypilotPanel diff --git a/selfdrive/ui/translations/main_pt-BR.ts b/selfdrive/ui/translations/main_pt-BR.ts index ff8a2efef..0bb217aa0 100644 --- a/selfdrive/ui/translations/main_pt-BR.ts +++ b/selfdrive/ui/translations/main_pt-BR.ts @@ -709,6 +709,10 @@ Isso pode levar até um minuto. sunnypilot sunnypilot + + sunnylink + + Setup @@ -895,6 +899,33 @@ Isso pode levar até um minuto. 5G + + SidebarSP + + DISABLED + + + + OFFLINE + OFFLINE + + + REGIST... + + + + ONLINE + ONLINE + + + ERROR + ERRO + + + SUNNYLINK + + + SoftwarePanel @@ -1091,6 +1122,33 @@ Isso pode levar até um minuto. Habilitar SSH + + SunnylinkPanel + + This is the master switch, it will allow you to cutoff any sunnylink requests should you want to do that. + + + + Enable sunnylink + + + + N/A + N/A + + + 🎉Welcome back! We're excited to see you've enabled sunnylink again! 🚀 + + + + Device ID + + + + 👋Not going to lie, it's sad to see you disabled sunnylink 😢, but we'll be here when you're ready to come back 🎉. + + + SunnypilotPanel diff --git a/selfdrive/ui/translations/main_th.ts b/selfdrive/ui/translations/main_th.ts index 1162f6440..19f5c20dd 100644 --- a/selfdrive/ui/translations/main_th.ts +++ b/selfdrive/ui/translations/main_th.ts @@ -705,6 +705,10 @@ This may take up to a minute. sunnypilot sunnypilot + + sunnylink + + Setup @@ -891,6 +895,33 @@ This may take up to a minute. 5G + + SidebarSP + + DISABLED + + + + OFFLINE + ออฟไลน์ + + + REGIST... + + + + ONLINE + ออนไลน์ + + + ERROR + เกิดข้อผิดพลาด + + + SUNNYLINK + + + SoftwarePanel @@ -1087,6 +1118,33 @@ This may take up to a minute. เปิดใช้งาน SSH + + SunnylinkPanel + + This is the master switch, it will allow you to cutoff any sunnylink requests should you want to do that. + + + + Enable sunnylink + + + + N/A + ไม่มี + + + 🎉Welcome back! We're excited to see you've enabled sunnylink again! 🚀 + + + + Device ID + + + + 👋Not going to lie, it's sad to see you disabled sunnylink 😢, but we'll be here when you're ready to come back 🎉. + + + SunnypilotPanel diff --git a/selfdrive/ui/translations/main_tr.ts b/selfdrive/ui/translations/main_tr.ts index fbc9292bc..e5c3f3f45 100644 --- a/selfdrive/ui/translations/main_tr.ts +++ b/selfdrive/ui/translations/main_tr.ts @@ -703,6 +703,10 @@ This may take up to a minute. sunnypilot sunnypilot + + sunnylink + + Setup @@ -889,6 +893,33 @@ This may take up to a minute. 5G + + SidebarSP + + DISABLED + + + + OFFLINE + ÇEVRİMDIŞI + + + REGIST... + + + + ONLINE + ÇEVRİMİÇİ + + + ERROR + HATA + + + SUNNYLINK + + + SoftwarePanel @@ -1085,6 +1116,33 @@ This may take up to a minute. SSH aç + + SunnylinkPanel + + This is the master switch, it will allow you to cutoff any sunnylink requests should you want to do that. + + + + Enable sunnylink + + + + N/A + N/A + + + 🎉Welcome back! We're excited to see you've enabled sunnylink again! 🚀 + + + + Device ID + + + + 👋Not going to lie, it's sad to see you disabled sunnylink 😢, but we'll be here when you're ready to come back 🎉. + + + SunnypilotPanel diff --git a/selfdrive/ui/translations/main_zh-CHS.ts b/selfdrive/ui/translations/main_zh-CHS.ts index 7b5a700a5..8b6b64d55 100644 --- a/selfdrive/ui/translations/main_zh-CHS.ts +++ b/selfdrive/ui/translations/main_zh-CHS.ts @@ -705,6 +705,10 @@ This may take up to a minute. sunnypilot sunnypilot + + sunnylink + + Setup @@ -891,6 +895,33 @@ This may take up to a minute. 5G + + SidebarSP + + DISABLED + + + + OFFLINE + 离线 + + + REGIST... + + + + ONLINE + 在线 + + + ERROR + 连接出错 + + + SUNNYLINK + + + SoftwarePanel @@ -1087,6 +1118,33 @@ This may take up to a minute. 启用SSH + + SunnylinkPanel + + This is the master switch, it will allow you to cutoff any sunnylink requests should you want to do that. + + + + Enable sunnylink + + + + N/A + N/A + + + 🎉Welcome back! We're excited to see you've enabled sunnylink again! 🚀 + + + + Device ID + + + + 👋Not going to lie, it's sad to see you disabled sunnylink 😢, but we'll be here when you're ready to come back 🎉. + + + SunnypilotPanel diff --git a/selfdrive/ui/translations/main_zh-CHT.ts b/selfdrive/ui/translations/main_zh-CHT.ts index b3f04483c..0515ac82a 100644 --- a/selfdrive/ui/translations/main_zh-CHT.ts +++ b/selfdrive/ui/translations/main_zh-CHT.ts @@ -705,6 +705,10 @@ This may take up to a minute. sunnypilot sunnypilot + + sunnylink + + Setup @@ -891,6 +895,33 @@ This may take up to a minute. 5G + + SidebarSP + + DISABLED + + + + OFFLINE + 已離線 + + + REGIST... + + + + ONLINE + 已連線 + + + ERROR + 錯誤 + + + SUNNYLINK + + + SoftwarePanel @@ -1087,6 +1118,33 @@ This may take up to a minute. 啟用 SSH 服務 + + SunnylinkPanel + + This is the master switch, it will allow you to cutoff any sunnylink requests should you want to do that. + + + + Enable sunnylink + + + + N/A + 無法使用 + + + 🎉Welcome back! We're excited to see you've enabled sunnylink again! 🚀 + + + + Device ID + + + + 👋Not going to lie, it's sad to see you disabled sunnylink 😢, but we'll be here when you're ready to come back 🎉. + + + SunnypilotPanel