添加NFC绑定红外设备方式,融合车端设备和扩展设备统一控制
This commit is contained in:
@@ -1507,7 +1507,11 @@ class SeatDemoService:
|
||||
merged.update(
|
||||
{
|
||||
"phase": "two_stage_complete",
|
||||
"utterance": str(manifest["utterance"]),
|
||||
"utterance": str(
|
||||
preview.get("utterance")
|
||||
if preview.get("orchestration_route") == "unified_can_infrared"
|
||||
else manifest["utterance"]
|
||||
),
|
||||
"provider_requested": selected_provider,
|
||||
"preview_request_id": preview_request_id,
|
||||
"supplement_of": preview_request_id,
|
||||
@@ -1574,7 +1578,24 @@ class SeatDemoService:
|
||||
merged["phase_execution_reports"] = {
|
||||
"local_rule": deepcopy(preview.get("execution_report")),
|
||||
"cloud_supplement": deepcopy(supplement.get("execution_report")),
|
||||
**deepcopy(preview.get("phase_execution_reports") or {}),
|
||||
}
|
||||
merged["operation_results"] = [
|
||||
*deepcopy(preview.get("operation_results") or []),
|
||||
*deepcopy(supplement.get("operation_results") or []),
|
||||
]
|
||||
if preview.get("orchestration_route") == "unified_can_infrared":
|
||||
merged["orchestration_route"] = "unified_can_infrared"
|
||||
for key in (
|
||||
"infrared_actions",
|
||||
"peripheral",
|
||||
"control_transports",
|
||||
):
|
||||
merged[key] = deepcopy(preview.get(key))
|
||||
merged["provider_used"] = (
|
||||
f"{supplement.get('provider_used') or 'cloud_supplement'}"
|
||||
"+infrared_local_rules"
|
||||
)
|
||||
if supplement.get("execution_report") is None:
|
||||
merged["execution_report"] = deepcopy(preview.get("execution_report"))
|
||||
successful = {"succeeded", "partially_succeeded", "no_action"}
|
||||
@@ -2039,18 +2060,6 @@ class SeatDemoService:
|
||||
"hardware mode refuses virtual or unverified vehicle actions: "
|
||||
+ ", ".join(unsupported)
|
||||
)
|
||||
if parsed.get("actions"):
|
||||
(
|
||||
self.vehicle_mqtt_settings
|
||||
if control_transport == WIRELESS_MQTT_TRANSPORT
|
||||
else self.hardware_settings
|
||||
).authorize(approval_token)
|
||||
if parsed.get("native_can_actions"):
|
||||
(
|
||||
self.vehicle_mqtt_settings
|
||||
if control_transport == WIRELESS_MQTT_TRANSPORT
|
||||
else self.vehicle_can_settings
|
||||
).authorize(approval_token)
|
||||
if not parsed.get("actions") and not parsed.get("native_can_actions"):
|
||||
raise HardwareSafetyError(
|
||||
"hardware mode requires at least one verified seat or vehicle CAN operation"
|
||||
@@ -2192,6 +2201,7 @@ class SeatDemoService:
|
||||
simulation_fault=simulation_fault,
|
||||
vehicle_profile=vehicle_profile,
|
||||
control_transport=control_transport,
|
||||
approval_token=approval_token,
|
||||
on_commands_validated=on_commands_validated,
|
||||
)
|
||||
|
||||
@@ -2467,6 +2477,13 @@ class SeatDemoService:
|
||||
|
||||
self._emit_validated_commands(result, on_commands_validated)
|
||||
|
||||
if hardware_request:
|
||||
self._authorize_compiled_hardware_delivery(
|
||||
parsed,
|
||||
approval_token,
|
||||
control_transport,
|
||||
)
|
||||
|
||||
safety_started = time.perf_counter()
|
||||
self._trace(
|
||||
traces,
|
||||
@@ -4162,6 +4179,34 @@ class SeatDemoService:
|
||||
event["execution_report"] = None
|
||||
callback(event)
|
||||
|
||||
def _authorize_compiled_hardware_delivery(
|
||||
self,
|
||||
parsed: dict[str, Any],
|
||||
approval_token: str | None,
|
||||
control_transport: str,
|
||||
) -> None:
|
||||
"""Authorize physical transports after commands are safe to display.
|
||||
|
||||
Parsing, schema validation and deterministic CAN compilation do not
|
||||
transmit frames. Keeping transport readiness checks after the
|
||||
``commands_validated`` callback lets every UI target show the same
|
||||
parsed commands, while these gates still run before any executor can
|
||||
open a CAN or MQTT transmission path.
|
||||
"""
|
||||
|
||||
if parsed.get("actions"):
|
||||
(
|
||||
self.vehicle_mqtt_settings
|
||||
if control_transport == WIRELESS_MQTT_TRANSPORT
|
||||
else self.hardware_settings
|
||||
).authorize(approval_token)
|
||||
if parsed.get("native_can_actions"):
|
||||
(
|
||||
self.vehicle_mqtt_settings
|
||||
if control_transport == WIRELESS_MQTT_TRANSPORT
|
||||
else self.vehicle_can_settings
|
||||
).authorize(approval_token)
|
||||
|
||||
def _process_orchestrated(
|
||||
self,
|
||||
utterance: str,
|
||||
@@ -4178,6 +4223,7 @@ class SeatDemoService:
|
||||
simulation_fault: str = "normal",
|
||||
vehicle_profile: VehicleProfile | None = None,
|
||||
control_transport: str = WIRED_CAN_TRANSPORT,
|
||||
approval_token: str | None = None,
|
||||
on_commands_validated: Callable[[dict[str, Any]], None] | None = None,
|
||||
) -> dict[str, Any]:
|
||||
"""Run isolated adapters under the selected physical-bus policy."""
|
||||
@@ -4444,6 +4490,13 @@ class SeatDemoService:
|
||||
|
||||
self._emit_validated_commands(result, on_commands_validated)
|
||||
|
||||
if hardware_request:
|
||||
self._authorize_compiled_hardware_delivery(
|
||||
parsed,
|
||||
approval_token,
|
||||
control_transport,
|
||||
)
|
||||
|
||||
self._trace(
|
||||
traces,
|
||||
request_id,
|
||||
@@ -5478,6 +5531,15 @@ class SeatDemoService:
|
||||
}
|
||||
)
|
||||
|
||||
def persist_composed_result(self, result: dict[str, Any]) -> None:
|
||||
"""Persist a validated result composed with a non-CAN control domain."""
|
||||
|
||||
request_id = str(result.get("request_id") or "")
|
||||
if not MODE_EDITOR_REQUEST_ID_PATTERN.fullmatch(request_id):
|
||||
raise ValueError("invalid composed request id")
|
||||
result.setdefault("trace_events", [])
|
||||
self._persist(result)
|
||||
|
||||
def _persist(self, result: dict[str, Any]) -> None:
|
||||
request_dir = self.artifact_root / result["request_id"]
|
||||
(request_dir / "functions").mkdir(parents=True, exist_ok=True)
|
||||
|
||||
Reference in New Issue
Block a user