feat: 增强FreeCAD自动布线结果汇总

dev
Zhaowenlong 3 weeks ago
parent 0b0c32e0c3
commit aaa2fd3654

@ -1195,6 +1195,7 @@ def route_eplan_connections_from_payload(doc, payload, options=None, prepared_la
"collision_samples": [],
"errors": [],
"error_samples": [],
"route_status_counts": {},
"routes": [],
}
if isinstance(prepared_layout, dict):
@ -1202,9 +1203,14 @@ def route_eplan_connections_from_payload(doc, payload, options=None, prepared_la
missing_endpoint_uuids = set()
lane_indexes_by_pair = {}
def add_status(status):
key = str(status or "").strip() or "Unknown"
report["route_status_counts"][key] = report["route_status_counts"].get(key, 0) + 1
for item in wires:
if not isinstance(item, dict):
report["skipped_invalid"] += 1
add_status("Invalid")
continue
start_uuid = _wire_item_value(item, "start_terminal_uuid")
end_uuid = _wire_item_value(item, "end_terminal_uuid")
@ -1212,6 +1218,7 @@ def route_eplan_connections_from_payload(doc, payload, options=None, prepared_la
end_terminal = terminals.get(end_uuid)
if start_terminal is None or end_terminal is None:
report["skipped_missing_terminal"] += 1
add_status("MissingTerminal")
for terminal_uuid in (start_uuid, end_uuid):
if terminal_uuid and terminal_uuid not in terminals:
missing_endpoint_uuids.add(terminal_uuid)
@ -1252,6 +1259,7 @@ def route_eplan_connections_from_payload(doc, payload, options=None, prepared_la
except Exception as exc:
error_text = str(exc)
report["errors"].append(error_text)
add_status("Error")
if len(report["error_samples"]) < 8:
report["error_samples"].append(
{
@ -1266,6 +1274,7 @@ def route_eplan_connections_from_payload(doc, payload, options=None, prepared_la
lane_indexes_by_pair[lane_key] = route_lane_index + 1
if result["route_status"] == "CollisionWarning":
report["collision_warnings"] += 1
add_status(result["route_status"])
route_collision_samples = []
for collision in list(result.get("collisions", []) or [])[:3]:
sample = dict(collision)
@ -1311,6 +1320,32 @@ def format_eplan_connection_route_report(report):
report.get("collision_warnings", 0),
report.get("skipped_missing_terminal", 0),
)
status_counts = report.get("route_status_counts", {})
if isinstance(status_counts, dict) and status_counts:
status_labels = {
"Routed": "正常",
"CollisionWarning": "碰撞告警",
"Error": "错误",
"MissingTerminal": "缺失端子",
"Invalid": "无效任务",
}
def status_count_value(value):
try:
return int(value or 0)
except Exception:
return 0
status_parts = []
for key in ("Routed", "CollisionWarning", "Error", "MissingTerminal", "Invalid"):
value = status_count_value(status_counts.get(key, 0))
if value > 0:
status_parts.append("{0} {1}".format(status_labels[key], value))
for key, value in sorted(status_counts.items()):
value = status_count_value(value)
if key in status_labels or value <= 0:
continue
status_parts.append("{0} {1}".format(key, value))
if status_parts:
message += "\n结果状态:{0}".format("".join(status_parts))
prepared_layout = report.get("prepared_layout")
if isinstance(prepared_layout, dict):
message += "\n布线布局空间:线槽路径 {0} 条,布线面 {1} 条,端子接入 {2} 条。".format(

@ -1288,6 +1288,62 @@ class AutoRoutingTest(unittest.TestCase):
self.assertEqual("terminal-start", report["error_samples"][0]["end_terminal_uuid"])
self.assertIn("different", report["error_samples"][0]["error"])
def test_route_eplan_connections_counts_route_statuses_for_summary(self):
_install_fake_freecad()
terminal_objects, _wiring_objects, routing_network, auto_routing = _reload_modules()
app = sys.modules["FreeCAD"]
doc = FakeDocument()
terminal_objects.ensure_root_group(doc, "project-1")
_terminal(doc, terminal_objects, "RouteStart", "route-start", app.Vector(0, 0, 0))
_terminal(doc, terminal_objects, "RouteEnd", "route-end", app.Vector(100, 0, 0))
_terminal(doc, terminal_objects, "CollisionStart", "collision-start", app.Vector(0, 100, 0))
_terminal(doc, terminal_objects, "CollisionEnd", "collision-end", app.Vector(100, 100, 0))
routing_network.create_route_carrier(
doc,
[app.Vector(0, 0, 20), app.Vector(100, 0, 20)],
project_uuid="project-1",
kind="WireDuct",
)
routing_network.create_route_carrier(
doc,
[app.Vector(0, 100, 100), app.Vector(100, 100, 100)],
project_uuid="project-1",
kind="WireDuct",
)
obstacle = doc.addObject("Part::Feature", "CollisionObstacle")
obstacle.Shape = FakeShape(FakeBoundBox(40, 60, 90, 110, 90, 110))
payload = {
"project_uuid": "project-1",
"wires": [
{
"wire_id": "wire-ok",
"start_terminal_uuid": "route-start",
"end_terminal_uuid": "route-end",
},
{
"wire_id": "wire-collision",
"start_terminal_uuid": "collision-start",
"end_terminal_uuid": "collision-end",
},
{
"wire_id": "wire-error",
"start_terminal_uuid": "route-start",
"end_terminal_uuid": "route-start",
},
],
}
report = auto_routing.route_eplan_connections_from_payload(doc, payload)
message = auto_routing.format_eplan_connection_route_report(report)
self.assertEqual(1, report["route_status_counts"]["Routed"])
self.assertEqual(1, report["route_status_counts"]["CollisionWarning"])
self.assertEqual(1, report["route_status_counts"]["Error"])
self.assertIn("结果状态", message)
self.assertIn("正常 1 条", message)
self.assertIn("碰撞告警 1 条", message)
self.assertIn("错误 1 条", message)
def test_route_eplan_connections_lane_index_is_per_terminal_pair(self):
_install_fake_freecad()
terminal_objects, _wiring_objects, routing_network, auto_routing = _reload_modules()
@ -1445,6 +1501,24 @@ class AutoRoutingTest(unittest.TestCase):
self.assertIn("首个错误:没有可用的线槽/路由路径网络", message)
self.assertIn("缺失示例terminal-a -> terminal-b", message)
def test_route_eplan_connections_report_ignores_non_numeric_status_counts(self):
_install_fake_freecad()
_terminal_objects, _wiring_objects, _routing_network, auto_routing = _reload_modules()
report = {
"routed": 1,
"collision_warnings": 0,
"skipped_missing_terminal": 0,
"route_status_counts": {
"Routed": "1",
"ExternalStatus": "not-a-number",
},
}
message = auto_routing.format_eplan_connection_route_report(report)
self.assertIn("正常 1 条", message)
self.assertNotIn("ExternalStatus", message)
def test_bind_wire_task_terminals_from_payload_does_not_create_wires(self):
_install_fake_freecad()
terminal_objects, wiring_objects, _routing_network, auto_routing = _reload_modules()

Loading…
Cancel
Save