fix(dashy): support desktop testing and mobile layout

This commit is contained in:
Harry Wu
2026-07-22 13:46:26 +08:00
parent 2d9cae2d86
commit 70cb2cadda
5 changed files with 122 additions and 6 deletions
+27 -4
View File
@@ -79,8 +79,10 @@ class MockParams:
class AppCache:
"""Centralized cache for expensive operations."""
def __init__(self):
def __init__(self, car_brand=None, openpilot_longitudinal_control=False):
self._params = None
self._car_brand_override = car_brand
self._openpilot_longitudinal_control_override = openpilot_longitudinal_control
self._car_params = None
self._car_params_time = 0
self._context = None
@@ -109,6 +111,12 @@ class AppCache:
def _parse_car_params(self):
"""Parse CarParams from Params store."""
if self._car_brand_override:
return {
'brand': self._car_brand_override,
'openpilot_longitudinal_control': self._openpilot_longitudinal_control_override,
}
result = {'brand': '', 'openpilot_longitudinal_control': False}
try:
# CarParams is cleared offroad/at boot; CarParamsPersistent keeps the last car's
@@ -790,7 +798,10 @@ async def no_cache_middleware(request, handler):
# --- Application Setup ---
async def on_startup(app):
"""Initialize app-level resources."""
app['cache'] = AppCache()
app['cache'] = AppCache(
car_brand=app['car_brand'],
openpilot_longitudinal_control=app['openpilot_longitudinal_control'],
)
app['ws_clients'] = set()
app['publisher_task'] = asyncio.create_task(_publisher_loop(app))
logger.info("Dashy server started")
@@ -808,13 +819,16 @@ async def on_cleanup(app):
logger.info("Dashy server stopped")
def setup_aiohttp_app(host: str, port: int, debug: bool):
def setup_aiohttp_app(host: str, port: int, debug: bool, car_brand=None,
openpilot_longitudinal_control=False):
logging.basicConfig(
level=logging.DEBUG if debug else logging.INFO,
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
)
app = web.Application(middlewares=[no_cache_middleware])
app['car_brand'] = car_brand
app['openpilot_longitudinal_control'] = openpilot_longitudinal_control
# API routes
app.router.add_get("/api/init", init_api)
@@ -846,9 +860,18 @@ def main():
parser.add_argument("--host", type=str, default="0.0.0.0", help="Host to listen on")
parser.add_argument("--port", type=int, default=5088, help="Port to listen on")
parser.add_argument("--debug", action="store_true", help="Enable debug mode")
parser.add_argument("--car-brand", type=str, help="Override the car brand for desktop UI testing")
parser.add_argument("--openpilot-longitudinal-control", action="store_true",
help="Expose settings that require openpilot longitudinal control")
args = parser.parse_args()
app = setup_aiohttp_app(args.host, args.port, args.debug)
app = setup_aiohttp_app(
args.host,
args.port,
args.debug,
car_brand=args.car_brand,
openpilot_longitudinal_control=args.openpilot_longitudinal_control,
)
web.run_app(app, host=args.host, port=args.port)
+59
View File
@@ -0,0 +1,59 @@
/* Responsive overrides for the dynamically-created Dashy settings panel. */
@media (max-width: 767px) {
/* Stack the category navigation above the settings content. */
.hud-panel-surface .flex.flex-1.min-h-0.w-full {
flex-direction: column;
}
.hud-panel-surface .flex.flex-1.min-h-0.w-full > .w-48.shrink-0 {
display: flex;
width: 100%;
max-height: 3.5rem;
flex: 0 0 auto;
overflow-x: auto;
overflow-y: hidden;
padding-block: 0.25rem;
border-right: 0;
border-bottom: 1px solid color-mix(in oklab, var(--color-base-content) 10%, transparent);
scrollbar-width: none;
-webkit-overflow-scrolling: touch;
}
.hud-panel-surface .flex.flex-1.min-h-0.w-full > .w-48.shrink-0::-webkit-scrollbar {
display: none;
}
.hud-panel-surface .flex.flex-1.min-h-0.w-full > .w-48.shrink-0 > button {
width: auto;
flex: 0 0 auto;
padding: 0.625rem 0.875rem;
white-space: nowrap;
}
/* Let cards use the complete viewport width and prevent horizontal drift. */
.hud-panel-surface .flex.flex-1.min-h-0.w-full > .flex-1.overflow-y-auto.p-4 {
width: 100%;
min-width: 0;
padding: 0.75rem;
overflow-x: hidden;
}
.hud-panel-surface .flex.flex-1.min-h-0.w-full > .flex-1.overflow-y-auto.p-4 .card {
width: 100%;
min-width: 0;
}
.hud-panel-surface .flex.flex-1.min-h-0.w-full > .flex-1.overflow-y-auto.p-4 .card .flex-1 {
min-width: 0;
}
}
@media (max-width: 374px) {
.hud-panel-surface .flex.flex-1.min-h-0.w-full > .flex-1.overflow-y-auto.p-4 {
padding: 0.5rem;
}
.hud-panel-surface .flex.flex-1.min-h-0.w-full > .flex-1.overflow-y-auto.p-4 .p-4 {
padding: 0.75rem;
}
}
+1
View File
@@ -9,6 +9,7 @@
<title>Dashy by dragonpilot</title>
<link rel="icon" href="/icons/icon-192x192.png">
<link rel="stylesheet" href="/css/styles.css">
<link rel="stylesheet" href="/css/responsive.css">
</head>
<body>
+21 -1
View File
@@ -17,7 +17,27 @@ Notes:
also still available via the existing DeveloperLayout button.
"""
from dragonpilot.settings import tr
from openpilot.selfdrive.ui.layouts.settings.developer import DESCRIPTIONS as _DEV_DESC
# Keep the dashy settings schema independent from the native Raylib UI. Importing
# DeveloperLayout just for these strings initializes gui_app at module import time,
# which blocks a headless serverd process on macOS.
_DEV_DESC = {
"enable_adb": (
"ADB (Android Debug Bridge) allows connecting to your device over USB or over the network. "
"See https://docs.comma.ai/how-to/connect-to-comma for more info."
),
"ssh_key": (
"Warning: This grants SSH access to all public keys in your GitHub settings. Never enter a GitHub username "
"other than your own. A comma employee will NEVER ask you to add their GitHub username."
),
"alpha_longitudinal": (
"<b>WARNING: openpilot longitudinal control is in alpha for this car and may disable Automatic Emergency "
"Braking (AEB).</b><br><br>On this car, openpilot defaults to the car's built-in ACC instead of openpilot's "
"longitudinal control. Enable this to switch to openpilot longitudinal control. Enabling Experimental mode "
"is recommended when enabling openpilot longitudinal control alpha. Changing this setting will restart "
"openpilot if the car is powered on."
),
}
_SEC = "Developer"
_DASHY = "DASHY"
+14 -1
View File
@@ -16,7 +16,20 @@ duplicates because these have no flags+param_type pair.
Drift detection: see system/tests/test_openpilot_mirror.py.
"""
from dragonpilot.settings import tr
from openpilot.selfdrive.ui.layouts.settings.toggles import DESCRIPTIONS as _TOGGLES_DESC
# Keep this web schema importable without initializing the native Raylib UI.
_TOGGLES_DESC = {
"OpenpilotEnabledToggle": "Use the openpilot system for adaptive cruise control and lane keep driver assistance. Your attention is required at all times to use this feature.",
"DisengageOnAccelerator": "When enabled, pressing the accelerator pedal will disengage openpilot.",
"LongitudinalPersonality": "Standard is recommended. In aggressive mode, openpilot will follow lead cars closer and be more aggressive with the gas and brake. In relaxed mode openpilot will stay further away from lead cars. On supported cars, you can cycle through these personalities with your steering wheel distance button.",
"IsLdwEnabled": "Receive alerts to steer back into the lane when your vehicle drifts over a detected lane line without a turn signal activated while driving over 31 mph (50 km/h).",
"AlwaysOnDM": "Enable driver monitoring even when openpilot is not engaged.",
"RecordFront": "Upload data from the driver facing camera and help improve the driver monitoring algorithm.",
"IsMetric": "Display speed in km/h instead of mph.",
"RecordAudio": "Record and store microphone audio while driving. The audio will be included in the dashcam video in comma connect.",
"DisableLogging": "Disable logging service",
"DisableUpdates": "Disable update service",
}
_SEC = "Openpilot"
_DASHY = "DASHY"