Aspects

General

Notes

  • As mentioned in the Introduction, Aspect models are described in RDF Turtle [turtle]. The aspect specification will therefore assume basic familiarity with Turtle.

  • For the definition of the different Model elements please refer to the Meta Model Elements.

Naming rules

The naming of Model Elements follows the naming Java naming conventions for classes, properties and methods.

  • The names of Aspects, Entities, Constraints and Characteristics follow the naming conventions for Java classes, i.e. UpperCamelCase.

  • The names of Properties, Operations and Units follow the naming conventions of Java methods, i.e. lowerCamelCase.

RDF/Turtle formatting rules

  • Each Aspect Model is defined in a separate TTL (Turtle) file.

  • The Turtle file containing an Aspect Model must have the same name as the Aspect.

  • Aspect Model files must be UTF-8 encoded and should not contain a byte order mark.

  • There should be one empty line between model element definitions.

  • Indentation should be done with three spaces.

  • There should be a space before every separating semicolon.

  • There should be padding spaces inside RDF lists and anonymous nodes (i.e. inside brackets and square brackets)

Attributes that all model elements have

Every model element (Aspects, Properties, Characteristics, Entities, Operations) has the following attributes:

Attributes Description Required

bamm:preferredName

Human readable name in a specific language. This attribute may be defined multiple times for different languages but only once for a specific language. There should be at least one preferredName defined with an "en" language tag.

bamm:description

Human readable description in a specific language. This attribute may be defined multiple times for different languages but only once for a specific language. There should be at least one description defined with an "en" language tag.

bamm:see

A reference to a related element in an external taxonomy, ontology or other standards document. The datatype is xsd:anyURI. This attribute may be defined multiple times.

Although both bamm:preferredName and bamm:description should be set at least once in every model element, in the following examples we will mostly leave them out to improve readability.

Declaring model elements

Using Namespaces

An Aspect model file should start with the BAMM prefix definitions. The empty namespace ":" should be used as local namespace, i.e. the versioned namespace in which the Aspect and its elements are defined. Other customer or domain specific namespaces can be defined additionally. However, the bamm-* namespaces are reserved for the meta model. Third party locations can be referred via other namespaces (e.g., "xsd:"). See Namespaces and Versions for more details on the topic.

@prefix : <urn:bamm:com.mycompany.myapplication:1.0.0#> .
@prefix bamm: <urn:bamm:io.openmanufacturing:meta-model:2.0.0#> .
@prefix bamm-c: <urn:bamm:io.openmanufacturing:characteristic:2.0.0#> .
@prefix bamm-e: <urn:bamm:io.openmanufacturing:entity:2.0.0#> .
@prefix unit: <urn:bamm:io.openmanufacturing:unit:2.0.0#> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .

Declaring Aspects

An Aspect is defined by marking its identifier with a bamm:Aspect and additional attributes. Note that the a is just a syntactic shortcut for rdf:type. In addition to the general attributes, every Aspect Model element has the following attributes:

Attributes Description Required

bamm:properties

The list of Properties of this Aspect. Leaving out this attribute completely is equivalent to having it present with an empty list as value.

bamm:operations

The list of Operations of this Aspect. Leaving out this attribute completely is equivalent to having it present with an empty list as value.

bamm:events

The list of Events of this Aspect.

  • Aspects follow the naming conventions for Java classes, i.e. UpperCamelCase.

  • Each Aspect model must be defined in its own file. The file name must be the same as the Aspect’s name.

  • The hierarchical namespace part in the Aspect’s URN can be freely chosen.

The definition of an Aspect should therefore have the following structure in TTL syntax; note though that unused namespaces can be left out:

@prefix : <urn:bamm:com.mycompany.myapplication:1.0.0#> .
@prefix bamm: <urn:bamm:io.openmanufacturing:meta-model:2.0.0#> .
@prefix bamm-c: <urn:bamm:io.openmanufacturing:characteristic:2.0.0#> .
@prefix bamm-e: <urn:bamm:io.openmanufacturing:entity:2.0.0#> .
@prefix unit: <urn:bamm:io.openmanufacturing:unit:2.0.0#> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .

:MyAspect a bamm:Aspect ;
   bamm:preferredName "My Aspect"@en ;
   bamm:preferredName "Mein Aspekt"@de ;
   bamm:description "This Aspect is an example."@en ;
   bamm:description "Dieser Aspekt ist ein Beispiel."@de ;
   bamm:properties ( :myProperty :anotherProperty ) ;
   # In this example, there are no operations.
   bamm:operations ( ) .

Declaring Properties

In addition to the attributes that all model elements have, Properties have the following attributes:

Attributes Description Required

bamm:characteristic

The Characteristic describing this Property.

bamm:exampleValue

An exemplary value the Property can take on that helps to understand the intended meaning of the property better. This can only be set for Properties with scalar data types (e.g., xsd:string or xsd:float, but not Entities). The data type of the bamm:exampleValue must be convertible to the effective data type of the Property’s Characteristic. For example, if the Characteristic’s bamm:dataType is xsd:int, xsd:short is also a valid type for the bamm:exampleValue. Refer to section Implicit Conversions for more details.

Example:

:materialNumber a bamm:Property ;
   bamm:preferredName "Material number"@en ;
   bamm:description "A material number"@en ;
   bamm:exampleValue "ABC123456-000" ;
   bamm:characteristic bamm-c:Text .

Declaring Characteristics

The attributes for Characteristics are described in detail in section Characteristics.

The dataType attribute may be omitted when creating a subclass of a Characteristic. The dataType attribute must be set when creating an instance of a Characteristic, except when the dataType attribute has been set in the class or one of the super-classes. When the dataType has been set in a superclass, the dataType may be set to a subclass of the dataType from one of the Characteristic superclasses. This allows the definition of generic Characteristics such as Collections, where all the semantics are fixed, except for the data type. For a Collection for example it is possible to define whether the collection is sorted or not and this definition can be then reused with different data types to define different collections.

Example:

:MachineState a bamm-c:State ;
   bamm:dataType xsd:string ;
   bamm-c:defaultValue "STANDBY" ;
   bamm-c:values ( "RUNNING" "STANDBY" "OFF" ) .

Declaring Quantifiables and Measurements

Whenever a Property represents a numeric, scalar value that the result of a measurent of some kind (e.g., using a sensor) and has a well-defined physical unit which is known at modeling time, use the Measurement Characteristic. If the value is numeric and has a physical unit but is not the result of a measurement (e.g., when it is calculated from other values), use the Quantifiable Characteristic.

See the following example that uses Measurement — usage of Quantifiable is analogous.

:ToolTemperature a bamm-c:Measurement ;
   bamm:dataType xsd:float ;
   bamm-c:unit unit:degreeCelsius .

:drillHeadTemperature a bamm:Property ;
   bamm:characteristic :ToolTemperature .

See section Units for information about the valid values for the bamm-c:unit attribute.

Declaring Single Entity

The following example shows how a Property is defined that uses the Single Entity Characteristic to specify an Entity as its dataType.

:AccelerationVector a bamm:Entity ;
   bamm:properties ( :x :y :z ) .

# Definition of Properties x, y and z for the Entity here
# ...

:acceleration a bamm:Property ;
   bamm:characteristic [
      a bamm-c:SingleEntity ;
      bamm:dataType :AccelerationVector
   ] .

Declaring Collections

There are four basic predefined types of Collections: Collection, List, Set and Sorted Set. The Collection definitions are shared and are available globally. They determine whether a specific collection is ordered or not and whether a specific collection may contain duplicates or not. In some cases the data type is also set in the shared Collection Characteristic.

These shared Collection Characteristics may not be changed in an Aspect Model, hence it is not allowed to create a subclass of the Collection Characteristic in an Aspect Model. To create a Collection Characteristic for a specific domain, the user should instantiate one of the Collection classes and define the data type or the element Characteristic for the Collection. In this example, the Characteristic resulting from the combination of Code, Length Constraint and Encoding Constraint is not defined inline in the Property, but defined standalone.

Example with a scalar data type:

:NumberList a bamm-c:List ;
   bamm:dataType xsd:float .

Example with a custom Entity as data type:

:MyEntity a bamm:Entity ;
   bamm:properties ( ) ;
   # ...
   .

:MyEntityList a bamm-c:List ;
   bamm:dataType :MyEntity .
The data type for the elements of a Collection can either be defined in the usual manner using the bamm:dataType attribute (see the examples above) or by defining a Characteristic for the Collection elements using the bamm-c:elementCharacteristic attribute, see the example below. It is recommended to explicitly create a Characteristic for the Collection elements instead of only defining the data type, since it allows to completely express the semantics of the elements.

Example with the bamm-c:elementCharacteristic attribute:

:numbers a bamm:Property ;
   bamm:characteristic :NumberList .

:NumberList a bamm-c:List ;
   bamm-c:elementCharacteristic [
      a bamm-c:Trait ;
      bamm-c:baseCharacteristic :Number ;
      bamm-c:constraint [
         a bamm-c:RangeConstraint ;
         bamm:description "Limits the range of the individual numbers in the list from 5 to 10."@en ;
         bamm-c:minValue "5"^^xsd:nonNegativeInteger ;
         bamm-c:maxValue "10"^^xsd:nonNegativeInteger ;
      ] ;
   ] .

:Number a bamm:Characteristic ;
   bamm:dataType xsd:nonNegativeInteger .

Declaring Enumerations

Describes a Property which may have a value from a predefined list of values. Also see Enumeration.

Example with literal xsd:string values:

:Status a bamm-c:Enumeration ;
   bamm:dataType xsd:string ;
   bamm-c:values ( "Complete" "In Progress" "Created" ) .

Example with literal xsd:integer values. Note that for xsd:integer, Turtle’s numeric literal syntax can be used:

:PrimesBelowTwenty a bamm-c:Enumeration ;
   bamm:dataType xsd:integer ;
   bamm-c:values ( 2 3 5 7 11 13 17 19 ) .

Example with literal xsd:int values:

:ValidOffsets a bamm-c:Enumeration ;
   bamm:dataType xsd:int ;
   bamm-c:values ( "-1"^^xsd:int "1"^^xsd:int ) .

Example with literal xsd:date values:

:MaintenanceDates a bamm-c:Enumeration ;
   bamm:dataType xsd:date ;
   bamm-c:values ( "2010-01-01"^^xsd:date "2012-05-07"^^xsd:date "2018-03-08"^^xsd:date ) .

Example with complex values:

Declaring an Enumeration with a complex value is usally done in order to add a description to the actual value, e.g., the state in the example below, which provides information regarding the meaning of the value. This description only exists in the aspect model and is not part of the payload provided by an Aspect at runtime. In order to define that a Property of an Entity is not part of the runtime data, the bamm:notInPayload attribute is used.

bamm:notInPayload cannot be used in Abstract Entities, but the setting for a specific property is inherited when Entities are extended.
:Results a bamm-c:Enumeration ;
   bamm:dataType :Result ;
   bamm-c:values ( :Success :Failed ) .

:Result a bamm:Entity ;
   bamm:properties ( :status [ bamm:property :description; bamm:notInPayload "true"^^xsd:boolean ] ) .

:Success a :Result ;
   :status "SUCCESS" ;
   :description "The process completed successfully." .

:Failed a :Result ;
   :status "FAILURE" ;
   :description "The process did not complete successfully." .
If the Property is part of the runtime data (like status in the example), it is directly referenced. Writing bamm:notInPayload false is not allowed.

Declaring State

As described in State Characteristic, State inherits from Enumeration and extends it with the default value attribute.

Example:

:MachineState a bamm-c:State ;
   bamm:dataType xsd:string ;
   bamm-c:defaultValue "STANDBY" ;
   bamm-c:values ( "RUNNING" "STANDBY" "OFF" ) .

Declaring Time Series

The TimeSeries Characteristic is a special kind of Collection. A Time Series is defined as a list of tuples of values with their respective specific point in time when they where recorded. This is, the Time Series is represented by a list of key/value pairs where the key is the time-stamp denoting when the value was recorded and the value is the recorded value. In order to describe these semantics the shared TimeSeries Characteristic is used. This is a subclass of the SortedSet Characteristic and defines that the dataType must be a subclass of the TimeSeriesEntity.

The TimeSeriesEntity is declared as an Abstract Entity. It defines the timestamp Property with the Timestamp Characteristic, which describes values containing timestamps conforming to xsd:dateTime, a date and time with or without time zone. It also defines value as an Abstract Property, i.e., a Property without a Characteristic.

To create a Time Series for a specific domain, the user should instantiate the TimeSeries Collection Characteristic and set the dataType to an Entity which extends the Abstract TimeSeries Entity in order to define the semantics for the value Property in the context of the specific domain. Please see the Declaring Abstract Entities section for information on how to extend an Abstract Entity.

Example:

:MachineStateTimeSeries a bamm-c:TimeSeries ;
   bamm:dataType :MachineStateTimeSeriesEntity .

:MachineStateTimeSeriesEntity a bamm:Entity ;
   bamm:extends bamm-e:TimeSeriesEntity ;
   bamm:properties ( :machineState ) .

:machineState a bamm:Property ;
   bamm:characteristic :MachineState .

:MachineState a bamm-c:State ;
   bamm:dataType xsd:string ;
   bamm-c:defaultValue "STANDBY" ;
   bamm-c:values ( "RUNNING" "STANDBY" "OFF" ) .
An Aspect should only have one Collection at root level. When modeling an Aspect with two or more collections at root level which contain related data, consider creating the model so that the related data is explicitly linked and contained in a single Collection. When modeling an Aspect with two or more collections at root level which contain unrelated data, consider creating separate Aspects each containing a single Collection.

Declaring Either

Describes a Property whose value can have one of two possible types (a disjoint union). This Characteristic is special since it does not directly define a data type. The data type is defined in the two Characteristics which define the left and right value of the disjoint union. Also see Either.

Example:

:Result a bamm-c:Either ;
   bamm-c:left :ErrorCode ;
   bamm-c:right :SuccessCode .

:ErrorCode a bamm-c:SingleEntity ;
   bamm:dataType :ErrorEntity .

:SuccessCode a bamm-c:SingleEntity ;
   bamm:dataType :SuccessEntity .

:ErrorEntity a bamm:Entity ;
   bamm:properties ( :errorCode :errorDescription ) .

:SuccessEntity a bamm:Entity ;
   bamm:properties ( :status ) .

Declaring Structured Value

Structured Values are intended to be used for Properties when all of the following conditions are met:

  • The value has a scalar, string-like value space

  • The value has a well-known structure consisting of different, separate parts

  • The parts can and should be described in more detail

  • The Property should not be decomposed/deconstructed into an Entity with separate Properties for each part

One of the main use cases is complex identifiers that encode context information such as provenance information, version numbers, locations codes and so on. It is unreasonable to split such a value up into separate Properties, because it complicates working with corresponding data: For example, such values could appear in payloads, databases or documents and would have to be converted back and forth, often times manually. On the other hand, properly describing the value and the parts it comprises can be difficult, especially in a machine-readable way.

Therefore, the Structured Value Characteristic can be used to describe the deconstruction of a value into its parts and linking each part to a separate Property definition.

The following table gives some simple examples to demonstrate the basic applicability of the Characteristic, and after that a complete concrete example is given.

Name Example Value Deconstruction Rule Elements

ISO 8601 date

"2019-09-27"^^xsd:date

(\d{4})-(\d{2})-(\d{2})

( :year "-" :month "-" :day )

Email Address

"user4711@example.com"

([\w\.-]+)@([\w\.-]+\.\w{2,4})

( :username "@" :host )

Hex-encoded color

"0xAC03BE"

0x([0-9A-Fa-f]{2})([0-9A-Fa-f]{2})([0-9A-Fa-f]{2})

( "0x" :red :green :blue )

The following code shows the Aspect model for the first example from the table. Note that when writing the deconstructionRule, backslashes (\) need to be escaped in order to produce valid RDF/Turtle syntax, i.e. write \\ instead of \.

:StructuredValueTest a bamm:Aspect ;
   bamm:properties ( :date ) ;
   bamm:operations () .

:date a bamm:Property ;
   bamm:exampleValue "2019-09-27"^^xsd:date ;
   bamm:characteristic :StructuredDate .

:StructuredDate a bamm-c:StructuredValue ;
   bamm:dataType xsd:date ;
   bamm-c:deconstructionRule "(\\d{4})-(\\d{2})-(\\d{2})" ;
   bamm-c:elements ( :year "-" :month "-" :day ) .

:year a bamm:Property ;
   bamm:characteristic :Year .

:month a bamm:Property ;
   bamm:characteristic :Month .

:day a bamm:Property ;
   bamm:characteristic :Day .

:Year a bamm:Characteristic ;
   bamm:dataType xsd:int .

:Month a bamm:Characteristic ;
   bamm:dataType xsd:int .

:Day a bamm:Characteristic ;
   bamm:dataType xsd:int .
Technically, bamm-c:elements would not be required just to parse corresponding payload; the regular expression given in the bamm-c:deconstructionRule would be sufficient. However, the elements fields serves two purposes: Firstly, it concisely describes how the meaning of the deconstruction rule corresponds with the named fields; secondly, it is used for validation: When a bamm:exampleValue is given (like in the example), the Aspect Model validator can automatically check if it can be deconstructed using the deconstruction rule and reconstructed using the elements, i.e., that the deconstruction rule actually does what the model author intended.

Using Unit Reference

As explained in the section Declaring Quantifiables and Measurements, some values only make sense when they also have a unit assigned to them. This unit definition is in many cases fixed at design time, does not change thereafter and therefore at runtime (in the JSON payload for example), only the actual value is transported.
There may be scenarios, however, where this permanent fixation on a specific unit might not be sufficient because the unit can only be determined dynamically at runtime, or is a kind of configuration parameter which must be set when the system is being deployed/starting up. In cases like this, a UnitReference characteristic instance can be used to include a dynamic reference to the desired unit from the Unit catalog and this information is then always included in the payload. The runtime payload refers to the unit using its bamm:curie, i.e., the unit’s URN’s element name prefixed with unit:.

For example an Aspect with the following model:

:ValueWithDynamicUnit a bamm:Aspect ;
  bamm:properties ( :value :unit ) ;
  bamm:operations ( ) .

:value a bamm:Property ;
   bamm:exampleValue "2.25"^^xsd:float ;
   bamm:characteristic :FloatValue .

:FloatValue a bamm:Characteristic ;
   bamm:dataType xsd:float .

:unit a bamm:Property ;
   bamm:characteristic bamm-c:UnitReference .

can produce a JSON payload that could look something like this:

{
  "value" : 2.25,
  "unit" : "unit:hectopascal"
}

Declaring Constraints and Traits

Consider the numbers Property that uses an instance of the List Characteristic:

:numbers a bamm:Property ;
   bamm:characteristic :NumberList .

:NumberList a bamm-c:List ;
   bamm:dataType xsd:integer .

To add a Length Constraint to the list, replace the use of the Characteristic with a new Trait instance. Set the original Characteristic as the Trait’s bamm-c:baseCharacteristic and add the required Constraint as a bamm-c:constraint to the Trait:

:numbers a bamm:Property ;
   bamm:characteristic [
     a bamm-c:Trait ;
     bamm-c:baseCharacteristic :NumberList ;
     bamm-c:constraint [
       a bamm-c:LengthConstraint ;
       bamm:description "Limits the number list to 10 elements"@en ;
       bamm-c:maxValue "10"^^xsd:nonNegativeInteger ;
     ]
   ]  .

:NumberList a bamm-c:List ;
   bamm:dataType xsd:integer .

Another more complex example is given below: The Property someIdentifier is defined that uses a Code instance using a dataType of xsd:string, combined with two Constraints: An Encoding Constraint that restricts the value space to US-ASCII and a Length Constraint that limits the string to 80 characters.

:someIdentifier a bamm:Property ;
   bamm:preferredName "Some identifier"@en ;
   bamm:description "An ASCII-encoded identifier with a maximum length of 80 characters"@en ;
   bamm:characteristic :CodeWithLengthAndAscii .

:CodeWithLengthAndAscii a bamm-c:Trait ;
   bamm:description "A string code limited to 80 ASCII characters"@en ;
   bamm-c:baseCharacteristic [
      a bamm-c:Code ;
      bamm:description "Denotes some kind of code with a string datatype"@en ;
      bamm:dataType xsd:string ;
   ] ;
   bamm-c:constraint [
      a bamm-c:EncodingConstraint ;
      bamm:value bamm:US-ASCII ;
      bamm:description "Limits the character encoding to US-ASCII"@en ;
   ] ;
   bamm-c:constraint [
      a bamm-c:LengthConstraint ;
      bamm:description "Limits the length to 80 characters"@en ;
      bamm-c:maxValue "80"^^xsd:nonNegativeInteger ;
   ] .

An example showing the Regular Expression Constraint is given below:

:timeStampsInJanuary a bamm:Property ;
   bamm:preferredName "Timestamps in January"@en ;
   bamm:description "Contains only timestamps in January of any year"@en ;
   bamm:characteristic [
      a bamm-c:Trait ;
      bamm-c:baseCharacteristic bamm-c:Timestamp ;
      bamm-c:constraint [
         a bamm-c:RegularExpressionConstraint ;
         bamm:value "\\d{4}-01-\\d\\dT.*" ;
      ] ;
   ] .
When writing the bamm:value, backslashes (\) need to be escaped in order to produce valid RDF/Turtle syntax, i.e. write \\ instead of \.

Declaring Entities

Entities have the following attributes:

Attributes Description Required

bamm:properties

The list of Properties which make up the Entity. Leaving out this attribute completely is equivalent to having it present with an empty list as value.

bamm:extends

The Entity which is extended by this Entity

Example:

:Error a bamm:Entity ;
   bamm:properties ( :errorCode :severity ) .

Extending Entities

Declaring that an Entity extends another Entity is done using the bamm:extends attribute in the Entity declaration.

Example:

:Student a bamm:Entity ;
    bamm:extends :Person ;
    bamm:properties ( :studentNumber ) .

:Teacher a bamm:Entity ;
    bamm:extends :Person ;
    bamm:properties ( :employeeNumber ) .

:Person a bamm:Entity ;
    bamm:properties ( :name :surname ) .

The extending Entities :Student and :Teacher contain the Properties declared in the extended Entity :Person as well as the Properties in their own declarations.

The effective Property names, i.e. the payload name when bamm:payloadName is used, or the name of the Property, must be unique across the entire Entity inheritance chain. Otherwise the corresponding runtime payload is ambiguous.

When one of the attributes bamm:payloadName, bamm:optional or bamm:notInPayload is used on a specific property usage, its value is also inherited by the extending Entities. Using the example of bamm:payloadName, we could modify the above example to enforce the alternative naming for the surname property in the generated payloads and this change would apply to the Person Entity (directly) and both Student and Teacher Entities (via inheritance):

:Person a bamm:Entity ;
    bamm:properties ( :name [ bamm:property :surname ; bamm:payloadName "familyName" ] ) .

Declaring Abstract Entities

In contrast to Entities, Abstract Entities cannot directly be used as data types. The main use case for Abstract Entities is to share Properties across multiple Entities. This can be achieved through inheritance: Abstract Entities can extend other Entities and Abstract Entities and can themselves be extended in a manner not dissimilar to how abstract classes are used in many programming languages.

In the following example, both SteeringWheel and Seat extend the Abstract Entity VehicleComponent. Both inherit the typeNumber and the manufacturer Properties:

:VehicleComponent a bamm:AbstractEntity ;
    bamm:properties ( :typeNumber :manufacturer ) .

:Steeringwheel a bamm:Entity ;
   bamm:extends :VehicleComponent ;
   bamm:properties ( :isMultifunction  ) .

:Seat a bamm:Entity ;
   bamm:extends :VehicleComponent ;
   bamm:properties ( :material ) .

Abstract Entities with Abstract Properties

When an Abstract Entity needs to be defined with a certain Property, but the modeler using the Abstract Entity (i.e., extending it) should be able to decide the Property’s Characteristic, the Property can be declared a bamm:AbstractProperty. An Abstract Property is similar to a Property, with two differences: Firstly, it has no bamm:Characteristic attribute and secondly, it must only be used in Abstract Entities. Consider the following example of two-dimensional vector which is declared as an Abstract Entity using two Abstract Properties for its x and y values, leaving for the user to decide which Characteristic and hence which data type should be used:

:Vec2 a bamm:AbstractEntity ;
   bamm:description "A two-dimensional vector"@en ;
   bamm:properties ( :x :y ) .

:x a bamm:AbstractProperty ;
   bamm:description "The x part of the vector"@en .

:y a bamm:AbstractProperty ;
   bamm:description "The y part of the vector"@en .

The usage of the Abstract Properties allows to specify the contract (a two-dimensional vector must have x and y Properties), but allows flexible reuse: Only when it is used, one must decide on the Characteristic and with it its effective datatype such as xsd:int, xsd:float or xsd:decimal.

To use the Vec2 Abstract Entity, the Characteristic to bind to the Abstract Properties is declared and then used as follows:

:IntegerNumber a bamm:Characteristic ;
   bamm:dataType xsd:integer .

:IntVec2 a bamm:Entity ;
   bamm:extends :Vec2 ;
   bamm:properties (
     [ bamm:extends :x ; bamm:characteristic :IntegerNumber ]
     [ bamm:extends :y ; bamm:characteristic :IntegerNumber ]
   ) .

Note that an Abstract Entity can have both bamm:Property​s and bamm:AbstractProperty​s (both are listed in bamm:properties). The properties list of an Entity that extends the Abstract Entity must specify the Characteristic to use for each of the Abstract Properties (and only those).

Declaring Operations

Operations have the following attributes:

Attributes Description Required

bamm:input

A list of references to Properties that describe the input to the operation. The attribute must be present, but the list may be empty.

bamm:output

A single reference to a Property that describes the output of the operation.

Example:

:toggle a bamm:Operation ;
   bamm:preferredName "Toggle"@en ;
   bamm:description "Switches the device on or off"@en ;
   bamm:input ( :toggleArgument ) ;
   bamm:output :toggleResult .

:toggleArgument a bamm:Property ;
   bamm:preferredName "Toggle argument"@en ;
   bamm:description "The argument for the toggling operation"@en ;
   bamm:characteristic :ToggleValues .

:ToggleValues a bamm-c:Enumeration ;
   bamm:preferredName "Toggle values"@en ;
   bamm:description "The possible input values for the toggle operation"@en ;
   bamm:dataType xsd:string ;
   bamm-c:values ( "on" "off" ) .

:toggleResult a bamm:Property ;
   bamm:preferredName "Toggle result"@en ;
   bamm:description "The result of the toggle operation"@en ;
   bamm:characteristic :ToggleResult .

:ToggleResult a bamm-c:Enumeration ;
   bamm:preferredName "Toggle result"@en ;
   bamm:description "The possible results of the toggle operation"@en ;
   bamm:dataType xsd:string ;
   bamm-c:values ( "ok" "denied" "unknown" ) .

Adding external references

The bamm:see attribute can be used to add references to related elements in an external taxonomy, ontology or standards document to Aspect model elements. Values for bamm:see must be URIs. The meaning of the reference is informative and implies no semantics such as equality or subsumption in either direction.

In the following example, bamm:see adds two references to external well-known vocabularies that have identifiers which are also valid URLs:

:lastName a bamm:Property ;
    bamm:see <https://schema.org/familyName> ;
    bamm:see <http://xmlns.com/foaf/0.1/lastName> ;
    bamm:characteristic bamm-c:Text .

If an external model element should be referenced that has a unique identifier which is not a URI, but a well-known resolver exists, you can either use the resolver’s URL or a synthetic URN. For example, for the Digital Object Identifier (DOI, [DOI]) 10.1109/NetSys.2017.7903949, you can use as the value for bamm:see either the URL https://doi.org/10.1109/NetSys.2017.7903949 or the URN urn:doi:10.1109/NetSys.2017.7903949.

If an external model element should be referenced that has a unique identifier which is not a URI and there is no well-known resolver, use a synthetic URN structure. One example are Object Identifiers as specified by ITU and ISO/IEC (OID) and the mapping to URNs in RFC 3061 [rfc3061], so for example, for the OID 1.3.6.1.4.1.1919.1.1.2, the corresponding bamm:see value would be urn:oid:1.3.6.1.4.1.1919.1.1.2:

:filterName a bamm:Property ;
    bamm:see <urn:oid:1.3.6.1.4.1.1919.1.1.2> ;
    bamm:characteristic bamm-c:Text .

If an external element should be referenced that has no unique identifier, bamm:see should not be used. In this case, refer to the external element in the current model element’s bamm:description, for example:

:organizationPerson a bamm:Property ;
    bamm:description "See ISO/IEC 11179-6:2015(E), section 3.35"@en ;
    bamm:characteristic bamm-c:Text .

Optional Properties

When Properties are used in Aspects and Entities, they can be marked as optional (not possible for properties of Abstract Entities). This means that a Property’s usage is optional, not the Property itself, which would make reusing a Property more difficult. In the following example, the Property toggleStatus is mandatory and the Property errorMessage is marked as optional in the Aspect. Note how the bamm:properties of the Aspect are defined, and how the definition for the toggleStatus Property itself does not differ from that of errorMessage.

@prefix : <urn:bamm:com.mycompany.myapplication:1.0.0#> .
@prefix bamm: <urn:bamm:io.openmanufacturing:meta-model:2.0.0#> .
@prefix bamm-c: <urn:bamm:io.openmanufacturing:characteristic:2.0.0#> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .

:MyAspect a bamm:Aspect ;
   bamm:properties (
     :toggleStatus
     [ bamm:property :errorMessage; bamm:optional true ]
   ) ;
   bamm:operations ( ) .

:toggleStatus a bamm:Property ;
   bamm:characteristic bamm-c:Boolean .

:errorMessage a bamm:Property ;
   bamm:characteristic bamm-c:Text .
If the Property’s use is optional, it is marked with bamm:optional true (like errorMessage in the example). However, if its use is mandatory (like toggleStatus in the example), the Property is directly referenced. Writing bamm:optional false is not allowed.
The setting of the bamm:optional attribute for a specific property is inherited from parent Entity by the Entities extending it using the Entity extension mechanism (bamm::extends).

Declaring Payload Names for Properties

When Properties are used in Aspects and Entities, a runtime payload name can be defined for the Property. This means that in the context of the Aspect or Entity (payload names cannot be defined for Abstract Entities) where the Property is used, the key of that Property in the runtime payload diverges from the Property’s local name. This allows for the separation of the semantic name of the Property and the corresponding key in the runtime payload. In the following example we define a Property errorMessage. In the Aspect it is defined that the corresponding key in the payload is error.

The value for the bamm:payloadName attribute must be of type xsd:string.
@prefix : <urn:bamm:com.mycompany.myapplication:1.0.0#> .
@prefix bamm: <urn:bamm:io.openmanufacturing:meta-model:2.0.0#> .
@prefix bamm-c: <urn:bamm:io.openmanufacturing:characteristic:2.0.0#> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .


:MyAspect a bamm:Aspect ;
   bamm:properties (
     [ bamm:property :errorMessage; bamm:payloadName "error" ]
   ) ;
   bamm:operations ( ) .

:errorMessage a bamm:Property ;
   bamm:characteristic bamm-c:Text .
A Property may not be marked as not being included in the payload using bamm:notInPayload true and have a payload name declared using bamm:payloadName.
It is also useful to know that the payload name definition is inherited from parent Entity by its children when using the Entity extension mechanism (bamm::extends).

Syntactic Shortcuts

When Properties use Characteristics classes, i.e. Characteristics that need to be instantiated, and the Characteristic instance is used in only one Property, the Characteristic may also be defined inline. Note that other Aspect Models can not refer to the Characteristic any more, because it no longer has an identifier.

Example: Regular definition of a Property

:numbers a bamm:Property ;
   bamm:characteristic :NumberList .

:NumberList a bamm-c:List ;
   bamm:dataType xsd:integer .

Example: Inlining the Characteristic definition

:numbers a bamm:Property ;
   bamm:characteristic [
      a bamm-c:List;
      bamm:dataType xsd:integer
   ] .

Localization of Aspect Models

To understand the possibilities for localization of the models and their implications it is important to understand the differences between the data types xsd:string and rdf:langString and/or their respective characteristic counterparts bamm-c:Text and bamm-c:MultiLanguageText.

To illustrate the differences between them and to give a typical example for localizable string that also needs to be included in the runtime payload, consider this model with a scalar text property:

:Test a bamm:Aspect;
    bamm:properties ( :text );
    bamm:operations ( ).

:text a bamm:Property ;
   bamm:characteristic bamm-c:Text .

The JSON payload for this model would then look like this:

{
  "text" : "My value"
}

Notice how the text is just a raw string, without any information about the language it is written in. When instead the text property is modeled as bamm-c:MultiLanguageText (instead of bamm-c:Text), the payload would change to include the information about the language and would look like this:

{
  "text" : {
    "en" : "Example multi language string"
  }
}

Another common use case is the use of localized texts strictly for documentation purposes. This means that the multilanguage strings can only be seen when modeling, they are not contained in the runtime payloads.

To illustrate how this is done, consider this example and imagine we would like the descriptions of the possible enumeration values to have localized version of the texts. This goal could be achieved by extending the model to look something like the following example:

:Results a bamm-c:Enumeration ;
   bamm:dataType :Result ;
   bamm-c:values ( :Success :Failed ) .

:Result a bamm:Entity ;
   bamm:properties ( :status [ bamm:property :description ; bamm:notInPayload true ] ) .

:status a bamm:Property ;
   bamm:characteristic bamm-c:Text .

:description a bamm:Property ;
   bamm:characteristic bamm-c:MultiLanguageText .

:Success a :Result ;
   :status "SUCCESS" ;
   :description "Der Prozess war erfolgreich."@de .

:Failed a :Result ;
   :status "FAILURE" ;
   :description "Der Prozess ist fehlgeschlagen."@de .

Note the use of the attribute notInPayload in usage of the property, ensuring that the description property will never be included in the runtime payloads.

It is even possible to provide the description in multiple languages. To achieve this, we need to change the type of the description property to the Set Characteristic:

:description a bamm:Property ;
  bamm:characteristic [
    a bamm-c:Set ;
    bamm-c:elementCharacteristic bamm-c:MultiLanguageText ;
  ] .

:Success a :Result ;
  :status "SUCCESS" ;
  :description (
    "Der Prozess war erfolgreich."@de
    "The process completed successfully."@en
  ) .

Notice how it is now possible to use the description property with multiple texts with different language tags (@de) to achieve the proper localization of the texts for linguistically diverse audiences.