From 52354a486d38e0d486ad8a11f1af7921dad0155c Mon Sep 17 00:00:00 2001 From: raghajaf Date: Fri, 6 Jun 2025 13:14:29 -0400 Subject: [PATCH 1/4] emit_schematic module is added. --- src/ansys/aedt/core/emit.py | 13 + .../aedt/core/emit_core/emit_schematic.py | 232 ++++++++++++++++++ tests/system/solvers/test_26_emit.py | 71 +++++- 3 files changed, 315 insertions(+), 1 deletion(-) create mode 100644 src/ansys/aedt/core/emit_core/emit_schematic.py diff --git a/src/ansys/aedt/core/emit.py b/src/ansys/aedt/core/emit.py index 71045b35f51..50dff892c23 100644 --- a/src/ansys/aedt/core/emit.py +++ b/src/ansys/aedt/core/emit.py @@ -29,6 +29,7 @@ from ansys.aedt.core.emit_core.couplings import CouplingsEmit from ansys.aedt.core.emit_core.emit_constants import EMIT_VALID_UNITS from ansys.aedt.core.emit_core.emit_constants import emit_unit_type_string_to_enum +from ansys.aedt.core.emit_core.emit_schematic import EmitSchematic from ansys.aedt.core.emit_core.results.results import Results from ansys.aedt.core.generic.general_methods import pyaedt_function_handler from ansys.aedt.core.modeler.schematic import ModelerEmit @@ -172,6 +173,7 @@ def __init__( ) self._modeler = ModelerEmit(self) self._couplings = CouplingsEmit(self) + self._schematic = EmitSchematic(self) if self._aedt_version > "2023.1": # the next 2 lines of code are needed to point # the EMIT object to the correct EmiApiPython @@ -216,6 +218,17 @@ def couplings(self): """ return self._couplings + @property + def schematic(self): + """EMIT Schematic. + + Returns + ------- + :class:`ansys.aedt.core.emit_core.emit_schematic.EmitSchematic` + EMIT schematic. + """ + return self._schematic + @pyaedt_function_handler() def version(self, detailed=False): """ diff --git a/src/ansys/aedt/core/emit_core/emit_schematic.py b/src/ansys/aedt/core/emit_core/emit_schematic.py new file mode 100644 index 00000000000..700863745f7 --- /dev/null +++ b/src/ansys/aedt/core/emit_core/emit_schematic.py @@ -0,0 +1,232 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2021 - 2025 ANSYS, Inc. and/or its affiliates. +# SPDX-License-Identifier: MIT +# +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + + +from ansys.aedt.core.generic.general_methods import pyaedt_function_handler + + +class EmitSchematic: + """Represents the EMIT schematic and provides methods to interact with it.""" + + def __init__(self, emit_instance): + """Initialize the EmitSchematic class. + + Parameters + ---------- + emit_instance : Emit + Instance of the Emit class. + """ + self.emit_instance = emit_instance + + @property + def emit_com_module(self): + """Retrieve the EmitCom module from the Emit instance. + + Returns + ------- + object + The EmitCom module. + + Raises + ------ + RuntimeError + If the EmitCom module cannot be retrieved. + """ + if not hasattr(self.emit_instance, "_odesign"): + raise RuntimeError("Emit instance does not have a valid '_odesign' attribute.") + try: + return self.emit_instance._odesign.GetModule("EmitCom") + except Exception as e: + raise RuntimeError(f"Failed to retrieve EmitCom module: {e}") + + @pyaedt_function_handler + def create_component(self, component_type, name=None, library=None): + """Create a component using the EmitCom module. + + Parameters + ---------- + component_type : str + Type of the component to create. + name : str, optional + Name of the component to create. Defaults to an empty string if not provided. + library : str, optional + Name of the component library. Defaults to an empty string if not provided. + + Returns + ------- + str + The ID of the created component. + + Raises + ------ + ValueError + If the component type is empty or no matching component is found. + RuntimeError + If the component creation fails. + """ + if not component_type: + raise ValueError("The 'component_type' argument is required.") + + name = name or "" + library = library or "" + + try: + # Retrieve matching components from the catalog + matching_components = self.emit_instance.modeler.components.components_catalog[component_type] + + if not matching_components: + self.emit_instance.logger.error(f"No component found for type '{component_type}'.") + raise ValueError(f"No component found for type '{component_type}'.") + + if len(matching_components) == 1: + # Use the single matching component + component = matching_components[0] + self.emit_instance.logger.info( + f"Using component '{component.name}' from library '{component.component_library}' for type '{component_type}'." + ) + else: + # Attempt to find an exact match + component = next((comp for comp in matching_components if comp.name == component_type), None) + if not component: + self.emit_instance.logger.error( + f"Multiple components found for type '{component_type}', but no exact match. Please specify a unique component." + ) + raise ValueError(f"Multiple components found for type '{component_type}', but no exact match.") + self.emit_instance.logger.info( + f"Using exact match component '{component.name}' from library '{component.component_library}' for type '{component_type}'." + ) + + # Create the component using the EmitCom module + new_component_id = self.emit_com_module.CreateEmitComponent( + name, component.name, component.component_library + ) + return new_component_id + except Exception as e: + self.emit_instance.logger.error(f"Failed to create component '{name}' of type '{component_type}': {e}") + raise RuntimeError(f"Failed to create component of type '{component_type}': {e}") + + @pyaedt_function_handler + def create_radio_antenna(self, radio_type, radio_name=None, antenna_name=None, library=None): + """Create a new radio and antenna and connect them. + + Parameters + ---------- + radio_type : str + Type of radio to create. For example, "Bluetooth". Must match + a radio name in the specified library. + radio_name : str, optional + Name to assign to the new radio. If ``None``, then an instance + name is assigned automatically. The default is ``None``. + antenna_name : str, optional + Name to assign to the new antenna. If ``None``, then an instance + name is assigned automatically. The default is ``None``. + library : str, optional + Name of the component library. If ``None``, then the default + library is used. The default is ``None``. + + Returns + ------- + tuple + A tuple containing the IDs of the created radio and antenna. + + Raises + ------ + RuntimeError + If the radio or antenna creation fails. + """ + radio_name = radio_name or "" + antenna_name = antenna_name or "" + library = library or "" + + try: + new_radio_id = self.create_component(radio_type, radio_name, library) + new_antenna_id = self.create_component("Antenna", antenna_name, "Antennas") + self.connect_components(new_antenna_id, new_radio_id) # Connect antenna to radio + return new_radio_id, new_antenna_id + except Exception as e: + self.emit_instance.logger.error(f"Failed to create radio of type '{radio_type}' or antenna: {e}") + raise RuntimeError(f"Failed to create radio of type '{radio_type}' or antenna: {e}") + + @pyaedt_function_handler + def connect_components(self, component_id_1, component_id_2): + """Connect two components in the schematic. + + Parameters + ---------- + component_id_1 : str + ID of the first component. + component_id_2 : str + ID of the second component. + + Raises + ------ + RuntimeError + If the connection fails. + """ + try: + component_name_1 = self.get_component_properties(component_id_1, "Name") + component_name_2 = self.get_component_properties(component_id_2, "Name") + self.emit_instance._oeditor.PlaceComponent(component_name_1, component_name_2) + self.emit_instance.logger.info( + f"Successfully connected components '{component_name_1}' and '{component_name_2}'." + ) + except Exception as e: + self.emit_instance.logger.error( + f"Failed to connect components '{component_id_1}' and '{component_id_2}': {e}" + ) + raise RuntimeError(f"Failed to connect components '{component_id_1}' and '{component_id_2}': {e}") + + @pyaedt_function_handler + def get_component_properties(self, component_id, property_key=None): + """Get properties of a component. + + Parameters + ---------- + component_id : str + ID of the component. + property_key : str, optional + Specific property key to retrieve. If ``None``, all properties are returned. + + Returns + ------- + dict or str + Dictionary containing all properties of the component if `property_key` is ``None``. + Otherwise, the value of the specified property key. + + Raises + ------ + KeyError + If the specified property key is not found. + """ + try: + props = self.emit_com_module.GetEmitNodeProperties(0, component_id, True) + props_dict = {prop.split("=", 1)[0]: prop.split("=", 1)[1] for prop in props} + if property_key is None: + return props_dict + if property_key in props_dict: + return props_dict[property_key] + raise KeyError(f"Property key '{property_key}' not found.") + except Exception as e: + self.emit_instance.logger.error(f"Failed to retrieve properties for component '{component_id}': {e}") + raise RuntimeError(f"Failed to retrieve properties for component '{component_id}': {e}") diff --git a/tests/system/solvers/test_26_emit.py b/tests/system/solvers/test_26_emit.py index 56881305690..f5076a9def5 100644 --- a/tests/system/solvers/test_26_emit.py +++ b/tests/system/solvers/test_26_emit.py @@ -26,9 +26,11 @@ import os import sys import tempfile +from unittest.mock import MagicMock import pytest +import ansys.aedt.core from ansys.aedt.core.generic import constants as consts from ansys.aedt.core.generic.general_methods import is_linux from tests.system.solvers.conftest import config @@ -1293,10 +1295,77 @@ def count_license_actions(license_file_path): assert checkouts == expected_checkouts and checkins == expected_checkins - @pytest.mark.skipif(config["desktopVersion"] < "2025.1", reason="Skipped on versions earlier than 2024 R2.") + @pytest.mark.skipif(config["desktopVersion"] < "2026.1", reason="Skipped on versions earlier than 2026 R1.") def test_25_components_catalog(self, add_app): self.aedtapp = add_app(project_name="catalog-list", application=Emit) comp_list = self.aedtapp.modeler.components.components_catalog["LTE"] assert len(comp_list) == 14 assert comp_list[12].name == "LTE BTS" assert comp_list[13].name == "LTE Mobile Station" + + @pytest.mark.skipif(config["desktopVersion"] < "2026.1", reason="Skipped on versions earlier than 2026 R1.") + def test_26_create_component(self, add_app): + self.aedtapp = add_app(project_name="create_component", application=Emit) + self.aedtapp.logger.info = MagicMock() + new_radio = self.aedtapp.schematic.create_component("MICS") + assert new_radio == 3 + self.aedtapp.logger.info.assert_called_with( + rf"Using component 'MICS' from library 'Radios\Commercial Unlicensed Systems\Medical' for type 'MICS'." + ) + with pytest.raises(TypeError) as e: + self.aedtapp.schematic.create_component() + assert "EmitSchematic.create_component() missing 1 required positional argument: 'component_type'" in str( + e.value + ) + with pytest.raises(RuntimeError) as e: + self.aedtapp.schematic.create_component("WrongComponent") + assert ( + "Failed to create component of type 'WrongComponent': No component found for type 'WrongComponent'." + ) in str(e.value) + with pytest.raises(RuntimeError) as e: + self.aedtapp.schematic.create_component("lte") + assert ( + "Failed to create component of type 'lte': Multiple components found for type 'lte', but no exact match." + ) in str(e.value) + + @pytest.mark.skipif(config["desktopVersion"] < "2026.1", reason="Skipped on versions earlier than 2026 R1.") + def test_27_create_radio_antenna(self, add_app): + self.aedtapp = add_app(project_name="radio_antenna", application=Emit) + new_radio, new_antenna = self.aedtapp.schematic.create_radio_antenna("MICS", "Radio", "Antenna") + assert new_radio == 3 + assert new_antenna == 4 + with pytest.raises(RuntimeError) as e: + self.aedtapp.schematic.create_radio_antenna("WrongComponent", "Radio", "Antenna") + assert "Failed to create radio of type 'WrongComponent'" in str(e.value) + + @pytest.mark.skipif(config["desktopVersion"] < "2026.1", reason="Skipped on versions earlier than 2026 R1.") + def test_28_connect_components(self, add_app): + self.aedtapp = add_app(project_name="connect_components", application=Emit) + self.aedtapp.logger.info = MagicMock() + new_radio = self.aedtapp.schematic.create_component("MICS") + new_antenna = self.aedtapp.schematic.create_component("Antenna") + self.aedtapp.schematic.connect_components(new_radio, new_antenna) + self.aedtapp.logger.info.assert_called_with(f"Successfully connected components 'MICS' and 'Antenna'.") + with pytest.raises(RuntimeError) as e: + self.aedtapp.schematic.connect_components(new_radio, 6) + assert ( + "Failed to connect components '3' and '6': " + "Failed to retrieve properties for component '6': Failed to execute gRPC AEDT command: GetEmitNodeProperties" + ) in str(e.value) + + @pytest.mark.skipif(config["desktopVersion"] < "2026.1", reason="Skipped on versions earlier than 2026 R1.") + def test_29_get_component_properties(self, add_app): + self.aedtapp = add_app(project_name="component_properties", application=Emit) + new_radio = self.aedtapp.schematic.create_component("MICS") + new_radio_props = self.aedtapp.schematic.get_component_properties(new_radio) + assert isinstance(new_radio_props, dict) + assert new_radio_props["Name"] == "MICS" + assert new_radio_props["Type"] == "RadioNode" + assert new_radio_props["IconAlias"] == ":Radio" + new_radio_name = self.aedtapp.schematic.get_component_properties(new_radio, "Name") + assert new_radio_name == "MICS" + with pytest.raises(RuntimeError) as e: + self.aedtapp.schematic.get_component_properties(new_radio, "WrongProp") + assert ("Failed to retrieve properties for component '3': \"Property key 'WrongProp' not found.\"") in str( + e.value + ) From 2efebd66eeb67ccbd911e4ac5d2d9905f0d4e607 Mon Sep 17 00:00:00 2001 From: pyansys-ci-bot <92810346+pyansys-ci-bot@users.noreply.github.com> Date: Fri, 6 Jun 2025 17:32:03 +0000 Subject: [PATCH 2/4] chore: adding changelog file 6240.added.md [dependabot-skip] --- doc/changelog.d/6240.added.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 doc/changelog.d/6240.added.md diff --git a/doc/changelog.d/6240.added.md b/doc/changelog.d/6240.added.md new file mode 100644 index 00000000000..3b6634a46e5 --- /dev/null +++ b/doc/changelog.d/6240.added.md @@ -0,0 +1 @@ +Emit_schematic module is added. \ No newline at end of file From 24282f55090662a8b7c982df1096a4830ed50ec3 Mon Sep 17 00:00:00 2001 From: raghajaf Date: Fri, 6 Jun 2025 13:34:50 -0400 Subject: [PATCH 3/4] Longer line error fix. --- src/ansys/aedt/core/emit_core/emit_schematic.py | 9 ++++++--- tests/system/solvers/test_26_emit.py | 3 ++- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/ansys/aedt/core/emit_core/emit_schematic.py b/src/ansys/aedt/core/emit_core/emit_schematic.py index 700863745f7..cf895347e89 100644 --- a/src/ansys/aedt/core/emit_core/emit_schematic.py +++ b/src/ansys/aedt/core/emit_core/emit_schematic.py @@ -103,18 +103,21 @@ def create_component(self, component_type, name=None, library=None): # Use the single matching component component = matching_components[0] self.emit_instance.logger.info( - f"Using component '{component.name}' from library '{component.component_library}' for type '{component_type}'." + f"Using component '{component.name}' from library '{component.component_library}" + "' for type '{component_type}'." ) else: # Attempt to find an exact match component = next((comp for comp in matching_components if comp.name == component_type), None) if not component: self.emit_instance.logger.error( - f"Multiple components found for type '{component_type}', but no exact match. Please specify a unique component." + f"Multiple components found for type '{component_type}', but no exact match." + " Please specify a unique component." ) raise ValueError(f"Multiple components found for type '{component_type}', but no exact match.") self.emit_instance.logger.info( - f"Using exact match component '{component.name}' from library '{component.component_library}' for type '{component_type}'." + f"Using exact match component '{component.name}' from library '{component.component_library}" + "' for type '{component_type}'." ) # Create the component using the EmitCom module diff --git a/tests/system/solvers/test_26_emit.py b/tests/system/solvers/test_26_emit.py index f5076a9def5..a6828272eef 100644 --- a/tests/system/solvers/test_26_emit.py +++ b/tests/system/solvers/test_26_emit.py @@ -1350,7 +1350,8 @@ def test_28_connect_components(self, add_app): self.aedtapp.schematic.connect_components(new_radio, 6) assert ( "Failed to connect components '3' and '6': " - "Failed to retrieve properties for component '6': Failed to execute gRPC AEDT command: GetEmitNodeProperties" + "Failed to retrieve properties for component '6': Failed to execute gRPC AEDT command:" + " GetEmitNodeProperties" ) in str(e.value) @pytest.mark.skipif(config["desktopVersion"] < "2026.1", reason="Skipped on versions earlier than 2026 R1.") From 11ba274bcd64036ff8a77aefcb7002a6d3ed5a19 Mon Sep 17 00:00:00 2001 From: raghajaf Date: Mon, 9 Jun 2025 13:53:29 -0400 Subject: [PATCH 4/4] Comments are partially applied. --- .../aedt/core/emit_core/emit_schematic.py | 27 ++++++++++--------- tests/system/solvers/test_26_emit.py | 22 +++++++-------- 2 files changed, 25 insertions(+), 24 deletions(-) diff --git a/src/ansys/aedt/core/emit_core/emit_schematic.py b/src/ansys/aedt/core/emit_core/emit_schematic.py index cf895347e89..b75538d0196 100644 --- a/src/ansys/aedt/core/emit_core/emit_schematic.py +++ b/src/ansys/aedt/core/emit_core/emit_schematic.py @@ -40,7 +40,7 @@ def __init__(self, emit_instance): self.emit_instance = emit_instance @property - def emit_com_module(self): + def _emit_com_module(self): """Retrieve the EmitCom module from the Emit instance. Returns @@ -61,21 +61,21 @@ def emit_com_module(self): raise RuntimeError(f"Failed to retrieve EmitCom module: {e}") @pyaedt_function_handler - def create_component(self, component_type, name=None, library=None): - """Create a component using the EmitCom module. + def create_component(self, component_type: str, name: str = None, library: str = None) -> int: + """Create a component. Parameters ---------- component_type : str Type of the component to create. name : str, optional - Name of the component to create. Defaults to an empty string if not provided. + Name of the component to create. AEDT defaults used if not provided. library : str, optional Name of the component library. Defaults to an empty string if not provided. Returns ------- - str + int The ID of the created component. Raises @@ -121,7 +121,7 @@ def create_component(self, component_type, name=None, library=None): ) # Create the component using the EmitCom module - new_component_id = self.emit_com_module.CreateEmitComponent( + new_component_id = self._emit_com_module.CreateEmitComponent( name, component.name, component.component_library ) return new_component_id @@ -130,7 +130,9 @@ def create_component(self, component_type, name=None, library=None): raise RuntimeError(f"Failed to create component of type '{component_type}': {e}") @pyaedt_function_handler - def create_radio_antenna(self, radio_type, radio_name=None, antenna_name=None, library=None): + def create_radio_antenna( + self, radio_type: str, radio_name: str = None, antenna_name: str = None, library: str = None + ) -> tuple[int, int]: """Create a new radio and antenna and connect them. Parameters @@ -165,14 +167,15 @@ def create_radio_antenna(self, radio_type, radio_name=None, antenna_name=None, l try: new_radio_id = self.create_component(radio_type, radio_name, library) new_antenna_id = self.create_component("Antenna", antenna_name, "Antennas") - self.connect_components(new_antenna_id, new_radio_id) # Connect antenna to radio + if new_radio_id and new_antenna_id: + self.connect_components(new_antenna_id, new_radio_id) # Connect antenna to radio return new_radio_id, new_antenna_id except Exception as e: self.emit_instance.logger.error(f"Failed to create radio of type '{radio_type}' or antenna: {e}") raise RuntimeError(f"Failed to create radio of type '{radio_type}' or antenna: {e}") @pyaedt_function_handler - def connect_components(self, component_id_1, component_id_2): + def connect_components(self, component_id_1: int, component_id_2: int): """Connect two components in the schematic. Parameters @@ -201,12 +204,12 @@ def connect_components(self, component_id_1, component_id_2): raise RuntimeError(f"Failed to connect components '{component_id_1}' and '{component_id_2}': {e}") @pyaedt_function_handler - def get_component_properties(self, component_id, property_key=None): + def get_component_properties(self, component_id: int, property_key: str = None) -> dict: """Get properties of a component. Parameters ---------- - component_id : str + component_id : int ID of the component. property_key : str, optional Specific property key to retrieve. If ``None``, all properties are returned. @@ -223,7 +226,7 @@ def get_component_properties(self, component_id, property_key=None): If the specified property key is not found. """ try: - props = self.emit_com_module.GetEmitNodeProperties(0, component_id, True) + props = self._emit_com_module.GetEmitNodeProperties(0, component_id, True) props_dict = {prop.split("=", 1)[0]: prop.split("=", 1)[1] for prop in props} if property_key is None: return props_dict diff --git a/tests/system/solvers/test_26_emit.py b/tests/system/solvers/test_26_emit.py index 498367f10ec..de8cbd2278c 100644 --- a/tests/system/solvers/test_26_emit.py +++ b/tests/system/solvers/test_26_emit.py @@ -30,7 +30,6 @@ import pytest -import ansys.aedt.core from ansys.aedt.core.generic import constants as consts from ansys.aedt.core.generic.general_methods import is_linux from tests.system.solvers.conftest import config @@ -69,7 +68,7 @@ def aedtapp(add_app): (sys.version_info < (3, 10) or sys.version_info > (3, 12)) and config["desktopVersion"] > "2024.2", reason="Emit API is only available for Python 3.10-3.12 in AEDT versions 2025.1 and later.", ) -@pytest.mark.skipif(config["desktopVersion"] == "2025.2", reason="WAITING") +# @pytest.mark.skipif(config["desktopVersion"] == "2025.2", reason="WAITING") class TestClass: @pytest.fixture(autouse=True) def init(self, aedtapp, local_scratch): @@ -1296,7 +1295,7 @@ def count_license_actions(license_file_path): assert checkouts == expected_checkouts and checkins == expected_checkins - @pytest.mark.skipif(config["desktopVersion"] < "2026.1", reason="Skipped on versions earlier than 2026 R1.") + @pytest.mark.skipif(config["desktopVersion"] < "2022.2", reason="Skipped on versions earlier than 2025 R2.") def test_25_components_catalog(self, add_app): self.aedtapp = add_app(project_name="catalog-list", application=Emit) comp_list = self.aedtapp.modeler.components.components_catalog["LTE"] @@ -1304,14 +1303,14 @@ def test_25_components_catalog(self, add_app): assert comp_list[12].name == "LTE BTS" assert comp_list[13].name == "LTE Mobile Station" - @pytest.mark.skipif(config["desktopVersion"] < "2026.1", reason="Skipped on versions earlier than 2026 R1.") + @pytest.mark.skipif(config["desktopVersion"] < "2025.2", reason="Skipped on versions earlier than 2025 R2.") def test_26_create_component(self, add_app): self.aedtapp = add_app(project_name="create_component", application=Emit) self.aedtapp.logger.info = MagicMock() new_radio = self.aedtapp.schematic.create_component("MICS") assert new_radio == 3 self.aedtapp.logger.info.assert_called_with( - rf"Using component 'MICS' from library 'Radios\Commercial Unlicensed Systems\Medical' for type 'MICS'." + r"Using component 'MICS' from library 'Radios\Commercial Unlicensed Systems\Medical' for type 'MICS'." ) with pytest.raises(TypeError) as e: self.aedtapp.schematic.create_component() @@ -1329,7 +1328,7 @@ def test_26_create_component(self, add_app): "Failed to create component of type 'lte': Multiple components found for type 'lte', but no exact match." ) in str(e.value) - @pytest.mark.skipif(config["desktopVersion"] < "2026.1", reason="Skipped on versions earlier than 2026 R1.") + @pytest.mark.skipif(config["desktopVersion"] < "2025.2", reason="Skipped on versions earlier than 2025 R2.") def test_27_create_radio_antenna(self, add_app): self.aedtapp = add_app(project_name="radio_antenna", application=Emit) new_radio, new_antenna = self.aedtapp.schematic.create_radio_antenna("MICS", "Radio", "Antenna") @@ -1339,23 +1338,22 @@ def test_27_create_radio_antenna(self, add_app): self.aedtapp.schematic.create_radio_antenna("WrongComponent", "Radio", "Antenna") assert "Failed to create radio of type 'WrongComponent'" in str(e.value) - @pytest.mark.skipif(config["desktopVersion"] < "2026.1", reason="Skipped on versions earlier than 2026 R1.") + @pytest.mark.skipif(config["desktopVersion"] < "2025.2", reason="Skipped on versions earlier than 2025 R2.") def test_28_connect_components(self, add_app): self.aedtapp = add_app(project_name="connect_components", application=Emit) self.aedtapp.logger.info = MagicMock() new_radio = self.aedtapp.schematic.create_component("MICS") new_antenna = self.aedtapp.schematic.create_component("Antenna") self.aedtapp.schematic.connect_components(new_radio, new_antenna) - self.aedtapp.logger.info.assert_called_with(f"Successfully connected components 'MICS' and 'Antenna'.") + self.aedtapp.logger.info.assert_called_with("Successfully connected components 'MICS' and 'Antenna'.") with pytest.raises(RuntimeError) as e: self.aedtapp.schematic.connect_components(new_radio, 6) assert ( - "Failed to connect components '3' and '6': " - "Failed to retrieve properties for component '6': Failed to execute gRPC AEDT command:" - " GetEmitNodeProperties" + "Failed to connect components '3' and '6': Failed to retrieve properties for component '6': " + "Failed to execute gRPC AEDT command: GetEmitNodeProperties" ) in str(e.value) - @pytest.mark.skipif(config["desktopVersion"] < "2026.1", reason="Skipped on versions earlier than 2026 R1.") + @pytest.mark.skipif(config["desktopVersion"] < "2025.2", reason="Skipped on versions earlier than 2025 R2.") def test_29_get_component_properties(self, add_app): self.aedtapp = add_app(project_name="component_properties", application=Emit) new_radio = self.aedtapp.schematic.create_component("MICS")