PIWorld 2020 Using PI Web API From Beginner To Advanced
PIWorld 2020 Using PI Web API From Beginner To Advanced
All rights reserved. No part of this publication may be reproduced, stored in a retrieval system, or transmitted, in any form or by any means,
mechanical, photocopying, recording, or otherwise, without the prior written permission of OSIsoft, LLC.
OSIsoft, the OSIsoft logo and logotype, Managed PI, OSIsoft Advanced Services, OSIsoft Cloud Services, OSIsoft Connected Services, PI ACE, PI
Advanced Computing Engine, PI AF SDK, PI API, PI Asset Framework, PI Audit Viewer, PI Builder, PI Cloud Connect, PI Connectors, PI Data
Archive, PI DataLink, PI DataLink Server, PI Developers Club, PI Integrator for Business Analytics, PI Interfaces, PI JDBC Driver, PI Manual
Logger, PI Notifications, PI ODBC Driver, PI OLEDB Enterprise, PI OLEDB Provider, PI OPC DA Server, PI OPC HDA Server, PI ProcessBook, PI
SDK, PI Server, PI Square, PI System, PI System Access, PI Vision, PI Visualization Suite, PI Web API, PI WebParts, PI Web Services, RLINK and
RtReports are all trademarks of OSIsoft, LLC.
All other trademarks or trade names used herein are the property of their respective owners.
2|P a ge
Table of Contents
Contents
Table of Contents ............................................................................................................................................................. 3
1. Introduction ............................................................................................................................................................. 5
Overview of Lab ................................................................................................................................................ 5
What is PI Web API? ......................................................................................................................................... 5
Goals for this Lab .............................................................................................................................................. 6
Section outline.................................................................................................................................................. 6
Out of scope topics ........................................................................................................................................... 6
Virtual Learning Environment ........................................................................................................................... 7
Exercise 1 – Exploring the PI Web API............................................................................................................................... 8
2. PI Web API Basics ....................................................................................................................................................10
Controllers.......................................................................................................................................................10
Methods ..........................................................................................................................................................10
URL parameters ...............................................................................................................................................11
Exercise 2 – Using URL parameters..................................................................................................................................12
3. Constructing PI Web API Requests ...........................................................................................................................14
HTTP verbs ......................................................................................................................................................14
Headers ...........................................................................................................................................................14
Request body...................................................................................................................................................15
Exercise 3 – Make requests in Postman ...........................................................................................................................16
4. Searching with PI Web API.......................................................................................................................................18
Traditional endpoints with filters .....................................................................................................................18
Using the Search controller ..............................................................................................................................18
Using the AFSearch methods ...........................................................................................................................18
Benefits of the AFSearch methods ...................................................................................................................19
Exercise 4 – Making queries with the AFSearch methods ................................................................................................20
5. WebId 2.0 ...............................................................................................................................................................21
WebId types ....................................................................................................................................................21
Exercise 5a – Decode WebIds ..........................................................................................................................................23
Exercise 5b – Generate a WebId......................................................................................................................................24
6. Batch requests ........................................................................................................................................................25
Structure of a batch request ............................................................................................................................25
Parent-Child requests ......................................................................................................................................26
Exercise 6a – Get System Endpoints ................................................................................................................................28
Exercise 6b – Create AF Hierarchy ...................................................................................................................................29
7. Channels .................................................................................................................................................................30
WebSockets .....................................................................................................................................................30
Query Parameters ...........................................................................................................................................31
Exercise 7 – Using Channels ............................................................................................................................................32
8. Stream updates .......................................................................................................................................................33
Registering for updates ....................................................................................................................................33
Retrieving updates ...........................................................................................................................................33
Exercise 8 – Using Stream Updates..................................................................................................................................34
9. OSIsoft GitHub ........................................................................................................................................................35
Final Exercise ..................................................................................................................................................................35
Appendix ........................................................................................................................................................................36
Postman Introduction .................................................................................................................................................36
Save the Date! ............................................................................................................... Error! Bookmark not defined.
4|P a ge
1. Introduction
Overview of Lab
This lab will go through some of the main functionality of the PI Web API, from basic
actions like retrieving a set of values, to signing up for streaming updates on a group
of attributes. This lab is designed for students who are familiar with the PI System
but are new to PI Web API. Advanced programming capabilities are not required, but
students should have some familiarity with general programming concepts.
Comparison to AF SDK
The PI Web API itself uses AF SDK for data access, so its functionality is a subset of
what AF SDK provides. This also means that it is not possible for PI Web API to
have better performance than AF SDK. However, for many applications the
performance difference is small, and PI Web API is much more flexible in terms of
what platforms and languages can be used. AF SDK is a .NET library, so it must be
run on Windows and in a language that supports loading .NET dlls. On the other
hand, PI Web API can be used by any platform and language that supports making
HTTP(S) requests.
5|P a ge
Goals for this Lab
The goal of this lab is to expose students to the capabilities of the PI Web API by
getting them familiar with navigating the documentation and making requests. After
taking this lab, students should understand:
1) How to navigate through various endpoints in a web browser
2) How to make requests through a non-browser HTTP client
3) How to interact with the PI Web API programmatically
Section outline
• PI Web API Basics (Google Chrome)
o Become familiar with the documentation
o Practice retrieving information from different endpoints in the browser
• Channels (Python)
o Brief overview of the WebSocket protocol
o See how the channels feature can be used to monitor for real-time changes
Indexed Search
PI Indexed Search and PI Indexed Search Crawler are optional features of PI Web
API. Indexed search runs as part of PI Web API, while the Search Crawler is an
independent service. The Search Crawler service gathers metadata from the PI
System and provides items for the Indexed Search for indexing. The pros/cons of
searching with Indexed Search are covered in Section 4, but we will focus on other
methods of searching and will not discuss configuring the Search Crawler service.
PISCHOOL Domain:
PICLIENT01 – This is our client machine that will be where we complete each of the
exercises for the lab. The three client applications that we will use are already installed:
Google Chrome, Postman, and Visual Studio Code (Python).
The user account that we will be using is PISCHOOL\student01. The password for
this account will be given by the lab instructor.
7|P a ge
Exercise 1 – Exploring the PI Web API
8) Navigate AF hierarchy
a. Go to the home page
b. Click on the AssetServers link
c. Click on Databases link for PISRV01
➢How many AF Databases do we have?
d. Click on the Elements Link for the NuGreen database
➢How many root elements are there in this Database?
e. By clicking the Elements links, navigate to
\\PISRV01 NuGreen\NuGreen\Houston\Cracking Process\Equipment\B-210
f. Click on the Value link
➢What is the current timestamp and value for the Fuel Savings attribute?
9|P a ge
2. PI Web API Basics
In this section we will examine the core concepts of PI Web API and see how we can
change what information is returned.
Controllers
Controllers are the top-level groupings that provide access to different types of objects or
functionality within the PI Web API. Some of the most commonly used controllers are listed
below:
The Stream and StreamSet controllers are particularly important. They provide the
functionality for reading/writing time-series data.
A stream is defined as either a tag on the PI Data Archive or an AF Attribute that has
a Data Reference configured (i.e. static AF Attributes are not a stream). A stream set
is a collection of multiple streams. The streams in a stream set may be defined by a
common parent element/attribute or can be a grouping of unrelated streams.
Methods
Each controller has one or more methods that are associated with it. The method describes the
actual action we want to take. Some examples of methods for the Element controller are listed
below:
URL parameters
URL parameters are used to pass additional values to a method to control what is returned.
Each method accepts a specific group of parameters, some of which may be required and
others may be optional (have a default value).
• SelectedFields (tells the PI Web API to omit unwanted fields from the response body)
• TimeZone (which time zone the PI Web API will interpret the supplied timestamps)
• BufferOption (controls whether or not to use PI Buffer Subsystem when writing data)
11 | P a g e
Exercise 2 – Using URL parameters
4) Get interpolated values for this attribute over the last day at 1-hour intervals for the same
attribute
a. Use the Stream controller’s GetInterpolated method
b. The following URL parameters can be used to specify the request details
➢?startTime=*-1d&endTime=*&interval=1h
c. Change the query so that only the timestamps and values are returned by using the
selectedFields URL parameter
➢&selectedFields=Items.Timestamp;Items.Value;
5) Get the average value for the same attribute over the last week
a. Use the Stream controller’s GetSummary method
b. The summaryType URL parameter defines the type of summary to calculate
➢?summaryType=Average
13 | P a g e
3. Constructing PI Web API Requests
In this section we will examine the building blocks of an HTTP request and see how
to construct requests that make changes to the PI System.
HTTP verbs
Through the browser, the only type of HTTP request we can make is a GET request. However,
to make any changes to the PI System (not purely retrieving data) we must use other HTTP
Verbs. Each method in the PI Web API requires a specific verb, depending on the action that is
being taken:
Headers
Headers are key/value pairs that accompany the request and contain metadata. Some headers
are usually supplied automatically by the client/library. For example, when we make requests
through a web browser, headers like Authorization generated automatically for us. However,
some headers may need to be specified explicitly depending on the request and the desired
behavior. Some important headers are described below:
• Authorization
This contains the authentication scheme (Basic, Negotiate, Bearer) as well as the
corresponding credentials for verifying the identity of the requester.
• Cache-Control
The PI Web API uses an AFCache to temporarily store AF SDK objects that have already been
retrieved. By default, the cache will refresh every 5 minutes. This header allows the requester to
specify a maximum age (in seconds) for cached objects. This ensures that anything returned by
the PI Web API was retrieved from the server within the specified time. This header does not
affect timeseries data, which is never cached and is always retrieved at the request time.
• Content-Type
This is a standard http header the describes the format of the request body (when supplied). For
PI Web API we will set this to application/json.
Request body
Unlike GET requests, which contain all of the request information in the URL and headers, other
request types require a payload to contain the data that is to be created or changed. This
payload is contained in the body of the HTTP request. PI Web API accepts and returns content
in the JSON (JavaScript Object Notation) form. JSON is a commonly used format of
representing objects in a human readable text format. Below, here is an example of JSON data
you may see returned from PI Web API.
{
"Links": {},
"Items": [
{
"Timestamp": "2020-01-15T18:05:11Z",
"Value": 7.873338,
"UnitsAbbreviation": "",
"Good": true,
"Questionable": false,
"Substituted": false,
"Annotated": false
},
{
"Timestamp": "2020-01-15T18:13:41Z",
"Value": 9.985083,
"UnitsAbbreviation": "",
"Good": true,
"Questionable": false,
"Substituted": false,
"Annotated": false
}
],
"UnitsAbbreviation": ""
}
JSON is made up of name/value pairs. For example, “Good” is a name with value “true”. Names
are strings, but the values can have different types, such as numbers, strings and true/false.
Also important is that each name is unique within an object (delimited by curly braces). The
other data type we see in this example is an ordered array (delimited by square braces), for
example the value corresponding to the name “Items” is an array containing two objects, each
representing a data event.
15 | P a g e
Exercise 3 – Make requests in Postman
This exercise and Exercise 4 will be using an application called Postman, which is another tool
for making HTTP requests. Unlike a web browser, we can customize our requests to have
actions besides GET, attach headers, and include body content. A quick introduction to
Postman can be found in the Appendix of this workbook.
Open Postman and look at the collection called “PIWorldLabExercises”. You will modify each
of the requests to retrieve the data specified in each question. Anywhere that you see TODO is
something that must be completed by you.
Postman does not have the built-in ability to do Kerberos (Negotiate) authentication, so for
these exercises we will use Basic authentication instead. To globally set the Authentication
header click “…” on the right side of the top-level folder.
Navigate to the Authorization tab and choose to add a Basic Auth header to all requests.
Specify the username PISCHOOL\student01 and enter the password that you were given. This
will set the Authorization header for all requests in this collection.
2) Create a new root AF element in that database called OldGreen based on the element
template “Enterprise”
a. Use the AssetDatabase controller’s CreateElement method
3) Create new child element under OldGreen named Generator
a. Use the Element controller’s CreateElement method
8) Write a set of 3 different values to this new tag using Tag’s WebId
a. Use the Stream controller’s UpdateValues method
17 | P a g e
4. Searching with PI Web API
A common task that you may need to perform when programming against the PI System is to
search for objects that match specific criteria. The PI Web API provides 3 ways to execute
search actions within the PI Web API:
1) Traditional endpoints with filters
2) Using the Search controller
3) Using Query methods that utilize the AFSearch classes in AF SDK
• Attributes (GetAttributesQuery)
• Elements (GetElementsQuery)
19 | P a g e
Exercise 4 – Making queries with the AFSearch methods
1) Using the Element controller’s GetElementsQuery method, search for AF elements that
meet the following
a. In the NuGreen database
b. Name contains the characters “b-2”
c. Element template is “Boiler”
3) Using the Attribute controller’s GetAttributesQuery method, search for AF attributes that
meet the following
a. In the NuGreen database
b. Associated element is based on the template “Unit”
c. Name contains the characters “flow"
6) Again, using the EventFrame controller’s GetEventFramesQuery method, search for the
5 most recent Event Frames that meet the following
a. In the NuGreen database
b. Severity is Critical
5. WebId 2.0
As we have seen previously, every primary resource within the PI Web API has a unique
identifier called a WebId. These WebIds are persistent, and therefore can be stored by a client
for future use. PI Web API Version 2017 R2 introduced a new version of WebId (2.0), which
adheres to an open standard and allows the possibility for WebIds to be constructed by a client.
Prior to this version 1.0 WebIds were opaque and had no publicly exposed standard for
understanding their structure.
WebId types
There are 5 different types of WebIds that are available. The type used will affect
what types of changes the WebId is resilient to. For example, if the name of an AF
element changes, a previously cached PathOnly WebId will no longer work, but an
Full or IDOnly WebId would still return the element. In many methods, you can
specify the type of WebId that you want to be returned to us by using a URL
parameter (e.g. ?webIdType=PathOnly).
Encodes all information, similar to WebID version 1.0. Full WebIDs are
Full
longer, but are more resistant to items being moved, renamed, or deleted.
Encodes only object IDs into the WebID. IDOnly WebIDs are shorter, and
IDOnly will always refer to the same item, even if it is moved. However, IDOnly
WebIDs will no longer be valid if the item is deleted.
Encodes only path information into the WebID. PathOnly WebIDs will
PathOnly always refer to the same location in the AF hierarchy, regardless of which
item is located there.
This type is similar to IDOnly, but is dedicated to resources on the local
(relative to the PI Web API instance) asset or data server. The local
asset/data server ID and path information is left out.
LocalIDOnly
Note: This type is not persistent or unique, and could represent different
items on different servers. It is not compatible with load balancer
configurations.
This type is similar to IDOnly, but is dedicated to resources on the default
asset server or data server. The default asset/data server ID and path
information is left out.
DefaultIDOnly
Note: This type is not persistent or unique, and could represent different
items on different servers. It is not compatible with load balancer
configurations.
21 | P a g e
The diagram below shows how a Full WebId for an AF element can be broken down
into its component parts:
2. Edit the script to make a request that returns the element \\NuGreen\NuGreen\Wichita
and decode the full WebId.
3. Edit the URL from your previous request to have it return a PathOnly WebId and decode
the components.
4. Edit the URL again to return the IDOnly form of the WebId and decode the components.
BONUS: Currently, this script only works for some object types like AF Elements or
Event Frames. Edit the script so that it can decode Full AF Attribute WebIds as well.
23 | P a g e
Exercise 5b – Generate a WebId
1. On PICLIENT01, open the file Exercise 5b – Generate a WebId.py in Visual Studio
Code.
3. Edit the script again to generate a PathOnly WebId for the PI tag CDT158 and use it to
make a request to the Stream controller for recorded values.
BONUS: Edit the script again to generate a WebId for the AF attribute
\\PISRV01\NuGreen\Tuscon\Distilling Process\Equipment\P-871|Process Feedrate and use
it to make a request to the Stream controller for the current value.
6. Batch requests
Every HTTP request has some overhead associated with it, both in terms of processing and
network traffic. In order to reduce repetitive processing and effects of latency, we can use the
Batch controller to bundle multiple request together and send them to PI Web API in one action.
This can result in substantial performance improvements.
The JSON body of the request is a list of objects that each correspond to one
individual sub-request. Within the sub-request object, individual name/value pairs
specify request details (Method, Resource, Content, Headers, etc).
25 | P a g e
The response body, would then look like:
{
"SubRequestID1": {
"Status": 200,
"Headers": {
"Content-Type": "application/json; charset=utf-8"
},
"Content": {
"Links": {
"Self": "https://servername/piwebapi/",
"AssetServers": "https://servername/piwebapi/assetservers",
"DataServers": "https://servername/piwebapi/dataservers",
"Omf": "https://servername/piwebapi/omf",
"Search": "https://servername/piwebapi/search",
"System": "https://servername/piwebapi/system"
}
}
},
"SubRequestID2": {
"Status": 200,
"Headers": {
"Content-Type": "application/json; charset=utf-8"
},
"Content": {
"Items": [
{
"WebId": "F1RSiOPKGTTUcUCFkVGxiCya9gUElTUlYwMQ",
"Name": "PISRV01"
}
]
}
}
}
Parent-Child requests
One potential issue when bundling our requests is that we may need the result from
one request before we can full define another request. For example, we might need
to use the WebId returned from request A in the URL for request B. PI Web API
provides a mechanism for this type of request, so that we can have specify some
requests to execute before others and use their results in subsequent requests.
To specify that a sub-request must execute after another, we can specify the Id of
the parent request in the child request’s “ParentIds” array. We can also specify an
array of “Parameters”, that reference results of previously executed requests. To
specify the parameter value, we use a syntax called JSONPath.
JSONPath gives a way to use the structure of unique names and arrays in JSON to define the
notation of a path. As with a file path in Windows, JSONPath gives us ways to access the
various sub-structures in any JSON objects.
Let’s look again at a JSON object.
{
"A": 1234,
"B": [
{"Val": 12},
{"Val": 34}
],
"C": {
"D": 5678
}
}
To be able to define a path, we first need an identifier for the whole JSON object. This is the “$”
character (think of a drive letter for a Windows path, or “/” for a Mac path). To refer to a child
element, we use the dot notation. For example “$.A” refers to the value 1234.
We can refer similarly to children of children, for example “$.C.D” is equal to 5678.
For arrays, we use typical index notation, for example $.B[0].Val refers to the value 12. In the
case of JSONPath, the first item is the list is access using the index 0.
The last path definition that we need, is a way to retrieve all objects within an array, we can do
so with the character “*”. For example, $.B[*].Val refers to an array with value 12, 34.
An example of a parent-child batch request is below. We reference the WebId returned in the
request “GetId” and then use it in the child request “GetValues”.
{
"GetId": {
"Method": "GET",
"Resource":
"https://servername/piwebapi/attributes?path=\\server\\mydb\\pump|flow"
},
"GetValues": {
"Method": "GET",
"Resource": "https://servername/piwebapi/streams/{0}/recorded",
"ParentIds": [
"GetId"
],
"Parameters": [
"$.GetId.Content.WebId"
]
}
}
The {0} in the “Resource” for the second request, tells PI Web API to insert the value of the first
parameter. If there were addition parameters, they would be referenced as {1}, {2}, {3}, etc.
27 | P a g e
Exercise 6a – Get System Endpoints
2. Build out a batch request body to return each of the endpoints under the System
controller by explicitly defining each request.
BONUS: Convert the individual child requests from part 3, into a group defined by a
“RequestTemplate” where the “Resource” field is specified by a parameter.
HINT: For an example, see request ID “8” in the documentation for the Batch controller’s
Execute method (link)
Exercise 6b – Create AF Hierarchy
2) Edit the script to build out a batch request that creates an AF hierarchy that looks like the
following:
HINT: If the request partially succeeds, but fails after the database was created, you will
need to delete the AF database before trying again. You can do this with Postman or
with PI System Explorer.
29 | P a g e
7. Channels
So far, we have seen how the PI Web API can be used to query for data at a point in
time. However, many applications need to be able to observe real-time data and be
notified when new events occur. Up to this point, the methods that we’ve explored
would require polling the same endpoints with periodic requests to check for new
data.
The Channels feature is designed for just this purpose. It allows a client to sign-up
and receive continuous updates about a stream or stream set.
WebSockets
Channels are unique within PI Web API in that they are implemented using the Web
Socket protocol rather than typical HTTP requests. Many programming languages
have libraries available that implement the WebSocket protocol and can be used with
Channels. To specify the secure WebSockets protocol the URL will begin with wss://
where we would normally see https://.
Web Sockets are different from HTTP requests in that a persistent connection is
maintained between the client and the server. This allows the server to initiate the
sending of messages to the client at any point while the socket is established,
without having to wait for a client request.
Query Parameters
When signing up for a Channel, there are two optional query parameters that can be
specified:
• includeInitialValues (default false) – If included and set to true, the Web API
will return the current value upon establishing the initial connection
• heartbeatRate (default never) – If included, the web socket will send an
empty message periodically, at the interval specified by this parameter
31 | P a g e
Exercise 7 – Using Channels
1) On PICLIENT01, open the file Exercise 7 – Using Channels.py in Visual Studio Code.
This file contains the skeleton code for creating and monitoring a WebSocket.
3) Create a channel for a stream set defined as streams under the element:
\\NuGreen\NuGreen\Tucson\Distilling Process\Equipment\B-117
BONUS: While listening to a channel, use any of the tools we have used to this point to make a
request to show the existing channel instances. How many messages have been sent for the
current channel?
8. Stream updates
The Stream Updates feature allows for similar functionality as channels but using
only HTTP requests. Unlike channels, stream updates require the client to actively
reach out to retrieve the updates, but it avoids the need to use WebSockets.
Retrieving updates
Once registered, clients can then make requests to retrieve updates. The point at
which updates are retrieved from is determined by a marker. The initial marker is
returned when stream is first registered. That marker is then passed in the URL of
the request, and then the PI Web API includes the next marker in the response body.
This provides multiple performance improvements over polling, because the PI Web
API already has the results being queued up for when the next retrieval request
comes. It also ensures that the client only receives new data and does not have to
filter out data that was already returned previously.
33 | P a g e
Exercise 8 – Using Stream Updates
1) On PICLIENT01, open the file Exercise 8 – Using Stream Updates.py in Visual Studio
Code. This contains the skeleton code for registering and retrieving stream updates
2) Complete the missing sections in order to register/retrieve Stream Updates on the tag
CDT158.
3) Run the script to retrieve updates and see that updates are retrieved for this tag. If
values are coming in too slowly, manually write some values to the tag between two
retrieval requests (using Postman or PI System Management Tools).
Bonus: Change the code to use the location header in each response for the URL in the next
request, rather than constructing it using the “LatestMarker”.
Bonus: Change the code to register/retrieve Stream Updates on a stream set consisting of the
tags sinusoid and sinusoidu using RegisterStreamSetUpdates and
RetrieveStreamSetUpdates.
9. OSIsoft GitHub
This site has examples that utilize PI Web API from various languages/frameworks.
These projects implement some basic functionality and a good place to start if you
are curious what an application could look like in one of the provided languages.
Final Exercise
1) Download one of the example applications from GitHub
2) Follow the README.md file to install any needed pre-requisites
3) Run the application and investigate the functionality
4) Make some changes to the application to change or add features
35 | P a g e
Appendix
Postman Introduction
Postman (https://www.getpostman.com) is a free, publicly available, and easy to use tool for
making HTTP requests. The UI is intuitive but also provides powerful functionality. The top half
of the right pane where you will write requests against PI Web API.
Example of a request:
From this pane, you can write the URL (①) that will used in the request, fill in the header
information (②) and if required the body information (③) as well. The send button will send this
request to the PI Web API Service.
After sending a request to PI Web API, a response will be received. This response might include
the data you requested (①) or some details about an issue your request had. The bottom half
of the right pane is this response. The most important part is the body of the response when you
are requesting information, but the status (②) and headers (③) will also tell you information
about your request or the impact (element creation, etc.) that it had on the targeted PI System.
③ ②
①
37 | P a g e
© Copyright 2020
OSIsoft, LLC