1. Introduction

Welcome to the py-capella-mbse Showcase notebook. This notebook will show you some basic (and not so basic) things that you can get done using this library. For more advanced features have a look around the nearby notebooks.

The below code loads the library and one of the test models:

[1]:
import capellambse
path_to_model = "../../../tests/data/melodymodel/5_0/Melody Model Test.aird"
model = capellambse.MelodyModel(path_to_model)
model
[1]:
<capellambse.model.MelodyModel at 0x7f3f44f97970>

Let’s go to the first practical example of working with the library!

1.1. Example 1: Actor functions

The below code will print every Actor available in the Logical Architecture layer

[2]:
for actor in model.la.all_actors:
    print(actor.name)
Multiport
Prof. S. Snape
Voldemort
R. Weasley
Prof. A. P. W. B. Dumbledore
Harry J. Potter

but we could also “zoom-in” to an actor of interest:

[3]:
model.la.all_actors.by_name("Prof. S. Snape")
[3]:

Prof. S. Snape (org.polarsys.capella.core.data.la:LogicalComponent)

allocated_functions
  1. LogicalFunction "Teaching" (a7acb298-d14b-4707-a419-fea272434541)
  2. LogicalFunction "maintain a layer of defense for the Sorcerer's Stone" (4a2a7f3c-d223-4d44-94a7-50dd2906a70c)
applied_property_value_groups
  1. PropertyValueGroup "DarkMagic.Power" (2a480409-57d1-46f8-a0ce-e574706a9a7c)
  2. PropertyValueGroup "DarkMagic.Power Level" (b1d7453b-69ab-4d81-ab8b-1e48b5870340)
applied_property_values

(Empty list)

components

(Empty list)

constraints

(Empty list)

context_diagramContext of Prof. S. Snape (uuid: 6f463eed-c77b-4568-8078-beec0536f243_context)
description

Good guy and teacher of brewing arts.

diagrams

(Empty list)

exchanges

(Empty list)

filtering_criteria

(Empty list)

functions
  1. LogicalFunction "Teaching" (a7acb298-d14b-4707-a419-fea272434541)
  2. LogicalFunction "maintain a layer of defense for the Sorcerer's Stone" (4a2a7f3c-d223-4d44-94a7-50dd2906a70c)
is_abstractFalse
is_actorTrue
is_humanTrue
nameProf. S. Snape
ownerLogicalComponentPkg "Structure" (84c0978d-9a32-4f5b-8013-5b0b6adbfd73)
parentLogicalComponentPkg "Structure" (84c0978d-9a32-4f5b-8013-5b0b6adbfd73)
partsBackreference to Part - omitted: can be slow to compute. Display this property directly to show.
physical_links

(Empty list)

physical_paths

(Empty list)

physical_ports

(Empty list)

ports
  1. ComponentPort "CP 1" (b4e39757-b0fd-41ff-a7b8-c9fc36de2ca9)
progress_statusNOT_SET
property_value_groups
  1. PropertyValueGroup "DarkMagic.Power" (2a480409-57d1-46f8-a0ce-e574706a9a7c)
  2. PropertyValueGroup "DarkMagic.Power Level" (b1d7453b-69ab-4d81-ab8b-1e48b5870340)
property_values

(Empty list)

pvmt<capellambse.extensions.pvmt.PropertyValueProxy object at 0x7f496cb3f010>
realized_components

(Empty list)

realized_system_components

(Empty list)

realizing_componentsBackreference to - omitted: can be slow to compute. Display this property directly to show.
realizing_physical_componentsBackreference to PhysicalComponent - omitted: can be slow to compute. Display this property directly to show.
related_exchangesBackreference to ComponentExchange - omitted: can be slow to compute. Display this property directly to show.
requirements

(Empty list)

state_machines

(Empty list)

summaryNone
traces

(Empty list)

uuid6f463eed-c77b-4568-8078-beec0536f243
xtypeorg.polarsys.capella.core.data.la:LogicalComponent

We can also turn the above data into a table, for example “actor function allocation”, using pandas.

For this, we first make sure pandas itself is installed, as well as an extension we’ll use later.

[ ]:
%pip install -q pandas openpyxl

Now we can use it together with capellambse:

[4]:
import pandas as pd

data = []
for actor in model.la.all_actors:
    actor_functions = "; ".join([function.name for function in actor.functions] or ["no functions assigned"])
    data.append(dict(actor=actor.name, functions=actor_functions))
df = pd.DataFrame(data)
df
[4]:
actor functions
0 Multiport LAF 1
1 Prof. S. Snape Teaching; maintain a layer of defense for the ...
2 Voldemort no functions assigned
3 R. Weasley assist Harry; break school rules
4 Prof. A. P. W. B. Dumbledore manage the school; advise Harry
5 Harry J. Potter kill He Who Must Not Be Named

and any pandas.DataFrame can always be turned into an Excel Spreadsheet, just like that:

[5]:
df.to_excel("01_intro_actor_functions.xlsx")

you can check the resulting file in the folder next to this notebook (right after you run the above cell)

Now that we’ve seen the basics, lets do something visually cool.

1.2. Example 2: working with diagrams

The below code will find some diagrams for us.

[6]:
for diagram in model.la.diagrams.by_type('LAB'):
    print(diagram.name)
[LAB] Wizzard Education
[LAB] Test Component Port Filter
[LAB] Hidden Wizzard Education

We can analyze which model objects are shown in a particular diagram.

[7]:
diagram = model.diagrams.by_name('[LAB] Wizzard Education')
diagram.nodes
[7]:
  1. Part "Hogwarts" (101ffa60-f8a2-4ea2-a0d8-d10910ceac06)
  2. LogicalFunction "produce Great Wizards" (0e71a0d3-0a18-4671-bba0-71b5f88f95dd)
  3. LogicalFunction "protect Students against the Death Eaters" (264fb47d-67b7-4bdc-8d06-8a0e5139edbf)
  4. Part "Campus" (a3194240-cd17-4998-8f8b-785233487ec3)
  5. Part "School" (018a8ae9-8e8e-4aea-8191-4abf844a79e3)
  6. LogicalFunction "educate Wizards" (957c5799-1d4a-4ac0-b5de-33a65bf1519c)
  7. Part "Whomping Willow" (1188fc31-789b-424f-a2d4-06791873a351)
  8. LogicalFunction "defend the surrounding area against Intruders" (7f2936ab-0b54-4e92-9f0c-85a9f0981959)
  9. Part "Prof. A. P. W. B. Dumbledore" (4c1f2b5d-0641-42c7-911f-7a42928580b8)
  10. LogicalFunction "manage the school" (f708bc29-d69f-42a0-90cc-11fc01054cd0)
  11. LogicalFunction "advise Harry" (beaf5ba4-8fa9-4342-911f-0266bb29be45)
  12. Part "Prof. S. Snape" (ccbad61a-39dc-4af8-8199-3fee30de2f1d)
  13. LogicalFunction "Teaching" (a7acb298-d14b-4707-a419-fea272434541)
  14. LogicalFunction "maintain a layer of defense for the Sorcerer's Stone" (4a2a7f3c-d223-4d44-94a7-50dd2906a70c)
  15. ComponentExchange "Headmaster Responsibilities" (c0bc49e1-8043-4418-8c0a-de6c6b749eab)
  16. ComponentExchange "Teacher Responsibilities" (9cbdd233-aff5-47dd-9bef-9be1277c77c3)
  17. Part "Harry J. Potter" (26543596-7646-4d81-8f15-c4e01ec930a7)
  18. LogicalFunction "kill He Who Must Not Be Named" (aa9931e3-116c-461e-8215-6b9fdbdd4a1b)
  19. Part "R. Weasley" (4d31caaf-210e-4bdf-982e-cdecbc80c947)
  20. LogicalFunction "assist Harry" (c1a42acc-1f53-42bb-8404-77a5c08c414b)
  21. LogicalFunction "break school rules" (edbd1ad4-31c0-4d53-b856-3ffa60e0e99b)
  22. ComponentExchange "Punishment" (85a1fb20-38ea-4d77-acd7-90a8c44dc695)
  23. FunctionalExchange "wizardry" (6545a77d-d224-4662-a5b2-3c016b78e33d)
  24. PortAllocation "" (a4e2bf11-0705-4f20-bf73-5fa5519954f7)
  25. PortAllocation "" (7d31ab50-63d6-46bb-bf53-1716175beae3)
  26. PortAllocation "" (317715cb-376c-4df6-a32c-433e3c081f8d)
  27. ComponentExchange "Learning" (3b3fc202-be5c-49ae-bf2f-1d61daf3bb50)
  28. PortAllocation "" (c1019d06-f376-48e3-832e-634a8ec59463)
  29. PortAllocation "" (4cbdf5fd-7268-470b-9811-b62ad67fded1)
  30. FunctionalExchange "assistance" (241f3901-11f0-4b00-a903-ed158cce73de)
  31. FunctionalExchange "friendship" (1bbb9b2d-517c-4f77-a35c-b3aa3f9422b8)
  32. PortAllocation "" (18fa81ee-8b16-4815-86ea-0c287ace43d8)
  33. ComponentExchange "Help for Harry" (d8655737-39ab-4482-a934-ee847c7ff6bd)
  34. FunctionalExchange "punish" (96a0cf4c-adfe-4490-92d1-bcf75ee77004)
  35. FunctionalExchange "educate & mature" (09efaeb7-2d50-40ed-a4da-46afcb9ca7a1)
  36. FunctionalExchange "Knowledge" (b1a817bc-40a9-4fc4-b62c-8dea4aa28915)
  37. PortAllocation "" (dda7a62a-f25f-46d8-8f05-867c616914c1)
  38. PortAllocation "" (fee1fff5-d751-401b-bb3c-2114a74f0c8a)
  39. PortAllocation "" (0f6e1aa0-942a-40a9-930f-c7df34b9d8eb)
  40. ComponentExchange "Care" (c31491db-817d-44b3-a27c-67e9cc1e06a2)
  41. PortAllocation "" (98760017-b3a3-46ca-b1ef-87eee9ea1600)
  42. PortAllocation "" (74bd0ab3-6a28-4025-822e-90201445a56e)
  43. PortAllocation "" (3ed5ae4f-8a4e-4690-9088-655990a1b77b)
  44. PortAllocation "" (299b98b8-8716-4dbc-bc7e-4b9349778c26)
  45. PortAllocation "" (14cabdd9-c36f-4e01-ad09-110f906ad725)
  46. PortAllocation "" (6d882e28-4208-41d0-b8a5-3a19e1805a34)
  47. FunctionalExchange "educate" (cdc69c5e-ddd8-4e59-8b99-f510400650aa)
  48. PortAllocation "" (c90bb30d-e36b-46a3-a3a1-e39fdcb519be)

And again there are warnings - there are quite a few visual filters in Capella and we are not handling all of those yet but mostly those that are used in our projects. The filter coverage will eventally improve, stay tuned.

And finally, you can display the diagram right in the notebook.

[8]:
diagram
[8]:

We use SVG diagrams a lot since they look great in documentation, are zoomable and really light-weight. To make integrating them into a pipeline easier, we also support some derived formats, which you can access using .as_<format> style attributes. With some additional dependencies set up (see the README), capellambse can also automatically convert these images to PNG format.

[9]:
print(repr(  diagram.as_svg          )[:100], "...")  # The raw SVG format as simple python `str`
print(repr(  diagram.as_datauri_svg  )[:100], "...")  # An SVG, base64-encoded as `data:` URI
print(repr(  diagram.as_html_img     )[:100], "...")  # An HTML `<img>` tag, using the above `data:` URI as `src`
print(repr(  diagram.as_png          )[:100], "...")  # A raw PNG byte stream, which can be written to a `.png` file
'<svg baseProfile="full" class="LogicalArchitectureBlank" height="611" style="shape-rendering: geome ...
'data:image/svg+xml;base64,PHN2ZyBiYXNlUHJvZmlsZT0iZnVsbCIgY2xhc3M9IkxvZ2ljYWxBcmNoaXRlY3R1cmVCbGFua ...
Markup('<img src="data:image/svg+xml;base64,PHN2ZyBiYXNlUHJvZmlsZT0iZnVsbCIgY2xhc3M9IkxvZ2ljYWxBcmNo ...
b'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x04\x8a\x00\x00\x02c\x08\x02\x00\x00\x00\xec\xe8m\xd2\ ...

It’s also possible to directly save a diagram to a file by calling its save method:

[10]:
diagram.save("[LAB] Wizzard Education.svg", "svg", pretty_print=True)
[11]:
with open("[LAB] Wizzard Education.svg", "r") as f:
    print(*f.readlines()[:10], "...", sep="")
<?xml version="1.0" encoding="utf-8" ?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:ev="http://www.w3.org/2001/xml-events" xmlns:xlink="http://www.w3.org/1999/xlink" baseProfile="full" class="LogicalArchitectureBlank" height="611" style="shape-rendering: geometricPrecision; font-family: 'Segoe UI'; font-size: 8pt; cursor: pointer;" version="1.1" viewBox="15 15 1162 611" width="1162">
  <defs>
    <symbol id="LogicalComponentSymbol" style="stroke: #000; stroke-width: 2;" viewBox="0 0 79 79">
      <path d="M18 237h46v43H18z" style="fill: #dbe6f4" transform="translate(0 -218)"/>
      <path d="M12 247h11v8H12z" style="fill: #dbe6f4" transform="translate(0 -218)"/>
      <path d="M12 261h11v8H12z" style="fill: #dbe6f4" transform="translate(0 -218)"/>
      <g transform="scale(0.90705135,1.1024734)">
        <path d="m 37.427456,20.821353 h 4.221475 V 50.90971 H 37.427456 Z M 39.538194,46.89517 H 56.75519 v 4.01454 H 39.538194 Z" style="fill: #000;stroke-width: 0.1;"/>
      </g>
...

Lets now try something else - we check if function port has any protocols (state machines) underneath:

[12]:
fnc = model.la.all_functions.by_name("defend the surrounding area against Intruders")
stms = fnc.outputs[0].state_machines
stms
[12]:
  1. StateMachine "FaultStates" (06cefb2b-534e-4453-9aba-fe53329197ad)

and we can also check what states it could have:

[13]:
stms[0].regions[0].states
[13]:
  1. State "normal defence" (e494e247-efce-4258-9cc6-fd799dbb0adf)
  2. State "erroneous defence" (81f3de46-4596-41b0-8569-c3c21161a2f6)
  3. State "no defence" (5b6a03d8-0ef9-4b2b-9a50-a745f490d663)

This concludes our introduction. There is a lot more you can do with the library - feel free to explore the examples collection or create an issue to ask for a specific use-case example and you may see it around pretty soon.