2021年11月17日 星期三

使用ElementTree處理stack.xml

以下包含xml建立,讀取,改寫,存檔等動作:


import xml.etree.ElementTree as ET
tree = ET.parse('d:/demo/stackup1.xml')
x = tree.getroot()


y = x.find('./Stackup/ELayers/Layers')
for child in y:
print(child.get('Elevation'))
child.set('UnionPrimitives', 'true')
child.set('Material', 'Copper')
tree.write('d:/demo/stachkup2.xml')

2021年11月12日 星期五

計算選取物件的XYZ邊界

 選擇多個物件,執行下面script,即可輸出選取物件的XYZ邊界座標。

import ScriptEnv

ScriptEnv.Initialize("Ansoft.ElectronicsDesktop")
oDesktop.RestoreWindow()
oProject = oDesktop.GetActiveProject()
oDesign = oProject.GetActiveDesign()
oEditor = oDesign.SetActiveEditor("3D Modeler")


def setModel(x):
objs = {True: [i for i in x if x[i]], False: [i for i in x if not x[i]]}
for b, o in objs.items():
if o:
oEditor.ChangeProperty(
[
"NAME:AllTabs",
[
"NAME:Geometry3DAttributeTab",
[
"NAME:PropServers",
] + o,
[
"NAME:ChangedProps",
[
"NAME:Model",
"Value:=" , b
]
]
]
])

def getBoundingBox(objs):
db = {}
for i in range(oEditor.GetNumObjects()):
name = oEditor.GetObjectName(i)
p = oEditor.GetPropertyValue('Geometry3DAttributeTab', name, 'Model')
db[name] = p

setModel({i :(i in oEditor.GetSelections()) for i in db.keys()})
result = oEditor.GetModelBoundingBox()
setModel(db)
return result

size = getBoundingBox(oEditor.GetSelections())
AddWarningMessage(str(size))




2021年11月10日 星期三

HFSS 3D Layout當中找出互連的物件群組

分層找出物理上互連的物件群組,針對沒有netname的物件也可以使用。這裡用到遞迴的函數。

import json
import ScriptEnv
ScriptEnv.Initialize("Ansoft.ElectronicsDesktop")
oDesktop.RestoreWindow()
oProject = oDesktop.GetActiveProject()
oDesign = oProject.GetActiveDesign()
oEditor = oDesign.GetActiveEditor()

objdic = {}
for layer in oEditor.GetStackupLayerNames():
objdic[layer] = oEditor.FilterObjectList('Type', '*', oEditor.FindObjects('Layer', layer))

result = {}
for layer in objdic:
for obj in objdic[layer]:
poly = oEditor.GetPolygon(obj)
x = oEditor.FindObjectsByPolygon(poly, layer)
if len(x) > 1:
result[obj] = x

def getConnect(key, g):
for i in result[key]:
if i not in g:
g.append(i)
getConnect(i, g)
else:
continue
return g

group = []
for obj in result:
x = getConnect(obj, [])
if sorted(x) not in group:
group.append(sorted(x))

with open('d:/demo/connect.json', 'w') as f:
json.dump(group, f, indent=4)
(圖一)輸出互連狀況


2021年11月9日 星期二

如何背景執行Python檔

如果我們想執行一隻Python程式,不會跳出任何視窗,只在背景模式執行,比方說監控電腦狀態並輸出log檔,可以使用pythonw.exe搭配start,就不會跳出任何視窗,範例如下。

test.bat

path=D:\myvenv\Scripts
start pythonw .\test.py

test.py

import os
import time
os.chdir(os.path.dirname(__file__))

while True:
with open('test.log', 'a') as f:
f.writelines(str(time.time()) + '\n')
time.sleep(1)

進一步我們可以將該程式(.bat)設定為開機執行。選擇該程式並按Windows鍵+R,跳出下面視窗再按確定即可。



2021年10月29日 星期五

利用desktopproxy中斷.aedt模擬

我們可以用指令執行aedt模擬,比如說

set path=C:\Program Files\AnsysEM\v221\Win64;%path%

start ansysedt.exe -ng -BatchSolve .\package.aedt

上述案例執行時間4分17秒。 

接下來我們用ansysedt指令執行,2分鐘後以desktopproxy -abort中斷模擬。

set path=C:\Program Files\AnsysEM\v221\Win64;%path%

start ansysedt.exe -ng -BatchSolve .\package.aedt

PING localhost -n 120 >NUL

desktopproxy -abort .\package.aedt

中斷之後,再重啟模擬到模擬結束共2分22秒

set path=C:\Program Files\AnsysEM\v221\Win64;%path%

start ansysedt.exe -ng -BatchSolve .\package.aedt

總共花了4分22秒,比一次完成執行僅僅多了約5秒。代表中斷之後重啟模擬是延續之前中斷之前的狀態,而非重新開始。

Steamlit手動排序項目


import time
import streamlit as st


def submit_up(n):
if n > 0:
x = st.session_state.waiting_list[n]
y = st.session_state.waiting_list[n - 1]
st.session_state.waiting_list[n - 1] = x
st.session_state.waiting_list[n] = y


def submit_down(n):
if n < len(st.session_state.waiting_list) - 1:
x = st.session_state.waiting_list[n]
y = st.session_state.waiting_list[n + 1]
st.session_state.waiting_list[n + 1] = x
st.session_state.waiting_list[n] = y


def submit_top(n):
st.session_state.waiting_list = [st.session_state.waiting_list.pop(n)] + st.session_state.waiting_list


def submit_bottom(n):
st.session_state.waiting_list = st.session_state.waiting_list + [st.session_state.waiting_list.pop(n)]


def delete(n):
st.session_state.waiting_list.pop(n)


if 'waiting_list' not in st.session_state:
st.session_state.waiting_list = ['A1', 'B2', 'C3', 'D4']

for n, i in enumerate(st.session_state.waiting_list):
with st.expander(i):
c1, c2, c3, c4, c5, c6, c7, c8, c9, c10 = st.columns(10)
with c1:
st.button('▲', key=f'move up_{i}', on_click=submit_up, args=(n,))
with c2:
st.button('▼', key=f'move down_{i}', on_click=submit_down, args=(n,))
with c3:
st.button('Top', key=f'move up_{i}', on_click=submit_top, args=(n,))
with c4:
st.button('Bottom', key=f'move down_{i}', on_click=submit_bottom, args=(n,))
with c8:
st.button('Delete', key=f'delete_{i}', on_click=delete, args=(n,))
(圖一)手動排序選單


如何用程式碼更改AEDT選項設定

AEDT當中所有的設定都存放在XML檔案當中:C:\Users\<UserName>\Documents\Ansoft\<AnsysProductNameversion>\config\<PC_NAME>_user.XML,比方HPC的設定等等。可以透過指令修改,比方:oDesktop.SetRegistryString('Desktop\Settings\ProjectOptions\HPCLicenseType' , 'Pool')。

處理機碼的指令包含如下:

  • DeleteRegistryEntry
  • DoesRegistryValueExist
  • GetRegistryInt
  • GetRegistryString
  • SetRegistryFromFile
  • SetRegistryInt
  • SetRegistryString

其他像是AEDT Option當中的選項設定也可以透過上述的函式來讀取或修改。

(圖一)AEDT選項設定視窗