feat: complete dual-seat whole-vehicle orchestration

This commit is contained in:
vee
2026-08-12 15:12:40 +08:00
parent 32379a1573
commit 9ce64b3a01
62 changed files with 9741 additions and 3950 deletions
+40 -3
View File
@@ -151,14 +151,18 @@ class SeatDemoHandler(BaseHTTPRequestHandler):
if path == "/api/runtime":
self._json(self.service.runtime_info())
return
if path == "/api/hardware/seat-state":
if path in {"/api/hardware/seat-state", "/api/hardware/vehicle-state"}:
query = parse_qs(parsed_url.query)
conversation_id = str(query.get("conversation_id", [""])[0])
vehicle_id = str(query.get("vehicle_id", [""])[0]) or None
hardware_client_id = str(query.get("hardware_client_id", [""])[0]) or None
try:
self._json(
self.service.synchronize_hardware_state(
(
self.service.synchronize_vehicle_state
if path == "/api/hardware/vehicle-state"
else self.service.synchronize_hardware_state
)(
conversation_id,
vehicle_id,
hardware_client_id=hardware_client_id,
@@ -190,7 +194,7 @@ class SeatDemoHandler(BaseHTTPRequestHandler):
HTTPStatus.BAD_REQUEST,
)
except Exception as exc: # noqa: BLE001 - surface passive CAN availability
self.log_error("physical seat-state synchronization failed: %s", exc)
self.log_error("physical CAN state synchronization failed: %s", exc)
self._json(
{
"error": "hardware_state_unavailable",
@@ -356,6 +360,39 @@ class SeatDemoHandler(BaseHTTPRequestHandler):
HTTPStatus.INTERNAL_SERVER_ERROR,
)
def do_DELETE(self) -> None: # noqa: N802 - stdlib handler API
parsed_url = urlparse(self.path)
path = unquote(parsed_url.path)
if not self._authorize(path):
return
prefix = "/api/mode-profiles/"
if not path.startswith(prefix):
self._json({"error": "not_found"}, HTTPStatus.NOT_FOUND)
return
mode_id = path.removeprefix(prefix).strip()
vehicle_id = str(parse_qs(parsed_url.query).get("vehicle_id", [""])[0]) or None
try:
self._json(
self.service.delete_user_mode_profile(mode_id, vehicle_id),
HTTPStatus.OK,
)
except KeyError:
self._json(
{"error": "not_found", "message": "未找到可删除的用户自定义模式。"},
HTTPStatus.NOT_FOUND,
)
except PermissionError as exc:
self._json(
{"error": "preset_mode_protected", "message": str(exc)},
HTTPStatus.FORBIDDEN,
)
except ValueError as exc:
self._json(
{"error": "invalid_request", "message": str(exc)},
HTTPStatus.BAD_REQUEST,
)
def _handle_extension_post(self, path: str) -> None:
action_map = {
"/api/extension/gscu/learn": "learn",