...
OPCUA Protocol Handler Flow:
OPCUA Protocol Handler Installation:
OPCUA Setup Instructions
- Unzip the downloaded zip file
- 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:
The table below lists all the parameters of opcua protocol handler and their description
...
Opcua Write:
Code Block language xml title Opcua Write Facet linenumbers true <ThingFacet Name="OPCWriteFacet"> <String KnownBy="OPCWriteAction" Name="OpcData"/> <String Name="NodeID"/> <Integer<String Name="AttribueIDOperation"/> <ConnectionConfig<Integer Name="OPCSubscribeConnectionConfigAttribueID"/> <Action<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:%]& SecurityMode=[%:Event.Argument.OPCSubscribeConnectionConfig.SecurityMode.Value:%]& UserName=[%:Event.Argument.OPCSubscribeConnectionConfig.SecurityOptions.UserName.Value:%]& Password=[%:Event.Argument.OPCSubscribeConnectionConfig.SecurityOptions.Password.Value:%]& Path=[%:Event.Argument.OPCSubscribeConnectionConfig.SecurityOptions.CertificationParameters.Path.Value:%]& ValidityInDay=[%:Event.Argument.OPCSubscribeConnectionConfig.SecurityOptions.CertificationParameters.ValidityInDay.Value:%]& AutoCertificateRenewal= [%:Event.Argument.OPCSubscribeConnectionConfig.SecurityOptions.CertificationParameters.AutoCertificateRenewal.Value:%]& PrivateKeyPwd=[%:Event.Argument.OPCSubscribeConnectionConfig.SecurityOptions.CertificationParameters.PrivateKeyPwd.Value:%]& OrgName=[%:Event.Argument.OPCSubscribeConnectionConfig.SecurityOptions.CertificationParameters.OrgName.Value:%]& KeySize=[%:Event.Argument.OPCSubscribeConnectionConfig.SecurityOptions.CertificationParameters.KeySize.Value:%]& AppUri=[%:Event.Argument.OPCSubscribeConnectionConfig.SecurityOptions.ApplicationIdentity.AppUri.Value:%]& AppName=[%:Event.Argument.OPCSubscribeConnectionConfig.SecurityOptions.ApplicationIdentity.AppName.Value:%]& ProductUri=[%:Event.Argument.OPCSubscribeConnectionConfig.SecurityOptions.ApplicationIdentity.ProductUri.Value:%]& 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>
Code Block language xml title write Initialization Query linenumbers true <Query> <DeleteAll> <OPCWriteModel> <writeId ne=""/> </OPCWriteModel> </DeleteAll>OPCWriteModel> <Create> </DeleteAll> <OPCWriteModel> <Create> <Operation> <OPCWriteModel> write </Operation> <Operation> <NodeID> Atomiton.OilAndGas.Test.Device1.TankData.Test.Tank1.Tank_1_FCU_Temperature </NodeID> <AttributeID>write $Null() </Operation> </AttributeID> <OPCSubscribeConnectionConfig> <NodeID> <ServerUri> opc.tcp://MSEDGEWIN10:49320ns=2;s=Atomiton.Device1.TankData.USSAV1S01HST.Tank1.Tank_1_FCU_Temperature </ServerUri>NodeID> <SecurityMode> <AttributeID> 2 </SecurityMode> $Null() <SecurityOptions> </AttributeID> <UserName/> <OPCSubscribeConnectionConfig> <Password/> <ApplicationIdentity> <ServerUri> <AppName> opc.tcp://MSEDGEWIN10:49320 atomitonClient@localhost </AppName>ServerUri> <AppUri> <SecurityMode> urn:localhost:OPCUATQL 0 </AppUri> <ProductUri> </SecurityMode> urn:atomiton.com:OPCUA <SecurityOptions> </ProductUri> <<UserName/ApplicationIdentity>> <CertificationParameters> <Password/> <OrgName> <ApplicationIdentity> atomiton </OrgName> <AppName> <Path> /atomiton/certs atomitonClient@localhost </Path> <PrivateKeyPwd> </AppName> tql123# </PrivateKeyPwd> <AppUri> <ValidityInDay> 3650 urn:localhost:OPCUATQL </ValidityInDay> <AutoCertificateRenewal> </AppUri> true <ProductUri> </AutoCertificateRenewal> <KeySize> urn:atomiton.com:OPCUA 2048 </KeySize> </CertificationParameters>ProductUri> </SecurityOptions> </OPCSubscribeConnectionConfig>ApplicationIdentity> <OpcData> 50 <CertificationParameters> </OpcData> </OPCWriteModel> </Create> </Query>
Code Block language xml title Write Update query linenumbers true <Query> <Find format="version,known"> <OPCWriteModel> <OrgName> <writeId ne=""/> </OPCWriteModel> </Find> <if condition="$Response.Message.Value/Find/Status eq 'Success'"> <then> atomiton <SetResponseData> <key> Message.Value.Find.Result.OPCWriteModel.OpcData.Value </OrgName> </key> <value> 200<Path> </value> </SetResponseData> <Update> /atomiton/certs <from> Result </from>Path> <Include> $Response.Message.Value.Find <PrivateKeyPwd> </Include> </Update> </then> </if> </Query>
Opcua Subscription:
Code Block language xml title Opcua Subscription Facet linenumbers true <Def Name="CertificationParams"> <String Name="OrgName"/>tql123# <String Name="Path"/> <String Name="PrivateKeyPwd"/> <String Name="ValidityInDay"/></PrivateKeyPwd> <String Name="AutoCertificateRenewal"/> <Integer Name="KeySize"/> </Def> <ValidityInDay> <Def Name="AppIdentity"> <String Name="AppName"/> <String Name="AppUri"/> <String Name="ProductUri"/> 3650 </Def> <Def Name="SecurityConfig"> <String Name="UserName"/> <String Name="Password"/></ValidityInDay> <AppIdentity Name="ApplicationIdentity"/> <CertificationParams Name="CertificationParameters"/> <AutoCertificateRenewal> </Def> <Def Name="ConnectionConfig"> <String Name="ServerUri"/> <Integer Name="SecurityMode"/> true <SecurityConfig Name="SecurityOptions"/> </Def> <Def Name="OPCUaSubscribe"> <String Name="NodeID" Cardinality="0..m"/> <String Name="AttributeID"/></AutoCertificateRenewal> <String Name="SubscribeChild"/> <String Name="PublishingInterval"/> <KeySize> <String Name="NotificationBufferSize"/> </Def> <ThingFacet Name="OPCSubscriberFacet"> <String Format="$ObjectFormat(xml)" KnownBy="OPCSubscriberAction" Name="SubscriptionData" update="auto"/> <String Name="Operation"/> <ConnectionConfig Name="OPCSubscribeConnectionConfig"/> 2048 <OPCUaSubscribe Name="OPCSubscriptionConfig"/> <Action Name="OPCSubscriberAction"> <Workflow Limit="1" Live="1" Timeout="-1"> <Task name="Main" while="true"> </KeySize> <Event as="ActionArgument" name="Argument"/> <Invoke name="InvokeOPCSubscription" post="opcua://?ServerUri=[%:Event.Argument.OPCSubscribeConnectionConfig.ServerUri.Value:%]& </CertificationParameters> </SecurityOptions> SecurityMode=[%:Event.Argument.OPCSubscribeConnectionConfig.SecurityMode.Value:%]& </OPCSubscribeConnectionConfig> <OpcData> UserName=[%:Event.Argument.OPCSubscribeConnectionConfig.SecurityOptions.UserName.Value:%]& Password=[%:Event.Argument.OPCSubscribeConnectionConfig.SecurityOptions.Password.Value:%]& Path=[%:Event.Argument.OPCSubscribeConnectionConfig.SecurityOptions.CertificationParameters.Path.Value:%]& 80 ValidityInDay=[%:Event.Argument.OPCSubscribeConnectionConfig.SecurityOptions.CertificationParameters.ValidityInDay.Value:%]& AutoCertificateRenewal= [%:Event.Argument.OPCSubscribeConnectionConfig.SecurityOptions.CertificationParameters.AutoCertificateRenewal.Value:%]& </OpcData> </OPCWriteModel> PrivateKeyPwd=[%:Event.Argument.OPCSubscribeConnectionConfig.SecurityOptions.CertificationParameters.PrivateKeyPwd.Value:%]& OrgName=[%:Event.Argument.OPCSubscribeConnectionConfig.SecurityOptions.CertificationParameters.OrgName.Value:%]& </Create> </Query>
Code Block language xml title Write Update query linenumbers true <Query> <Find format="version,known"> <OPCWriteModel> <writeId ne=""/> </OPCWriteModel> </Find> <if KeySize=[%:Event.Argument.OPCSubscribeConnectionConfig.SecurityOptions.CertificationParameters.KeySize.Value:%]& condition="$Response.Message.Value/Find/Status eq 'Success'"> <then> <SetResponseData> <key> AppUri=[%:Event.Argument.OPCSubscribeConnectionConfig.SecurityOptions.ApplicationIdentity.AppUri.Value:%]&Message.Value.Find.Result.OPCWriteModel.OpcData.Value </key> <value> 200 AppName=[%:Event.Argument.OPCSubscribeConnectionConfig.SecurityOptions.ApplicationIdentity.AppName.Value:%]& ProductUri=[%:Event.Argument.OPCSubscribeConnectionConfig.SecurityOptions.ApplicationIdentity.ProductUri.Value:%]& </value> </SetResponseData> <Update> Operation=[%:Event.Argument.Operation.Value:%]" scope="process" waitFor="Argument"> <from> <Message> Result </from> <Value> <Include> <OPCSubscriptionConfig> $Response.Message.Value.Find </Include> [:Event.Argument.OPCSubscriptionConfig:]</Update> </then> </OPCSubscriptionConfig> </if> </Query>
Opcua Subscription:
Code Block language xml title Opcua Subscription Facet linenumbers true <Def Name="CertificationParams"> <String Name="OrgName"/> </Value> <String Name="Path"/> </Message><String Name="PrivateKeyPwd"/> </Invoke><String Name="ValidityInDay"/> <String Name="AutoCertificateRenewal"/> <Output As="ActionResult"<Integer Name="ResultKeySize"/> </Def> <Value><Def Name="AppIdentity"> <String Name="AppName"/> <SubscriptionData> <String Name="AppUri"/> <String Name="ProductUri"/> <Include> </Def> <Def Name="SecurityConfig"> Invoke.InvokeOPCSubscription.Message.Value<String Name="UserName"/> <String Name="Password"/> </Include><AppIdentity Name="ApplicationIdentity"/> <CertificationParams Name="CertificationParameters"/> </SubscriptionData>Def> <Def Name="ConnectionConfig"> </Value><String Name="ServerUri"/> <Integer Name="SecurityMode"/> </Output> </Task><SecurityConfig Name="SecurityOptions"/> </Workflow> Def> </Action> </ThingFacet>
Code Block language xml title Subscription Initialization Query linenumbers true <Query> <DeleteAll><Def Name="OPCUaSubscribe"> <String Name="NodeID" Cardinality="0..m"/> <OPCSubscriberModel> <subscribeId ne<String Name="AttributeID"/> </OPCSubscriberModel> </DeleteAll> <String Name="SubscribeChild"/> <Create> <OPCSubscriberModel> <String Name="PublishingInterval"/> <Operation> <String Name="NotificationBufferSize"/> </Def> subscription <ThingFacet Name="OPCSubscriberFacet"> <String </Operation> Format="$ObjectFormat(xml)" KnownBy="OPCSubscriberAction" Name="SubscriptionData" update="auto"/> <String Name="Operation"/> <OPCSubscribeConnectionConfig> <ConnectionConfig Name="OPCSubscribeConnectionConfig"/> <OPCUaSubscribe Name="OPCSubscriptionConfig"/> <ServerUri> <Action Name="OPCSubscriberAction"> <Workflow Limit="1" Live="1" opc.tcp://MSEDGEWIN10:49320Timeout="-1"> <Task name="Main" </ServerUri>while="true"> <SecurityMode> <Event as="ActionArgument" name="Argument"/> 2 </SecurityMode> <Invoke name="InvokeOPCSubscription" post="opcua://?ServerUri=[%:Event.Argument.OPCSubscribeConnectionConfig.ServerUri.Value:%]& <SecurityOptions> <UserName/> SecurityMode=[%:Event.Argument.OPCSubscribeConnectionConfig.SecurityMode.Value:%]& <Password/> <ApplicationIdentity> UserName=[%:Event.Argument.OPCSubscribeConnectionConfig.SecurityOptions.UserName.Value:%]& Password=[%:Event.Argument.OPCSubscribeConnectionConfig.SecurityOptions.Password.Value:%]& Path=[%:Event.Argument.OPCSubscribeConnectionConfig.SecurityOptions.CertificationParameters.Path.Value:%]& <AppName> ValidityInDay=[%:Event.Argument.OPCSubscribeConnectionConfig.SecurityOptions.CertificationParameters.ValidityInDay.Value:%]& AutoCertificateRenewal= [%:Event.Argument.OPCSubscribeConnectionConfig.SecurityOptions.CertificationParameters.AutoCertificateRenewal.Value:%]& atomitonClient@localhost PrivateKeyPwd=[%:Event.Argument.OPCSubscribeConnectionConfig.SecurityOptions.CertificationParameters.PrivateKeyPwd.Value:%]& </AppName> OrgName=[%:Event.Argument.OPCSubscribeConnectionConfig.SecurityOptions.CertificationParameters.OrgName.Value:%]& <AppUri> urn:localhost:OPCUATQL KeySize=[%:Event.Argument.OPCSubscribeConnectionConfig.SecurityOptions.CertificationParameters.KeySize.Value:%]& </AppUri> <ProductUri>AppUri=[%:Event.Argument.OPCSubscribeConnectionConfig.SecurityOptions.ApplicationIdentity.AppUri.Value:%]& urn:atomiton.com:OPCUA AppName=[%:Event.Argument.OPCSubscribeConnectionConfig.SecurityOptions.ApplicationIdentity.AppName.Value:%]& </ProductUri> ProductUri=[%:Event.Argument.OPCSubscribeConnectionConfig.SecurityOptions.ApplicationIdentity.ProductUri.Value:%]& </ApplicationIdentity> <CertificationParameters> Operation=[%:Event.Argument.Operation.Value:%]" scope="process" waitFor="Argument"> <OrgName><Message> <Value> atomiton </OrgName> <OPCSubscriptionConfig> <Path>/atomiton/certs</Path> [:Event.Argument.OPCSubscriptionConfig:] <PrivateKeyPwd> </OPCSubscriptionConfig> tql123# </PrivateKeyPwd>Value> </Message> <ValidityInDay> </Invoke> 3650 <Output As="ActionResult" Name="Result"> </ValidityInDay> <Value> <AutoCertificateRenewal> <SubscriptionData> true <Include> </AutoCertificateRenewal> <KeySize> Invoke.InvokeOPCSubscription.Message.Value 2048 </Include> </KeySize>SubscriptionData> </CertificationParameters>Value> </SecurityOptions> </OPCSubscribeConnectionConfig>Output> <OPCSubscriptionConfig> </Task> </Workflow> <NodeID> </Action> </ThingFacet>
Code Block language xml title Subscription Initialization Query linenumbers true <Query> <DeleteAll> ns=2;s=Vopak.Device1.TankData.USSAV1S01HST.Tank1<OPCSubscriberModel> <subscribeId </NodeID>ne=""/> </OPCSubscriberModel> </DeleteAll> <NodeID> <Create> <OPCSubscriberModel> ns=2;s=Vopak.Device1.TankData.USSAV1S01HST.Tank2 <Operation> </NodeID> subscription <AttributeID</>Operation> <OPCSubscribeConnectionConfig> <PublishingInterval>1000</PublishingInterval> <ServerUri> <NotificationBufferSize>5000</NotificationBufferSize> <SubscribeChild>opc.tcp://MSEDGEWIN10:49320 </ServerUri> <SecurityMode> true 2 </SubscribeChild> </OPCSubscriptionConfig>SecurityMode> <SecurityOptions> <SubscriptionData>$Null()</SubscriptionData> <SubscriptionPayload>$Null()</SubscriptionPayload><UserName/> <<Password/OPCSubscriberModel>> </Create> </Query>
Code Block language xml title Subscription Deletion Query linenumbers true <Query> <DeleteAll> <ApplicationIdentity> <OPCSubscriberModel> <subscribeId ne=""/> <AppName> </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 language xml title Multiple topics subscription linenumbers true <NodeID> atomitonClient@localhost ns=2;s=Atomiton.OilAndGas.Test.Device1.TankData.Test.Tank1 </NodeID>AppName> <NodeID> <AppUri> 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.
...
language | xml |
---|---|
title | Xml Output Format |
linenumbers | true |
...
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 language xml title Subscription Deletion Query linenumbers true <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 language xml title Multiple topics subscription linenumbers true <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 | ||||||
---|---|---|---|---|---|---|
| ||||||
<SubscriptionData Value="" Version="1"> <Known> <ServerTimeStamp/> <OpcUaNodes> <OpcUaNode> <NodeID>ns=2;s <ServerTimeStamp/> <NodeID>ns=2;s=Atomiton.OilAndGas.Test.Device1.TankData.Test.Tank1.Tank_1_Agitator_RAWMotor_LevelRunning_Inches<Bit</NodeID> <NodeValue>500.0<<NodeValue>false</NodeValue> <StatusCode>GOOD</StatusCode> <SourceTimeStamp>03/07/17 19:53:39.8876995 GMT</SourceTimeStamp> <DataType>Double<<DataType>Boolean</DataType> </OpcUaNode> <OpcUaNode> <ServerTimeStamp/> <NodeID>ns=2;s=Atomiton.OilAndGas.Test.Device1.TankData.Test.Tank1.Tank_1_steaming_in_auto_selected_HMI<FCU_Temperature</NodeID> <NodeValue>false<<NodeValue>999.0</NodeValue> <StatusCode>GOOD</StatusCode> <SourceTimeStamp>03/07/17 19:53:39.8876995 GMT</SourceTimeStamp> <DataType>Boolean<<DataType>Float</DataType> </OpcUaNode> <OpcUaNode> <ServerTimeStamp/> <NodeID>ns=2;s=Atomiton.OilAndGas.Test.Device1.TankData.Test.Tank1.Tank_1_unld_PP_Motor_Running_Bit<Gallon_Value</NodeID> <NodeValue>false<<NodeValue>1.34547004E15</NodeValue> <StatusCode>GOOD</StatusCode> <SourceTimeStamp>03/07/17 19:53:39.8876995 GMT</SourceTimeStamp> <DataType>Boolean<<DataType>Double</DataType> </OpcUaNode> <OpcUaNode> <ServerTimeStamp/> <NodeID>ns=2;s=Atomiton.OilAndGas.Test.Device1.TankData.Test.Tank2Tank1.Tank_1_2Loading_AgitatorPP_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.Tank2Tank1.Tank_21_RAW_FCULevel_Temperature<Inches</NodeID> <NodeValue>56<NodeValue>500.0</NodeValue> <StatusCode>GOOD</StatusCode> <SourceTimeStamp>03/07/17 19:53:39.8876995 GMT</SourceTimeStamp> <DataType>Float<<DataType>Double</DataType> </OpcUaNode> <OpcUaNode> <ServerTimeStamp/> <NodeID>ns=2;s=Atomiton.OilAndGas.Test.Device1.TankData.Test.Tank2Tank1.Tank_2_Gallon_Value<_1_steaming_in_auto_selected_HMI</NodeID> <NodeValue>1.34547004E15<<NodeValue>false</NodeValue> <StatusCode>GOOD</StatusCode> <SourceTimeStamp>03/07/17 19:53:39.8876995 GMT</SourceTimeStamp> <DataType>Double<<DataType>Boolean</DataType> </OpcUaNode> <OpcUaNode> <ServerTimeStamp/> <NodeID>ns=2;s=Atomiton.OilAndGas.Test.Device1.TankData.Test.Tank2Tank1.Tank_21_Loadingunld_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_RAWMotor_LevelRunning_Inches<Bit</NodeID> <NodeValue>34.6<<NodeValue>false</NodeValue> <StatusCode>GOOD</StatusCode> <SourceTimeStamp>03/07/17 19:53:39.8876995 GMT</SourceTimeStamp> <DataType>Double<<DataType>Boolean</DataType> </OpcUaNode> <OpcUaNode> <ServerTimeStamp/> <NodeID>ns=2;s=Atomiton.OilAndGas.Test.Device1.TankData.Test.Tank2.Tank_2_steaming_in_auto_selected_HMI<FCU_Temperature</NodeID> <NodeValue>false<<NodeValue>56.0</NodeValue> <StatusCode>GOOD</StatusCode> <SourceTimeStamp>03/07/17 19:53:39.8876995 GMT</SourceTimeStamp> <DataType>Boolean<<DataType>Float</DataType> </OpcUaNode> <OpcUaNode> <ServerTimeStamp/> <NodeID>ns=2;s=Atomiton.OilAndGas.Test.Device1.TankData.Test.Tank2.Tank_2_unld_PP_Motor_Running_Bit<Gallon_Value</NodeID> <NodeValue>false<<NodeValue>1.34547004E15</NodeValue> <StatusCode>GOOD</StatusCode> <SourceTimeStamp>03/07/17 19:53:39.8876995 GMT</SourceTimeStamp> <DataType>Boolean<<DataType>Double</DataType> </OpcUaNode> <OpcUaNode> </OpcUaNodes> </Known> </SubscriptionData> <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.
- Note down the security mode used by the Kepserver, this is one of the important query parameter.
- 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 | ||
---|---|---|
| ||
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.
- Copy these certificates on to the machine that is running the Kepserver, and import these certificates in Trusted Clients tab of configuration manager.
- Go to the Run time tab of Kepserver and then reinitialize the server for the new settings to take place.
- Restart the subscription in AStack and it should start working this time.
Troubleshooting:
- 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.