8. Property Values and Property Value Management Tool (PVMT) support¶
capellambse provides access to property values and property value groups, as well as the additional information maintained by the Property Value Management Tool (PVMT) extension.
Let’s first take a look at how to work with basic property values.
[1]:
import capellambse
model = capellambse.MelodyModel(
"../../../tests/data/melodymodel/5_0/Melody Model Test.aird"
)
Model objects can own property values and PV groups. To access those, use the property_values
and property_value_groups
attributes respectively:
[2]:
obj = model.search("LogicalComponent").by_name("Whomping Willow")
[3]:
obj.property_values
[3]:
- IntegerPropertyValue "cars_defeated": 1 (a928fa22-cef7-4357-9b87-675a432f6591)
[4]:
obj.property_values[0]
[4]:
cars_defeated (org.polarsys.capella.core.data.capellacore:IntegerPropertyValue)
applied_property_value_groups | (Empty list) |
---|---|
applied_property_values | (Empty list) |
constraints | (Empty list) |
description | |
diagrams | (Empty list) |
enumerations | (Empty list) |
filtering_criteria | (Empty list) |
layer | LogicalArchitecture "Logical Architecture" (853cb005-cba0-489b-8fe3-bb694ad4543b) |
name | cars_defeated |
parent | "Whomping Willow" (3bdd4fa2-5646-44a1-9fa6-80c68433ddb7) |
progress_status | NOT_SET |
property_value_groups | (Empty list) |
property_values | (Empty list) |
pvmt | Property Value Management for IntegerPropertyValue "cars_defeated": 1 (a928fa22-cef7-4357-9b87-675a432f6591) |
requirements | (Empty list) |
summary | None |
traces | (Empty list) |
uuid | a928fa22-cef7-4357-9b87-675a432f6591 |
validation | <capellambse.extensions.validation._validate.ElementValidation object at 0x720dec0f03b0> |
value | 1 |
xtype | org.polarsys.capella.core.data.capellacore:IntegerPropertyValue |
[5]:
obj.property_value_groups
[5]:
- PropertyValueGroup "Stats" (81bcc3d3-24d2-411e-a296-9943029acfd9)
8.1. dict-like access to property values¶
In addition to standard attribute-based access, these property value-related attributes can also behave like dicts in some cases. Here the dict key equates to the name
of a property value or group, and the dict value equates to either the value
of a property value object, or a list of PV objects in the group (which again can behave dict-like).
This significantly shortens the way to a specific value. For comparison, this would be the “usual” attribute-based way of accessing it:
[6]:
obj.property_value_groups.by_name("Stats").property_values.by_name("WIS").value
[6]:
150
And here is the same again, leveraging the dict-like behavior:
[7]:
obj.property_value_groups["Stats"]["WIS"]
[7]:
150
This of course also works for ungrouped property values:
[8]:
obj.property_values["cars_defeated"]
[8]:
1
[9]:
obj.property_value_groups["Stats"]
[9]:
- IntegerPropertyValue "HP": 8000 (0e95950d-272f-4b50-b68d-ee8fed002c94)
- IntegerPropertyValue "STR": 42 (32be6f26-4b33-4861-b501-3bfce3df94cb)
- IntegerPropertyValue "AGI": 0 (addb1e4a-9ecc-411c-b7ef-b76388e5840d)
- IntegerPropertyValue "WIS": 150 (7c8c9c21-86b9-4dba-9c7c-cd9db2f09c11)
- IntegerPropertyValue "INT": 12 (647a5565-a1de-4e15-ab21-eb628eea413c)
[10]:
obj.property_value_groups["Stats"]["WIS"]
[10]:
150
These property values can also be written to:
[11]:
obj.property_value_groups["Stats"]["INT"] = 18
obj.property_value_groups["Stats"]
[11]:
- IntegerPropertyValue "HP": 8000 (0e95950d-272f-4b50-b68d-ee8fed002c94)
- IntegerPropertyValue "STR": 42 (32be6f26-4b33-4861-b501-3bfce3df94cb)
- IntegerPropertyValue "AGI": 0 (addb1e4a-9ecc-411c-b7ef-b76388e5840d)
- IntegerPropertyValue "WIS": 150 (7c8c9c21-86b9-4dba-9c7c-cd9db2f09c11)
- IntegerPropertyValue "INT": 18 (647a5565-a1de-4e15-ab21-eb628eea413c)
9. Property Value Management (PVMT)¶
Property values become much more powerful when using the Property Value Management Tool extension. This extension groups property values into domains and groups, and allows to automatically apply certain groups based on specific conditions. These conditions may include the object class, the architectural layer, and other already applied property values.
Metadata about the defined domains and groups is stored in a package named “EXTENSIONS” at the root level of the model, which is conveniently accessible as model.pvmt
. The package will automatically be created if it does not exist yet.
[12]:
model.pvmt
[12]:
EXTENSIONS (org.polarsys.capella.core.data.capellacore:PropertyValuePkg)
applied_property_value_groups | (Empty list) |
---|---|
applied_property_values | (Empty list) |
constraints | (Empty list) |
description | |
diagrams | (Empty list) |
domains |
|
filtering_criteria | (Empty list) |
name | EXTENSIONS |
parent | <capellambse.model.MelodyModel object at 0x720df69da180> |
progress_status | NOT_SET |
property_value_groups | (Empty list) |
property_values | (Empty list) |
pvmt | Property Value Management for PropertyValuePkg "EXTENSIONS" (fdbeb3b8-e1e2-4c6d-aff4-bccb1b9f437f) |
requirements | (Empty list) |
summary | None |
traces | (Empty list) |
uuid | fdbeb3b8-e1e2-4c6d-aff4-bccb1b9f437f |
validation | <capellambse.extensions.validation._validate.ElementValidation object at 0x720dec2e55b0> |
xtype | org.polarsys.capella.core.data.capellacore:PropertyValuePkg |
From there, we can easily enumerate the defined domains:
[13]:
model.pvmt.domains
[13]:
- ManagedDomain "DarkMagic" (3763dd54-a878-446a-9330-b5d9c7121865)
And see which groups are defined in that domain:
[14]:
domain = model.pvmt.domains["DarkMagic"]
domain.groups
[14]:
- ManagedGroup "DarkMagic.Power" (1e241678-282c-46f3-abbd-e0cf34e743ee)
- ManagedGroup "DarkMagic.Power Level" (a0cb5a23-955e-43d6-a633-2c4e66991364)
[15]:
group = domain.groups["Power Level"]
group
[15]:
Power Level (org.polarsys.capella.core.data.capellacore:PropertyValueGroup)
applied_property_value_groups | (Empty list) |
---|---|
applied_property_values | (Empty list) |
constraints | (Empty list) |
diagrams | (Empty list) |
filtering_criteria | (Empty list) |
fullname | DarkMagic.Power Level |
name | Power Level |
parent | PropertyValuePkg "DarkMagic" (3763dd54-a878-446a-9330-b5d9c7121865) |
progress_status | NOT_SET |
property_value_groups | (Empty list) |
property_values |
|
pvmt | Property Value Management for PropertyValueGroup "Power Level" (a0cb5a23-955e-43d6-a633-2c4e66991364) |
requirements | (Empty list) |
selector | SelectorRules(raw='[PROPERTY]DarkMagic.Power.Max<10000.0[/PROPERTY]\n[ARCHITECTURE]LOGICAL[/ARCHITECTURE]') |
summary | None |
traces | (Empty list) |
uuid | a0cb5a23-955e-43d6-a633-2c4e66991364 |
validation | <capellambse.extensions.validation._validate.ElementValidation object at 0x720dec0f1850> |
xtype | org.polarsys.capella.core.data.capellacore:PropertyValueGroup |
Group definitions also have a selector
, which contains rules that determine the applicable model elements.
The current ruleset can be introspected by reading the attributes of the selector
:
[16]:
print(group.selector.classes)
print(group.selector.layers)
print(group.selector.properties)
()
(<class 'capellambse.model.layers.la.LogicalArchitecture'>,)
(('DarkMagic.Power.Max', '<', '10000.0'),)
The ManagedGroup object provides some helper methods that interpret this selector:
[17]:
?group.find_applicable
Signature: group.find_applicable() -> 'c.ElementList'
Docstring: Find all elements in the model that this group applies to.
File: ~/devspace/capellambse/capellambse/extensions/pvmt/_config.py
Type: method
[18]:
group.find_applicable()
[18]:
- "Harry J. Potter" (a8c46457-a702-41c4-a971-c815c4c5a674)
- "Prof. A. P. W. B. Dumbledore" (08e02248-504d-4ed8-a295-c7682a614f66)
- "R. Weasley" (ff7b8672-84db-4b93-9fea-22a410907fb1)
- "Prof. S. Snape" (6f463eed-c77b-4568-8078-beec0536f243)
[19]:
?group.applies_to
Signature: group.applies_to(obj: 'c.ModelObject') -> 'bool'
Docstring: Determine whether this group applies to a model element.
File: ~/devspace/capellambse/capellambse/extensions/pvmt/_config.py
Type: method
[20]:
dumbledore = model.search("LogicalComponent").by_name(
"Prof. A. P. W. B. Dumbledore"
)
group.applies_to(dumbledore)
[20]:
True
And finally, a group can be applied to an element with the apply
method. If the group was already applied earlier, the existing group instance will be returned:
[21]:
group.apply(dumbledore)
[21]:
DarkMagic.Power Level (org.polarsys.capella.core.data.capellacore:PropertyValueGroup)
applied_property_value_groups |
|
---|---|
applied_property_values | (Empty list) |
constraints | (Empty list) |
description | |
diagrams | (Empty list) |
filtering_criteria | (Empty list) |
layer | LogicalArchitecture "Logical Architecture" (853cb005-cba0-489b-8fe3-bb694ad4543b) |
name | DarkMagic.Power Level |
parent | "Prof. A. P. W. B. Dumbledore" (08e02248-504d-4ed8-a295-c7682a614f66) |
progress_status | NOT_SET |
property_value_groups | (Empty list) |
property_values | |
pvmt | Property Value Management for PropertyValueGroup "DarkMagic.Power Level" (6cf12387-7187-4b91-9efe-8fedb8a148cb) |
requirements | (Empty list) |
summary | None |
traces | (Empty list) |
uuid | 6cf12387-7187-4b91-9efe-8fedb8a148cb |
validation | <capellambse.extensions.validation._validate.ElementValidation object at 0x720dec24dcd0> |
values | |
xtype | org.polarsys.capella.core.data.capellacore:PropertyValueGroup |
Each model element can have several property value groups applied to it. PVMT-managed groups can be easily inspected by using the element’s pvmt
attribute:
[22]:
dumbledore.pvmt
[22]:
Property Value Management
Owner: "Prof. A. P. W. B. Dumbledore" (08e02248-504d-4ed8-a295-c7682a614f66)
ManagedGroup "DarkMagic.Power" (1e241678-282c-46f3-abbd-e0cf34e743ee) | ||
---|---|---|
Min | 800.0 | 0.0 |
Max | 1600.0 | 10000.0 |
ManagedGroup "DarkMagic.Power Level" (a0cb5a23-955e-43d6-a633-2c4e66991364) | ||
Skill | EnumerationPropertyLiteral "Mighty" (1e5efe87-d919-4bd0-af2b-7c976ef9da96) | EnumerationPropertyLiteral "TheOneWhoShallNotBeNamed" (4da42696-28e2-4f90-bfb6-90ba1fc52d01) |
Property | Value | Default |
The groupdefs
attribute will give access to the definitions of all groups that apply to this element:
[23]:
dumbledore.pvmt.groupdefs
[23]:
- ManagedGroup "DarkMagic.Power" (1e241678-282c-46f3-abbd-e0cf34e743ee)
- ManagedGroup "DarkMagic.Power Level" (a0cb5a23-955e-43d6-a633-2c4e66991364)
On the other hand, the applied_groups
attribute will yield the group instances that are currently applied to the object.
Note: This list may be missing some groups from groupdefs
. These can be applied using the group definition’s apply
method (see above).
[24]:
dumbledore.pvmt.applied_groups
[24]:
- PropertyValueGroup "DarkMagic.Power" (42dc9aeb-a06d-4012-8bc6-02fb06f94cdc)
- PropertyValueGroup "DarkMagic.Power Level" (6cf12387-7187-4b91-9efe-8fedb8a148cb)
Property values can also be accessed using convenient dict-like semantics.
With keys like “Domain.Group”, an applied group instance will be returned, where the group is applied first if needed:
[25]:
dumbledore.pvmt["DarkMagic.Power"]
[25]:
DarkMagic.Power (org.polarsys.capella.core.data.capellacore:PropertyValueGroup)
applied_property_value_groups |
|
---|---|
applied_property_values | (Empty list) |
constraints | (Empty list) |
description | |
diagrams | (Empty list) |
filtering_criteria | (Empty list) |
layer | LogicalArchitecture "Logical Architecture" (853cb005-cba0-489b-8fe3-bb694ad4543b) |
name | DarkMagic.Power |
parent | "Prof. A. P. W. B. Dumbledore" (08e02248-504d-4ed8-a295-c7682a614f66) |
progress_status | NOT_SET |
property_value_groups | (Empty list) |
property_values | |
pvmt | Property Value Management for PropertyValueGroup "DarkMagic.Power" (42dc9aeb-a06d-4012-8bc6-02fb06f94cdc) |
requirements | (Empty list) |
summary | None |
traces | (Empty list) |
uuid | 42dc9aeb-a06d-4012-8bc6-02fb06f94cdc |
validation | <capellambse.extensions.validation._validate.ElementValidation object at 0x720df5da19d0> |
values | |
xtype | org.polarsys.capella.core.data.capellacore:PropertyValueGroup |
Keys may also contain a Property, in which case the value of that property is returned directly. This is similar to the basic property values shown in the first part of this notebook. However, like in the case without a Property, the group will first be applied if needed. Newly applied groups have all their properties set to the default values from the group definition.
[26]:
dumbledore.pvmt["DarkMagic.Power.Max"]
[26]:
1600.0
This latter style also supports directly setting individual properties.
[27]:
dumbledore.pvmt["DarkMagic.Power.Max"] = 9000
dumbledore.pvmt["DarkMagic.Power.Max"]
[27]:
9000.0