添加红外扩展

This commit is contained in:
minghanchen
2026-08-28 17:27:43 +08:00
parent fd13d9f1ee
commit 6d75944c0f
11 changed files with 1602 additions and 75 deletions
+95 -5
View File
@@ -349,11 +349,11 @@ operations:
) as response:
console_styles = response.read().decode("utf-8")
with self.opener.open(
f"{self.base_url}/self-extension.js?v=nfc-toy-33", timeout=3
f"{self.base_url}/self-extension.js?v=gscu-tcp-37", timeout=3
) as response:
extension_script = response.read().decode("utf-8")
with self.opener.open(
f"{self.base_url}/self-extension.css?v=nfc-toy-33", timeout=3
f"{self.base_url}/self-extension.css?v=gscu-tcp-37", timeout=3
) as response:
extension_styles = response.read().decode("utf-8").replace("\r\n", "\n")
with self.opener.open(
@@ -393,8 +393,8 @@ operations:
self.assertIn('<body class="console-v2">', html)
self.assertIn('id="v2BootScreen"', html)
self.assertIn('正在加载车机控制与实时状态', html)
self.assertIn('src="/self-extension.js?v=nfc-toy-33"', html)
self.assertIn('href="/self-extension.css?v=nfc-toy-33"', html)
self.assertIn('src="/self-extension.js?v=gscu-tcp-37"', html)
self.assertIn('href="/self-extension.css?v=gscu-tcp-37"', html)
self.assertNotIn("self-calibration", html)
self.assertNotIn("self-repair", html)
self.assertNotIn("self-evolution", html)
@@ -639,7 +639,7 @@ operations:
self.assertIn("CAN 指令已提交,等待车辆状态确认", console_script)
self.assertIn('canvas.addEventListener("webglcontextlost"', app_script)
self.assertIn('"cognitive-agent:module-change"', app_script)
self.assertIn('const CACHE_VERSION = "cognitive-agent-pad-v210"', service_worker)
self.assertIn('const CACHE_VERSION = "cognitive-agent-pad-v214"', service_worker)
self.assertIn('"/app.js?v=dual-seat-107"', service_worker)
self.assertIn('"/assets/pets/self-extension-cat.png?v=3"', service_worker)
self.assertIn(".then(() => self.skipWaiting())", service_worker)
@@ -1037,6 +1037,96 @@ operations:
self.assertEqual(result["transport"], "simulation")
self.assertFalse(result["physical_state_confirmed"])
def test_self_extension_tcp_configuration_endpoint_updates_runtime(self) -> None:
original_extension = SeatDemoHandler.extension
extension = SelfExtensionService(SimulationGateway())
SeatDemoHandler.extension = extension
try:
with tempfile.TemporaryDirectory() as directory:
with patch.dict(
os.environ,
{"GSCU_RUNTIME_CONFIG_PATH": f"{directory}/gateway.json"},
clear=False,
):
request = urllib.request.Request(
f"{self.base_url}/api/extension/gscu/config",
method="POST",
headers={"Content-Type": "application/json"},
data=json.dumps(
{"listen_host": "127.0.0.1", "port": 45444}
).encode("utf-8"),
)
with self.opener.open(request, timeout=3) as response:
result = json.loads(response.read().decode("utf-8"))
persisted = json.loads(
Path(directory, "gateway.json").read_text(encoding="utf-8")
)
finally:
extension.close()
SeatDemoHandler.extension = original_extension
self.assertTrue(result["success"])
self.assertEqual(result["transport"], "tcp")
self.assertEqual(result["listen_host"], "127.0.0.1")
self.assertEqual(result["port"], 45444)
self.assertEqual(
persisted,
{"transport": "tcp", "listen_host": "127.0.0.1", "port": 45444},
)
def test_infrared_slot_catalog_api_and_confirmed_erase_all(self) -> None:
original_extension = SeatDemoHandler.extension
with tempfile.TemporaryDirectory() as directory:
extension = SelfExtensionService(
SimulationGateway(),
catalog_db_path=Path(directory, "infrared-slots.sqlite3"),
)
SeatDemoHandler.extension = extension
try:
for slot, name in ((12, "电视开关"), (3, "空调制冷")):
request = urllib.request.Request(
f"{self.base_url}/api/extension/gscu/slots/{slot}",
method="PUT",
headers={"Content-Type": "application/json"},
data=json.dumps({"name": name, "source": "tcp"}).encode("utf-8"),
)
with self.opener.open(request, timeout=3) as response:
self.assertEqual(response.status, 200)
with self.opener.open(
f"{self.base_url}/api/extension/gscu/slots", timeout=3
) as response:
catalog = json.loads(response.read().decode("utf-8"))
self.assertEqual([item["slot"] for item in catalog["slots"]], [3, 12])
delete_request = urllib.request.Request(
f"{self.base_url}/api/extension/gscu/slots/3",
method="DELETE",
)
with self.opener.open(delete_request, timeout=3) as response:
deleted = json.loads(response.read().decode("utf-8"))
self.assertTrue(deleted["removed"])
self.assertFalse(deleted["device_signal_erased"])
erase_request = urllib.request.Request(
f"{self.base_url}/api/extension/gscu/erase-all",
method="POST",
headers={"Content-Type": "application/json"},
data=json.dumps({"confirm": "ERASE_ALL"}).encode("utf-8"),
)
with self.opener.open(erase_request, timeout=3) as response:
erased = json.loads(response.read().decode("utf-8"))
self.assertTrue(erased["catalog_cleared"])
self.assertEqual(erased["catalog_removed_count"], 1)
with self.opener.open(
f"{self.base_url}/api/extension/gscu/slots", timeout=3
) as response:
empty_catalog = json.loads(response.read().decode("utf-8"))
self.assertEqual(empty_catalog["slots"], [])
finally:
SeatDemoHandler.extension = original_extension
def test_main_request_routes_live_nfc_peripheral_to_gscu(self) -> None:
original_extension = SeatDemoHandler.extension
original_nfc = SeatDemoHandler.nfc