DSD-DBS / py-capellambse

A Python 3 headless implementation of the Capella modeling tool.

Home Page:https://dsd-dbs.github.io/py-capellambse/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Declared Logical components not appearing as contained parts of the root logical system

Ghipag opened this issue · comments

Hi all,
I am using the decl.apply() method to update the logical architecture of a (currently empty) Capella model. I am successfully adding the logical components to the Capella model and these appear in the Capella model when I open the project. However these logical components (or coffee machine in my example below) do not have any entries in their "representing parts" or "Typed Elements" properties, nor do they appear in their parents "contained parts" or "sub logical components" properties.
As a result, the logical components I add to the model in this way can't be added to any Logical Architecture Diagrams [LAB]. Is there a workaround for this?

This is a stripped-down version of the code I am using that should recreate the issue:

import capellambse
from capellambse import decl, helpers

capella_model = capellambse.MelodyModel("capella/blank_project/blank_project.aird") # this is a black capella project
    
# to start, get root component and function of logical architecture
root_component = capella_model.la.root_component
structure = capella_model.sa.component_package
root_function = capella_model.sa.root_function

# defining model change in yaml string
model_yaml_update = f"""
- parent: !uuid {root_component.uuid}
  extend:
    components:
      - name: Coffee Machine
        allocated_functions:
          - !promise brew coffee
- parent: !uuid {root_function.uuid}
  extend:
    functions:
      - name: brew coffee
        promise_id: brew coffee
        inputs:
          - name: Portafilter port
          - name: Steam port
            promise_id: steam input
        outputs:
          - name: Fluid port
          - name: Waste port
            promise_id: waste output
      - name: produce steam
        inputs:
          - name: Water port
          - name: Power port
          - name: User command
        outputs:
          - name: Steam port
            promise_id: steam output
      - name: collect process waste
        inputs:
          - name: Waste port
            promise_id: waste input
    exchanges:
      - name: Steam
        source: !promise steam output
        target: !promise steam input
      - name: Waste
        source: !promise waste output
        target: !promise waste input"""

 #apply change to model 
with open(output_file_name, "w") as f:
    f.write(model_yaml_update)
 
decl.apply(capella_model,output_file_name)
capella_model.save()

Thanks for any help

fair point, @Ghipag - parts aren't instantiated on component creation. And as a side effect, you need to create Parts additionally and link those up with defining Components. The workaround is to either "declare" parts next to components (quite a duplication) or click them in the UI later.

We didn't auto-create parts as Capella still has this "allow component reuse via parts" where parts are quite a thing - pretty much like class/block instances, one compoent may have many parts that may all have different names and be connected to different things but will have same definitions (ports and assigned functions). I guess it is safe to assume that this is a fairly unpopular option and the impact of not creating parts on Component creation on usability is pretty bad.

Maybe we can add an option (default) for decl to understand that it is in a "single-part mode" or "part re-use enabled-model" and if it is in the default model type - create parts on component creation and rename/update parts on component rename/update (as in this mode they are 1 - 1). @Wuestengecko , in your opinion can we create 1 default part for every new component / would this create any trouble? I think this will make the decl thing a bit more user-friendly.

image