Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

OPCUA Protocol Handler Installation: Download the protocol handlers zip file from the link below

http://sandbox.atomiton.com:8080/fid-downloads/res/downloads/protocolhandlers.zip

once downloaded unzip it.  After you unzip it go to protocolhandlers/Opcua directory and copy


Date
Download Location
Version
4/11/2018Download1.1.1
7/17/2020Download2.0.0


OPCUA Setup Instructions

  1. Unzip the downloaded zip file
  2. Copy the sff.bundle.ext.opc.jar from this location to the sff.auto.launch folder which is present in your A-Stack Prime folder.


OPCUA Protocol Parameters:

...

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.

Usage of opcua protocol handler:

Opcua Write:

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:

    Code Block
    languagexml
    titleOpcua Write Facet
    linenumberstrue
      <ThingFacet Name="OPCWriteFacet">
        <String NameKnownBy="OpcDataOPCWriteAction" KnownByName="OPCSubscriberActionOpcData"/>
    
       <String Name="NodeID"/>
        <Integer<String Name="AttributeIDOperation"/>
        <String<Integer Name="OperationAttribueID"/>
        <ConnectionConfig Name="OPCWriteConnectionConfigOPCSubscribeConnectionConfig"/>
    
       <Action Name="OPCSubscriberActionOPCWriteAction">
     
        <Workflow Limit="1" Live="1" Timeout="-1">
    
           <Task name="Main" >
              <Event as="ActionArgument" name="Argument"/>
     
            <Invoke getname="opcua://InvokeOPCWrite" waitForpost="Argument" name="InvokeOPCWrite" Operation="[%:Event.Argument.Operation.Value:%]" 
                ServerUri="opcua://?ServerUri=[%:Event.Argument.OPCWriteConnectionConfigOPCSubscribeConnectionConfig.ServerUri.Value:%]" 
                SecurityMode="&amp;
    			SecurityMode=[%:Event.Argument.OPCWriteConnectionConfigOPCSubscribeConnectionConfig.SecurityMode.Value:%]" 
                UserName="&amp;
    			UserName=[%:Event.Argument.OPCWriteConnectionConfigOPCSubscribeConnectionConfig.SecurityOptions.UserName.Value:%]"
                Password="&amp;
    			Password=[%:Event.Argument.OPCWriteConnectionConfigOPCSubscribeConnectionConfig.SecurityOptions.Password.Value:%]"
                Path="&amp;
    			Path=[%:Event.Argument.OPCWriteConnectionConfigOPCSubscribeConnectionConfig.SecurityOptions.CertificationParameters.Path.Value:%]"
                ValidityInDay="&amp;
    			ValidityInDay=[%:Event.Argument.OPCWriteConnectionConfigOPCSubscribeConnectionConfig.SecurityOptions.CertificationParameters.ValidityInDay.Value:%]"
                AutoCertificateRenewal="&amp;
    			AutoCertificateRenewal=
    			[%:Event.Argument.OPCWriteConnectionConfigOPCSubscribeConnectionConfig.SecurityOptions.CertificationParameters.AutoCertificateRenewal.Value:%]"&amp;
                	PrivateKeyPwd="[%:Event.Argument.OPCWriteConnectionConfigOPCSubscribeConnectionConfig.SecurityOptions.CertificationParameters.PrivateKeyPwd.Value:%]"&amp;
                	OrgName="[%:Event.Argument.OPCWriteConnectionConfigOPCSubscribeConnectionConfig.SecurityOptions.CertificationParameters.OrgName.Value:%]"&amp;
                KeySize="[%:Event.Argument.OPCWriteConnectionConfigOPCSubscribeConnectionConfig.SecurityOptions.CertificationParameters.KeySize.Value:%]"&amp;
                AppUri="[%:Event.Argument.OPCWriteConnectionConfigOPCSubscribeConnectionConfig.SecurityOptions.ApplicationIdentity.AppUri.Value:%]"&amp; 
                AppName="[%:Event.Argument.OPCWriteConnectionConfigOPCSubscribeConnectionConfig.SecurityOptions.ApplicationIdentity.AppName.Value:%]"&amp;                             
    			ProductUri="[%:Event.Argument.OPCWriteConnectionConfigOPCSubscribeConnectionConfig.SecurityOptions.ApplicationIdentity.ProductUri.Value:%]"&amp;
                NodeIDOperation="[%:Event.Argument.NodeIDOperation.Value:%]" scope="local" waitFor="Argument">
              AttributeID="[%:Event.Argument.AttributeID.Value:%]"><Message>
                <Value>
       <Message>           <Payload>
       <Value>                 "[%:Event.Argument.opcDataOpcData.Value:%]"
                  </Value>Payload>
                  <NodeID>
                   </Message>   [%:Event.Argument.NodeID.Value:%]
           </Invoke>       </NodeID>
       <Output As="ActionResult" Name="Result">         <AttributeID>
       <Value>               <OpcData>[%:InvokeEvent.InvokeOPCWriteArgument.MessageAttributeID.Value:%]</OpcData>
                  </Value>AttributeID>
                </Output>Value>
              </Task>Message>
            </Workflow>Invoke>
           </Action> <Output  </ThingFacet>
    Code Block
    languagexml
    titlewrite Initialization Query
    linenumberstrue
    <Query>As="ActionResult" Name="Result">
      <DeleteAll>     <OPCWriteModel>   <Value>
       <writeId ne=""/>     </OPCWriteModel>   </DeleteAll><OpcData>
      <Create>     <OPCWriteModel>       <Operation>
    <Include>
    				Invoke.InvokeOPCWrite.Message.Value
           Write       </Operation>Include>
          <OPCWriteConnectionConfig>      </OpcData>
      <ServerUri>        </Value>
      opc.tcp://ServerURL:ServerPort
            </ServerUri>Output>
          </Task>
     <SecurityMode>   </Workflow>
      </Action>
    </ThingFacet>


    Code Block
    languagexml
    titlewrite Initialization Query
    linenumberstrue
     <Query>
      2  <DeleteAll>
          </SecurityMode>  <OPCWriteModel>
          <SecurityOptions>           <UserName<writeId ne=""/>
              <Password</>OPCWriteModel>
        </DeleteAll>
        <Create>
    <ApplicationIdentity>        <OPCWriteModel>
        <AppName>        <Operation>
          atomitonClient@localhost          write
      </AppName>          </Operation>
      <AppUri>          <NodeID>
        urn:localhost:OPCUATQL             </AppUri>ns=2;s=Atomiton.Device1.TankData.USSAV1S01HST.Tank1.Tank_1_FCU_Temperature
                <ProductUri></NodeID>
                <AttributeID>
     urn:atomiton.com:OPCUA             </ProductUri>  $Null()
            </ApplicationIdentity>    </AttributeID>
          <CertificationParameters>      <OPCSubscribeConnectionConfig>
          <OrgName>          <ServerUri>
        atomiton             </OrgName>   opc.tcp://MSEDGEWIN10:49320
             <Path>       </ServerUri>
           /atomiton/certs         <SecurityMode>
       </Path>             <PrivateKeyPwd>    0
              123lk#      </SecurityMode>
          </PrivateKeyPwd>          <SecurityOptions>
      <ValidityInDay>               3650   <UserName/>
             </ValidityInDay>           <Password/>
             <AutoCertificateRenewal>           <ApplicationIdentity>
        true             </AutoCertificateRenewal>       <AppName>
         <KeySize>               2048        atomitonClient@localhost
        </KeySize>           </CertificationParameters>         </SecurityOptions>AppName>
             </OPCWriteConnectionConfig>       <NodeID>         ns=2;s=Atomiton.OilAndGas.Device1.TankData.USSAV1S01HST.Tank1.Tank_1_FCU_Temperature<AppUri>
           </NodeID>       <AttributeID>         13     urn:localhost:OPCUATQL
     </AttributeID>       <OpcData>         1024       </OpcData>AppUri>
        </OPCWriteModel>   </Create> </Query>
    Code Block
    languagexml
    titleWrite Update query
    linenumberstrue
    <Query>   <Find format="version,known">     <OPCWriteModel>       <writeId ne=""/><ProductUri>
         </OPCWriteModel>   </Find>   <if condition="$Response.Message.Value/Find/Status eq 'Success'">     <then>       <SetResponseData>  urn:atomiton.com:OPCUA
          <key>           Message.Value.Find.Result.OPCWriteModel.OpcData.Value
            </key>ProductUri>
            <value>           200 </ApplicationIdentity>
           </value>       </SetResponseData>      <CertificationParameters>
    <Update>         <from>           Result    <OrgName>
            </from>         <Include>           $Response.Message.Value.Findatomiton
            </Include>       </Update>     </then>   </if> </Query>

    Opcua Subscription:

    Code Block
    languagexml
    titleOpcua Subscription Facet
    linenumberstrue
    	<Def Name="CertificationParams">OrgName>
             <String Name="OrgName"/>         <String Name="Path"/>    <Path>
        <String Name="PrivateKeyPwd"/>         <String Name="ValidityInDay"/>         <String Name="AutoCertificateRenewal"/>
        /atomiton/certs
           <Integer Name="KeySize"/>                </Def>Path>
              <Def Name="AppIdentity">         <String Name="AppName"/>   <PrivateKeyPwd>
         <String Name="AppUri"/>         <String Name="ProductUri"/>     </Def>      <Def Name="SecurityConfig"> tql123#
            <String Name="UserName"/>         <String Name="Password"/>     </PrivateKeyPwd>
       <AppIdentity Name="ApplicationIdentity"/>          <CertificationParams Name="CertificationParameters"/>           <ValidityInDay>
    </Def>          <Def Name="ConnectionConfig">         <String Name="ServerUri"/>       3650
     <Integer Name="SecurityMode"/>           <SecurityConfig Name="SecurityOptions"/>          </Def>ValidityInDay>
           <Def Name="OPCUaSubscribe">       <String Name="NodeID" Cardinality="0..m"/>       <String Name="AttributeID"/><AutoCertificateRenewal>
           <String Name="SubscribeChild"/>     </Def>        <ThingFacet Name="OPCSubscriberFacet">        true
        <String Format="$ObjectFormat(xml)" Name="SubscriptionPayload" KnownBy="OPCSubscriberAction" update="auto"/>       <String Name="Operation"/>       <ConnectionConfig Name="OPCSubscribeConnectionConfig"/></AutoCertificateRenewal>
           <OPCUaSubscribe Name="OPCSubscriptionConfig"/>       <Action Name="OPCSubscriberAction">        <KeySize>
    <Workflow Limit="1" Live="1" Timeout="-1">           <Task name="Main" while="true">             2048
      <Event as="ActionArgument" name="Argument"/>             <Invoke AppName="[%:Event.Argument.OPCSubscribeConnectionConfig.SecurityOptions.ApplicationIdentity.AppName.Value:%]"  AppUri="[%:Event.Argument.OPCSubscribeConnectionConfig.SecurityOptions.ApplicationIdentity.AppUri.Value:%]"  AutoCertificateRenewal="[%:Event.Argument.OPCSubscribeConnectionConfig.SecurityOptions.CertificationParameters.AutoCertificateRenewal.Value:%]" 
    KeySize="[%:Event.Argument.OPCSubscribeConnectionConfig.SecurityOptions.CertificationParameters.KeySize.Value:%]" 
    OPCSubscriptionConfig="[%:Event.Argument.OPCSubscriptionConfig:%]" 
    Operation="[%:Event.Argument.Operation.Value:%]" 
    OrgName="[%:Event.Argument.OPCSubscribeConnectionConfig.SecurityOptions.CertificationParameters.OrgName.Value:%]" 
    Password="[%:Event.Argument.OPCSubscribeConnectionConfig.SecurityOptions.Password.Value:%]" 
    Path="[%:Event.Argument.OPCSubscribeConnectionConfig.SecurityOptions.CertificationParameters.Path.Value:%]" 
    PrivateKeyPwd="[%:Event.Argument.OPCSubscribeConnectionConfig.SecurityOptions.CertificationParameters.PrivateKeyPwd.Value:%]" 
    ProductUri="[%:Event.Argument.OPCSubscribeConnectionConfig.SecurityOptions.ApplicationIdentity.ProductUri.Value:%]" 
    SecurityMode="[%:Event.Argument.OPCSubscribeConnectionConfig.SecurityMode.Value:%]" 
    ServerUri="[%:Event.Argument.OPCSubscribeConnectionConfig.ServerUri.Value:%]"
    UserName="[%:Event.Argument.OPCSubscribeConnectionConfig.SecurityOptions.UserName.Value:%]" 
    ValidityInDay="[%:Event.Argument.OPCSubscribeConnectionConfig.SecurityOptions.CertificationParameters.ValidityInDay.Value:%]" 
    get="opcua://Subscribe" name="InvokeOPCSubscription" scope="process" waitFor="Argument"/>  </KeySize>
                        </CertificationParameters>
                    </SecurityOptions>
                </OPCSubscribeConnectionConfig>
       <Output As="ActionResult" Name="Result">       <OpcData>
           <Value>         80
           <SubscriptionPayload>     </OpcData>
            </OPCWriteModel>
        <Include>Invoke.InvokeOPCSubscription.Message.Value</Include>
     </Create>
    </Query>
    


    Code Block
    languagexml
    titleWrite Update query
    linenumberstrue
    <Query>
      <Find format="version,known">
        <OPCWriteModel>
         </SubscriptionPayload> <writeId ne=""/>
        </OPCWriteModel>
      </Find>
      <if  </Value>condition="$Response.Message.Value/Find/Status eq 'Success'">
        <then>
          <SetResponseData>
            <key>
              Message.Value.Find.Result.OPCWriteModel.OpcData.Value
            </Output>key>
            <value>
              </Task>200
            </Workflow>value>
          </Action>SetResponseData>
          </ThingFacet>

    Note: The output is stored in the variable SubscriptionPayload although the Known By is on the variable SubscriptionData, this has been done to preserve the Xml structure and avoid TP processing. 

    Code Block
    languagexml
    titleSubscription Initialization Query
    linenumberstrue
    <Query>
      <DeleteAll>
    <Update>
            <from>
       <OPCSubscriberModel>       <subscribeId ne=""/>Result
         </OPCSubscriberModel>   </DeleteAll>from>
      <Create>     <OPCSubscriberModel> <Include>
         <Operation>     $Response.Message.Value.Find
       subscription       </Operation>Include>
          <OPCSubscribeConnectionConfig></Update>
        </then>
       <ServerUri>
    </if>
    </Query>


  • Opcua Subscription:

    Code Block
    languagexml
    titleOpcua Subscription Facet
    linenumberstrue
    	<Def Name="CertificationParams">
             opc.tcp://MSEDGEWIN10:49320<String Name="OrgName"/>
            </ServerUri><String Name="Path"/>
          <String Name="PrivateKeyPwd"/>
    <SecurityMode>      <String Name="ValidityInDay"/>
       2         </SecurityMode><String Name="AutoCertificateRenewal"/>
          <Integer Name="KeySize"/>
    <SecurityOptions>    </Def>
          <UserName/<Def Name="AppIdentity">
              <Password<String Name="AppName"/>
          <String Name="AppUri"/>
      <ApplicationIdentity>    <String Name="ProductUri"/>
        </Def>
      <AppName>  <Def Name="SecurityConfig">
          <String Name="UserName"/>
       atomitonClient@localhost   <String Name="Password"/>
            </AppName><AppIdentity Name="ApplicationIdentity"/>
          <CertificationParams Name="CertificationParameters"/>
        <AppUri></Def>
        <Def Name="ConnectionConfig">
          <String  urn:localhost:OPCUATQLName="ServerUri"/>
          <Integer Name="SecurityMode"/>
         </AppUri> <SecurityConfig Name="SecurityOptions"/>
        </Def>
    	<Def Name="OPCUaSubscribe">
    		<String Name="NodeID"  <ProductUri>Cardinality="0..m"/>
            <String Name="AttributeID"/>
         urn:atomiton.com:OPCUA   <String Name="SubscribeChild"/>
            </ProductUri><String Name="PublishingInterval"/>
            <String Name="NotificationBufferSize"/>
    	</ApplicationIdentity>Def>
    
    	<ThingFacet Name="OPCSubscriberFacet">
      		<String Format="$ObjectFormat(xml)" KnownBy="OPCSubscriberAction" Name="SubscriptionData" update="auto"/>
    <CertificationParameters>  		<String Name="Operation"/>
      		<ConnectionConfig Name="OPCSubscribeConnectionConfig"/>
      		<OPCUaSubscribe Name="OPCSubscriptionConfig"/>
     <OrgName>    		<Action Name="OPCSubscriberAction">
        	<Workflow Limit="1" Live="1" Timeout="-1">
      atomiton    		<Task name="Main" while="true">
          </OrgName>  		<Event           <Path>/atomiton/certs</Path>as="ActionArgument" name="Argument"/>
            			<Invoke    <PrivateKeyPwd>
        name="InvokeOPCSubscription" post="opcua://?ServerUri=[%:Event.Argument.OPCSubscribeConnectionConfig.ServerUri.Value:%]&amp;
             tql123#             </PrivateKeyPwd>SecurityMode=[%:Event.Argument.OPCSubscribeConnectionConfig.SecurityMode.Value:%]&amp;
                 <ValidityInDay>        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;
      3650      			 ValidityInDay=[%:Event.Argument.OPCSubscribeConnectionConfig.SecurityOptions.CertificationParameters.ValidityInDay.Value:%]&amp;
    					 AutoCertificateRenewal=	 
      </ValidityInDay>						[%:Event.Argument.OPCSubscribeConnectionConfig.SecurityOptions.CertificationParameters.AutoCertificateRenewal.Value:%]&amp;
            			 PrivateKeyPwd=[%:Event.Argument.OPCSubscribeConnectionConfig.SecurityOptions.CertificationParameters.PrivateKeyPwd.Value:%]&amp;
        <AutoCertificateRenewal>    			 OrgName=[%:Event.Argument.OPCSubscribeConnectionConfig.SecurityOptions.CertificationParameters.OrgName.Value:%]&amp;
             true             </AutoCertificateRenewal>KeySize=[%:Event.Argument.OPCSubscribeConnectionConfig.SecurityOptions.CertificationParameters.KeySize.Value:%]&amp;
                 <KeySize>               2048AppUri=[%:Event.Argument.OPCSubscribeConnectionConfig.SecurityOptions.ApplicationIdentity.AppUri.Value:%]&amp;
                  </KeySize>       AppName=[%:Event.Argument.OPCSubscribeConnectionConfig.SecurityOptions.ApplicationIdentity.AppName.Value:%]&amp;
    					   </CertificationParameters>ProductUri=[%:Event.Argument.OPCSubscribeConnectionConfig.SecurityOptions.ApplicationIdentity.ProductUri.Value:%]&amp;
              </SecurityOptions>       </OPCSubscribeConnectionConfig>       <OPCSubscriptionConfig>
      Operation=[%:Event.Argument.Operation.Value:%]" scope="process" waitFor="Argument">
         <NodeID>     			 <Message>
        ns=2;s=Atomiton.OilAndGas.Test.Device1.TankData.Test.Tank1         </NodeID>			<Value>
             <AttributeID/>     				<OPCSubscriptionConfig>
       <SubscribeChild>           true    				[:Event.Argument.OPCSubscriptionConfig:]
           </SubscribeChild>       				</OPCSubscriptionConfig>
          <SubscriptionPayload>$Null()</SubscriptionPayload>     </OPCSubscriberModel> 		  	</Create>
    </Query>
    Code Block
    languagexml
    titleSubscription Deletion Query
    linenumberstrue
    <Query>
      <DeleteAll>Value>
              			</Message>
            		   </Invoke>
         <OPCSubscriberModel>   		   <Output <subscribeId neAs="ActionResult" Name="Result"/>
           </OPCSubscriberModel>   			<Value>
       </DeleteAll> </Query>

    Note: It is possible to subscribe to multiple root nodes using a single facet, separate the NodeID's with ;; delimiter in subscription initialization query as shown below

    Code Block
    languagexml
    titleMultiple topics subscription
    linenumberstrue
    		 <NodeID>       			<SubscriptionData>
       ns=2;s=Atomiton.OilAndGas.Test.Device1.TankData.Test.Tank1;;ns=2;s=Atomiton.OilAndGas.Test.Device1.TankData.Test.Tank1           </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.

...

languagexml
titleXml Output Format
linenumberstrue

...

  • 				<Include>
                

...

  •       				Invoke.InvokeOPCSubscription.Message.Value
        

...

  •           				</Include>
      

...

  •           			</SubscriptionData>
        

...

  •       			</Value>
            

...

  • 		   </Output>
          		</Task>
        	</Workflow>
     

...

  • 	 </Action>
    	</ThingFacet>


    Code Block
    languagexml
    titleSubscription Initialization Query
    linenumberstrue
    <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=Atomiton.OilAndGas.Test.Device1.TankData.

...

  • Test.Tank1

...

  • 
            </NodeID>
          

...

  •   <NodeID>
              	ns=2;s=Atomiton.OilAndGas.Test.Device1.TankData.Test.Tank2
     

...

  •        </NodeID>
           

...

  •  <AttributeID/>
            <PublishingInterval>1000</PublishingInterval>
            

...

  • <NotificationBufferSize>5000</

...

  • NotificationBufferSize>
            <SubscribeChild>
       

...

  •        true
         

...

  •    </SubscribeChild>
          </OPCSubscriptionConfig>
        

...

  •   <SubscriptionData>$Null()</SubscriptionData>
          <SubscriptionPayload>$Null()</SubscriptionPayload>
        

...

  • </OPCSubscriberModel>
      </Create>
    </Query>
    


    Code Block
    languagexml
    titleSubscription Deletion Query
    linenumberstrue
    <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

    Code Block
    languagexml
    titleMultiple topics subscription
    linenumberstrue
    		 <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.


Code Block
languagexml
titleXml Output Format
linenumberstrue
  <SubscriptionData Value="" Version="1">
    <Known>
        <OpcUaNodes>
 <OpcUaNodes>           <OpcUaNode>
 <OpcUaNode>               <ServerTimeStamp/>
                <NodeID>ns=2;s=Atomiton.OilAndGas.Test.Device1.TankData.USSAV1S01HSTTest.Tank1.Tank_1_Agitator_Motor_Running_Bit</NodeID>
                <NodeValue>false</NodeValue>
                <StatusCode>GOOD</StatusCode>
                <SourceTimeStamp>08<SourceTimeStamp>03/1007/1617 0019:3853:2739.08239508876995 GMT</SourceTimeStamp>
                <DataType>Boolean</DataType>
            </OpcUaNode>
            <OpcUaNode>
                <ServerTimeStamp/>
                <NodeID>ns=2;s=Atomiton.OilAndGas.Test.Device1.TankData.USSAV1S01HSTTest.Tank1.Tank_1_FCU_Temperature</NodeID>
                <NodeValue>201<NodeValue>999.0</NodeValue>
                <StatusCode>GOOD</StatusCode>
                <SourceTimeStamp>08<SourceTimeStamp>03/1007/1617 0019:3853:2739.08239508876995 GMT</SourceTimeStamp>
                <DataType>Float</DataType>
            </OpcUaNode>
            <OpcUaNode>
                <ServerTimeStamp/>
                <NodeID>ns=2;s=Atomiton.OilAndGas.Test.Device1.TankData.USSAV1S01HSTTest.Tank1.Tank_1_Gallon_Value</NodeID>
                <NodeValue>1.34646997E15<34547004E15</NodeValue>
                <StatusCode>GOOD</StatusCode>
                <SourceTimeStamp>08<SourceTimeStamp>03/1007/1617 0019:3853:2739.08239508876995 GMT</SourceTimeStamp>
                <DataType>Double</DataType>
            </OpcUaNode>
            <OpcUaNode>
                <ServerTimeStamp/>
                <NodeID>ns=2;s=Atomiton.OilAndGas.Test.Device1.TankData.USSAV1S01HSTTest.Tank1.Tank_1_Loading_PP_Motor_Running_Bit</NodeID>
                <NodeValue>false</NodeValue>
                <StatusCode>GOOD</StatusCode>
              <SourceTimeStamp>08  <SourceTimeStamp>03/1007/1617 0019:3853:2739.08239508876995 GMT</SourceTimeStamp>
                <DataType>Boolean</DataType>
            </OpcUaNode>
            <OpcUaNode>
                <ServerTimeStamp/>
                <NodeID>ns=2;s=Atomiton.OilAndGas.Test.Device1.TankData.USSAV1S01HSTTest.Tank1.Tank_1_RAW_Level_Inches</NodeID>
               <NodeValue>568 <NodeValue>500.0</NodeValue>
                <StatusCode>GOOD</StatusCode>
               <SourceTimeStamp>08 <SourceTimeStamp>03/1007/1617 0019:3853:2739.08239508876995 GMT</SourceTimeStamp>
                <DataType>Double</DataType>
            </OpcUaNode>
            <OpcUaNode>
                <ServerTimeStamp/>
                <NodeID>ns=2;s=Atomiton.OilAndGas.Test.Device1.TankData.USSAV1S01HSTTest.Tank1.Tank_1_steaming_in_auto_selected_HMI</NodeID>
                <NodeValue>false</NodeValue>
                <StatusCode>GOOD</StatusCode>
                <SourceTimeStamp>08<SourceTimeStamp>03/1007/1617 0019:3853:2739.08239508876995 GMT</SourceTimeStamp>
                <DataType>Boolean</DataType>
            </OpcUaNode>
            <OpcUaNode>
                <ServerTimeStamp/>
                <NodeID>ns=2;s=Atomiton.OilAndGas.Test.Device1.TankData.USSAV1S01HSTTest.Tank1.Tank_1_unld_PP_Motor_Running_Bit</NodeID>
                <NodeValue>false</NodeValue>
                <StatusCode>GOOD</StatusCode>
              <SourceTimeStamp>08  <SourceTimeStamp>03/1007/1617 0019:3853:2739.08239508876995 GMT</SourceTimeStamp>
                <DataType>Boolean</DataType>
            </OpcUaNode>
            <OpcUaNode>
               </OpcUaNodes> <ServerTimeStamp/>
                </Known><NodeID>ns=2;s=Atomiton.OilAndGas.Test.Device1.TankData.Test.Tank2.Tank_2_Agitator_Motor_Running_Bit</NodeID>
                </SubscriptionPayload><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>



    

Kepserver certificate setup steps:

  • Open the Kepserver  Configuration Manager, by right clicking on kepserver icon in the task-bar and then clicking on OPC UA Configuration.Image Added


  • Note down the security mode used by the Kepserver, this is one of the important query parameter.


Image Added


  • When the security mode is not None, the subscription or publish will fail for the first time, with the below message, this is expected behavior as the certificates are not updated in Kepserver.


Code Block
titleOPCUA Error
Caused by: com.prosysopc.ua.client.ServerConnectionException: Server not connected: opc.tcp://MSEDGEWIN10:49320 [http://opcfoundation.org/UA/SecurityPolicy#Basic128Rsa15,SignAndEncrypt]
              at com.prosysopc.ua.client.UaClient.E(Unknown Source)
              at com.prosysopc.ua.client.AddressSpace.browse(Unknown Source)
              at com.prosysopc.ua.client.AddressSpace.browse(Unknown Source)
              at com.prosysopc.ua.client.AddressSpace.browse(Unknown Source)
              at com.atomiton.sff.imp.netty.opc.client.OPCUaClient.subscribeToAllChildNodes(OPCUaClient.java:237)
              at com.atomiton.sff.imp.netty.opc.OpcHandlerImpl.CreateSubscription(OpcHandlerImpl.java:194)
              at com.atomiton.sff.imp.netty.opc.SffOpcHandler.connect(SffOpcHandler.java:399)
              at com.atomiton.sff.imp.netty.opc.SffOpcHandler.afterAdd(SffOpcHandler.java:103)
              at org.jboss.netty.channel.DefaultChannelPipeline.callAfterAdd(DefaultChannelPipeline.java:342)
              at org.jboss.netty.channel.DefaultChannelPipeline.addLast(DefaultChannelPipeline.java:108)
              at com.atomiton.sff.imp.netty.NettyContext.addPipelineHandler(NettyContext.java:4950)
              at com.atomiton.sff.imp.netty.NettyContext.addLast(NettyContext.java:5008)
              at com.atomiton.sff.imp.netty.NettyContext.modifyPipeline(NettyContext.java:4672)
              at com.atomiton.sff.imp.netty.NettyContext.newModifiedPipeline(NettyContext.java:4793)
              at com.atomiton.sff.imp.netty.NettyContext.newInstance(NettyContext.java:4414)
              at com.atomiton.sff.imp.facet.SffWdlFacet.wdlInvokeConnect(SffWdlFacet.java:1226)
              at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
              at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
              at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
              at java.lang.reflect.Method.invoke(Method.java:498)
              at oda.concurrent.imp.MethodSignature.invoke(MethodSignature.java:446)
              at oda.concurrent.dataflow.imp.DfTask.call(DfTask.java:1352)
              at oda.concurrent.dataflow.imp.DfTask.delegate(DfTask.java:1374)
              at com.atomiton.sff.imp.facet.SffWdlFacet.wdlInvoke(SffWdlFacet.java:1103)
              at sun.reflect.GeneratedMethodAccessor11.invoke(Unknown Source)
              at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
              at java.lang.reflect.Method.invoke(Method.java:498)
              at oda.concurrent.imp.MethodSignature.invoke(MethodSignature.java:446)
              at oda.concurrent.dataflow.imp.DfTask.call(DfTask.java:1297)
              at java.util.concurrent.ForkJoinTask$AdaptedCallable.exec(ForkJoinTask.java:1424)
              at java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:289)
              at java.util.concurrent.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1056)
              at java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1692)
              at java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:157)


  • The A-stack will generate the certificate files in the path "PKI/CA/{path provided in the query}" for example when we use above query, the certificates are saved in "PKI/CA/atomiton/certs" folder.

Image Added

  • Copy these certificates on to the machine that is running the Kepserver, and import these certificates in Trusted Clients tab of configuration manager.

Image Added

  • Go to the Run time tab of Kepserver and then reinitialize the server for the new settings to take place.

Image Added

  • Restart the subscription in AStack and it should start working this time.


Troubleshooting:

  1. If we are still getting server not connected error even after certificates are imported and connectivity between the system running AStack and system running Kepserver is validated, then it might be firewall issues, try adding exceptions in firewall and test.