Brand-specific capabilities (hyundai_alpha_long_available,
subaru_has_sng) only resolved from CarPlatformBundle, which requires
manual car selection. Auto-fingerprinted vehicles had no bundle,
leaving these capabilities at default false — hiding vehicle settings
on the dashboard despite working on the device UI.
Add _resolve_brand_capabilities() with bundle-first, CP-fallback
pattern matching the device UI layouts (hyundai.py, subaru.py).
Fixes https://community.sunnypilot.ai/t/5126
* py py py
* sunnylink too
* refactor
* this is not needed anymore
* mici mici
* ugh
* retry CI
* ui: refactor default model name handling
Move DEFAULT_MODEL constant into sunnypilot/models/default_model.py
and remove the one-liner common/model.py. Strip the hardcoded
" (Default)" suffix from the constant value so each UI site appends
it contextually, keeping the raw model name clean for the schema
payload to sunnylink.
Replace the DefaultModel param approach with schema["default_model"]
injected at schema assembly time, eliminating a redundant param write
on every sunnylinkd start. Remove DefaultModel from params_keys.h and
params_metadata.json.
Update update_default_model_name() to do a targeted regex replacement
instead of overwriting the whole file, since the constant now lives in
a module with other code.
---------
Co-authored-by: Jason Wen <haibin.wen3@gmail.com>
* ci: simplify cereal validation to sparse-checkout + pycapnp, drop scons build
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
* more
* fix: resolve cereal_dir to absolute path before passing to capnp.load
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
* ci: init opendbc submodule after sparse checkout to resolve car.capnp symlink
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
* try to break it
* Revert "try to break it"
This reverts commit 79ce135c5f.
* try to break it
* Revert "try to break it"
This reverts commit 1eaa9e79e6.
---------
Co-authored-by: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
* 1
* fix
* uh
* more
* for now
* v2
* update
* more subs
* readme
* vehicle
* cycle init
* options
* new
* combine
* new
* dynamic unit
* default
* move it
* syncing more
* more
* boom shakalaka
* rearrange
* partial availability
* move
* more
* more
* hide
* move
* revert
* more
* new
* set
* sync
* dynamic
* slightly more
* update
* update
* less
* in another pr
* more
* move and fix
* device type
* order
* order
* order
* fixes
* ew
* Revert "fixes"
This reverts commit 53a2adb45a.
* sunnylink: bundle-first capabilities + protocol_version
Bundle-first brand resolution, fix steer_control_type to use
CP.steerControlType (physical) not lateralTuning.which() (tuning class),
add Subaru/Hyundai opaque per-platform flags from CarPlatformBundle, and
embed PROTOCOL_VERSION in the capabilities payload.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* sunnylink: tighten settings_ui gates against Raylib parity
Brand gates on MadsMainCruiseAllowed/MadsUnifiedEngagementMode (rivian +
tesla-no-bus); convert enablement->visibility on items Raylib hides
(DisableUpdates, EnableGithubRunner, EnableCopyparty, QuickBootToggle,
HyundaiLongitudinalTuning, LaneTurnValue, LagdToggleDelay); drop spurious
offroad_only on DynamicExperimentalControl + DisengageOnAccelerator and
SpeedLimit policy/offset over-gates; replace offroad_only with not_engaged
on AlphaLongitudinalEnabled/Toyota long toggles; extend release-branch
NOTs with is_sp_release; add Test Maneuvers section with attestation,
move LongitudinalManeuverMode in alongside new LateralManeuverMode.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* sunnylink: extend settings_ui validator for new fields
Add SchemaItem fields title_param_suffix (object form), needs_onroad_cycle,
blocked, requires_attestation; add option-level enablement to SchemaOption;
add visibility/enablement/attestation_required to PanelSection; add
not_engaged Rule type; replace vehicle_settings inline shape with
VehicleBrandSettings def (title/description/items).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* sunnylink: inject torque tune options from versions JSON
Read latcontrol_torque_versions.json at schema generation time and
override TorqueControlTune options so adding a version to the JSON
flows to the dashboard without editing settings_ui.json by hand.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* sunnylink: per-bug regression tests for settings_ui parity
Cover the audit findings end-to-end: MADS brand gates, Test Maneuvers
section + attestation, validator accepts the JSON, dynamic torque
options match the versions JSON, SP dev items gate on is_sp_release as
well as is_release, spurious offroad_only dropped from
DisengageOnAccelerator and DynamicExperimentalControl, and offroad_only
replaced with not_engaged on AlphaLongitudinalEnabled and the Toyota
long toggles. Validator test skips when jsonschema is unavailable.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* sunnylink: protocol_version sentinel + opaque-flag tests
Pin PROTOCOL_VERSION to KNOWN_PROTOCOL_VERSIONS so a bump shows up in
review, and assert subaru_has_sng / hyundai_alpha_long_available are
declared with safe False defaults.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* schema: convert ShowAdvancedControls visibility to enablement
Items previously hidden when ShowAdvancedControls is off now render
as disabled with an ADVANCED tooltip. Same treatment for dependency-
based hides (LagdToggleDelay, LaneTurnValue) so users see what's
available and why it's locked. CameraOffset gets the Advanced gate it
was missing.
Affected: DisableUpdates, EnableGithubRunner, EnableCopyparty,
QuickBootToggle, LaneTurnValue, LagdToggleDelay, CameraOffset, and the
test_maneuvers section.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* sunnylink: route resume_queued to athena direct
Backend is retiring the CloudFront proxy on stg.api.sunnypilot.ai that
currently forwards ws|settings|navigation to athena.sunnylink.ai. Once
retired, /ws/{id}/resume_queued only resolves via athena.sunnylink.ai.
SunnylinkApi.resume_queued now temporarily swaps self.api_host to
ATHENA_HOST while re-entering api_get (preserves the SunnylinkEnabled
gate and existing JWT/UA header handling). Other device calls
(device/{id}/roles, device/{id}/users, v2/pilotauth/, backups) continue
to hit the sunnylink main API host unchanged.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* legacy code
* no
* new
* tests
* lint
* fix
* too verbose
* sunnylink: per-page YAML authoring for settings_ui + named rule macros
Replace hand-edited 2200-line settings_ui.json with a per-page YAML source
tree under settings_ui_src/, plus named rule fragments (`$ref` macros) so
the same condition isn't repeated verbatim across items.
Authoring surface (settings_ui_src/):
pages/<page>.yaml one file per panel; sections/items/sub_panels inline
pages/vehicle.yaml per-brand settings (kind: vehicle -> vehicle_settings)
_macros.yaml named rule fragments referenced via {$ref: "#/macros/<name>"}
_schemas/*.json JSON Schemas for IDE autocomplete + CI validation
Pages today: steering, cruise, display, visuals, toggles, device, software,
developer, models, vehicle (10).
Tools:
compile_settings_ui.py read src tree, resolve $refs, emit settings_ui.json
(--check mode for CI to fail on hand-edits)
extract_settings_ui.py one-shot: settings_ui.json -> per-page YAML
apply_macros.py one-shot: substitute matching rule blocks with $ref
Rule-block dedup wins (top duplicates collapsed to single macros):
offroad (9x), longitudinal (4x), longitudinal_and_icbm (5x),
hide_on_mici (4x), advanced_only (3x), mads_full_platforms (4x ~30-line
nested any/all/not -> 1 macro + 4x one-line $ref).
Validator drift fixes:
- Accept not_engaged rule type (already in schema.json + used by
AlphaLongitudinalEnabled, ToyotaEnforceStockLongitudinal,
ToyotaStopAndGoHack, LateralManeuverMode, LongitudinalManeuverMode).
- Enforce {title, description, items} shape on every vehicle brand
instead of allowing bare-list variants.
Wire format unchanged: compiled settings_ui.json structurally identical to
the prior hand-edited file, so the device generator (generate_settings_schema.py),
SettingsCapabilities, and frontend renderer all keep working without changes.
Tests: 16 new compiler tests (roundtrip, $ref semantics, depth/cycle limits,
page-tree integrity, vehicle kind routing). Existing 42 regression tests in
test_settings_changes.py and test_settings_schema.py remain green.
README rewritten for the new flow:
- Decision table for offroad_only / not_engaged / param / capability
- Multi-condition composition examples (AND/OR/mixed/3-way/negation)
- Full feature walkthrough (multi-toggle + sub_panel + new macro)
- Workflows for changing rules, widget type, deprecating an item
- All How-To examples migrated from JSON to YAML
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* sunnylink: add `details` field for popover/modal help text
Adds an optional `details` field on settings items, distinct from the inline
`description`. When present, the frontend renders an info ("i") button on the
row that opens a modal with this content. Either field may be present alone,
or both together; an item with only `details` and no `description` shows just
the title + info button (no inline body).
Migrates `AutoLaneChangeTimer` as the first user: the safety caveat
("Please use caution when using this feature. Only use the blinker when
traffic and road conditions permit.") moves out of the inline description
into `details`, leaving the description focused on what the timer actually
does.
Schema changes:
- settings_ui.schema.json: SchemaItem.details (string, optional)
- settings_ui_src/_schemas/page.schema.json: Item.details (mirror)
- compile_settings_ui.py / extract_settings_ui.py: ordered after description
Frontend support lands in sunnylink-frontend on the design-overhaul branch.
Old frontends ignore the unknown key.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* ui: refactor UIStateSP init to eliminate getattr and double update_params
- Remove update_params() and reset_onroad_sleep_timer() from UIStateSP.__init__;
__init__ is now pure attr initialization with no I/O or side effects
- Add _sp_initialized flag to UIStateSP.update_params() to fire
reset_onroad_sleep_timer() exactly once after first real param load,
keeping the call in SP territory and out of stock _initialize()
- Replace getattr(self, 'has_longitudinal_control') / getattr(self, 'CP')
in _enforce_constraints with direct attr access; safe because
_enforce_constraints is only called from update_params(), which only
runs after UIState._initialize() has set both attrs
- Rename _enforce_sp_constraints → _enforce_constraints
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix
* exec
* more exec
* humanize
* sync
---------
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
remove ws_queue thread and associated api endpoint
- Simplified thread management by removing unused `ws_queue`.
- Eliminated `resume_queued` API call for better maintainability.