ObjectTypes
objectTypes:
- browseName: MySensorType
components:
properties:
organizes:
methods:
browseName
-
The browse name is a normative name for the OPCUA node it represents, and must be chosen with care. Indeed, the browseName is used by OPCUA clients to browse the tree of nodes by their access path. The path of a node in the tree is made of browseNames.
-
We will follow the naming style already used by companion standards such as Device Integration, Analyser Device Integration, Robotics etc. which are referenced to ensure a uniform style.
-
It is commonly accepted that the BrowseName should be a term expressed in 'English' to allow for internationalization of the API.
-
The use of acronyms or abbreviations should be avoided and the use of an explicit term or combination of terms should be preferred
-
The use of the naming convention called "PascalCase" is strongly recommended. The first letter of the name starts with a capital letter, in case of a compound name (e.g. Adjective+Name), the two terms are pasted without space and each term starts with a capital letter.
-
In practice, it consists of alpha numeric characters. A browse name must not start with a number.
-
For Instance
- ❌ capteur_de_temperature (incorrect because it contains French terms, does not use PascalCase)
- ❌ temperature_Sensor (incorrect because of _ or spaces in the name)
- ✅ TemperatureSensor (correct because terms in English according to convention)
subtypeOf
subtypeOf
specifies the ObjectType from which the new ObjectType is derived. If ommitted, the modeler assume that the object type derives fromBaseObjectType
in the ua namespace.
objectTypes:
- browseName: MySensorType
subtypeOf: di:DeviceType
Components
Properties
Methods
Example:
# yaml-language-server: $schema=../../schemas/nodeset2.schema.json
namespaceUri: http://sterfive.com/UA/test/
objects:
- browseName: Calculator
organizedBy: /ua:Objects
methods:
- browseName: AddTwoValues
inputArguments:
- name: Operand2
dataType: ua:Double
description: La valeur de l'opérande 1
- name: Operand1
dataType: ua:Double
outputArguments:
- name: Result
dataType: ua:Double
Click here to see the generated XML File
<UAObject NodeId="ns=1;i=1000" BrowseName="1:Calculator">
<DisplayName>Calculator</DisplayName>
<References>
<Reference ReferenceType="HasTypeDefinition">i=58</Reference>
<Reference ReferenceType="Organizes" IsForward="false">i=85</Reference>
<Reference ReferenceType="HasComponent">ns=1;i=1001</Reference>
</References>
</UAObject>
<UAMethod NodeId="ns=1;i=1001" BrowseName="1:AddTwoValues" ParentNodeId="ns=1;i=1000">
<DisplayName>AddTwoValues</DisplayName>
<References>
<Reference ReferenceType="HasProperty">ns=1;i=1002</Reference>
<Reference ReferenceType="HasProperty">ns=1;i=1003</Reference>
</References>
</UAMethod>
<UAVariable NodeId="ns=1;i=1002" BrowseName="InputArguments" ParentNodeId="ns=1;i=1001" ValueRank="1" ArrayDimensions="2" DataType="Argument">
<DisplayName>InputArguments</DisplayName>
<Description>the definition of the input argument of method 1:Calculator.1:AddTwoValues</Description>
<References>
<Reference ReferenceType="HasTypeDefinition">i=68</Reference>
<Reference ReferenceType="HasModellingRule">i=78</Reference>
</References>
<Value>
<ListOfExtensionObject xmlns="http://opcfoundation.org/UA/2008/02/Types.xsd">
<ExtensionObject>
<TypeId>
<Identifier>i=297</Identifier>
</TypeId>
<Body>
<Argument>
<Name>Operand2</Name>
<DataType>
<Identifier>i=11</Identifier>
</DataType>
<ValueRank>-1</ValueRank>
<ArrayDimensions/>
<Description>
<Text/>
</Description>
</Argument>
</Body>
</ExtensionObject>
<ExtensionObject>
<TypeId>
<Identifier>i=297</Identifier>
</TypeId>
<Body>
<Argument>
<Name>Operand1</Name>
<DataType>
<Identifier>i=11</Identifier>
</DataType>
<ValueRank>-1</ValueRank>
<ArrayDimensions/>
<Description>
<Text/>
</Description>
</Argument>
</Body>
</ExtensionObject>
</ListOfExtensionObject>
</Value>
</UAVariable>
<UAVariable NodeId="ns=1;i=1003" BrowseName="OutputArguments" ParentNodeId="ns=1;i=1001" ValueRank="1" ArrayDimensions="1" DataType="Argument">
<DisplayName>OutputArguments</DisplayName>
<Description>the definition of the output arguments of method 1:Calculator.1:AddTwoValues</Description>
<References>
<Reference ReferenceType="HasTypeDefinition">i=68</Reference>
<Reference ReferenceType="HasModellingRule">i=78</Reference>
</References>
<Value>
<ListOfExtensionObject xmlns="http://opcfoundation.org/UA/2008/02/Types.xsd">
<ExtensionObject>
<TypeId>
<Identifier>i=297</Identifier>
</TypeId>
<Body>
<Argument>
<Name>Result</Name>
<DataType>
<Identifier>i=11</Identifier>
</DataType>
<ValueRank>-1</ValueRank>
<ArrayDimensions/>
<Description>
<Text/>
</Description>
</Argument>
</Body>
</ExtensionObject>
</ListOfExtensionObject>
</Value>
</UAVariable>
- inputArguments describes the input arguments of the method.
- name contains the name of the argument. We use the PascalCase convention and a universal name
- dataType refers to the data type of the argument. The dataType contains the name of the data type. If this data type is not defined in this YML document, we precede the name with the namespace alias with a colon. For example:
conventions
modelingRule is "Mandatory" by default
- components and features added to an ObjectType or VariableType have a
modellingRule: Mandatory
by default. - You must explicitly add
modellingRule: Optional
to make it optional. - This is a design choice to make the model more straighforward to build.
- In the rare circunstances, you may want to add a component to an ObjectType or VariableType that have no modellyingRule, you must add
modellingRule: false
to the component.
objectTypes:
- browseName: MySensorType
components:
- browseName: MyMandatoryComponent
# this component is mandatory
# because the modellingRule is not specified and default to "Mandatory"
- browseName: MyOptionalComponent
modellingRule: Optional
- browseName: MyComponentWithNoModelingRule
modellingRule: false
- browseName: <MyOptionalPlaceholderComponent>
modellingRule: OptionalPlaceholder
- browseName: <MyMandatoryPlaceholderComponent>
modellingRule: MandatoryPlaceholder
overloading of optional components or properties
It is sometimes necessary to make mandatory a component that is marked as optional in the base ObjectType. To do this, we redefine
For example, the ParamerSet
function group defined in the DeviceType
ObjectType of the di
namespace is optional and needs to be made mandatory in your derived type because it will be enriched with variable parameters specific to your device.
namespaces:
- di
objectTypes:
- browseName: MySensorDeviceType
subtypeOf: di:DeviceType
components:
# le composant ParameterSet defini dans di:DeviceType est redéfini et rendu obligatoire
# dans MySensorDeviceType
- browseName: di:ParameterSet
components:
- browseName: Temperature
dataType: ua:Double
Note:
- be sure to put the overloaded property or component in the correct
components:
,properties:
ormethods:
category - the browseName of the overloaded property or component must be expressed in the same namespace as in the Base Type. Don't forget to prefix the browseName with the corresponding namespace alias.
turning optional properties into mandatory properties
It is possible to expose optional elements defined in the ObjectType and turn them into mandatory
properties in your ObjectType by using the promotedToMandatory
property
For instance, if you want to enforce the CurrentState.Name
to be mandatory and LastTransition.Id
and LastTransition.TransitionTime
to be made Mandatory
in your state machine type you can use the following definition:
stateMachines:
- browseName: CustomStateMachineType
subtypeOf: ua:FiniteStateMachineType
promotedToMandatory:
- CurrentState.Name
- LastTransition.Id
- LastTransition.TransitionTime
``̀
## how to know the structure of a basic type
We recommand that you consult the PDF documentation associated with the imported models to understand the structure of the Types you wish to use in your model.
You can also resort to exploring the types in the OPC UA tree with an OPCUA client. This technique is also very efficient but requires some practice.