diff --git a/src/Mod/FreeCADExchange/AutoRouting.py b/src/Mod/FreeCADExchange/AutoRouting.py index 6b3adee..008d806 100644 --- a/src/Mod/FreeCADExchange/AutoRouting.py +++ b/src/Mod/FreeCADExchange/AutoRouting.py @@ -1138,6 +1138,7 @@ def route_all_from_payload(doc, payload, options=None): } ) report["missing_endpoint_uuids"] = sorted(missing_endpoint_uuids) + _write_auto_route_batch_diagnostic(doc, report) return report @@ -1180,6 +1181,53 @@ def format_route_all_report(report): return message +def _clear_auto_route_batch_diagnostics(doc): + group = WiringObjects.ensure_diagnostic_group(doc, _project_uuid(doc)) + removed = 0 + for obj in list(getattr(group, "Group", []) or []): + if (getattr(obj, "QetDiagnosticKind", "") or "").strip() != "AutoRouteBatch": + continue + try: + group.removeObject(obj) + except Exception: + try: + group.Group = [ + candidate + for candidate in list(getattr(group, "Group", []) or []) + if candidate is not obj + ] + except Exception: + pass + try: + if doc.getObject(getattr(obj, "Name", "")) is not None: + doc.removeObject(obj.Name) + removed += 1 + except Exception: + pass + return removed + + +def _write_auto_route_batch_diagnostic(doc, report): + if doc is None or not isinstance(report, dict): + return None + if not report.get("errors") and not report.get("missing_endpoint_uuids") and report.get("collision_warnings", 0) <= 0: + return None + project_uuid = _project_uuid(doc) + group = WiringObjects.ensure_diagnostic_group(doc, project_uuid) + _clear_auto_route_batch_diagnostics(doc) + diagnostic = doc.addObject("App::DocumentObjectGroup", _unique_name(doc, "QETAutoRouteDiagnostic")) + diagnostic.Label = "QET Auto Route Diagnostic" + _set_string(diagnostic, "QetDiagnosticKind", "AutoRouteBatch", "QET diagnostic kind") + _set_string( + diagnostic, + "QetDiagnosticJson", + json.dumps(report, ensure_ascii=False), + "QET auto-routing batch diagnostic payload", + ) + group.addObject(diagnostic) + return diagnostic + + def _iter_wire_tasks(doc): try: task_group = doc.getObject("QETWiring_01_Tasks") diff --git a/tests/python/freecad_exchange_auto_routing_test.py b/tests/python/freecad_exchange_auto_routing_test.py index 07c4de3..0ee9b9b 100644 --- a/tests/python/freecad_exchange_auto_routing_test.py +++ b/tests/python/freecad_exchange_auto_routing_test.py @@ -929,6 +929,34 @@ class AutoRoutingTest(unittest.TestCase): self.assertTrue(report["missing_endpoint_samples"][0]["start_found"]) self.assertFalse(report["missing_endpoint_samples"][0]["end_found"]) + def test_route_all_writes_diagnostic_object_for_missing_terminal(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, "TerminalStart", "terminal-start", app.Vector(0, 0, 0)) + payload = { + "project_uuid": "project-1", + "wires": [ + { + "wire_id": "wire-1", + "start_terminal_uuid": "terminal-start", + "end_terminal_uuid": "terminal-missing", + } + ], + } + + report = auto_routing.route_all_from_payload(doc, payload) + diagnostic_group = doc.getObject("QETWiring_05_Diagnostics") + + self.assertEqual(1, report["skipped_missing_terminal"]) + self.assertIsNotNone(diagnostic_group) + self.assertEqual(1, len(diagnostic_group.Group)) + diagnostic = diagnostic_group.Group[0] + self.assertEqual("AutoRouteBatch", diagnostic.QetDiagnosticKind) + self.assertIn("terminal-missing", diagnostic.QetDiagnosticJson) + def test_route_all_report_calls_out_local_unbound_terminals(self): _install_fake_freecad() terminal_objects, _wiring_objects, _routing_network, auto_routing = _reload_modules()