Sparx Systems Forum

Enterprise Architect => Automation Interface, Add-Ins and Tools => Topic started by: DionEngels on January 26, 2021, 06:29:43 pm

Title: Creating Part Properties from Python via COM
Post by: DionEngels on January 26, 2021, 06:29:43 pm
Hi all,
Recently I started a project that involves placing SysML blocks and parts in EA via a COM connection.

I’ve previously made a little plugin for EA using C# and the API, but for this project, I use Python and simply connect via COM to EA. This works exactly the same.
However, I’ve gotten stuck on an issue. In this case, I want to create three Blocks, let’s name them B1, B2, and B3. My objective is to add a Composition relation between B1 and B2, and B1 and B3 (with B1 parent in both cases). To complete this composition, I would also like two part properties to be created that are child elements of B1, one with the type B2, the other with the type B3. This is similar to what would happen if you use the “Synchronize Structural Elements” button that is available for SysML Internal Block Diagrams (which are also called CompositeStructure in EA).

Creating the three Block elements was not that difficult, as I had done this before. I was also able to connect B1 with B2 and B1 with B3 using a connector of composite type, see the Python code below:
Code: [Select]
connector = part.Connectors.AddNew("", "Composition")
connector.SupplierID = type.ElementID
connector.SupplierEnd.Aggregation = 2
connector.Update()
It took some time to figure out you needed this Aggregation 2. Using this, the Relationship also became visible in EA as a composite relationship.

However, EA did not automatically show the part properties of B1 that you would get if you made this connection via the EA client. These part properties would only show up when you used the “Synchronize Structural Elements” button after creating an IBD. Thus, I set on to creating these Part Properties manually, using the following code:
Code: [Select]
part_in_type = type.Elements.AddNew("", 'Part')
part_in_type.PropertyType = part.ElementID
part_in_type.Update()
type.Elements.Refresh()
Here, I create an Element of type “Part”, which I connect to the part using its ElementID. These showed up nicely, however, this is where the problem showed up.

At this point, already with two part properties for B1, when you click “Synchronize Structural Elements”, EA created two additional part properties, which look identical. The only difference is that the part properties I created (for some reason) are shown as “Properties” in a Block Definition Diagram, while the ones EA creates are properly shown as “Parts”.  I tried moving them around by, for example, enabling isReference (which makes it a reference instead of a part), and this indeed moved the EA created "Parts" to "References". It also moved my created parts from "Properties" to "References", but I couldn't get them to move to "Parts".

I’ve checked the parts that I’ve created and EA creates out using my C# plugin, and they are completely identical as far as I can see. Does anyone know what I am doing wrong or how I can emulate the “Synchronize Structural Elements” button for Internal Block Diagrams? Thanks very much in advance!
Title: Re: Creating Part Properties from Python via COM
Post by: qwerty on January 26, 2021, 07:59:18 pm
I remember something along that lines. We had a similar issues (and some explanation which slipped my mind). Which EA version are you using?

q.
Title: Re: Creating Part Properties from Python via COM
Post by: DionEngels on January 26, 2021, 09:30:38 pm
Quote
I remember something along that lines. We had a similar issues (and some explanation which slipped my mind). Which EA version are you using?

q.

I am using version 14.1.1431
Title: Re: Creating Part Properties from Python via COM
Post by: Geert Bellekens on January 26, 2021, 09:52:51 pm
If the elements you create behave different from the elements created by EA, then there must be an actual difference you should be able to find.

What I usually do is export the contents of all the relevant tables (t_object, t_xref to start with) and compare them field per field.

In most cases you will find the difference that way. In some cases the difference is harder to spot (tagged values that belong to a certain MDG have a guid that starts with the same characters)

Geert

PS. Are you sure you need to create a "Composition" I tend to only use "Association" and set the aggregationkind if needed. Otherwise you get Aggregation in the connector type. Again, to know for sure, compare your connector with the one created manually.
Title: Re: Creating Part Properties from Python via COM
Post by: qwerty on January 26, 2021, 10:32:00 pm
IIRC we had that similar issue coming from a misunderstanding from what parts are. They are actually doppelganger of some element. And we had this too that there was a double of that doppelganger. But I really can't recall the circumstances. This did initially happen with creating things manually. So likely you have a similar issue. I tried your code with 13.5 and it worked as it should. Will give it a try with V14 later.

q.
Title: Re: Creating Part Properties from Python via COM
Post by: DionEngels on January 27, 2021, 12:13:48 am
Thank you for both your help.
I haven't figured out what is happening yet, but to give you both a bit of an update, I've exported the package in which I place the elements as XML using Publish -> Publish As.
In there, I started looking for my element to see if I could see a difference between the connectors I made / EA made or the parts I made / EA made.
Quote
What I usually do is export the contents of all the relevant tables (t_object, t_xref to start with) and compare them field per field.
I want sure how to do this what Geert mentioned, but figured that this was giving the same information. If Geert would like to share how to export those tables, that would be very nice. I am by no means an EA expert.

My connections seem exactly the same (they weren't but now are). The only thing I was missing was IsNavigable, which I now added.
My part properties seem to be mostly similar as well, except for one link. While my self created parts show
Code: [Select]
<xrefs/>, the EA created parts show:
Code: [Select]
<xrefs value="$XREFPROP=$XID={E131852B-676A-40fb-AF74-0D9901942C0D}$XID;$NAM=CustomProperties$NAM;$TYP=element property$TYP;$VIS=Public$VIS;$PAR=0$PAR;$DES=@PROP=@NAME=_connectorRef@ENDNAME;@TYPE=string@ENDTYPE;@VALU=&lt;SOURCE&gt;@ENDVALU;@PRMT=@ENDPRMT;@ENDPROP;@PROP=@NAME=isReference@ENDNAME;@TYPE=boolean@ENDTYPE;@VALU=0@ENDVALU;@PRMT=@ENDPRMT;@ENDPROP;$DES;$CLT={D7C29EB2-DDD4-416b-A0AC-A50BF709E465}$CLT;$SUP={91F2A682-91B9-4b27-BC8B-CAD334CE94A9}$SUP;$ENDXREF;"/>
I noticed that this XML entry has the name "xrefs", which is also one of the tables that Geert is referring to. This extra information seems to be what distinguishes the two.

I am still trying to figure out how to replicate this, but if you have any suggestions, please let me know.
Title: Re: Creating Part Properties from Python via COM
Post by: Geert Bellekens on January 27, 2021, 12:35:37 am
I want sure how to do this what Geert mentioned, but figured that this was giving the same information. If Geert would like to share how to export those tables, that would be very nice. I am by no means an EA expert.
Hi Dion,

You are doing the right thing, but looking at the xmi is looking at derived/transformed information, which can make things harder than it needs to be.

EA stores it's models in a database. You have the options of a standalone database (.eapx, .feap) or use a proper database (SQL Server, MySQL, ...)
Using an SQL Client you can query the tables in that database and look directly at the contents.
(EA also has an SQL client you can use to query it's own table. See Database Builder. Don't trust the results you get form the SQL scratch pad though)

I'm using mostly SQL Server databases, so the SQL client I use there is SSMS. For .eap files I use an SQL client called AnySQL Maestro

The refdata snippet you shared probably corresponds to EA.Element.Customproperties

Geert
Title: Re: Creating Part Properties from Python via COM
Post by: qwerty on January 27, 2021, 02:37:17 am
Having something to fondle with would be easier. However, it looks like you are assuming that a composition will create a part. It doesn't. They are completely independent.

q.
Title: Re: Creating Part Properties from Python via COM
Post by: DionEngels on January 28, 2021, 12:35:06 am
Okay, I've been working on it some more, and I've still not figured out what is going on.
Quote
The refdata snippet you shared probably corresponds to EA.Element.Customproperties
This was correct. However, I was not able to set these CustomProperties when adding my parts to EA via Python, even though they are the only difference at this point. Have you got any experience with setting these properties Geert?

Furthermore, I installed AnySQL Maestro to look at the database, however, I was not able to connect to the EA database. Probably because I have no clue what I am doing with that program, and I was not able to find a simple tutorial. Do you have a link to some documentation on how to query EA via AnySQL Maestro.
In the same spirit, I also checked out the Database Builder but there I could not figure out how to connect to a Data Model. It only seemed to give me the option to create one, while I had looked in my EA eapx that I am trying out my Python connection in.

Quote
Having something to fondle with would be easier. However, it looks like you are assuming that a composition will create a part. It doesn't. They are completely independent.

q.
I am not really sure what you mean here qwerty? I am currently creating the parts myself and trying to link them to a connection I made. Furthermore, EA seems to be able to create the correct parts when you select "Synchronize Structural Elements" on an Internal Block Diagram if you only add the Connections yourself. Could you explain some more what you thing is happening?
Title: Re: Creating Part Properties from Python via COM
Post by: Geert Bellekens on January 28, 2021, 12:39:42 am
Connect AnySQL Maestro

- Add new connection
- Choose Provider: Microsoft Jet 4.0 OLE db provider
- Select you .eapx file as the database file name (enable All Files (*.*) before you can select the .eapx file)
- That's all

Geert
Title: Re: Creating Part Properties from Python via COM
Post by: qwerty on January 28, 2021, 01:41:06 am
Python has almost any DB connector and I once used that for M$Access. But then there's the trouble with Jet 3 or 4 and what do I know. So I ended up just using EA's repository.SQLQuery and parse the XML result (import xml.etree.ElementTree as ET). Works fine for almost all cases (except for t_genopt which sometimes causes hickups).

q.
Title: Re: Creating Part Properties from Python via COM
Post by: DionEngels on January 28, 2021, 02:00:03 am
Connect AnySQL Maestro

- Add new connection
- Choose Provider: Microsoft Jet 4.0 OLE db provider
- Select you .eapx file as the database file name (enable All Files (*.*) before you can select the .eapx file)
- That's all

Geert
Thanks Geert, this works perfectly. With this, I've been able to find one difference between the Python-made part properties and the EA-made part properties.
The difference is located within t_xref. There is a connection between the EA-made part properties and the connector between two blocks I made and connected (which should result in this part property). The Client is the part property, while the supplier is the connection.
See the below for the exact info in the t_xref table:
Code: [Select]
XrefID: {18D07A91-42BB-4bf8-A3F1-210E91796B6B}
Name: CustomProperties               
Type: element property               
Visibility: Public               
Namespace:                 
Requirement:               
Constraint:                
Behaviour:               
Partition: 0               
Description: @PROP=@NAME=_connectorRef@ENDNAME;@TYPE=string@ENDTYPE;@VALU=<SOURCE>@ENDVALU;@PRMT=@ENDPRMT;@ENDPROP;@PROP=@NAME=isReference@ENDNAME;@TYPE=boolean@ENDTYPE;@VALU=0@ENDVALU;@PRMT=@ENDPRMT;@ENDPROP;                   
Client: {FB323599-99DA-4e41-AFF7-6DB373B9187E}               
Supplier: {544A9846-A5B7-46db-99F2-322CC1FB8398}                 
Link
I was not really sure how to recreate this, since this seems to be CustomProperty, and not a connector. Also because this connection is not visible when you look at the Relationship tab in EA. Since you both have more experience with this than I do, do you know how you can manually create such an entry in the t_xref table? Especially since Geert immediately pointed out that I should have this table, I am curious to know what this means.
Title: Re: Creating Part Properties from Python via COM
Post by: qwerty on January 28, 2021, 03:40:39 am
There is an EA property called CustomProperty. Have you looked into that? It's possible to create entries in t_xref. But you're juggling with burning sticks then.

q.