fix(scenes): restore cinema seat controls and ordered romantic lighting

This commit is contained in:
Miayui
2026-09-22 13:01:46 +08:00
parent 4d99702acd
commit 6b9ee0f349
24 changed files with 908 additions and 83 deletions
+44 -5
View File
@@ -846,6 +846,45 @@ operations:
)
)
def test_uploaded_seat_preset_executes_four_local_axes_through_mode_api(self) -> None:
scene = {
"id": "n7-cinema-seat-test", "name": "影院模式", "label": "影院模式",
"aliases": ["影院模式"], "description": "车端副驾预设", "icon": "film",
"origin": "headunit", "scope": {"vehicle_ids": ["denza_n7"]},
"actions": [{
"type": "seat_preset", "at_ms": 0, "domain": "local_vehicle",
"capability": "local_scene.seat_preset", "target_scope": "vehicle",
"operation": "set", "parameters": {"targets_pulse": [246, 112, 405, 342]},
}],
}
with tempfile.TemporaryDirectory() as directory:
registry = ModeProfileRegistry(Path(directory) / "presets", user_root=Path(directory) / "modes")
with patch.object(self.service, "mode_profiles", registry), patch.object(
self.service._vehicle_mqtt_transport, "publish_n7_control_transfer",
side_effect=AssertionError("dry run must not publish"),
):
self.service.import_n7_mode_scene(scene)
request = urllib.request.Request(
f"{self.base_url}/api/mode-profiles/n7-cinema-seat-test/execute",
method="POST", headers={"Content-Type": "application/json"},
data=json.dumps({
"vehicle_id": "denza_n7", "execution_mode": "dry_run",
"control_transport": "wireless_mqtt",
"client_type": "web_console_mode_card",
}).encode("utf-8"),
)
with self.opener.open(request, timeout=5) as response:
result = json.loads(response.read().decode("utf-8"))
self.assertEqual(result["status"], "succeeded")
self.assertEqual(result.get("n7_transfer_candidates", []), [])
operations = result["function_configs"]["seat"]["spec"]["operations"]
self.assertEqual(
[(op["capability"], op["parameters"]["position_pct"]) for op in operations],
[("seat.set_longitudinal_position", 51), ("seat.set_cushion_tilt", 30),
("seat.set_backrest_recline", 44), ("seat.set_legrest_height", 53)],
)
self.assertTrue(all(op["target"]["instance"] == "passenger" for op in operations))
def test_saved_mode_accepts_prefixed_self_extension_flow_key(self) -> None:
with tempfile.TemporaryDirectory() as directory:
extension = SelfExtensionService(
@@ -997,7 +1036,7 @@ operations:
def runtime_url(file_name: str, source_url: str) -> str:
hashed = runtime_assets.get(file_name)
return f"/{hashed}" if hashed else source_url
with self.opener.open(f"{self.base_url}/app.js?v=dual-seat-147-video-media", timeout=3) as response:
with self.opener.open(f"{self.base_url}/app.js?v=dual-seat-148-seat-preset", timeout=3) as response:
app_script = response.read().decode("utf-8")
with self.opener.open(
f"{self.base_url}/gesture-control.js?v=android-pad-9", timeout=3
@@ -1084,7 +1123,7 @@ operations:
self.assertIn("CMD 0x431 · FB 0x388 · CH1", template)
self.assertNotIn("透明车体 · 实体设备", template)
self.assertIn(
f'src="{runtime_url("app.js", "/app.js?v=dual-seat-147-video-media")}"',
f'src="{runtime_url("app.js", "/app.js?v=dual-seat-148-seat-preset")}"',
html,
)
self.assertIn('import "../styles.css";', vite_entry)
@@ -1433,7 +1472,7 @@ operations:
self.assertIn(f'/{runtime_assets[asset_name]}', service_worker)
else:
self.assertIn(
'const CACHE_VERSION = "cognitive-agent-pad-v334-video-media"',
'const CACHE_VERSION = "cognitive-agent-pad-v336-seat-preset"',
service_worker,
)
self.assertIn('/console-v2.css?v=delivery-state-69', service_worker)
@@ -1442,7 +1481,7 @@ operations:
self.assertIn('/assistant-chat.js?v=codex-assistant-39-video-media', service_worker)
self.assertIn('/energy-monitor.css?v=energy-monitor-5-dialog-size', service_worker)
self.assertIn('/energy-monitor.js?v=energy-monitor-5-performance', service_worker)
self.assertIn('"/app.js?v=dual-seat-147-video-media"', service_worker)
self.assertIn('"/app.js?v=dual-seat-148-seat-preset"', service_worker)
self.assertIn('/firmware-workbench-entry.css?v=2', service_worker)
self.assertIn('/firmware-workbench-entry.js?v=3', service_worker)
self.assertIn('/firmware-workbench-theme.js?v=1', service_worker)
@@ -1910,7 +1949,7 @@ operations:
) as response:
extension_script = response.read().decode("utf-8")
with self.opener.open(
f"{self.base_url}/app.js?v=dual-seat-147-video-media", timeout=3
f"{self.base_url}/app.js?v=dual-seat-148-seat-preset", timeout=3
) as response:
app_script = response.read().decode("utf-8")