mhamel

PI Web API: Javascript Client

Discussion created by mhamel Employee on Apr 26, 2014
Latest reply on Dec 10, 2014 by gonmerciel

This is a copy of the blog of Brad Hess, Sr. Software Developer at OSIsoft

 

In our last post, we built a simple C# application to get all the Pumps in Wichita out of our database.  Today we're going to do that in Javascript.  If you're following along with my code, simply open the attached HTML file in the text editor of your choice.  If you're starting from scratch, just create a new HTML file with the contents here:

 
1
2
3
4
5
6
7
8
9
10
<!DOCTYPE html>
 
<htmllang="en"xmlns="http://www.w3.org/1999/xhtml">
<head>
    <metacharset="utf-8"/>
    <title>Wichita Pumps</title>
</head>
<body>
</body>
</html>

 Much like last time, the first thing we want to do is add a library that'll help us immensely in the rest of our project.  Within the <head> html element, add a reference to jQuery.  jQuery is a javascript library that makes previously painful Javascript tasks easy. 

 
1
<scripttype="text/javascript"src="http://ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script>

Now that we have jQuery available, we can start writing our own scripts.  I've created a couple of <script> tags within my HTML head in order to allow myself to code inline.

 

One of our first steps is to define some variables to get our URLs set up.  For this purpose, I'm going to include a quick helper method to get myself a .NET-style string format utility in Javascript.  Thanks much to vCampus Team alum Michael van der Veeken for sharing this one with me!  This extends javascript's string type (the 'prototype') to add a format method.

 
1
2
3
4
5
6
7
8
9
10
11
if(!String.prototype.format) {
    String.prototype.format = function() {
        varargs = arguments;
        returnthis.replace(/{(\d+)}/g, function(match, number) {
            returntypeofargs[number] != 'undefined'
              ? args[number]
              : match
            ;
        });
    };
}

 So now I can go ahead and declare some variables within my script tags.  Of course, as always, you'll want to the server and database names to make sense in your own environment:     

 
var databasePath = "\\\\phlafs04\\nugreen";
var databaseUrl = "https://restdemo.osisoft.int/piwebapi/assetdatabases?path={0}".format(databasePath);
var plantSearchUrl;
var pumpSearchUrl;

 Awesome.  Let's make sure this is working correctly.  We'll load up our (currently empty) page in a browser, and check out databaseUrl in the Javascript console.  Look for this in the Developer Tools in your browser (I use Chrome).

 

8420.Screenshot-_2800_23_2900_.png

 

 So far, so good.  Now let's use our jQuery library to actually get some data.  Use the jQuery getJSON function to call this URL.  We'll grab the Elements link out of the response, and add our query.

 
$.getJSON(databaseUrl, function (database) {
    plantSearchUrl = database.Links.Elements + "?templateName=Plant&nameFilter=Wichita&searchFullHierarchy=true";
});

 Now let's take a look again in the browser:

 

 

 

0216.Screenshot-_2800_24_2900_.png

 

Oops!  This will happen with a stock PI Web API configuration.  The browser's Same Origin Policy prevents cross-origin requests by default.  PI Web API supports CORS, an industry-standard solution, to work around this problem (see http://enable-cors.org for more information).  PI Web API's CORS support can be adjusted using the PI Web API configuration-- either by making requests against the Web API's /configuration endpoints, or by manually modifying PI Web API's AF configuration database.  You'll want to set "CorsOrigins" to either your hostname, or to "*" to enable CORS traffic from any host.

 

In this screenshot, "RESTDEMO" is my PI Web API instance name.  Your instance name is usually the same as your hostname.

 

 

 
       $.getJSON(databaseUrl, function (database) {
            plantSearchUrl = database.Links["Elements"] + "?templateName=Plant&nameFilter=Wichita&searchFullHierarchy=true";

            $.getJSON(plantSearchUrl, function (plant) {
                pumpSearchUrl = plant.Items[0].Links["Elements"] + "?templateName=Pump&searchFullHierarchy=true";

                $.getJSON(pumpSearchUrl, function (pumps)
                {
                    var pumpsDomElement = $("#pumps");
                    var jqResults = $(pumps.Items);

                    jqResults.each(function (index, element)
                    {
                        pumpsDomElement.append("<li>" + element.Name + "</li>");
                    });
                });
            });
        });

 What are we doing here?  In the second callback, we're adding a variable to store a reference to the pumps element in the DOM.  DOM traversal is expensive, so you wouldn't want to make that call for each element in the result list.  Next, we're jQuery-ifying our JSON results, so that we can use the convenient shorthand each function from jQuery, which allows for a function to be executed for each object in the list.  Finally, for each object in the list, we're adding HTML to the DOM node of our list, to have the name of the pump appear as a list item.

Here's our results in the browser!

 

2867.25.png

 

Thanks for staying tuned.  This concludes our set of basic posts to get you up and running with the PI System Web API in both C# and Javascript.

 

Find the file here.

Outcomes