diff --git a/selfdrive/ui/sunnypilot/layouts/settings/vehicle/__init__.py b/selfdrive/ui/sunnypilot/layouts/settings/vehicle/__init__.py
index 1b6c35df2..86d9e6169 100644
--- a/selfdrive/ui/sunnypilot/layouts/settings/vehicle/__init__.py
+++ b/selfdrive/ui/sunnypilot/layouts/settings/vehicle/__init__.py
@@ -9,6 +9,7 @@ from openpilot.system.ui.widgets import Widget
from openpilot.system.ui.widgets.list_view import ButtonAction
from openpilot.system.ui.widgets.scroller_tici import Scroller
+from openpilot.selfdrive.ui.sunnypilot.layouts.settings.vehicle.brands.factory import BrandSettingsFactory
from openpilot.selfdrive.ui.sunnypilot.layouts.settings.vehicle.platform_selector import PlatformSelector, LegendWidget
from openpilot.selfdrive.ui.ui_state import ui_state
from openpilot.system.ui.sunnypilot.widgets.list_view import ListItemSP
@@ -17,6 +18,9 @@ from openpilot.system.ui.sunnypilot.widgets.list_view import ListItemSP
class VehicleLayout(Widget):
def __init__(self):
super().__init__()
+ self._brand_settings = None
+ self._brand_items = []
+ self._current_brand = None
self._platform_selector = PlatformSelector(self._update_brand_settings)
self._vehicle_item = ListItemSP(title=self._platform_selector.text, action_item=ButtonAction(text=tr("Select")),
@@ -27,14 +31,33 @@ class VehicleLayout(Widget):
self.items = [self._vehicle_item, self._legend_widget]
self._scroller = Scroller(self.items, line_separator=True, spacing=0)
+ @staticmethod
+ def get_brand():
+ if bundle := ui_state.params.get("CarPlatformBundle"):
+ return bundle.get("brand", "")
+ elif ui_state.CP and ui_state.CP.carFingerprint != "MOCK":
+ return ui_state.CP.brand
+ return ""
+
def _update_brand_settings(self):
self._vehicle_item._title = self._platform_selector.text
self._vehicle_item.title_color = self._platform_selector.color
vehicle_text = tr("Remove") if ui_state.params.get("CarPlatformBundle") else tr("Select")
self._vehicle_item.action_item.set_text(vehicle_text)
+ brand = self.get_brand()
+ if brand != self._current_brand:
+ self._current_brand = brand
+ self._brand_settings = BrandSettingsFactory.create_brand_settings(brand)
+ self._brand_items = self._brand_settings.items if self._brand_settings else []
+
+ self.items = [self._vehicle_item, self._legend_widget] + self._brand_items
+ self._scroller = Scroller(self.items, line_separator=True, spacing=0)
+
def _update_state(self):
self._update_brand_settings()
+ if self._brand_settings:
+ self._brand_settings.update_settings()
self._platform_selector.refresh()
def _render(self, rect):
diff --git a/selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/__init__.py b/selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/__init__.py
new file mode 100644
index 000000000..e69de29bb
diff --git a/selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/base.py b/selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/base.py
new file mode 100644
index 000000000..8d83fdf91
--- /dev/null
+++ b/selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/base.py
@@ -0,0 +1,16 @@
+"""
+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 abc
+
+
+class BrandSettings(abc.ABC):
+ def __init__(self):
+ self.items = []
+
+ @abc.abstractmethod
+ def update_settings(self) -> None:
+ """Update the settings based on the current vehicle brand."""
diff --git a/selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/body.py b/selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/body.py
new file mode 100644
index 000000000..d1c9ea5d6
--- /dev/null
+++ b/selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/body.py
@@ -0,0 +1,15 @@
+"""
+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.
+"""
+from openpilot.selfdrive.ui.sunnypilot.layouts.settings.vehicle.brands.base import BrandSettings
+
+
+class BodySettings(BrandSettings):
+ def __init__(self):
+ super().__init__()
+
+ def update_settings(self):
+ pass
diff --git a/selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/chrysler.py b/selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/chrysler.py
new file mode 100644
index 000000000..ad62dba56
--- /dev/null
+++ b/selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/chrysler.py
@@ -0,0 +1,15 @@
+"""
+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.
+"""
+from openpilot.selfdrive.ui.sunnypilot.layouts.settings.vehicle.brands.base import BrandSettings
+
+
+class ChryslerSettings(BrandSettings):
+ def __init__(self):
+ super().__init__()
+
+ def update_settings(self):
+ pass
diff --git a/selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/factory.py b/selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/factory.py
new file mode 100644
index 000000000..678732296
--- /dev/null
+++ b/selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/factory.py
@@ -0,0 +1,45 @@
+"""
+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.
+"""
+from openpilot.selfdrive.ui.sunnypilot.layouts.settings.vehicle.brands.base import BrandSettings
+from openpilot.selfdrive.ui.sunnypilot.layouts.settings.vehicle.brands.body import BodySettings
+from openpilot.selfdrive.ui.sunnypilot.layouts.settings.vehicle.brands.chrysler import ChryslerSettings
+from openpilot.selfdrive.ui.sunnypilot.layouts.settings.vehicle.brands.ford import FordSettings
+from openpilot.selfdrive.ui.sunnypilot.layouts.settings.vehicle.brands.gm import GMSettings
+from openpilot.selfdrive.ui.sunnypilot.layouts.settings.vehicle.brands.honda import HondaSettings
+from openpilot.selfdrive.ui.sunnypilot.layouts.settings.vehicle.brands.hyundai import HyundaiSettings
+from openpilot.selfdrive.ui.sunnypilot.layouts.settings.vehicle.brands.mazda import MazdaSettings
+from openpilot.selfdrive.ui.sunnypilot.layouts.settings.vehicle.brands.nissan import NissanSettings
+from openpilot.selfdrive.ui.sunnypilot.layouts.settings.vehicle.brands.psa import PSASettings
+from openpilot.selfdrive.ui.sunnypilot.layouts.settings.vehicle.brands.rivian import RivianSettings
+from openpilot.selfdrive.ui.sunnypilot.layouts.settings.vehicle.brands.subaru import SubaruSettings
+from openpilot.selfdrive.ui.sunnypilot.layouts.settings.vehicle.brands.tesla import TeslaSettings
+from openpilot.selfdrive.ui.sunnypilot.layouts.settings.vehicle.brands.toyota import ToyotaSettings
+from openpilot.selfdrive.ui.sunnypilot.layouts.settings.vehicle.brands.volkswagen import VolkswagenSettings
+
+
+class BrandSettingsFactory:
+ _BRAND_MAP: dict[str, type[BrandSettings]] = {
+ "body": BodySettings,
+ "chrysler": ChryslerSettings,
+ "ford": FordSettings,
+ "gm": GMSettings,
+ "honda": HondaSettings,
+ "hyundai": HyundaiSettings,
+ "mazda": MazdaSettings,
+ "nissan": NissanSettings,
+ "psa": PSASettings,
+ "rivian": RivianSettings,
+ "subaru": SubaruSettings,
+ "tesla": TeslaSettings,
+ "toyota": ToyotaSettings,
+ "volkswagen": VolkswagenSettings,
+ }
+
+ @staticmethod
+ def create_brand_settings(brand: str) -> BrandSettings | None:
+ cls = BrandSettingsFactory._BRAND_MAP.get(brand)
+ return cls() if cls is not None else None
diff --git a/selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/ford.py b/selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/ford.py
new file mode 100644
index 000000000..8871087e0
--- /dev/null
+++ b/selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/ford.py
@@ -0,0 +1,15 @@
+"""
+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.
+"""
+from openpilot.selfdrive.ui.sunnypilot.layouts.settings.vehicle.brands.base import BrandSettings
+
+
+class FordSettings(BrandSettings):
+ def __init__(self):
+ super().__init__()
+
+ def update_settings(self):
+ pass
diff --git a/selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/gm.py b/selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/gm.py
new file mode 100644
index 000000000..edcd17cdb
--- /dev/null
+++ b/selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/gm.py
@@ -0,0 +1,15 @@
+"""
+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.
+"""
+from openpilot.selfdrive.ui.sunnypilot.layouts.settings.vehicle.brands.base import BrandSettings
+
+
+class GMSettings(BrandSettings):
+ def __init__(self):
+ super().__init__()
+
+ def update_settings(self):
+ pass
diff --git a/selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/honda.py b/selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/honda.py
new file mode 100644
index 000000000..fec68795a
--- /dev/null
+++ b/selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/honda.py
@@ -0,0 +1,15 @@
+"""
+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.
+"""
+from openpilot.selfdrive.ui.sunnypilot.layouts.settings.vehicle.brands.base import BrandSettings
+
+
+class HondaSettings(BrandSettings):
+ def __init__(self):
+ super().__init__()
+
+ def update_settings(self):
+ pass
diff --git a/selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/hyundai.py b/selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/hyundai.py
new file mode 100644
index 000000000..f6849eb20
--- /dev/null
+++ b/selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/hyundai.py
@@ -0,0 +1,59 @@
+"""
+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.
+"""
+from openpilot.selfdrive.ui.sunnypilot.layouts.settings.vehicle.brands.base import BrandSettings
+from openpilot.selfdrive.ui.ui_state import ui_state
+from openpilot.system.ui.lib.multilang import tr
+from openpilot.system.ui.sunnypilot.widgets.list_view import multiple_button_item_sp
+from opendbc.car.hyundai.values import CAR, CANFD_UNSUPPORTED_LONGITUDINAL_CAR, UNSUPPORTED_LONGITUDINAL_CAR
+
+
+class HyundaiSettings(BrandSettings):
+ def __init__(self):
+ super().__init__()
+ self.alpha_long_available = False
+
+ tuning_texts = [tr("Off"), tr("Dynamic"), tr("Predictive")]
+ self.longitudinal_tuning_item = multiple_button_item_sp(tr("Custom Longitudinal Tuning"), "", tuning_texts,
+ button_width=300, callback=self._on_tuning_selected,
+ param="HyundaiLongitudinalTuning", inline=False)
+ self.items = [self.longitudinal_tuning_item]
+
+ @staticmethod
+ def _on_tuning_selected(index):
+ ui_state.params.put("HyundaiLongitudinalTuning", index)
+
+ def update_settings(self):
+ self.alpha_long_available = False
+ bundle = ui_state.params.get("CarPlatformBundle")
+ if bundle:
+ platform = bundle.get("platform")
+ self.alpha_long_available = CAR[platform] not in (UNSUPPORTED_LONGITUDINAL_CAR | CANFD_UNSUPPORTED_LONGITUDINAL_CAR)
+ elif ui_state.CP:
+ self.alpha_long_available = ui_state.CP.alphaLongitudinalAvailable
+
+ tuning_param = int(ui_state.params.get("HyundaiLongitudinalTuning") or "0")
+ long_enabled = ui_state.has_longitudinal_control
+
+ long_tuning_descs = [
+ tr("Your vehicle will use the Default longitudinal tuning."),
+ tr("Your vehicle will use the Dynamic longitudinal tuning."),
+ tr("Your vehicle will use the Predictive longitudinal tuning."),
+ ]
+ long_tuning_desc = long_tuning_descs[tuning_param] if tuning_param < len(long_tuning_descs) else long_tuning_descs[0]
+
+ longitudinal_tuning_disabled = not ui_state.is_offroad() or not long_enabled
+ if longitudinal_tuning_disabled:
+ if not ui_state.is_offroad():
+ long_tuning_desc = tr("This feature is unavailable while the car is onroad.")
+ elif not long_enabled:
+ long_tuning_desc = tr("This feature is unavailable because sunnypilot Longitudinal Control (Alpha) is not enabled.")
+
+ self.longitudinal_tuning_item.action_item.set_enabled(not longitudinal_tuning_disabled)
+ self.longitudinal_tuning_item.set_description(long_tuning_desc)
+ self.longitudinal_tuning_item.show_description(True)
+ self.longitudinal_tuning_item.action_item.set_selected_button(tuning_param)
+ self.longitudinal_tuning_item.set_visible(self.alpha_long_available)
diff --git a/selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/mazda.py b/selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/mazda.py
new file mode 100644
index 000000000..d354f0f34
--- /dev/null
+++ b/selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/mazda.py
@@ -0,0 +1,15 @@
+"""
+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.
+"""
+from openpilot.selfdrive.ui.sunnypilot.layouts.settings.vehicle.brands.base import BrandSettings
+
+
+class MazdaSettings(BrandSettings):
+ def __init__(self):
+ super().__init__()
+
+ def update_settings(self):
+ pass
diff --git a/selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/nissan.py b/selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/nissan.py
new file mode 100644
index 000000000..7b3446a1a
--- /dev/null
+++ b/selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/nissan.py
@@ -0,0 +1,15 @@
+"""
+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.
+"""
+from openpilot.selfdrive.ui.sunnypilot.layouts.settings.vehicle.brands.base import BrandSettings
+
+
+class NissanSettings(BrandSettings):
+ def __init__(self):
+ super().__init__()
+
+ def update_settings(self):
+ pass
diff --git a/selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/psa.py b/selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/psa.py
new file mode 100644
index 000000000..6b767d332
--- /dev/null
+++ b/selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/psa.py
@@ -0,0 +1,15 @@
+"""
+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.
+"""
+from openpilot.selfdrive.ui.sunnypilot.layouts.settings.vehicle.brands.base import BrandSettings
+
+
+class PSASettings(BrandSettings):
+ def __init__(self):
+ super().__init__()
+
+ def update_settings(self):
+ pass
diff --git a/selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/rivian.py b/selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/rivian.py
new file mode 100644
index 000000000..876aa2d2e
--- /dev/null
+++ b/selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/rivian.py
@@ -0,0 +1,15 @@
+"""
+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.
+"""
+from openpilot.selfdrive.ui.sunnypilot.layouts.settings.vehicle.brands.base import BrandSettings
+
+
+class RivianSettings(BrandSettings):
+ def __init__(self):
+ super().__init__()
+
+ def update_settings(self):
+ pass
diff --git a/selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/subaru.py b/selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/subaru.py
new file mode 100644
index 000000000..66e7ec1d5
--- /dev/null
+++ b/selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/subaru.py
@@ -0,0 +1,54 @@
+"""
+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.
+"""
+from openpilot.selfdrive.ui.sunnypilot.layouts.settings.vehicle.brands.base import BrandSettings
+from openpilot.selfdrive.ui.ui_state import ui_state
+from openpilot.system.ui.lib.multilang import tr
+from openpilot.system.ui.sunnypilot.widgets.list_view import toggle_item_sp
+from opendbc.car.subaru.values import CAR, SubaruFlags
+
+
+class SubaruSettings(BrandSettings):
+ def __init__(self):
+ super().__init__()
+ self.has_stop_and_go = False
+
+ self.stop_and_go_toggle = toggle_item_sp(tr("Stop and Go (Beta)"), "", param="SubaruStopAndGo", callback=self._on_toggle_changed)
+
+ self.stop_and_go_manual_parking_brake_toggle = toggle_item_sp(tr("Stop and Go for Manual Parking Brake (Beta)"), "",
+ param="SubaruStopAndGoManualParkingBrake", callback=self._on_toggle_changed)
+
+ self.items = [self.stop_and_go_toggle, self.stop_and_go_manual_parking_brake_toggle]
+
+ def _on_toggle_changed(self, _):
+ self.update_settings()
+
+ def stop_and_go_disabled_msg(self):
+ if not self.has_stop_and_go:
+ return tr("This feature is currently not available on this platform.")
+ elif not ui_state.is_offroad():
+ return tr("Enable \"Always Offroad\" in Device panel, or turn vehicle off to toggle.")
+ return ""
+
+ def update_settings(self):
+ bundle = ui_state.params.get("CarPlatformBundle")
+ if bundle:
+ platform = bundle.get("platform")
+ config = CAR[platform].config
+ self.has_stop_and_go = not (config.flags & (SubaruFlags.GLOBAL_GEN2 | SubaruFlags.HYBRID))
+ elif ui_state.CP:
+ self.has_stop_and_go = not (ui_state.CP.flags & (SubaruFlags.GLOBAL_GEN2 | SubaruFlags.HYBRID))
+
+ disabled_msg = self.stop_and_go_disabled_msg()
+ descriptions = [
+ tr("Experimental feature to enable auto-resume during stop-and-go for certain supported Subaru platforms."),
+ tr("Experimental feature to enable stop and go for Subaru Global models with manual handbrake. " +
+ "Models with electric parking brake should keep this disabled. Thanks to martinl for this implementation!")
+ ]
+
+ for toggle, desc in zip([self.stop_and_go_toggle, self.stop_and_go_manual_parking_brake_toggle], descriptions, strict=True):
+ toggle.action_item.set_enabled(self.has_stop_and_go and ui_state.is_offroad())
+ toggle.set_description(f"{disabled_msg}
{desc}" if disabled_msg else desc)
diff --git a/selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/tesla.py b/selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/tesla.py
new file mode 100644
index 000000000..46d536c65
--- /dev/null
+++ b/selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/tesla.py
@@ -0,0 +1,43 @@
+"""
+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.
+"""
+from openpilot.selfdrive.ui.sunnypilot.layouts.settings.vehicle.brands.base import BrandSettings
+from openpilot.selfdrive.ui.ui_state import ui_state
+from openpilot.system.ui.lib.multilang import tr
+from openpilot.system.ui.sunnypilot.widgets.list_view import toggle_item_sp
+
+COOP_STEERING_MIN_KMH = 23
+OEM_STEERING_MIN_KMH = 48
+KM_TO_MILE = 0.621371
+
+
+class TeslaSettings(BrandSettings):
+ def __init__(self):
+ super().__init__()
+ self.coop_steering_toggle = toggle_item_sp(tr("Cooperative Steering (Beta)"), "", param="TeslaCoopSteering")
+ self.items = [self.coop_steering_toggle]
+
+ def update_settings(self):
+ is_metric = ui_state.is_metric
+ unit = "km/h" if is_metric else "mph"
+
+ display_value_coop = COOP_STEERING_MIN_KMH if is_metric else round(COOP_STEERING_MIN_KMH * KM_TO_MILE)
+ display_value_oem = OEM_STEERING_MIN_KMH if is_metric else round(OEM_STEERING_MIN_KMH * KM_TO_MILE)
+
+ coop_steering_disabled_msg = tr("Enable \"Always Offroad\" in Device panel, or turn vehicle off to toggle.")
+ coop_steering_warning = tr(f"Warning: May experience steering oscillations below {display_value_oem} {unit} during turns, " +
+ "recommend disabling this feature if you experience these.")
+ coop_steering_desc = (
+ f"{coop_steering_warning}
" +
+ f"{tr('Allows the driver to provide limited steering input while openpilot is engaged.')}
" +
+ f"{tr(f'Only works above {display_value_coop} {unit}.')}"
+ )
+
+ if not ui_state.is_offroad():
+ coop_steering_desc = f"{coop_steering_disabled_msg}
{coop_steering_desc}"
+
+ self.coop_steering_toggle.set_description(coop_steering_desc)
+ self.coop_steering_toggle.action_item.set_enabled(ui_state.is_offroad())
diff --git a/selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/toyota.py b/selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/toyota.py
new file mode 100644
index 000000000..e061a8a22
--- /dev/null
+++ b/selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/toyota.py
@@ -0,0 +1,15 @@
+"""
+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.
+"""
+from openpilot.selfdrive.ui.sunnypilot.layouts.settings.vehicle.brands.base import BrandSettings
+
+
+class ToyotaSettings(BrandSettings):
+ def __init__(self):
+ super().__init__()
+
+ def update_settings(self):
+ pass
diff --git a/selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/volkswagen.py b/selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/volkswagen.py
new file mode 100644
index 000000000..a6d44c5e4
--- /dev/null
+++ b/selfdrive/ui/sunnypilot/layouts/settings/vehicle/brands/volkswagen.py
@@ -0,0 +1,15 @@
+"""
+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.
+"""
+from openpilot.selfdrive.ui.sunnypilot.layouts.settings.vehicle.brands.base import BrandSettings
+
+
+class VolkswagenSettings(BrandSettings):
+ def __init__(self):
+ super().__init__()
+
+ def update_settings(self):
+ pass
diff --git a/selfdrive/ui/sunnypilot/layouts/settings/vehicle/platform_selector.py b/selfdrive/ui/sunnypilot/layouts/settings/vehicle/platform_selector.py
index 60bc335ce..db9059527 100644
--- a/selfdrive/ui/sunnypilot/layouts/settings/vehicle/platform_selector.py
+++ b/selfdrive/ui/sunnypilot/layouts/settings/vehicle/platform_selector.py
@@ -123,19 +123,16 @@ class PlatformSelector(Button):
gui_app.set_modal_overlay(dialog, callback=callback)
def refresh(self):
- self.brand = ""
self.color = style.YELLOW
self._platform = tr("Unrecognized Vehicle")
self.set_text(tr("No vehicle selected"))
if bundle := ui_state.params.get("CarPlatformBundle"):
self._platform = bundle.get("name", "")
- self.brand = bundle.get("brand", "")
self.set_text(self._platform)
self.color = style.BLUE
elif ui_state.CP and ui_state.CP.carFingerprint != "MOCK":
self._platform = ui_state.CP.carFingerprint
- self.brand = ui_state.CP.brand
self.set_text(self._platform)
self.color = style.GREEN
self.set_enabled(True)