Applying a PropertyValue that is defined in PVMT Add-on to a new Component

Hi there,

I have a set of property values defined in my Capella model using the PVMT Add-On.

When I add a new component and look at the ‘Property Values’ tab I can see which property values could be applied to this model element:

What I am trying to do is to add a new component/port using Python4Capella and then apply already defined PropertyValues to this element and set their values.

How do I get the existing property value object to add to my new element?

I tried the following for a newly added port, but it will not add the existing property value group:

pvg=PropertyValueGroup()
pvg.set_name('Snippet Design Domain.Snippet Port Allocation') 
pp.get_java_object().getAppliedPropertyValueGroups().add(pvg.get_java_object())

Thank you and kind regards

Janis

You need to set the appliedPropertyValueGroups EReference:

project = myCapellaModel.get_system_engineering().get_java_object().eContainer()

# you need to change this to get your PropertyValueGroup, here I took the first one
propertyGroupToApply = PropertyValueGroup(project.getOwnedPropertyValuePkgs().get(0).getOwnedPropertyValuePkgs().get(0).getOwnedPropertyValueGroups().get(0))

pvg.get_java_object().getAppliedPropertyValueGroups().add(propertyGroupToApply.get_java_object())

You will also need to do the same thing to apply each each property value:

# also took the first one
propertyValueToApply = PropertyValue(propertyGroupToApply.get_java_object().getOwnedPropertyValues().get(0))

pv = PropertyValue()
pv.get_java_object().getAppliedPropertyValues().add(propertyValueToApply.get_java_object())
....

Hi Yvan,

thank you for the quick answer, this works perfectly :slight_smile:

What I can’t figure out though is how to afterwards set the property value in case of an enum. I found this thread where you suggested the following solution:

@staticmethod
def set_p_v_value(elem, PVName, value):
    for group in elem.get_java_object().getOwnedPropertyValueGroups():
        for pv in group.getOwnedPropertyValues():
            if PVName == pv.getName():
                if isinstance(java_object, JavaObject):
                    pv.setValue(value.get_java_object())
                else:
                    pv.setValue(value)
                return

What exactly is ‘java_object’? is this supposed to be ‘value’?

Under this assumption I still get the following error:

py4j.Py4JException: Method setValue([class java.lang.String]) does not exist

This is for pv of type org.polarsys.capella.core.data.capellacore.impl.EnumerationPropertyValueImpl

I think that I still missing something here. Do I need to provide the new value as type org.polarsys.capella.core.data.capellacore.impl.EnumerationPropertyLiteralImpl?

Kind regards

Janis

The is in the code snippet is used to distinguish primitive values (string, int, …) for Objects from the Python4Capella API. Each Python4Capella Objects has a link to the Java Object via get_java_object(). The Java Oject can then be passed to the Java Capella API.

This method doesn’t exists yet in the Python4Capella API but you can add it to your pvmt.py file if you need it:

In the PropertyValuePkgs under the project, you have the list of EnumerationPropertyType that you can use, enumerations are stored here, you can reference them and their literals to set the value of your properties:

myEnumerationPropertyType = EnumerationPropertyType(project.getOwnedPropertyValuePkgs().get(0).getOwnedPropertyValuePkgs().get(0).getOwnedEnumerationPropertyTypes().get(0))

value = myEnumerationPropertyType.get_owned_literals().get(0)
pv.setValue(value)

I think the PVMT addon API should be changed to make more sens…

Hi. Thank you for the answer.

Implementing this I encountered something wierd. I have a method to find the PropertyValueGroup to add to my port:

@staticmethod
def get_property_value_group(capellaModel, propertyValuePkgName, propertyValueGroupName):
    project = capellaModel.get_system_engineering().get_java_object().eContainer()
                               
    for pv_package in project.getOwnedPropertyValuePkgs().get(0).getOwnedPropertyValuePkgs():
        if pv_package.getName() == propertyValuePkgName:
            for pv_group in pv_package.getOwnedPropertyValueGroups():
                print(pv_group)
                if pv_group.getName() == propertyValueGroupName:
                    return PropertyValueGroup(pv_group)

I iterate over multiple objects, add a physical port (pp) an then call the following:

pvg = get_property_value_group(model, 'Snippet Design Domain', 'Snippet Port Allocation')
            
pp.get_java_object().getOwnedPropertyValueGroups().add(pvg.get_java_object())
pp.get_java_object().getAppliedPropertyValueGroups().add(pvg.get_java_object())

For the first element this works fine, but for the second the PropertyValueGroup named ‘Snippet Port Allocation’ is not present anymore. Here the console output containing the print statement from the method above:

Start adding snippetPort 'PI_POWER_NONE' to snippetInstance 'AUX_Supply_Fuse'
org.polarsys.capella.core.data.capellacore.impl.PropertyValueGroupImpl@ea49e27 (id: 16c59e7d-179a-4afb-acd5-f71ed9ac41eb, sid: _qNB8gPd2EeyhxaUKB8OeLQ) (name: Snippet Allocation) (visibleInDoc: true, visibleInLM: true, summary: null, review: null)
org.polarsys.capella.core.data.capellacore.impl.PropertyValueGroupImpl@5baded37 (id: a6b331bd-c42f-41cf-8596-df0991bd799d, sid: _Yzw0kA8lEe25A6P9TGVpoQ) (name: Snippet Port Allocation) (visibleInDoc: true, visibleInLM: true, summary: null, review: null)
Adding successfull!

Start adding snippetPort 'PO_POWER_NONE' to snippetInstance 'AUX_Supply_Fuse'
org.polarsys.capella.core.data.capellacore.impl.PropertyValueGroupImpl@ea49e27 (id: 16c59e7d-179a-4afb-acd5-f71ed9ac41eb, sid: _qNB8gPd2EeyhxaUKB8OeLQ) (name: Snippet Allocation) (visibleInDoc: true, visibleInLM: true, summary: null, review: null)
org.polarsys.capella.core.data.capellacore.impl.PropertyValueGroupImpl@545d9128 (id: 4c27e7d2-34ca-4324-b0b3-72e05ea16f36, sid: _eh-8YBIqEe20JZa14ka6eA) (name: Snippet Link Allocation) (visibleInDoc: true, visibleInLM: true, summary: null, review: null)
org.polarsys.capella.core.data.capellacore.impl.PropertyValueGroupImpl@11a3a80 (id: 81e720af-925d-4a6f-b627-9d0e4458b572, sid: _foq4EsPpEe2dIo-kaSPCmA) (name: Snippet Net Allocation) (visibleInDoc: true, visibleInLM: true, summary: null, review: null)
org.polarsys.capella.core.data.capellacore.impl.PropertyValueGroupImpl@154f7867 (id: 5dc901db-b9d2-4dbc-8b4d-5dc17cfecea6, sid: _HksgQBSmEe289rq7SVqFyQ) (name: Snippet External Interface Allocation) (visibleInDoc: true, visibleInLM: true, summary: null, review: null)
org.polarsys.capella.core.data.capellacore.impl.PropertyValueGroupImpl@1221611f (id: 142fc9c1-9c5c-4d8b-9c4c-7cee3e1aa775, sid: _ikBxgJsOEe2ncoHrfAQzsw) (name: Snippet Design Allocation) (visibleInDoc: true, visibleInLM: true, summary: null, review: null)

‘Snippet Port Allocation’ should be the second element in the list return by pv_package.getOwnedPropertyValueGroups() as during the first call, but it is not there anymore. Is there an obvious reason for this behaviour?

If I alter the script so that it runs through the ‘Snippet Port Allocation’ group is also not longer present in Capella using the PVMT Add-On.

Kind regards

Janis

You need to create a new PropertyValueGroup as you did in the first code sample and then reference the PropertyValueGroup returned by your get_property_value_group() method using the getAppliedPropertyValues() EReference.

pvg=PropertyValueGroup()
pvg.set_name('Snippet Design Domain.Snippet Port Allocation') 

pvgToApply = get_property_value_group(model, 'Snippet Design Domain', 'Snippet Port Allocation')
pvg.get_java_object().getAppliedPropertyValueGroups().add(pvgToApply.get_java_object())

pp.get_owned_property_value_groups().add(pvg)
pp.get_java_object().getAppliedPropertyValueGroups().add(pvg.get_java_object())

I think this code should work… Your initial problem comes from the fact that an EObject can only be contained in one EReference so EMF is moving the EObject when added to an other containment EReference.

Hi,

now it works, I can successfully add and set the PropertyValues using my script :slight_smile:

If I then try to modify one of the newly added PVs using the PVMT Add-On I get the following error:

An error has occurred. See error log for more details.
Cannot invoke "org.polarsys.capella.core.data.capellacore.EnumerationPropertyType.getOwnedLiterals()" because the return value of "org.polarsys.capella.core.data.capellacore.EnumerationPropertyValue.getType()" is null

I checked the difference between my newly added PVs and manually added PVs. For the ones added by the script I indeed get a type of None, for the manually added ones the folling type:

org.polarsys.capella.core.data.capellacore.impl.EnumerationPropertyTypeImpl@25ac91cf (id: 77cc4931-e839-4fe3-8132-c1068764f431, sid: _fGORIA8lEe25A6P9TGVpoQ) (name: isSnippetPortEnum) (visibleInDoc: true, visibleInLM: true, summary: null, review: null)

I think there is still something missing in the way I construct the PV. My script looks like this right now:

pvg=PropertyValueGroup()
pvg.set_name('Snippet Design Domain.Snippet Port Allocation')
            
pvgToApply  = get_property_value_group(model, 'Snippet Design Domain', 'Snippet Port Allocation')
            
pvg.get_java_object().getAppliedPropertyValueGroups().add(pvgToApply.get_java_object())
            
pv = PropertyValue(kind = "EnumerationPropertyValue")
pv.set_name('isSnippetPort')
            
pvToApply = get_property_value(pvgToApply, 'isSnippetPort')
            
pv.get_java_object().getAppliedPropertyValues().add(pvToApply.get_java_object())
            
value = get_p_v_value_enum_literal(model, 'Snippet Design Domain', 'isSnippetPortEnum', pvmt_direction)
pv.set_value(value)
            
pvg.get_owned_property_values().add(pv)
            
pp.get_owned_property_value_groups().add(pvg)
pp.get_java_object().getAppliedPropertyValueGroups().add(pvg.get_java_object())

with following methods:

@staticmethod
def get_property_value(propertyValueGroup, propertyValueName):
    pvs = propertyValueGroup.get_java_object().getOwnedPropertyValues()
                                     
    for pv in pvs:
        if pv.getName() == propertyValueName:
            return PropertyValue(pv)

@staticmethod               
def get_p_v_value_enum_literal(capellaModel, propertyValuePkgName, enumName, literalName):
    project = capellaModel.get_system_engineering().get_java_object().eContainer()
    
    pv_packages = project.getOwnedPropertyValuePkgs().get(0).getOwnedPropertyValuePkgs()
                                     
    for pv_package in pv_packages:
        if pv_package.getName() == propertyValuePkgName:
            for pv_enum in pv_package.getOwnedEnumerationPropertyTypes():
                if pv_enum.getName() == enumName:
                    for pv_enum_literal in pv_enum.getOwnedLiterals():
                        if pv_enum_literal.getName() == literalName:
                            return pv_enum_literal

Thank you so much for the help, otherwise it would have been really hard for me to figure this out.

Kind regards,

Janis

1 Like

That’s not strait forward… That’s why an API at the Python level would be great. I’ll link this discussion in the issue.