Skip to content

FEAT: SAM Bot #6145

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 22 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 47 additions & 0 deletions .github/workflows/ci_cd.yml
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,53 @@ jobs:
python -c "import ansys.aedt.core; from ansys.aedt.core import __version__"



build-application-windows:
name: "Build SAM Bot - Windows"
runs-on: windows-latest
needs: [pr-title]
steps:
- uses: actions/checkout@v4

- uses: actions/setup-python@v5
with:
python-version: ${{ env.MAIN_PYTHON_VERSION }}

- name: Install Dependencies
run: pip install .[freeze]

- name: Extract version
run: |
python src/ansys/aedt/core/extensions/pyaedt_bot/installer/extract_version.py

- name: Freeze application
run: pyinstaller src/ansys/aedt/core/extensions/pyaedt_bot/installer/frozen.spec

- name: Install NSIS
run: choco install nsis -y

- name: Run NSIS
shell: pwsh
if: always()
run: |
Set-StrictMode -Version Latest
$ErrorActionPreference = "Stop"

$setupPath = "src/ansys/aedt/core/extensions/pyaedt_bot/installer/setup.nsi"

if (!(Test-Path -Path $setupPath)) {
Write-Error "NSIS script not found at $setupPath"
}
& makensis $setupPath

# - name: List output
# run: ls -R dist

- uses: actions/upload-artifact@v4
with:
name: SAM-Bot-Installer-windows
path: dist/pyaedt_bot/SAM-Bot-Installer-windows.exe

unit-tests:
name: Running unit tests
needs: [smoke-tests]
Expand Down
1 change: 1 addition & 0 deletions codecov.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ ignore:
- "src/ansys/aedt/core/visualization/advanced/sbrplus/hdm_utils.py"
- "src/ansys/aedt/core/extensions/installer"
- "src/ansys/aedt/core/extensions/templates"
- "src/ansys/aedt/core/extensions/pyaedt_bot"
- "src/ansys/aedt/core/common_rpc.py"
- "src/ansys/aedt/core/internal/grpc_plugin_dll_class.py"
- "src/ansys/aedt/core/edb.py"
Expand Down
1 change: 1 addition & 0 deletions doc/changelog.d/6145.added.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
SAM Bot
11 changes: 6 additions & 5 deletions doc/source/Resources/pyaedt_installer_from_aedt.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@
is_linux = os.name == "posix"
is_windows = not is_linux


VENV_DIR_PREFIX = ".pyaedt_env"

"""
Expand All @@ -52,7 +51,6 @@
else:
VENV_DIR = os.path.join(os.environ["HOME"], VENV_DIR_PREFIX)


DISCLAIMER = (
"This script will download and install certain third-party software and/or "
"open-source software (collectively, 'Third-Party Software'). Such Third-Party "
Expand Down Expand Up @@ -274,9 +272,11 @@ def install_pyaedt():
subprocess.run([str(python_exe), "-m", "pip", "install", "--upgrade", "pip"], check=True) # nosec
subprocess.run([str(pip_exe), "--default-timeout=1000", "install", "wheel"], check=True) # nosec
if args.version <= "231":
subprocess.run([str(pip_exe), "--default-timeout=1000", "install", "pyaedt[all]=='0.9.0'"], check=True) # nosec
subprocess.run([str(pip_exe), "--default-timeout=1000", "install", "pyaedt[all]=='0.9.0'"],
check=True) # nosec
subprocess.run([str(pip_exe), "--default-timeout=1000", "install", "jupyterlab"], check=True) # nosec
subprocess.run([str(pip_exe), "--default-timeout=1000", "install", "ipython", "-U"], check=True) # nosec
subprocess.run([str(pip_exe), "--default-timeout=1000", "install", "ipython", "-U"],
check=True) # nosec
subprocess.run([str(pip_exe), "--default-timeout=1000", "install", "ipyvtklink"], check=True) # nosec
else:
subprocess.run([str(pip_exe), "--default-timeout=1000", "install", "pyaedt[all]"], check=True) # nosec
Expand Down Expand Up @@ -308,7 +308,8 @@ def install_pyaedt():
if args.version <= "231":
subprocess.run([str(pip_exe), "pip=1000", "install", "pyaedt[all]=='0.9.0'"], check=True) # nosec
subprocess.run([str(pip_exe), "--default-timeout=1000", "install", "jupyterlab"], check=True) # nosec
subprocess.run([str(pip_exe), "--default-timeout=1000", "install", "ipython", "-U"], check=True) # nosec
subprocess.run([str(pip_exe), "--default-timeout=1000", "install", "ipython", "-U"],
check=True) # nosec
subprocess.run([str(pip_exe), "--default-timeout=1000", "install", "ipyvtklink"], check=True) # nosec
else:
subprocess.run([str(pip_exe), "--default-timeout=1000", "install", "pyaedt[all]"], check=True) # nosec
Expand Down
60 changes: 51 additions & 9 deletions doc/source/User_guide/extensions.rst
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

You can launch extensions in standalone mode from the console or a Python script.


Pre-installed extensions
------------------------

Expand Down Expand Up @@ -151,15 +152,6 @@

Shielding effectiveness automated workflow HFSS.


.. grid-item-card:: Point cloud generator
:link: pyaedt_extensions_doc/hfss/point_cloud_generator
:link-type: doc
:margin: 2 2 0 0

Generate object and surface conforming point clouds.


.. grid-item-card:: Move it
:link: pyaedt_extensions_doc/hfss/move_it
:link-type: doc
Expand Down Expand Up @@ -200,6 +192,14 @@
Import different schematic files (ACS, SP, CIR, QCV) into Circuit.


.. grid-item-card:: Circuit configuration
:link: pyaedt_extensions_doc/circuit/circuit_configuration
:link-type: doc
:margin: 2 2 0 0

Apply simulation configuration to a Circuit design.


Twin Builder extensions
~~~~~~~~~~~~~~~~~~~~~~~

Expand Down Expand Up @@ -330,3 +330,45 @@
aedtapp.modeler.create_sphere([0, 0, 0], 20)

app.release_desktop(False, False)


SAM Bot

Check warning on line 335 in doc/source/User_guide/extensions.rst

View workflow job for this annotation

GitHub Actions / vale

[vale] doc/source/User_guide/extensions.rst#L335

[Google.Headings] 'SAM Bot' should use sentence-style capitalization.
Raw output
{"message": "[Google.Headings] 'SAM Bot' should use sentence-style capitalization.", "location": {"path": "doc/source/User_guide/extensions.rst", "range": {"start": {"line": 335, "column": 1}}}, "severity": "WARNING"}
-------

SAM Bot (Smart AEDT Manager) is a standalone utility that provides a floating GUI for launching PyAEDT-based automation scripts quickly and easily.
It enables a drag-and-drop experience and a right-click context menu for executing extensions defined in a TOML configuration file.

**Key features:**

- Launch PyAEDT extensions directly without opening AEDT manually.
- Use a TOML file to define and organize multiple automation scripts.
- Drag the bot across the screen or dock it in a convenient location.
- Access the context menu by right-clicking on the bot icon.

.. image:: ../_static/sam_bot_example.png
:width: 300
:alt: SAM Bot Interface

**Installation:**

You can download and install SAM Bot by visiting the following link:

`Download SAM Bot <https://github.com/ansys/pyaedt/releases/latest/>`_

After downloading the `.exe` file, you can run it directly.
To customize the configuration, set the `PYAEDT_BOT_CONFIG` environment variable to the path of your TOML file.

**Example TOML file:**

.. code:: toml

interpreter = "Your_Python_Interpreter"

[Project]
extension_1 = { name = "Import Nastran/STL", script = "project/import_nastran.py" }

[NewSection]
extension_1 = { name = "Custom extension", script = "custom_script.py" }
extension_2 = { name = "Choke Designer", script = "hfss/choke_designer.py" }

**Note:** SAM Bot is compatible with Python 3.10 and is typically used with a virtual environment managed by PyAEDT.
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,11 @@ Circuit extensions
:margin: 2 2 0 0

Import different schematic files (ACS, SP, CIR, QCV) into Circuit.


.. grid-item-card:: Circuit configuration
:link: circuit_configuration
:link-type: doc
:margin: 2 2 0 0

Apply simulation configuration to a Circuit design.
2 changes: 0 additions & 2 deletions doc/source/User_guide/pyaedt_extensions_doc/hfss/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,13 @@ HFSS extensions

Edit a source from file data in HFSS.


.. grid-item-card:: Shielding effectiveness
:link: shielding
:link-type: doc
:margin: 2 2 0 0

Shielding effectiveness workflow in HFSS.


.. grid-item-card:: Move it
:link: move_it
:link-type: doc
Expand Down
Binary file added doc/source/_static/sam_bot_example.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions doc/styles/config/vocabularies/ANSYS/accept.txt
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ COM interface
[Cc]omponents
Conda
CPython
datas
DesignXploration
docstring
[Dd]ocstrings
Expand Down
4 changes: 4 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,10 @@ examples = [
"plotly>=6.0,<6.1",
"scikit-rf>=0.30.0,<1.8",
]
freeze = [
"pyaedt[all]",
"pyinstaller"
]

[tool.setuptools.dynamic]
version = {attr = "ansys.aedt.core.__version__"}
Expand Down
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
46 changes: 46 additions & 0 deletions src/ansys/aedt/core/extensions/pyaedt_bot/assets/config.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
interpreter = ""

[Project]
extension_1 = { name = "Import Nastran/STL", script = "project/import_nastran.py" }
extension_2 = { name = "Generate report", script = "circuit/create_report.py" }
extension_3 = { name = "Configure layout", script = "circuit/configure_edb.py" }
extension_4 = { name = "Advanced Fields Calculator", script = "circuit/advanced_fields_calculator.py" }
extension_5 = { name = "Point Cloud Generator", script = "circuit/points_cloud.py" }

[Circuit]
extension_1 = { name = "Import Schematic", script = "circuit/import_schematic.py" }
extension_2 = { name = "Circuit Configuration", script = "circuit/circuit_configuration.py" }

[HFSS]
extension_1 = { name = "Choke Designer", script = "hfss/choke_designer.py" }
extension_2 = { name = "Shielding Effectiveness", script = "hfss/shielding_effectiveness.py" }
extension_3 = { name = "Move IT", script = "hfss/move_it.py" }
extension_4 = { name = "Push from Transient", script = "hfss/push_excitation_from_file.py" }

[HFSS3DLayout]
extension_1 = { name = "Export to 3D", script = "hfss3dlayout/export_to_3d.py" }
extension_2 = { name = "Push from Transient", script = "hfss3dlayout/push_excitation_from_file_3dl.py" }
extension_3 = { name = "Export Layout info", script = "hfss3dlayout/export_layout.py" }
extension_4 = { name = "Advanced Cutout", script = "hfss3dlayout/export_layout.py" }
extension_5 = { name = "Parametrize Layout", script = "hfss3dlayout/parametrize_edb.py" }
extension_6 = { name = "Arbitrary Waveports", script = "hfss3dlayout/generate_arbitrary_wave_ports.py" }
extension_7 = { name = "Via merging", script = "hfss3dlayout/via_clustering_extension.py" }
extension_8 = { name = "Post Layout Design", script = "hfss3dlayout/post_layout_design_toolkit.py" }

[Maxwell3D]
extension_1 = { name = "Fields distribution", script = "maxwell3d/fields_distribution.py" }

[Maxwell2D]
extension_1 = { name = "Fields distribution", script = "maxwell3d/fields_distribution.py" }

[Icepak]
extension_1 = { name = "Create Power map", script = "icepak/power_map_from_csv.py" }

[TwinBuilder]
extension_1 = { name = "Export to Circuit", script = "twinbuilder/convert_to_circuit.py" }

[EMIT]

[Q3D]

[Q2D]
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# -*- 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.

import os
import re

try:
THIS_PATH = os.path.dirname(__file__)
except NameError:
THIS_PATH = os.getcwd()

with open("src/ansys/aedt/core/__init__.py", "r") as f:
content = f.read()

match = re.search(r'__version__\s*=\s*["\']([^"\']+)["\']', content)
if match:
with open(os.path.join(THIS_PATH, "VERSION"), "w") as v:
v.write(match.group(1))
Loading
Loading