# name : Extract physical component definition # script-type : Python # description : Extract a pseudo hierarchy of PA elements to xlsx # popup : enableFor(org.polarsys.capella.core.data.capellacore.CapellaElement) ''' This script allows to extract the interfaces of the selected Physical Component (NodePC or Actor), i.e. the list of physical links, paths, allocated functional exchanges and target components. It will create a folder "Components_interfaces" in the selected Capella project with the resulting xlsx file. ''' # To run it: # - enable Developer capabilities if not already done (see documentation in the help menu) # - you can run this script by launching the contextual menu "Run As / EASE Script..." # on this script. # - By default, the model selected is IFE sample (aird path of the model written below) # - you can also run this script according to a configuration (script selected, arguments) # and modify the configuration by launching the contextual menu "Run As / Run configurations..." # on this script. # - create a new "EASE Script" configuration # - define the name of the configuration: "Export_a_pseudo_hierarchy_of_PA_elements_to_xlsx.py" (for instance) # - define the Script Source path: "workspace://Python4Capella/sample_scripts/Export_a_pseudo_hierarchy_of_PA_elements_to_xlsx.py" # # include needed for the Capella modeller API include('workspace://Python4Capella_byIRT/simplified_api/capella.py') if False: from simplified_api.capella import * # include needed for utilities include('workspace://Python4Capella_byIRT/utilities/CapellaPlatform.py') if False: from utilities.CapellaPlatform import * # include needed to read/write xlsx files from openpyxl import * from openpyxl.formatting.rule import ColorScaleRule,CellIsRule,FormulaRule from openpyxl.styles import Alignment, NamedStyle, Font, colors, Color, PatternFill from openpyxl.styles.differential import DifferentialStyle from openpyxl.styles.borders import Border, Side # Retrieve the Element from the current selection try: elem = NodePC(CapellaPlatform.getFirstSelectedElement()) except: try: elem = PhysicalActor(CapellaPlatform.getFirstSelectedElement()) except: print("The selected element is not a node PC or an actor !") # create a folder in the project model_path = CapellaPlatform.getModelPath(elem) project_name = model_path[0:(model_path.index("/", 1) + 1)] project = CapellaPlatform.getProject(project_name) folder = CapellaPlatform.getFolder(project, "Components_interfaces") # preparing excel file export xlsx_file_name = CapellaPlatform.getAbsolutePath(folder) + '/' + elem.get_name() + '_interfaces.xlsx' # create a workbook workbook = Workbook() # writing excel file header worksheet = workbook.active worksheet.title = 'Interfaces' worksheet["A1"] = 'Physical link' worksheet["B1"] = 'Physical path' worksheet["C1"] = 'Functional exchange' worksheet["D1"] = 'Direction' worksheet["E1"] = 'Target component' # retrieving elements from the model i=2 if (isinstance(elem, NodePC) or isinstance(elem, PhysicalActor)): #Browse all physical links for pp in elem.get_contained_physical_ports(): for pl in pp.get_physical_links(): worksheet.cell(row = i, column = 1).value = pl.get_name() #Get the other end of the physical link for pc in pl.get_connected_components(): if pc != elem: target_pc = pc break worksheet.cell(row = i, column = 5).value = target_pc.get_name() i=i+1 #List all the component exchanges and functional exchanges directly allocated to the physical link for ce in pl.get_allocated_component_exchanges(): for fe in ce.get_allocated_functional_exchanges(): worksheet.cell(row = i, column = 3).value = fe.get_name() #Identify if the functional exchange is an input or an output of the component source_pf = fe.get_source_function() target_pf = fe.get_target_function() direction = '' for bpc in elem.get_deployed_behavior_p_cs(): if source_pf in bpc.get_allocated_functions(): direction = 'out' elif target_pf in bpc.get_allocated_functions(): direction = 'in' worksheet.cell(row = i, column = 4).value = direction i = i+1 #List all the component exchanges and functional exchanges directly allocated a physical path that involve the current physical link met_ppaths = [] for ppaths in pl.get_involving_physical_paths(): if not (ppaths in met_ppaths): #avoid double apparition of the physical paths, in the case of multiple involvements of the same physical link met_ppaths.append(ppaths) worksheet.cell(row = i, column = 2).value = ppaths.get_name() i=i+1 for ce in ppaths.get_allocated_component_exchanges(): for fe in ce.get_allocated_functional_exchanges(): worksheet.cell(row = i, column = 3).value = fe.get_name() source_pf = fe.get_source_function() target_pf = fe.get_target_function() direction = '' for bpc in elem.get_deployed_behavior_p_cs(): if source_pf in bpc.get_allocated_functions(): direction = 'out' elif target_pf in bpc.get_allocated_functions(): direction = 'in' if direction == '':#Cover the case where the NodePC is only "transfering" the FE, which may happen in the case of physical paths direction = 'in/out' worksheet.cell(row = i, column = 4).value = direction i = i+1 else: print("The selected element is not a physical node component or a Physical Actor !") bd = Side(border_style='medium') chosen_border = Border(left=bd, top=bd,right=bd, bottom=bd) chosen_alignment = Alignment(wrap_text=True,vertical='top') first_row = worksheet[1] Color_font = Font(color= colors.BLUE) for cell in first_row: cell.font = Color_font for row in worksheet.iter_rows(): for cell in row: cell.alignment = chosen_alignment cell.border = chosen_border column_width = 17 worksheet.column_dimensions['A'].width = column_width worksheet.column_dimensions['B'].width = column_width worksheet.column_dimensions['C'].width = column_width worksheet.column_dimensions['D'].width = column_width worksheet.column_dimensions['E'].width = column_width # Save the xlsx file workbook.save(xlsx_file_name) print('saving excel file') # refresh CapellaPlatform.refresh(folder)