From c126e2e2bed14459f412a4469c7aed1c92b8557e Mon Sep 17 00:00:00 2001 From: Tom Kane Date: Fri, 30 Jan 2026 14:44:20 +0000 Subject: [PATCH] Updated duplicate device names to use PVs to identify --- src/techui_builder/builder.py | 34 ++++++++++++++------------- tests/conftest.py | 44 ++++++++++++++++++++++++++++++----- tests/test_builder.py | 22 +++++++++++++----- 3 files changed, 72 insertions(+), 28 deletions(-) diff --git a/src/techui_builder/builder.py b/src/techui_builder/builder.py index a1247ca3..d7e169f8 100644 --- a/src/techui_builder/builder.py +++ b/src/techui_builder/builder.py @@ -395,24 +395,26 @@ def _fix_duplicate_names(self, node: JsonMap) -> None: if not node.children: return - # Count occurrences of each display_name - name_counts: defaultdict[str | None, int] = defaultdict(int) + # group by display_name + name_groups: defaultdict[str | None, list] = defaultdict(list) for child in node.children: - if child.display_name: - name_counts[child.display_name] += 1 - - # Track which number we're on for each duplicate name - name_indices: defaultdict[str | None, int] = defaultdict(int) - - # Update display names for duplicates + name_groups[child.display_name].append(child) + + # fix duplicates by appending identifiers + for name, children in name_groups.items(): + if name and len(children) > 1: + # append pv names when present + for child in children: + if "P" in child.macros: + child.display_name = f"{name} ({child.macros['P']})" + + # append NO PV NAME and enumeration when there is no pv name + no_pv_children = [c for c in children if "P" not in c.macros] + for i, child in enumerate(no_pv_children, 1): + child.display_name = f"{name} (NO PV NAME {i})" + + # recursively fix children for child in node.children: - if child.display_name and name_counts[child.display_name] > 1: - name_indices[child.display_name] += 1 - child.display_name = ( - f"{child.display_name} {name_indices[child.display_name]}" - ) - - # Recursively fix children self._fix_duplicate_names(child) def write_json_map( diff --git a/tests/conftest.py b/tests/conftest.py index 70dcf8fa..8ad9d2b2 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -59,16 +59,48 @@ def example_json_map(): @pytest.fixture def example_display_names_json(): # Create test json map with correct display names - test_map_det1 = JsonMap("test_child_bob.bob", "Detector 1", exists=False) - test_map_det2 = JsonMap("test_child_bob.bob", "Detector 2", exists=False) - test_map_dev1 = JsonMap("test_child_bob.bob", "Device 1", exists=False) - test_map_dev2 = JsonMap("test_child_bob.bob", "Device 2", exists=False) + test_map_det1 = JsonMap( + "test_child_bob.bob", + "Detector (PV-DET-01)", + macros={"P": "PV-DET-01"}, + exists=False, + ) + test_map_det2 = JsonMap( + "test_child_bob.bob", + "Detector (PV-DET-02)", + macros={"P": "PV-DET-02"}, + exists=False, + ) + test_map_det3 = JsonMap( + "test_child_bob.bob", + "Detector (PV-DET-03)", + macros={"P": "PV-DET-03"}, + exists=False, + ) + test_map_det4 = JsonMap( + "test_child_bob.bob", + "Detector (NO PV NAME 1)", + macros={"R": "NON-P-MACRO"}, + exists=False, + ) + test_map_dev1 = JsonMap( + "test_child_bob.bob", + "Device (PV-DEV-01)", + macros={"P": "PV-DEV-01"}, + exists=False, + ) + test_map_dev2 = JsonMap( + "test_child_bob.bob", + "Device (PV-DEV-02)", + macros={"P": "PV-DEV-02"}, + exists=False, + ) test_map = JsonMap("test_bob.bob", "Beamline") test_map_dev1.children.append(test_map_det1) test_map_dev1.children.append(test_map_det2) - test_map_dev2.children.append(test_map_det1) - test_map_dev2.children.append(test_map_det2) + test_map_dev2.children.append(test_map_det3) + test_map_dev2.children.append(test_map_det4) test_map.children.append(test_map_dev1) test_map.children.append(test_map_dev2) diff --git a/tests/test_builder.py b/tests/test_builder.py index d0cd9730..39e3a936 100644 --- a/tests/test_builder.py +++ b/tests/test_builder.py @@ -345,19 +345,29 @@ def test_fix_duplicate_names_recursive(builder, example_display_names_json): ) test_display_names_json_det1 = JsonMap( - "test_child_bob.bob", "Detector", exists=False + "test_child_bob.bob", "Detector", macros={"P": "PV-DET-01"}, exists=False ) test_display_names_json_det2 = JsonMap( - "test_child_bob.bob", "Detector", exists=False + "test_child_bob.bob", "Detector", macros={"P": "PV-DET-02"}, exists=False + ) + test_display_names_json_det3 = JsonMap( + "test_child_bob.bob", "Detector", macros={"P": "PV-DET-03"}, exists=False + ) + test_display_names_json_det4 = JsonMap( + "test_child_bob.bob", "Detector", macros={"R": "NON-P-MACRO"}, exists=False + ) + test_display_names_json_dev1 = JsonMap( + "test_child_bob.bob", "Device", macros={"P": "PV-DEV-01"}, exists=False + ) + test_display_names_json_dev2 = JsonMap( + "test_child_bob.bob", "Device", macros={"P": "PV-DEV-02"}, exists=False ) - test_display_names_json_dev1 = JsonMap("test_child_bob.bob", "Device", exists=False) - test_display_names_json_dev2 = JsonMap("test_child_bob.bob", "Device", exists=False) test_display_names_json = JsonMap("test_bob.bob", "Beamline") test_display_names_json_dev1.children.append(test_display_names_json_det1) test_display_names_json_dev1.children.append(test_display_names_json_det2) - test_display_names_json_dev2.children.append(test_display_names_json_det1) - test_display_names_json_dev2.children.append(test_display_names_json_det2) + test_display_names_json_dev2.children.append(test_display_names_json_det3) + test_display_names_json_dev2.children.append(test_display_names_json_det4) test_display_names_json.children.append(test_display_names_json_dev1) test_display_names_json.children.append(test_display_names_json_dev2)