Skip to content

Relations

Josef edited this page Apr 24, 2023 · 9 revisions

Managing Relations in CAEX

In these programming examples, relations between CAEXObjects are created and processed. The following examples are provided:

Working with Class Instance Relations

In AutomationML, the CAEX elements SystemUnitFamilyType, InterfaceFamilyType, RoleFamilyType and AttributeFamilyType are referred to as classes. It is possible, to instantiate classes; classes and their instances are associated by class-instance relations.

InternalElement creation by class instantiation

InternalElementType objects (called InternalElements) can be created by instantiation of SystemUnitFamilyType objects. A class instance always contains all elements of the class and a reference back to the original class.

using Aml.Engine.CAEX;

void CreateSystemUnitClassInstance(CAEXDocument document)
{
    // add a new engineering project as an Instance Hierarchy and a SystemUnitClass Library
    // which provides devices to be used in the project
    var engineeringProject = document.CAEXFile.InstanceHierarchy.Append("EngineeringProject");
    var devices = document.CAEXFile.SystemUnitClassLib.Append("Devices");

    // Adding a Product as a new SystemUnitClass to the SystemUnitClassLib 
    var motionController = devices.SystemUnitClass.Append("ControllerS400");
    // the technical data of the product is provided by an ECLASS identifier
    motionController.Attribute.Append("ECLASS").Value = "19234103";

    // Insertion of a new class instance (InternalElement) in the InstanceHierarchy
    // The instance also contains the ECLASS attribute of the class
    engineeringProject.Insert(motionController.CreateClassInstance());
    var ctrl1 = engineeringProject.InternalElement[0];

    // The class-instance relation is saved in the InternalElement
    Debug.Assert(ctrl1.SystemUnitClass.Equals(motionController));
    Debug.Assert(ctrl1.RefBaseSystemUnitPath == motionController.CAEXPath());

    // In this example, it might be better to read the attributes from an ECLASS catalog and
    // not assign the ECLASS identifier to the instance
    var ctrl2 = engineeringProject.InternalElement.Append("motionController");

    static void AddECLASSAttributes(InternalElementType element, SystemUnitFamilyType eclass)
    {
        // add the class reference without any attributes
        element.SystemUnitClass = eclass;
        if (eclass.Attribute["ECLASS"].Value == "19234103")
        {
            // you need a ECLASS license to get the data, this is only an example
            element.SetAttributeValue("MC_Power", 220.0);
        }
    }    
    AddECLASSAttributes(ctrl2, motionController);
}

The XML Text, created by this example is shown below.

<?xml version="1.0"?>

<CAEXFile xmlns="http://www.dke.de/CAEX" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
FileName="" SchemaVersion="3.0">
<SuperiorStandardVersion>AutomationML 2.10</SuperiorStandardVersion>
<SourceDocumentInformation LastWritingDateTime="2021-09-05T21:17:08.6325152+02:00"
OriginVersion="" OriginID="" OriginName=""/>
<InstanceHierarchy Name="EngineeringProject">
<Version>0</Version>
    <InternalElement Name="ControllerS400" 
	RefBaseSystemUnitPath="Devices/ControllerS400" 
	ID="9e4509fd-a7ed-486a-a1b0-5c3e1a0ef2e4">	
        <Attribute Name="ECLASS">
            <Value>19234103</Value>
        </Attribute>
    </InternalElement>
    <InternalElement Name="motionController" 
	RefBaseSystemUnitPath="Devices/ControllerS400" 
	ID="19d14e6f-ced6-4c7b-a887-61fd34b8791e">
        <Attribute Name="MC_Power" AttributeDataType="xs:double">
            <Value>220</Value>
        </Attribute>
    </InternalElement>
</InstanceHierarchy>

<SystemUnitClassLib Name="Devices">
<Version>0</Version>
    <SystemUnitClass Name="ControllerS400" ID="11596537-28fc-4154-b72d-ec0572f9df15">
        <Attribute Name="ECLASS">
            <Value>19234103</Value>
        </Attribute>
    </SystemUnitClass>
</SystemUnitClassLib>
</CAEXFile>

Back To Top

ExternalInterface creation by class instantiation

ExternalInterfaceType objects (called ExternalInterfaces) can be created by instantiation of InterfaceFamilyType objects. ExternalInterfaces are needed to create instance to instance relations.

using Aml.Engine.AmlObjects;
using Aml.Engine.CAEX;

void CreateInterfaceClassInstance(CAEXDocument document)
{
    // add a new logistic project as an Instance Hierarchy 
    var logisticsProject = document.CAEXFile.InstanceHierarchy.Append("LogisticsProject");

    // import the standard AutomationML Interfaceclass library into the document
    var interfaceClassLib = AutomationMLInterfaceClassLibType.InterfaceClassLib(document);

    // add a distributing switch to your project
    var dswitch = logisticsProject.New_InternalElement("distributing switch");

    // the switch should contain one input and two outputs
    // the standard interface class 'order' is used to model the distribution
    var order = document.FindByPath(AutomationMLInterfaceClassLib.Order) as InterfaceFamilyType;

    if (order == null)
    {
        throw new Exception("The standard interface class 'Order' doesnot exist");
    }

    // create three new class instances (ExternalInterface),
    // the instances contain the interface class attribute 'Direction'
    var input = order.CreateClassInstance();
    var out1 = order.CreateClassInstance();
    var out2 = order.CreateClassInstance();

    // the direction value is needed, because CAEX doesnot
    // provide directed instance to instance relations
    input.Attribute["Direction"].Value = "In";
    out1.Attribute["Direction"].Value = "Out";
    out2.Attribute["Direction"].Value = "Out";

    // the direction attribute is defined in the standard attribute type library
    // the possible values are defined in a nominal value constraint
    // you can ensure, that the assigned values are in the nominal value collection
    // see the attrubte examples in the wiki for details.

    dswitch.Insert(input);
    dswitch.Insert(out1, asFirst:false);
    dswitch.Insert(out2, asFirst: false);
}

The XML Text for the created Element instances is shown below.

<?xml version="1.0"?>
<CAEXFile xmlns="http://www.dke.de/CAEX" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
FileName="" SchemaVersion="3.0">
<SuperiorStandardVersion>AutomationML 2.10</SuperiorStandardVersion>
<SourceDocumentInformation LastWritingDateTime="2021-09-05T22:43:33.129284+02:00" 
OriginVersion="" OriginID="" OriginName=""/>
<InstanceHierarchy Name="LogisticsProject">
<Version>0</Version>
<InternalElement Name="distributing switch" ID="66a8be30-237c-4025-ae28-760efddf1b6a">
    <ExternalInterface Name="Order" ID="8e85dc9a-a9a2-4b63-9659-a98f35e85d23" 
	RefBaseClassPath="AutomationMLInterfaceClassLib/AutomationMLBaseInterface/Order">
        <Attribute Name="Direction" RefAttributeType="AutomationMLBaseAttributeTypeLib/Direction" 
		AttributeDataType="xs:string">
            <Value>In</Value>
        </Attribute>
    </ExternalInterface>
    <ExternalInterface Name="Order" ID="16849f1f-5cc0-4c14-b607-41356d8e90e8" 
	RefBaseClassPath="AutomationMLInterfaceClassLib/AutomationMLBaseInterface/Order">
        <Attribute Name="Direction" RefAttributeType="AutomationMLBaseAttributeTypeLib/Direction" 
		AttributeDataType="xs:string">
            <Value>Out</Value>
        </Attribute>
    </ExternalInterface>
    <ExternalInterface Name="Order" ID="3c15cc27-96c6-45e1-add7-70e2b0c0d2f6" 
	RefBaseClassPath="AutomationMLInterfaceClassLib/AutomationMLBaseInterface/Order">
        <Attribute Name="Direction" RefAttributeType="AutomationMLBaseAttributeTypeLib/Direction" 
		AttributeDataType="xs:string">
            <Value>Out</Value>
        </Attribute>
    </ExternalInterface>
</InternalElement>
</InstanceHierarchy>

Back To Top

RoleRequirement creation by class instantiation.

RoleRequirementType objects (called RoleRequirements) can be created by instantiation of RoleFamilyType objects. RoleRequirements are attached to InternalElements to add a meaning to the element.

void RoleInstantiation(CAEXDocument document)
{
    // adding a RoleClass library and a role class
    var roleClassLib = document.CAEXFile.RoleClassLib.Append("AutomationRoleClasses");
    var switchRole = roleClassLib.RoleClass.Append("Switch");

    // adding attributes to the roleClass
    switchRole.Attribute.Append("NumberOfPoles").AttributeDataType = 
				AttributeTypeType.ClrToXmlType(typeof(int));
    switchRole.Attribute.Append("NumberOfThrows").AttributeDataType = 
				AttributeTypeType.ClrToXmlType(typeof(int));

    // creating an Instance hierarchy and some instances of switches
    var engineeringProject = document.CAEXFile.InstanceHierarchy.Append("EngineeringProject");
    var pushButtonSwitch = engineeringProject.InternalElement.Append("pushButtonSwitch");

    // make this element to a switch by insertion of a RoleClass instance
    // the RoleClass instance is a RoleRequirement object which is inserted
    // into the RoleRequirements colllection of the element. The role class attributes
    // are copied to the created RoleRequirement object, too.
    pushButtonSwitch.Insert(switchRole.CreateClassInstance());

    // Alternate RoleClass assignment, here it is necessary to explicity request
    // the creation of the attributes by setting the 'addInstance' parameter to 'true'.
    // The 'addUnique' is set to false here, because the element contains this RoleClass
    // assignment already. Multiple assignments of the same RoleClass are
    // not excluded. The 'addSupportedRoleClass' is an obsolete parameter in CAEX 3.0 documents.
	
    pushButtonSwitch.AddRoleClassReference(switchRole, 
        addSupportedRoleClass: false, addUnique: false, addInstance: true);

    // if you want to copy the RoleClass attributes to the InternalElement
    pushButtonSwitch.CopyAttributesFrom(switchRole, includingValues:false);
}

The XML Text, created by this example is shown below.

<?xml version="1.0"?>
<CAEXFile xmlns="http://www.dke.de/CAEX" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" FileName="" SchemaVersion="3.0">
<SuperiorStandardVersion>AutomationML 2.10</SuperiorStandardVersion>
<SourceDocumentInformation LastWritingDateTime="2021-09-05T20:03:04.1021275+02:00" OriginVersion="" OriginID="" OriginName=""/>
<InstanceHierarchy Name="EngineeringProject">
<Version>0</Version>
    <InternalElement Name="pushButtonSwitch" ID="6a80e7ab-7334-4629-809b-f4654aac959b">
        <Attribute Name="NumberOfPoles" AttributeDataType="xs:int"/>
        <Attribute Name="NumberOfThrows" AttributeDataType="xs:int"/>
        <RoleRequirements RefBaseRoleClassPath="AutomationRoleClasses/Switch">
            <Attribute Name="NumberOfPoles" AttributeDataType="xs:int"/>
            <Attribute Name="NumberOfThrows" AttributeDataType="xs:int"/>
        </RoleRequirements>
        <RoleRequirements RefBaseRoleClassPath="AutomationRoleClasses/Switch">
            <Attribute Name="NumberOfPoles" AttributeDataType="xs:int"/>
            <Attribute Name="NumberOfThrows" AttributeDataType="xs:int"/>
        </RoleRequirements>
    </InternalElement>
</InstanceHierarchy>

<RoleClassLib Name="AutomationRoleClasses">
<Version>0</Version>
    <RoleClass Name="Switch">
        <Attribute Name="NumberOfPoles" AttributeDataType="xs:int"/>
        <Attribute Name="NumberOfThrows" AttributeDataType="xs:int"/>
    </RoleClass>
</RoleClassLib>
</CAEXFile>

Back To Top

Attribute creation by class instantiation

AttributeType objects (called Attributes) can be created by instantiation of AttributeFamilyType objects.

Back To Top

Working with Instance to Instance Relations

Creation of instance to instance relations with InternalLinks

InternalLinkType objects (called InternalLinks) relate two InternalElements. The linkage uses ExternalInterfaces, attached to the InternalElements.

using Aml.Engine.CAEX;

var document = CAEXDocument.New_CAEXDocument ();
var instanceHierarchy = document.CAEXFile.InstanceHierarchy.Append("instanceHierarchy");
var interfaceClassLib = document.CAEXFile.InterfaceClassLib.Append("interfaceClassLib");
var interfaceClass = interfaceClassLib.InterfaceClass.Append("interfaceClass");

// create an InternalElement which is a common parent to hold the InternalLink
var linkParent = instanceHierarchy.InternalElement.Append ("linkParent");

// create the instances
var internalElementA = linkParent.InternalElement.Append ("internalElementA");
var internalElementB = linkParent.InternalElement.Append ("internalElementB");

// create the Interfaces for the InternalLink connection
internalElementA.ExternalInterface.Append ("a");
internalElementB.ExternalInterface.Append ("b");

// create the instance to instance relation
var relation = InternalLinkType.New_InternalLink (internalElementA.ExternalInterface["a"], internalElementB.ExternalInterface["b"], "rel1");

// an alternative way is, to use the InternalLink collection
// var relation = linkParent.InternalLink.Append ("rel1");
// relation.AInterface = internalElementA.ExternalInterface["a"];
// relation.BInterface = internalElementB.ExternalInterface["b"];

Back To Top

Creation of class to class relations using AutomationML Base Classes

Class to class relations define inheritance relationships between a base class and its derived subclass. Relationships are only defined between classes of the same type, which are RoleFamilyType, SystemUnitFamilyType, InterfaceFamilyType and AttributeFamilyType.

using Aml.Engine.CAEX;
using Aml.Engine.AmlObjects;

var document = CAEXDocument.New_CAEXDocument ();

// the first solution shows an implementation, which uses existing libraries and classes
void methodWithClasses ()
{
    // add the AutomationMLInterfaceClassLib
    var amlBaseICLib = AutomationMLInterfaceClassLibType.InterfaceClassLib(document);
    var interfaceClassLib = document.CAEXFile.InterfaceClassLib.Append("interfaceClassLib");

    var interfaceClass = interfaceClassLib.InterfaceClass.Append("interfaceClassClass");
    var interfaceClass.BaseClass = amlBaseICLib.AutomationMLClass(AutomationMLInterfaceClassLib.AutomationMLBaseInterface);
}

// the second solution shows an implementation, which uses the standardized class path
void methodWithClassPath ()
{
    var interfaceClassLib = document.CAEXFile.InterfaceClassLib.Append("interfaceClassLib");
    var interfaceClass = interfaceClassLib.InterfaceClass.Append("interfaceClassClass");
    
    // creates a class relation to the AutomationML Base Interface Class
    interfaceClass.MakeAutomationMLBaseInterface();
}

References

Back To Top

Clone this wiki locally