5 ways to access MTConnect data from a web application

Hi! This article is very old and outdated. You might consider checking out this newer article on web access to MTConnect.


The MTConnect standard has opened up a lot of possibilities for builder-neutral applications within a machine shop. By exposing machine tool data in a standard XML form, it allows us to develop monitoring tools without delving into the peculiarities of each machine tool builder’s proprietary communication mechanisms.

How well does MTConnect integrate with the great experiment in open standards: the web itself? Can we use HTML5 and AJAX to create a pure web-based MTConnect application? Well… yes and no.

To start, let’s look at how you can access MTConnect data in a web application.

Accessing the data

If you’re coding an HTML5 application, obviously you’ll be using Javascript. Most likely you’re using a framework such as jQuery to simplify client-side tasks such as handling AJAX requests and manipulating the DOM.

The MTConnect Institute provides a demo agent running at http://agent.mtconnect.org that you can use for initial testing. Of course, you’ll run into a problem right away:

 $.ajax({
   url: 'http://agent.mtconnect.org',
   success: function(data, textStatus, jqXHR){
     console.log(data);
   },
   error: function(jqXHR, textStatus, errorThrown){
     console.log('ERROR: ' + textStatus);
   }
 });

Oops. You’re not agent.mtconnect.org, are you? If you’re like me, you’re developing and running your web application on localhost. And there’s the first problem: the same-origin policy prevents your application from sending an AJAX request to a different domain. You’ll need to find a workaround. Here are some possibilities…

1) Run on the same server

This is the most straightforward. Obviously, if your MTConnect Agent and your awesome web application are served from the same place, then an AJAX request from one to the other isn’t a cross-origin request, and the browser will happily allow it.

When you can use this: When you have control over both the MTConnect agent and your web application. Both must be served basically from the same domain: if the domain, subdomain, or even the port number differ, the browser will consider AJAX requests from your web app to be cross-origin, and disallow them.

How would you do this: If you’re using the reference agent provided by MTConnect, that’s a tough one. Modify the source code so that you can specify another directory to serve via HTTP, and put your web app in that directory.

2) Disable browser security

Someone reading this article right now is thinking, “Gosh, if my browser security settings won’t let me send a cross-origin AJAX request, can I just disable my browser security?”

You naughty person. I bet you turned off your antivirus program because you were tired of seeing all those warnings pop up, didn’t you?

When you can use this: Never. If you do, don’t tell me about it.

How would you use this: If your browser allows you to turn off web security, the settings will differ by browser.

3) Access the data via JSONP

JSONP is a process that involves dynamically creating a <script> tag, with a src attribute that points to the data you want to load. You can load a script from anywhere, so same-origin doesn’t even come into play. The catch is that resource you point to with src must be valid Javascript, so typically you wrap your data into a JSON object, and then wrap a Javascript function around that object.

So how does this help? The MTConnect agent doesn’t return data in this format, so it doesn’t seem workable. Well… Yahoo! provides a service called YQL, which provides the ability (among other things) to wrap existing webservices as JSONP. Of course, Yahoo!’s webservices can only access your MTConnect agent if it’s on the public internet.

When you can use this: When your MTConnect agent is publicly accessible via the web. You’ll have to abide by Yahoo!’s terms of service: currently 100k calls per day per application, with additional per-IP restrictions.

How would you use this: I’m not personally familiar with  JSONP usage, but it might look something like this:

  var url = 'http://query.yahooapis.com/v1/public/yql?q=select * from xml where url="http://agent.mtconnect.org"&amp;amp;amp;format=json&amp;amp;amp;callback=cbfunc&amp;amp;amp;jsoncallback=?';

 var cbfunc = function(object){
   console.log('Hello. I am the ');
   console.log(object.query.results);
 }

 $.getJSON(url);

To fetch other MTConnect resources, just change the URL. The callback function is called when the JSONP request completes. The parameter will be an object, that contains a query object, that contains the results object, which is the actual result of the query. In this case, object.query.results is the MTConnectDevices document returned when we request http://agent.mtconnect.org.

The jQuery.getJSON function is a convenience function: I’m pretty sure it wraps jQuery.ajax, and that there’s a way to send JSONP requests via jQuery.ajax. Note that there’s no error handler callback, as you might see with a typical AJAX call. According to the documentation, the error callback is not called for JSONP requests, so you may never find out about an error loading the data.

4) Cross-Origin Resource Sharing

CORS, or cross-origin resource sharing, is a mechanism that allows the http server to specify that it will allow certain origins to send AJAX requests. The browser will send an Origin header containing your web application’s origin. The http server may then allow the AJAX request to proceed by sending back an Access-Control-Allow-Origin header. This tells the browser to allow the cross-origin AJAX request.

The catch?

First, CORS is relatively new in web terms. For example, Internet Explorer did not support CORS until IE8. Do you know anyone still using IE6 or IE7? I do. Older browsers will simply disallow the cross-origin AJAX requests as usual.

Second, this obviously requires server-side support, because the http server must respond with a certain header. If you’re using the reference agent provided by the MTConnect Institute, this is an easy change, but requires you to build the agent from source:

  1. Download the C++ agent source code from GitHub.
  2. Open agent/agent.cpp.
  3. Locate the Agent::on_request method.
  4. Find the line that reads: outgoing.headers[“Content-Type”] = “text/xml”;
  5. Add a line right below it: outgoing.headers[“Access-Control-Allow-Origin”] = “*”;
  6. Save and build.

This will cause the agent to answer all requests with an Access-Control-Allow-Origin: * header. Consequently, any browser that supports CORS will allow AJAX requests to complete successfully. Is this a security risk? Right now, MTConnect is read-only, and this simply enables a script to access via AJAX data that was already accessible to the client. For my purposes, no it’s not, but do your own due diligence and apply your own security criteria.

When you can use this: If your web application targets only modern browsers which definitely support CORS.

How would you use this: Configure your MTConnect agent to send the appropriate http header. In jQuery, you may also need to set $.support.cors = true. From there, AJAX requests to your MTConnect agent should work.

5) Proxy your agent

Remember how the easiest workaround was simply to make sure your web application and your MTConnect agent shared an origin? If you don’t control the MTConnect agent, you can still proxy it through the same server that serves your web application.

Creating a proxy is exactly the approach taken in the MTConnect Graphr project. In it, the author includes a simple loader.php script that proxies the requested URL.

When you can use this: If you have enough control over your web application’s server to run a PHP script, or otherwise proxy the MTConnect agent data through your server.

How would you use this: Let’s say you’re using the loader.php script provided with Graphr. Your application is located at http://localhost/awesomeMTConnectApp, and you want to fetch data from http://agent.mtconnect.org.

Instead of sending an AJAX request to http://agent.mtconnect.org, you would send the request to http://localhost/loader.php?url=http://agent.mtconnect.org. As far as the browser is concerned, your app on localhost is now loading data from localhost. Same origin.

Conclusion

It’s a little disappointing that there isn’t a pure HTML/Javascript solution for fetching MTConnect data.

  • CORS comes very close to doing so: it requires only an additional header from the server. But it is not yet universally supported.
  • YQL requires a public-facing agent, and creates a dependency on Yahoo!.
  • Setting up a proxy is simple, but requires backend support.

Still, each solution does enable us to access MTConnect data. Personally, I’ve been using CORS for demonstrations (since I can control what browser is used), and proxies elsewhere. It’s not a pure HTML/Javascript solution, but it is a working solution, and that’s what counts.

Sometime in the near future I’ll cover what sort of MTConnect data you can access, and work toward a basic monitoring application. I know, there are already plenty of monitoring apps out there, but what’s one more?

Advertisements

2 thoughts on “5 ways to access MTConnect data from a web application

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s