Skip to end of metadata
Go to start of metadata

You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 12 Next »

A-Stack supports OPC-UA protocol Handler, that can be used to subscribe/update various nodes present on OPC-UA server.


 OPCUA Protocol Handler Flow:

OPCUA Protocol Parameters:

The table below lists all the parameters of opcua protocol handler and their description

Parameter Name

Parameter Description

ConnectionConfig

A def containing all the information about connection and security parameters of OPCUA server, it has the following fields ServerUri, SecurityConfig and SecurityMode (0-6).

Security Mode             Description

0                                                  None

1                                                  128-bit RSA Sign

2                                                  128-bit RSA Sign and encrypt

3                                                  256-bit Basic Sign

4                                                  256-bit Basic Sign and encrypt

5                                                  256-bit SHA Sign

6                                                  256-bit SHA Sign and encrypt 

SecurityConfig

A def containing information about security parameters of the server, it has the following fields UserName, Password, ApplicationIdentity and CertificationParameters.

ApplicationIdentity

A def Containing information about the client’s Idenitiy, it has following fields AppName, AppUri and ProductUri.

CertificationParameters

A def containing information about the connection’s certificate parameters, it has following parameters     OrgName, Path, PrivateKeyPwd, ValidityInDay, AutoCertificateRenewal and KeySize.

Operation

This field specifies the operation to be performed, the operation are subscription and write.

NodeID

This parameter is used in case of write Operation, the Node ID on which the write operation is to be performed.

AttributeID

This parameter is used in case of write Operation, the Attribute ID of the respective Node ID on  which the write operation is to be performed.

OpcData

This parameter is used in case of write Operation, and this specifies the write value.

OPCUaSubscribe

A def specific to subscribe operation, It has fields like     

NodeID: the Node Id to which we need to subscribe.

AttributeID: attribute ID is optional for subscription.

SubscribeChild: Whether you want to subscribe to child nodes also.

PublishingInterval: The frequency at which the OPCUA Server will publish data to this subscriber.

NotificationBufferSize: The Buffer size that stores incoming subscription data, increase this value if you see buffer overflows and data misses.


Usage of opcua protocol handler:

  • Opcua Write:

    Opcua Write Facet
    <ThingFacet Name="OPCWriteFacet">
      <String KnownBy="OPCWriteAction" Name="OpcData"/>
      <String Name="NodeID"/>
      <String Name="Operation"/>
      <Integer Name="AttribueID"/>
      <ConnectionConfig Name="OPCSubscribeConnectionConfig"/>
      <Action Name="OPCWriteAction">
        <Workflow Limit="1" Live="1" Timeout="-1">
          <Task name="Main">
            <Event as="ActionArgument" name="Argument"/>
            <Invoke name="InvokeOPCWrite" post="opcua://?ServerUri=[%:Event.Argument.OPCSubscribeConnectionConfig.ServerUri.Value:%]&amp;
    			SecurityMode=[%:Event.Argument.OPCSubscribeConnectionConfig.SecurityMode.Value:%]&amp;
    			UserName=[%:Event.Argument.OPCSubscribeConnectionConfig.SecurityOptions.UserName.Value:%]&amp;
    			Password=[%:Event.Argument.OPCSubscribeConnectionConfig.SecurityOptions.Password.Value:%]&amp;
    			Path=[%:Event.Argument.OPCSubscribeConnectionConfig.SecurityOptions.CertificationParameters.Path.Value:%]&amp;
    			ValidityInDay=[%:Event.Argument.OPCSubscribeConnectionConfig.SecurityOptions.CertificationParameters.ValidityInDay.Value:%]&amp;
    			AutoCertificateRenewal=
    			[%:Event.Argument.OPCSubscribeConnectionConfig.SecurityOptions.CertificationParameters.AutoCertificateRenewal.Value:%]&amp;
            	PrivateKeyPwd=[%:Event.Argument.OPCSubscribeConnectionConfig.SecurityOptions.CertificationParameters.PrivateKeyPwd.Value:%]&amp;
            	OrgName=[%:Event.Argument.OPCSubscribeConnectionConfig.SecurityOptions.CertificationParameters.OrgName.Value:%]&amp;
                KeySize=[%:Event.Argument.OPCSubscribeConnectionConfig.SecurityOptions.CertificationParameters.KeySize.Value:%]&amp;
                AppUri=[%:Event.Argument.OPCSubscribeConnectionConfig.SecurityOptions.ApplicationIdentity.AppUri.Value:%]&amp; 
                AppName=[%:Event.Argument.OPCSubscribeConnectionConfig.SecurityOptions.ApplicationIdentity.AppName.Value:%]&amp;                             
    			ProductUri=[%:Event.Argument.OPCSubscribeConnectionConfig.SecurityOptions.ApplicationIdentity.ProductUri.Value:%]&amp;
                Operation=[%:Event.Argument.Operation.Value:%]" scope="local" waitFor="Argument">
              <Message>
                <Value>
                  <Payload>
                        [%:Event.Argument.OpcData.Value:%]
                  </Payload>
                  <NodeID>
                      [%:Event.Argument.NodeID.Value:%]
                  </NodeID>
                  <AttributeID>
                      [%:Event.Argument.AttributeID.Value:%]
                  </AttributeID>
                </Value>
              </Message>
            </Invoke>
            <Output As="ActionResult" Name="Result">
              <Value>
                <OpcData>
                  <Include>
    				Invoke.InvokeOPCWrite.Message.Value
                  </Include>
                </OpcData>
              </Value>
            </Output>
          </Task>
        </Workflow>
      </Action>
    </ThingFacet>
    write Initialization Query
     <Query>
        <DeleteAll>
            <OPCWriteModel>
                <writeId ne=""/>
            </OPCWriteModel>
        </DeleteAll>
        <Create>
            <OPCWriteModel>
                <Operation>
                    write
                </Operation>
                <NodeID>
                    ns=2;s=Atomiton.Device1.TankData.USSAV1S01HST.Tank1.Tank_1_FCU_Temperature
                </NodeID>
                <AttributeID>
                    $Null()
                </AttributeID>
                <OPCSubscribeConnectionConfig>
                    <ServerUri>
                        opc.tcp://MSEDGEWIN10:49320
                    </ServerUri>
                    <SecurityMode>
                        0
                    </SecurityMode>
                    <SecurityOptions>
                        <UserName/>
                        <Password/>
                        <ApplicationIdentity>
                            <AppName>
                                atomitonClient@localhost
                            </AppName>
                            <AppUri>
                                urn:localhost:OPCUATQL
                            </AppUri>
                            <ProductUri>
                                urn:atomiton.com:OPCUA
                            </ProductUri>
                        </ApplicationIdentity>
                        <CertificationParameters>
                            <OrgName>
                                atomiton
                            </OrgName>
                            <Path>
                                /atomiton/certs
                            </Path>
                            <PrivateKeyPwd>
                                tql123#
                            </PrivateKeyPwd>
                            <ValidityInDay>
                                3650
                            </ValidityInDay>
                            <AutoCertificateRenewal>
                                true
                            </AutoCertificateRenewal>
                            <KeySize>
                                2048
                            </KeySize>
                        </CertificationParameters>
                    </SecurityOptions>
                </OPCSubscribeConnectionConfig>
                <OpcData>
                    80
                </OpcData>
            </OPCWriteModel>
        </Create>
    </Query>
    
    Write Update query
    <Query>
      <Find format="version,known">
        <OPCWriteModel>
          <writeId ne=""/>
        </OPCWriteModel>
      </Find>
      <if condition="$Response.Message.Value/Find/Status eq 'Success'">
        <then>
          <SetResponseData>
            <key>
              Message.Value.Find.Result.OPCWriteModel.OpcData.Value
            </key>
            <value>
              200
            </value>
          </SetResponseData>
          <Update>
            <from>
              Result
            </from>
            <Include>
              $Response.Message.Value.Find
            </Include>
          </Update>
        </then>
      </if>
    </Query>
  • Opcua Subscription:

    Opcua Subscription Facet
    	<Def Name="CertificationParams">
          <String Name="OrgName"/>
          <String Name="Path"/>
          <String Name="PrivateKeyPwd"/>
          <String Name="ValidityInDay"/>
          <String Name="AutoCertificateRenewal"/>
          <Integer Name="KeySize"/>
        </Def>
        <Def Name="AppIdentity">
          <String Name="AppName"/>
          <String Name="AppUri"/>
          <String Name="ProductUri"/>
        </Def>
        <Def Name="SecurityConfig">
          <String Name="UserName"/>
          <String Name="Password"/>
          <AppIdentity Name="ApplicationIdentity"/>
          <CertificationParams Name="CertificationParameters"/>
        </Def>
        <Def Name="ConnectionConfig">
          <String Name="ServerUri"/>
          <Integer Name="SecurityMode"/>
          <SecurityConfig Name="SecurityOptions"/>
        </Def>
    	<Def Name="OPCUaSubscribe">
    		<String Name="NodeID" Cardinality="0..m"/>
            <String Name="AttributeID"/>
            <String Name="SubscribeChild"/>
            <String Name="PublishingInterval"/>
            <String Name="NotificationBufferSize"/>
    	</Def>
    
    	<ThingFacet Name="OPCSubscriberFacet">
      		<String Format="$ObjectFormat(xml)" KnownBy="OPCSubscriberAction" Name="SubscriptionData" update="auto"/>
      		<String Name="Operation"/>
      		<ConnectionConfig Name="OPCSubscribeConnectionConfig"/>
      		<OPCUaSubscribe Name="OPCSubscriptionConfig"/>
      		<Action Name="OPCSubscriberAction">
        	<Workflow Limit="1" Live="1" Timeout="-1">
          		<Task name="Main" while="true">
            		<Event as="ActionArgument" name="Argument"/>
            			<Invoke name="InvokeOPCSubscription" post="opcua://?ServerUri=[%:Event.Argument.OPCSubscribeConnectionConfig.ServerUri.Value:%]&amp;
                         SecurityMode=[%:Event.Argument.OPCSubscribeConnectionConfig.SecurityMode.Value:%]&amp;
                         UserName=[%:Event.Argument.OPCSubscribeConnectionConfig.SecurityOptions.UserName.Value:%]&amp;
    					 Password=[%:Event.Argument.OPCSubscribeConnectionConfig.SecurityOptions.Password.Value:%]&amp;
    					 Path=[%:Event.Argument.OPCSubscribeConnectionConfig.SecurityOptions.CertificationParameters.Path.Value:%]&amp;
            			 ValidityInDay=[%:Event.Argument.OPCSubscribeConnectionConfig.SecurityOptions.CertificationParameters.ValidityInDay.Value:%]&amp;
    					 AutoCertificateRenewal=	 
    						[%:Event.Argument.OPCSubscribeConnectionConfig.SecurityOptions.CertificationParameters.AutoCertificateRenewal.Value:%]&amp;
            			 PrivateKeyPwd=[%:Event.Argument.OPCSubscribeConnectionConfig.SecurityOptions.CertificationParameters.PrivateKeyPwd.Value:%]&amp;
            			 OrgName=[%:Event.Argument.OPCSubscribeConnectionConfig.SecurityOptions.CertificationParameters.OrgName.Value:%]&amp;
                         KeySize=[%:Event.Argument.OPCSubscribeConnectionConfig.SecurityOptions.CertificationParameters.KeySize.Value:%]&amp;
                         AppUri=[%:Event.Argument.OPCSubscribeConnectionConfig.SecurityOptions.ApplicationIdentity.AppUri.Value:%]&amp;
                         AppName=[%:Event.Argument.OPCSubscribeConnectionConfig.SecurityOptions.ApplicationIdentity.AppName.Value:%]&amp;
    					 ProductUri=[%:Event.Argument.OPCSubscribeConnectionConfig.SecurityOptions.ApplicationIdentity.ProductUri.Value:%]&amp;
                         Operation=[%:Event.Argument.Operation.Value:%]" scope="process" waitFor="Argument">
              			 <Message>
                			<Value>
                  				<OPCSubscriptionConfig>
                      				[:Event.Argument.OPCSubscriptionConfig:]
                  				</OPCSubscriptionConfig>
                		  	</Value>
              			</Message>
            		   </Invoke>
            		   <Output As="ActionResult" Name="Result">
              			<Value>
                			<SubscriptionData>
                  				<Include>
                      				Invoke.InvokeOPCSubscription.Message.Value
                  				</Include>
                			</SubscriptionData>
              			</Value>
            		   </Output>
          		</Task>
        	</Workflow>
     	 </Action>
    	</ThingFacet>
    Subscription Initialization Query
    <Query>
      <DeleteAll>
        <OPCSubscriberModel>
          <subscribeId ne=""/>
        </OPCSubscriberModel>
      </DeleteAll>
      <Create>
        <OPCSubscriberModel>
          <Operation>
            subscription
          </Operation>
          <OPCSubscribeConnectionConfig>
            <ServerUri>
              opc.tcp://MSEDGEWIN10:49320
            </ServerUri>
            <SecurityMode>
              2
            </SecurityMode>
            <SecurityOptions>
              <UserName/>
              <Password/>
              <ApplicationIdentity>
                <AppName>
                  atomitonClient@localhost
                </AppName>
                <AppUri>
                  urn:localhost:OPCUATQL
                </AppUri>
                <ProductUri>
                  urn:atomiton.com:OPCUA
                </ProductUri>
              </ApplicationIdentity>
              <CertificationParameters>
                <OrgName>
                  atomiton
                </OrgName>
                <Path>/atomiton/certs</Path>
                <PrivateKeyPwd>
                  tql123#
                </PrivateKeyPwd>
                <ValidityInDay>
                  3650
                </ValidityInDay>
                <AutoCertificateRenewal>
                  true
                </AutoCertificateRenewal>
                <KeySize>
                  2048
                </KeySize>
              </CertificationParameters>
            </SecurityOptions>
          </OPCSubscribeConnectionConfig>
          <OPCSubscriptionConfig>
            <NodeID>
              ns=2;s=Vopak.Device1.TankData.USSAV1S01HST.Tank1
            </NodeID>
            <NodeID>
              ns=2;s=Vopak.Device1.TankData.USSAV1S01HST.Tank2
            </NodeID>
            <AttributeID/>
            <PublishingInterval>1000</PublishingInterval>
            <NotificationBufferSize>5000</NotificationBufferSize>
            <SubscribeChild>
              true
            </SubscribeChild>
          </OPCSubscriptionConfig>
          <SubscriptionData>$Null()</SubscriptionData>
          <SubscriptionPayload>$Null()</SubscriptionPayload>
        </OPCSubscriberModel>
      </Create>
    </Query>
    
    Subscription Deletion Query
    <Query>
      <DeleteAll>
        <OPCSubscriberModel>
          <subscribeId ne=""/>
        </OPCSubscriberModel>
      </DeleteAll>
    </Query>
  • Note: It is possible to subscribe to multiple root nodes using a single facet, use multiple Node ID's as shown in above subscription query

    Multiple topics subscription
    		 <NodeID>
              	ns=2;s=Atomiton.OilAndGas.Test.Device1.TankData.Test.Tank1
            </NodeID>
            <NodeID>
              	ns=2;s=Atomiton.OilAndGas.Test.Device1.TankData.Test.Tank2
            </NodeID>

     

Opcua Subscription Message Output Format: The output message of opcua subscription is an xml structure that has array of opcua nodes as shown below.


Xml Output Format
  <SubscriptionData Value="" Version="1">
    <Known>
        <OpcUaNodes>
            <OpcUaNode>
                <ServerTimeStamp/>
                <NodeID>ns=2;s=Atomiton.OilAndGas.Test.Device1.TankData.Test.Tank1.Tank_1_Agitator_Motor_Running_Bit</NodeID>
                <NodeValue>false</NodeValue>
                <StatusCode>GOOD</StatusCode>
                <SourceTimeStamp>03/07/17 19:53:39.8876995 GMT</SourceTimeStamp>
                <DataType>Boolean</DataType>
            </OpcUaNode>
            <OpcUaNode>
                <ServerTimeStamp/>
                <NodeID>ns=2;s=Atomiton.OilAndGas.Test.Device1.TankData.Test.Tank1.Tank_1_FCU_Temperature</NodeID>
                <NodeValue>999.0</NodeValue>
                <StatusCode>GOOD</StatusCode>
                <SourceTimeStamp>03/07/17 19:53:39.8876995 GMT</SourceTimeStamp>
                <DataType>Float</DataType>
            </OpcUaNode>
            <OpcUaNode>
                <ServerTimeStamp/>
                <NodeID>ns=2;s=Atomiton.OilAndGas.Test.Device1.TankData.Test.Tank1.Tank_1_Gallon_Value</NodeID>
                <NodeValue>1.34547004E15</NodeValue>
                <StatusCode>GOOD</StatusCode>
                <SourceTimeStamp>03/07/17 19:53:39.8876995 GMT</SourceTimeStamp>
                <DataType>Double</DataType>
            </OpcUaNode>
            <OpcUaNode>
                <ServerTimeStamp/>
                <NodeID>ns=2;s=Atomiton.OilAndGas.Test.Device1.TankData.Test.Tank1.Tank_1_Loading_PP_Motor_Running_Bit</NodeID>
                <NodeValue>false</NodeValue>
                <StatusCode>GOOD</StatusCode>
                <SourceTimeStamp>03/07/17 19:53:39.8876995 GMT</SourceTimeStamp>
                <DataType>Boolean</DataType>
            </OpcUaNode>
            <OpcUaNode>
                <ServerTimeStamp/>
                <NodeID>ns=2;s=Atomiton.OilAndGas.Test.Device1.TankData.Test.Tank1.Tank_1_RAW_Level_Inches</NodeID>
                <NodeValue>500.0</NodeValue>
                <StatusCode>GOOD</StatusCode>
                <SourceTimeStamp>03/07/17 19:53:39.8876995 GMT</SourceTimeStamp>
                <DataType>Double</DataType>
            </OpcUaNode>
            <OpcUaNode>
                <ServerTimeStamp/>
                <NodeID>ns=2;s=Atomiton.OilAndGas.Test.Device1.TankData.Test.Tank1.Tank_1_steaming_in_auto_selected_HMI</NodeID>
                <NodeValue>false</NodeValue>
                <StatusCode>GOOD</StatusCode>
                <SourceTimeStamp>03/07/17 19:53:39.8876995 GMT</SourceTimeStamp>
                <DataType>Boolean</DataType>
            </OpcUaNode>
            <OpcUaNode>
                <ServerTimeStamp/>
                <NodeID>ns=2;s=Atomiton.OilAndGas.Test.Device1.TankData.Test.Tank1.Tank_1_unld_PP_Motor_Running_Bit</NodeID>
                <NodeValue>false</NodeValue>
                <StatusCode>GOOD</StatusCode>
                <SourceTimeStamp>03/07/17 19:53:39.8876995 GMT</SourceTimeStamp>
                <DataType>Boolean</DataType>
            </OpcUaNode>
            <OpcUaNode>
                <ServerTimeStamp/>
                <NodeID>ns=2;s=Atomiton.OilAndGas.Test.Device1.TankData.Test.Tank2.Tank_2_Agitator_Motor_Running_Bit</NodeID>
                <NodeValue>false</NodeValue>
                <StatusCode>GOOD</StatusCode>
                <SourceTimeStamp>03/07/17 19:53:39.8876995 GMT</SourceTimeStamp>
                <DataType>Boolean</DataType>
            </OpcUaNode>
            <OpcUaNode>
                <ServerTimeStamp/>
                <NodeID>ns=2;s=Atomiton.OilAndGas.Test.Device1.TankData.Test.Tank2.Tank_2_FCU_Temperature</NodeID>
                <NodeValue>56.0</NodeValue>
                <StatusCode>GOOD</StatusCode>
                <SourceTimeStamp>03/07/17 19:53:39.8876995 GMT</SourceTimeStamp>
                <DataType>Float</DataType>
            </OpcUaNode>
            <OpcUaNode>
                <ServerTimeStamp/>
                <NodeID>ns=2;s=Atomiton.OilAndGas.Test.Device1.TankData.Test.Tank2.Tank_2_Gallon_Value</NodeID>
                <NodeValue>1.34547004E15</NodeValue>
                <StatusCode>GOOD</StatusCode>
                <SourceTimeStamp>03/07/17 19:53:39.8876995 GMT</SourceTimeStamp>
                <DataType>Double</DataType>
            </OpcUaNode>
            <OpcUaNode>
                <ServerTimeStamp/>
                <NodeID>ns=2;s=Atomiton.OilAndGas.Test.Device1.TankData.Test.Tank2.Tank_2_Loading_PP_Motor_Running_Bit</NodeID>
                <NodeValue>false</NodeValue>
                <StatusCode>GOOD</StatusCode>
                <SourceTimeStamp>03/07/17 19:53:39.8876995 GMT</SourceTimeStamp>
                <DataType>Boolean</DataType>
            </OpcUaNode>
            <OpcUaNode>
                <ServerTimeStamp/>
                <NodeID>ns=2;s=Atomiton.OilAndGas.Test.Device1.TankData.Test.Tank2.Tank_2_RAW_Level_Inches</NodeID>
                <NodeValue>34.6</NodeValue>
                <StatusCode>GOOD</StatusCode>
                <SourceTimeStamp>03/07/17 19:53:39.8876995 GMT</SourceTimeStamp>
                <DataType>Double</DataType>
            </OpcUaNode>
            <OpcUaNode>
                <ServerTimeStamp/>
                <NodeID>ns=2;s=Atomiton.OilAndGas.Test.Device1.TankData.Test.Tank2.Tank_2_steaming_in_auto_selected_HMI</NodeID>
                <NodeValue>false</NodeValue>
                <StatusCode>GOOD</StatusCode>
                <SourceTimeStamp>03/07/17 19:53:39.8876995 GMT</SourceTimeStamp>
                <DataType>Boolean</DataType>
            </OpcUaNode>
            <OpcUaNode>
                <ServerTimeStamp/>
                <NodeID>ns=2;s=Atomiton.OilAndGas.Test.Device1.TankData.Test.Tank2.Tank_2_unld_PP_Motor_Running_Bit</NodeID>
                <NodeValue>false</NodeValue>
                <StatusCode>GOOD</StatusCode>
                <SourceTimeStamp>03/07/17 19:53:39.8876995 GMT</SourceTimeStamp>
                <DataType>Boolean</DataType>
            </OpcUaNode>
        </OpcUaNodes>
    </Known>
</SubscriptionData>

          

  • No labels