Advent of SysML v2 | Lesson 13 – Ports, Interfaces, Items and Flows

Hello and welcome back to the Advent of SysML v2 – a daily, hands-on mini-course designed to bring you up to speed with the new SysML v2 standard and the modern Syside tooling that makes you productive from day one.

By the end of this lesson, you will:

  • Learn about ports and interfaces
  • Learn about items and flows
  • Learn about a recursive pattern to refine connections

If you want to dive deeper into the world of SysML v2, check out The SysML v2 Book, where this topic is also discussed in more detail.

Ports and Interfaces

After the previous lesson, Santa is glad that we can already connect things, but even with his limited systems engineering skills, he knows that real components are usually connected via ports.

Ports are dedicated interaction points of a component that can be used in a standard way without needing to know the component behind it. For example, USB ports can be connected regardless of the device they are on, serving as a great level of abstraction to save us from the countless kinds of cables.

In SysML v2, ports are simple structural features with their own keyword used to expose features of their owners. They also have definitions and usages, and can have features to model what can be accessed through them. Most of the time, the features are directed, which means they have either of the “in”, “out”, or “inout” modifiers to denote the direction in which things will flow through the port. We will discuss this in a minute. Furthermore, all these features must be referential, as the port only exposes things – it does not contain anything itself.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
package L13_Ports_and_Interfaces {
// Components definitions
part def Sleigh {
abstract ref part reindeer : Reindeer [9];
port eyelet : HarnessConnectionPoint;
}

part def Reindeer {
ref part pulling : Sleigh;
port harnessLoop : ~HarnessConnectionPoint;
}

// Port definitions
port def HarnessConnectionPoint {
// …
}

// Interface definitions connecting ports, composing flows
interface def HarnessInterface {
end port sleighPort : HarnessConnectionPoint;
end port reindeerPort : ~HarnessConnectionPoint;
}

// …

// Connection definitions connecting components, composing interface
connection def Harness {
end part sleigh : Sleigh crosses reindeer.pulling;
end part reindeer : Reindeer crosses sleigh.reindeer;

interface : HarnessInterface connect sleigh.eyelet to reindeer.harnessLoop;
}
}

Let us extend our example with ports. Line 14 demonstrates a port definition “HarnessConnectionPoint”, which we will leave empty for now. This definition can be used to define port usages in the “Reindeer” and “Sleigh” definitions (lines 5 and 10). Ports can only be connected in a useful way if they are compatible, which is most easily achieved by using the same definition but “turning it inside out” on one side – more precisely, by conjugating it. In the conjugated port definition, “in” features become “out” features, and vice versa; “inout” features remain unchanged. Line 10 illustrates conjugation: the definition after the colon starts with the “~” character, which means we are using the conjugated version of the port definition.

It is very important to note that in SysML, ports themselves are never directed. Although it is legal to declare a directed port, it will mean that the component with this feature can emit or consume ports, and this is definitely not your intent.

Once we have ports, we can connect them with interfaces. Interfaces are special connections that can be used with ports only. While it is possible to use interfaces without connection definitions, we demonstrate a useful pattern to refine the previous connection and specify exactly how the sleigh and the reindeer are connected.

Line 19 illustrates an interface definition. It can be declared the same way as a connection definition, but its ends are always ports. We also use conjugation here when typing the ends.

With this definition, we will create an interface usage inside the connection definition. Line 31 shows how to do this: just like connection usages, but with the “interface” keyword instead of the “connection” keyword. The connected ports are accessed via “reindeer” and “sleigh”, which are the ends of the connection. This way, whenever a sleigh and a reindeer are connected with a harness, their ports will be automatically connected with an interface as well.

Items and Flows

Let us focus on the ports now. What is still missing is to specify what kind of things should be exchanged via the ports. This is where items come to play.

An item is very similar to a part, but it represents an entity that is exchanged or passed around in the system, rather than a component. That said, every part is also an item in its own right. Items also have definitions, but you will often find that it is worth declaring a part definition instead. An item definition cannot define a part usage, but a part definition can define an item usage.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package L13_Items_and_Flows {
// …
// Port definitions
port def HarnessConnectionPoint {
out item command : Command;
in item feedback : Feedback;
}

// Item definitions
item def Command;
item def Feedback;

// Interface definitions connecting ports, composing flows
interface def HarnessInterface {
end port eyelet : HarnessConnectionPoint;
end port harnessLoop : ~HarnessConnectionPoint;

flow of Command from eyelet.command to harnessLoop.command;
flow of Feedback from harnessLoop.feedback to eyelet.feedback;
}
}

Lines 11 and 12 above show two item definitions. They are empty now, but items usually have attributes that characterize the kind of information they carry or their properties.

We use these item definitions to define the item usages in our port definition in lines 6 and 7. As we said before, these will be directed features: the “command” item is an output, while the “feedback” item is an input. This is in accordance with how we used the port definition for the ports: reindeer has the conjugated, “inside-out” version.

Now that we have the directed item usages in the ports, we can zoom into our connection even further and specify what will flow through the interfaces between the ports.

A flow is not a connection, but it behaves like one. It is actually an action that represents the act of transferring an output to an input on the other side. Flow definitions exist, but it is usually enough to use flow usages.

Line 19 inside the interface definition specifies that when two ports are connected with this interface, there should be a flow of commands from the eyelet’s “command” output feature to the harness loop’s “command” input feature. A similar flow of “Feedback” is also declared in line 20.

Again, flows can be created without interfaces, but we wanted to demonstrate this pattern to gradually refine a connection into a complete description of what flows where.

Putting It All Together

You will see the complete model below. Actually, it is not different from the snippet you have already seen, but looking at it in this way emphasizes the refinement pattern.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
package L13_Connections_Interfaces_Flows {
// Components definitions
part def Sleigh {
abstract ref part reindeer : Reindeer [9];
port eyelet : HarnessConnectionPoint;
}

part def Reindeer {
ref part pulling : Sleigh;
port harnessLoop : ~HarnessConnectionPoint;
}

// Port definitions
port def HarnessConnectionPoint {
out item command : Command;
in item feedback : Feedback;
}

// Item definitions
item def Command;
item def Feedback;

// Connection definitions connecting components, composing interface
connection def Harness {
end part sleigh : Sleigh crosses reindeer.pulling;
end part reindeer : Reindeer crosses sleigh.reindeer;

interface : HarnessInterface connect sleigh.eyelet to reindeer.harnessLoop;
}

// Interface definitions connecting ports, composing flows
interface def HarnessInterface {
end port eyelet : HarnessConnectionPoint;
end port harnessLoop : ~HarnessConnectionPoint;

flow of Command from eyelet.command to harnessLoop.command;
flow of Feedback from harnessLoop.feedback to eyelet.feedback;
}

// Connecting in a context
part def ReindeerDrawnSleighAssembly{
part sleigh : Sleigh;
abstract part reindeer : Reindeer [9];
part rudolph [1] : Reindeer subsets reindeer;

// Internal structure, including the interface and the flows in that
// are automatically set up when the connection is established.
connection harnesses : Harness connect [1] sleigh to [9] reindeer;
connection subsets harnesses {
end [1] part :>> sleigh references ReindeerDrawnSleighAssembly::sleigh;
end [1] part :>> reindeer references rudolph;
}
}
}

On the entity side, we first model the parts, then zoom in on the ports, and then further refine our view to the items that can be exchanged through the ports. In parallel, on the connection side, we first model the connection definition, then zoom in on the actual interfaces between the connected parts, the flows between the directed features of the ports connected by the interfaces.

As a result, we have a recursive blueprint for harnesses, which can be easily instantiated by simply declaring a connection between a sleigh and a reindeer. Every instance of the connection in lines 48 and 49 will automatically contain the interfaces with the flows.

Now Santa is happy.

Challenge for Tomorrow

You are now a master of connecting things in SysML. Let’s practice this by continuing the challenge from yesterday. Head over to Syside Cloud and do the following tasks:

  1. Define the items to be exchanged between Santa and the sleigh. For example, Santa may issue commands like “take off” or “land” (why don’t you model this with an enum and add it as an attribute of the item def?), and the sleigh can provide the current position (again, this could be a pair of attributes, just saying).
  2. Define a port definition for the interactions between Santa and the sleigh. Add the items that should flow between the ports.
  3. Specify an interface for the port type and model the flows within it.
  4. Use the interface in the connection definition that you created yesterday (or you can use our sample solution as a starting point).

Summary

In this episode, you learned about different ways to connect more specific modeling elements, including interfaces and flows. You also learned about the accompanying types, such as ports and items. You can now combine all this into cool patterns to model connections at different levels! If you haven’t yet done so, it is now time to go to Syside Cloud to do the challenge – and don’t forget to come back tomorrow for another episode of the Advent of SysML v2!

Cookies