Creating a module for OPC XML-DA

We have an MHE vendor who without saying their name, they are a german company and the #2 world based on 2020 revenue. I think it's because they saved money by not switching to OPC-UA. OK, gripe complete.

Part of the equipment which Ignition would monitor and control has a data source which is OPC XML-DA, which seems cutting edge, first announced in 1999.

We have read this post:

For us, we're not willing to pay for kepware because we already pay for Ignition. What is coming to mind is to use the module SDK to combine the two things below:

Basically create a driver for OPC XML-DA that would use existing drivers for OPC XML-DA and make the data available inside of Ignition's normal workflow.

As a basic mandatory question before we started such investigation I'd like to ask the group if anyone has ever worked on such a thing or knows of any other existing example which is similar enough to be helpful.

Thanks,

Nick

OPC connections are an extension point, so if you were going the module SDK route you could technically build a module that adds an “OPC XML-DA” type of OPC connection.

I don’t know if you’ll have any luck finding an OPC XML-DA toolkit/SDK for Java. If you can’t find a toolkit to use I would personally consider this whole idea a nonstarter.

There’s no way this costs you less than just paying for Kepware or some other OPC gateway product, either in actual dollars paid for the toolkit, or the time you and others will spend trying to get this working.

2 Likes

The (5 year old, unmaintained) SDK you linked is just using code-generation off the WSDL provided by the OPC foundation.
Sepasoft’s web services module ($3500) includes code generation off a WSDL: SOAP Configuration - MES Platform 3.0 - Sepasoft MES Help Documentation

Might be worth evaluating. I concur with Kevin that creating your own module is definitely not going to save you money.

Ha, I don’t think I saw that 2nd GitHub link in his post. My eyes seem to automatically skip link previews.

Hmmm. Looks interesting. Maybe early 2022 if nobody tries first. Somebody ought to ping me before the holidays this year.

It looks easier than I had originally thought as long as you just need the client side. I looked at the spec and the WSDL… definitely the worst part is going to be dealing with the XML/SOAP/JAX-RS/:face_vomiting: part of the Java ecosystem. If the GitHub repo he linked to happens to “just work” that would be a lucky break.

Finding servers in the wild to develop and test against might be a bit of a challenge as well.

I generally approach this sort of project with a sponsor who has the target equipment....

He said they don't even want to pay for a Kepserver... do it for the exposure? :laughing: :laughing: :laughing:

edit: okay, maybe there's a hidden market for this module somewhere, but he's only the 2nd person in the last ~13 years who I've heard ask about OPC XML-DA.

Google will lead the lost and desperate here.... (:

I don't always charge a sponsor--remote access to the hardware may suffice if the the task is relatively straightforward.

An OPC UA to OPC DA-XML gateway might be a fun holiday project as a more substantial Milo example :thinking:

walmart is such that going and getting the funding for kepware is probably a larger task than building the module. Its called b-e-a-u-r-a-c-r-a-c-y.

Our general approach is going to be to ask this vendor to jump into the 21st century and move to OPC-UA in the future and/or put this so that we can just access it through the AB PLC that is literally 20 feet away from the equipment in question.

I am going to test that JAVA OPC XML DA SDK since we do of course have an actual live source of OPC DA-XML data with a known IP, port, and open firewall route.

Nick

1 Like

Orthogonal, I think.

1 Like

@Kevin.Herron

I spent a few hours on this and there is some actual substance in this library.

Here are a few things I have found so far.

  1. It requires JDK 1.8 for mvn clean package to work so compatibility to JDK 11 would have to be sorted.

  2. There is a function in test called “OPCXmlDaClientITest” and when you first try to run it, you get a 301 redirect error. What appears to be a test website its trying to access is here:

http://info.advosol.com/XMLDADemo/XML_Sim/opcxmldaserver.asmx

By updating the URL in test–> resources --.> application_properties then running the test class, I can see the following response content:

So because it seems to contain functionality which can communicate with what appears to be a valid OPC XML DA server, I think I will continue to research its contents and figure out what it will take to merge it together with the Ignition SDK opc-ua-device example.

Thoughts?

Nick

Seems worth continued exploration.

My concern after looking at it is that it’s expecting to run inside a Spring application and Ignition is not a Spring application. If, for example, you just created a simple Java command line application and tried to use the client in the main method it would likely fail.

Pardon my lack of Java experience here…trying my best.

If I was to considering taking it out of spring, what would I take it to? just plain java and remove any dependency it has on spring?

No idea. I have zero experience with Spring.

Hmm, easier than I thought:

import java.util.Locale;

import org.springframework.oxm.jaxb.Jaxb2Marshaller;
import ua.tumakha.yuriy.opc.xmlda.sdk.client.OpcXmlDaClient;
import ua.tumakha.yuriy.opc.xmlda.sdk.model.BrowseResponse;

public class Main {

    public static void main(String[] args) {
        Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
        marshaller.setContextPath("ua.tumakha.yuriy.opc.xmlda.sdk.model");

        OpcXmlDaClient client = new OpcXmlDaClient();
        client.setDefaultUri("http://info.advosol.com/XMLDADemo/XML_Sim/opcxmldaserver.asmx");
        client.setDefaultLocale(Locale.US);
        client.setMarshaller(marshaller);
        client.setUnmarshaller(marshaller);

        BrowseResponse response = client.browse();
        
        response.getElements().forEach(
            e ->
                System.out.printf("name=%s, path=%s%n", e.getItemName(), e.getItemPath())
        );
    }

}

results:

12:04:28.320 [main] INFO org.springframework.ws.soap.saaj.SaajSoapMessageFactory - Creating SAAJ 1.3 MessageFactory with SOAP 1.1 Protocol
12:04:28.328 [main] DEBUG org.springframework.ws.soap.saaj.SaajSoapMessageFactory - Using MessageFactory class [com.sun.xml.internal.messaging.saaj.soap.ver1_1.SOAPMessageFactory1_1Impl]
12:04:28.389 [main] DEBUG org.springframework.ws.client.core.WebServiceTemplate - Opening [org.springframework.ws.transport.http.HttpUrlConnection@649d209a] to [http://info.advosol.com/XMLDADemo/XML_Sim/opcxmldaserver.asmx]
12:04:28.413 [main] INFO org.springframework.oxm.jaxb.Jaxb2Marshaller - Creating JAXBContext with context path [ua.tumakha.yuriy.opc.xmlda.sdk.model]
12:04:28.573 [main] DEBUG org.springframework.ws.client.MessageTracing.sent - Sent request [SaajSoapMessage {http://opcfoundation.org/webservices/XMLDA/1.0/}Browse]
12:04:28.766 [main] DEBUG org.springframework.ws.client.MessageTracing.received - Received response [SaajSoapMessage {http://opcfoundation.org/webservices/XMLDA/1.0/}BrowseResponse] for request [SaajSoapMessage {http://opcfoundation.org/webservices/XMLDA/1.0/}Browse]
name=SimulatedData, path=null
name=Static, path=null
name=Dynamic, path=null
name=ServerInfo, path=null
name=EventSources, path=null
name=DW_INOUT1, path=null

Still relies on Spring, but doesn’t seem to require running inside the context of a Spring application.

Next step would be trying to get this working on JDK 11. Probably requires updating the Spring dependency versions to start.

Thanks for that example that shows how to use the API, I did the same but slightly different for server status.

I will work on making it build in JDK11.

package ua.tumakha.yuriy.opc.xmlda.sdk;

import org.springframework.oxm.jaxb.Jaxb2Marshaller;
import ua.tumakha.yuriy.opc.xmlda.sdk.client.OpcXmlDaClient;
import ua.tumakha.yuriy.opc.xmlda.sdk.model.GetStatusResponse;
import ua.tumakha.yuriy.opc.xmlda.sdk.model.ServerStatus;

import java.util.Locale;

class nonSpringContextTest {

    public static void main(String[] args) {
        Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
        marshaller.setContextPath("ua.tumakha.yuriy.opc.xmlda.sdk.model");

        OpcXmlDaClient client = new OpcXmlDaClient();
        client.setDefaultUri("http://info.advosol.com/XMLDADemo/XML_Sim/opcxmldaserver.asmx");
        client.setDefaultLocale(Locale.US);
        client.setMarshaller(marshaller);
        client.setUnmarshaller(marshaller);

        GetStatusResponse statusResponse = client.getStatus();
        ServerStatus serverStatus = statusResponse.getStatus();

        System.out.println(serverStatus.getVendorInfo());
        System.out.println(serverStatus.getProductVersion());
        System.out.println(serverStatus.getStatusInfo());
        System.out.println(statusResponse.getGetStatusResult().getServerState());
        System.out.println(serverStatus.getSupportedLocaleIDs());
        System.out.println(serverStatus.getSupportedInterfaceVersions());
    }
Advosol Inc., Advosol Inc.
OPC XML-DA V1.0, XML DA Simulation Server
Started
RUNNING
[en-us, de]
[XML_DA_VERSION_1_0]

Process finished with exit code 0

Nick

Early Christmas gift :stuck_out_tongue:

Getting it to work on JDK 11 was probably too big an ask for someone new to the Java ecosystem:

2 Likes

@Kevin.Herron greatly appreciated thank you. I see that you have not only done java version compatibility but also made it so its mainly based off of

import org.opcfoundation.xmlda.*;

Looking at the available SDK examples I had originally thought about using “opc-ua-device” but it seems like the wrong entry point because what we want to end up with is this:

So it seems to be that if there happened to be an example that is the OPC-DA driver modifying that is really the shortest path. But I see that the OPC-DA module is a paid module so probably not.