Skip navigation
All Places > PI Developers Club > Blog > 2017 > December
2017
ray

PI Web API 2017 R2 is released!

Posted by ray Employee Dec 29, 2017

I am pleased to announce the release of PI Web API 2017 R2, our suite of REST services for interacting with the PI System. The PI Web API is a member of the Developer Technologies suite of products. Click to see our Technical Support Product Release Bulletin which in turn will direct you to the right pages in our Download Center. We have stopped shipping the dedicated PI Web API install kit. Instead, PI Web API is part of PI AF Services 2017 R2.

 

There are many enhancements and bug fixes in this release. I encourage you to read the Release Notes to learn about what we did. Improving performance is Job #1! You'll find many work items that were directed at improving speeds of data retrieval and search. I wanted to mention two features:

 

WebId 2.0: we have received many comments about our WebId concept which are unique identifiers to just about everything you reference through PI Web API. While accurate, they can get to be a bit big. To address this, we have introduced WebId 2.0. We now have different types of WebId that vary in length and precision. It is even possible to create WebIds yourself if you already have access to AF SDK object ids. Let me know if this is interesting to you.

 

Channels: we have received a lot of positive feedback about our websocket "Channel" implementation. One of your biggest problems, it seems, is that you can't be completely sure if the channel is healthy if you have not received data updates for a while. For technical reasons, we are unable to implement the web socket standard RFC6455 "Ping" and "Pong" features to ascertain health. What we have done instead is allow you to request a periodic "heartbeat" response which consists of an empty message if there are no data values to send.

 

I hope you can upgrade to PI Web API 2017 R2 soon. Let me know what you think!

I am pleased to announce the release of several products in the PI SQL family which are members of the Developer Technologies suite of products:

All of these products provide access to PI System data through SQL queries. Click on these product names to see the Technical Support Product Release Announcements which in turn will direct you to the right pages in the Technical Support Download Center. There are just too many enhancements and bug fixes to list them all here. Congratulations to the OSIsoft PI SQL development team on these releases!

Introduction

 

This is an R package that integrates the PI System with R through PI Web API. It was built with the PI Web API 2017 Swagger definition. With this package, you can retrieve PI data without having to generate the URL for each request.

 

You can visit the GitHub repository of this library here.

 

Requirements

 

  • R 3.4+

 

Installation

 

This R package is not available on CRAN. You should download it directly from this GitHub repository by using the devtools R package. If you don't have it installed, please use the command below:

 

install.packages("devtools")

 

Then, load the library and install the PI Web API R package with the install_github method:

 

library(devtools)
install_github("osimloeff/PI-Web-API-Client-R")

 

If the installation is successful, the command below will load the package:

 

library(piwebapi)

 

If you want to uninstall this package, use the command below:

 

remove.packages("piwebapi")

 

 

Documentation

 

All the methods and classes from this R package are described on its documentation, which can be opened by typing on the R console:

 

help(package="piwebapi") 

 

Examples

 

Please refer to the following examples to understand how to use this library:

 

Create an intance of the piwebapi top level object.

 

Basic Authentication

 

useKerberos <- FALSE
username <- "myusername"
password <- "mypassword"
validateSSL <- TRUE
debug <- TRUE
piWebApiService <- piwebapi$new("https://webserver/piwebapi", useKerberos, username, password, validateSSL, debug)

 

Kerberos Authentication

 

useKerberos <- TRUE
username <- NULL
password <- NULL
validateSSL <- TRUE
debug <- TRUE
piWebApiService <- piwebapi$new("https://webserver/piwebapi", useKerberos, username, password, validateSSL, debug)

 

 

If you want to use basic authentication instead of Kerberos, set useKerberos to FALSE. If you are having issues with your SSL certificate and you want to ignore this error, set validateSSL to FALSE. If you want to receive a log about each HTTP request, set debug to TRUE.

 

 

Retrieve data from the main PI Web API endpoint

 

response1 = piWebApiService$home$get()

 

Get the PI Data Archive WebId

response2 = piWebApiService$dataServer$getByPath("\\\\piservername", "WebId")

 

Get current values in bulk using the StreamSet/GetValuesAdHoc

 

 

response3a = piWebApiService$point$getByPath("\\\\JUPITER001\\sinusoidu")
response3b = piWebApiService$point$getByPath("\\\\JUPITER001\\cdt158")
response3c = piWebApiService$point$getByPath("\\\\JUPITER001\\sinusoid")
webIds <- c(response3a$WebId, response3b$WebId, response3c$WebId)
response3d = piWebApiService$streamSet$getValuesAdHoc(webIds)

 

Retrieving PI data to an R data frame

 

 

response4a <- piWebApiService$data$getRecordedValues(path = "pi:\\\\PISRV1\\sinusoid", startTime = "y-200d", endTime = "t")
response4b <- piWebApiService$data$getRecordedValues(path = "pi:\\\\PISRV1\\sinusoid", startTime = "y-200d", endTime = "t", selectedFields = "items.value;items.timestamp")
response4c <- piWebApiService$data$getRecordedValues(path = "af:\\\\PISRV1\\UCDavisBuildings\\Buildings\\Buildings\\Academic Surge Building\\Electricity|Demand", startTime = "y-200d", endTime = "t")


response5a <- piWebApiService$data$getInterpolatedValues(path = "pi:\\\\PISRV1\\sinusoid", startTime = "y-2d", endTime = "t", interval = "1h")
response5b <- piWebApiService$data$getInterpolatedValues(path = "pi:\\\\PISRV1\\sinusoid", startTime = "y-2d", endTime = "t", interval = "1h", selectedFields = "items.value;items.timestamp")
response5c <- piWebApiService$data$getInterpolatedValues(path = "af:\\\\PISRV1\\UCDavisBuildings\\Buildings\\Buildings\\Academic Surge Building\\Electricity|Demand", startTime = "y-2d", endTime = "t", interval = "1h")


response6a <- piWebApiService$data$getPlotValues(path = "pi:\\\\PISRV1\\sinusoid", startTime = "y-2d", endTime = "t", intervals = 30)
response6b <- piWebApiService$data$getPlotValues(path = "pi:\\\\PISRV1\\sinusoid", startTime = "y-2d", endTime = "t", intervals = 30, selectedFields = "items.value;items.timestamp")
response6c <- piWebApiService$data$getPlotValues(path = "af:\\\\PISRV1\\UCDavisBuildings\\Buildings\\Buildings\\Academic Surge Building\\Electricity|Demand", startTime = "y-2d", endTime = "t", intervals = 30)


response7a <- piWebApiService$data$getMultipleRecordedValues(paths = paths, startTime = "y-200d", endTime = "t")
response7b <- piWebApiService$data$getMultipleRecordedValues(paths = paths, startTime = "y-200d", endTime = "t", selectedFields = "items.items.value;items.items.timestamp")


response8a <- piWebApiService$data$getMultipleInterpolatedValues(paths = paths, startTime = "y-200d", endTime = "t", interval = "1h")
response8b <- piWebApiService$data$getMultipleInterpolatedValues(paths = paths, startTime = "y-200d", endTime = "t", interval = "1h", selectedFields = "items.items.value;items.items.timestamp")


response9a <- piWebApiService$data$getMultiplePlotValues(paths = paths, startTime = "y-200d", endTime = "t", intervals = 30)
response9b <- piWebApiService$data$getMultiplePlotValues(paths = paths, startTime = "y-200d", endTime = "t", intervals = 30, selectedFields = "items.items.value;items.items.timestamp")

 

 

The path from the methods above should start with "pi:" (if your stream is a PI Point) or "af:" (if your stream is an AF attribute).

 

Create a PI Point

 

newPoint <- PIPoint(NULL, NULL, "SINUSOIDR", NULL, "12 Hour Sine Wave", "classic", "Float32", NULL, NULL, NULL, NULL, NULL)
response10 = piWebApiService$dataServer$createPoint("s0TJVKOA0Ws0KihcA8rM1GogUElGSVRORVNTLVNSVjI", newPoint)
Send values in bulk using the StreamSet/UpdateValuesAdHoc


timedValue1 <- PITimedValue(timestamp = "2017-04-26T17:40:54Z", value = 30)
timedValue2 <- PITimedValue(timestamp = "2017-04-27T17:40:54Z", value = 31)
timedValue3 <- PITimedValue(timestamp = "2017-04-26T17:40:54Z", value = 32)
timedValue4 <- PITimedValue(timestamp = "2017-04-27T17:40:54Z", value = 33)
t1 <- list(timedValue1, timedValue2)
t2 <- list(timedValue3, timedValue4)
s1 <- PIStreamValues(webId = webIds[1], items = t1);
s2 <- PIStreamValues(webId = webIds[2], items = t2);
values <- list(s1, s2)
response11 <- piWebApiService$streamSet$updateValuesAdHoc(values, "BufferIfPossible", "Replace");
Update the description from a PI Point


createdPoint <- piWebApiService$point$getByPath("\\\\PIFITNESS-SRV2\\SINUSOIDR")
updatePoint <- PIPoint()
updatePoint$Descriptor <- "12 Hour Sine Wave for R"
response12 <- piWebApiService$point$update(createdPoint$WebId, updatePoint)

 

Delete a PI Point

 

response13 <- piWebApiService$point$delete(createdPoint$WebId)

 

Using PI Batch to increase performance

 

getSinReq <- list(Method = "GET", Resource = "https://cross-platform-lab-uc2017.osisoft.com/piwebapi/points?path=\\\\pifitness-srv2\\sinusoid")
getCdtReq <- list(Method = "GET", Resource = "https://cross-platform-lab-uc2017.osisoft.com/piwebapi/points?path=\\\\pifitness-srv2\\cdt158")
getData <- list(Method = "GET", Resource = "https://cross-platform-lab-uc2017.osisoft.com/piwebapi/streamsets/value?webid={0}&webid={1}")
getData$Parameters <- c("$.sinu.Content.WebId", "$.cdt.Content.WebId")
getData$ParentIds <- c("sinu", "cdt")
batch <- list(sinu = getSinReq, cdt = getCdtReq, data = getData);
response14 <- piWebApiService$batch$execute(batch)
content(response11)

 

 

Create a SecurityEntry on an element

 

allowRight <- array(1:2)
allowRight[1] = "Read"
allowRight[2] = "ReadData"
denyRights <- array(1:3)
denyRights[1] = "Write"
denyRights[2] = "Execute"
denyRights[3] = "Admin"
securityEntry <- PISecurityEntry(securityIdentityName = "SwaggerIdentity", allowRights = as.list(allowRight), denyRights = as.list(denyRights))
response15 <- piWebApiService$element$createSecurityEntry(elementWebId, securityEntry, TRUE);

 

Get a SecurityEntry of an element

 

response16 <- piWebApiService$element$getSecurityEntries(elementWebId)

 

Update a SecurityEntry of an element

 

allowRight <- array(1)
allowRight[1] = "Read"
denyRights <- array(1:4)
denyRights[1] = "Write"
denyRights[2] = "Execute"
denyRights[3] = "Admin"
denyRights[4] = "ReadData"
securityEntry <- PISecurityEntry(allowRights = allowRight, denyRights = denyRights)
response17 <- piWebApiService$element$updateSecurityEntry("SwaggerIdentity", elementWebId, securityEntry, TRUE)

 

 

Final Remarks

 

We hope that data scientists will be able to integrate the PI System with R easier using this R package since it can return R data frame objects.

 

Please share your comments and suggestions below!

Introduction

 

Today we release our first version of the PI Web API client library for Python . The purpose of using this library is to make it easier the integration of a Python application with the PI System through PI Web API. This library is a client RESTful web service. All server methods from PI Web API 2017 are available on the library. As a result, you don't need to generate the URL in order to make an HTTP request. The library will generate for you automatically!

 

You can visit the GitHub repository of this library here.

 

Requirements

 

  • Python 2.7 or Python 3.4+

 

Installation

 

Before we start, it is good to mention that we don't recommend using this library with Anaconda. Try to use a clean Python instance instead.

 

pip install

 

If the python package is hosted on Github, you can install directly from Github

 

pip install git+https://github.com/osimloeff/PI-Web-API-Client-Python.git

 

You may need to run pip with root permission: sudo pip install git+https://github.com/osimloeff/PI-Web-API-Client-Python.git. If you are using Windows, remember to open the command prompt running as administrator. You must have Git installed on your machine.

 

Then import the package:

 

import osisoft.pidevclub.piwebapi 

 

Setuptools

 

Install via Setuptools.

 

python setup.py install --user

 

(or sudo python setup.py install to install the package for all users)

 

 

Then import the package:

import osisoft.pidevclub.piwebapi

 

 

This library was tested using PyCharm 2017.1.5.

 

 

Documentation

 

All classes and methods are described on the DOCUMENTATION.

 

Examples

 

Please check the test_main.py from this repository. Below there are also code snippets written in Python for you to get started using this library:

 

Create an instance of the PI Web API top level object.

 

    from osisoft.pidevclub.piwebapi.pi_web_api_client import PIWebApiClient
    client = PIWebApiClient("https://test.osisoft.com/piwebapi", False, "username", "password", True)  

 

Only Basic Authentication is available in this version. Therefore, the variable useKerberos should always be False. Do not forget to set the username and password accordingly.

 

Retrieving PI data to an Python pandas data frame

 

    df1 = client.data.get_recorded_values("pi:\\\\JUPITER001\\cdt158", None, None, "*-9d", None, None, None, None, "*-10d", None)df4 = client.data.get_multiple_recorded_values(["pi:\\JUPITER001\sinusoid", "pi:\\JUPITER001\sinusoidu", "pi:\\JUPITER001\cdt158"],None, "*", None, None, None, None, "*-1d", None)
    df2 = client.data.get_interpolated_values("pi:\\JUPITER001\\sinusoidu",None, "*", None, None, "2h", None, "*-1d", None)
    df3 = client.data.get_plot_values("pi:\\\\JUPITER001\\sinusoidu", None, "*", 10, None, "*-3d", None)
    df4 = client.data.get_recorded_values("pi:\\\\PISRV1\\sinusoid", None, None, "*", None, None, None, "items.value;items.timestamp", "*-1d", None)
    df5 = client.data.get_recorded_values("pi:\\\\PISRV1\\sinusoid", None, None, "*", None, None, None, "items.good;items.questionable;items.substituted", "*-1d", None)
    
    dfs1 = client.data.get_multiple_recorded_values(["pi:\\\\JUPITER001\\sinusoid", "pi:\\\\JUPITER001\\sinusoidu", "pi:\\\\JUPITER001\\cdt158", "af:\\\\JUPITER001\\Vitens\\Vitens\\Friesland province\\01 Production sites\\Production Site Noordbergum\\Distribution\\Quality|pH"],None, "*", None, None, None, None, "*-1d", None)
    dfs2 = client.data.get_multiple_interpolated_values(["pi:\\\\JUPITER001\\sinusoid", "pi:\\\\JUPITER001\\sinusoidu", "pi:\\\\JUPITER001\\cdt158", "af:\\\\JUPITER001\\Vitens\\Vitens\\Friesland province\\01 Production sites\\Production Site Noordbergum\\Distribution\\Quality|pH"], "*", None, None, "1d", None, "*-5d", None)
    dfs3 = client.data.get_multiple_plot_values(["pi:\\\\JUPITER001\\sinusoid", "pi:\\\\JUPITER001\\sinusoidu", "pi:\\\\JUPITER001\\cdt158", "af:\\\\JUPITER001\\Vitens\\Vitens\\Friesland province\\01 Production sites\\Production Site Noordbergum\\Distribution\\Quality|pH"], "*", 10, None, "*-1d", None)
    dfs4 = client.data.get_multiple_recorded_values(paths, None, "*", None, None, None, "items.items.value;items.items.timestamp", "*-1d", None)
    dfs5 = client.data.get_multiple_interpolated_values(paths, "*", None, None, "1h", "items.items.value;items.items.timestamp", "*-5d", None)

 

 

The path from the methods above should start with "pi:" (if your stream is a PI Point) or "af:" (if your stream is an AF attribute).

 

Get the PI Data Archive WebId

 

    dataServer = client.dataServer.get_by_path("\\\\JUPITER001", None);

 

Create a new PI Point

 

    newPoint = PIPoint()
    newPoint.name  = "SINUSOID_TEST"
    newPoint.descriptor = "Test PI Point for Python PI Web API Client"
    newPoint.point_class = "classic"
    newPoint.point_type = "float32"
    newPoint.future = False
    res = client.dataServer.create_point_with_http_info(dataServer.web_id, newPoint);    

 

Get PI Points WebIds

 

 

    point1 = client.point.get_by_path("\\\\JUPITER001\\sinusoid", None)
    point2 = client.point.get_by_path("\\\\JUPITER001\\cdt158", None)
    point3 = client.point.get_by_path("\\\\JUPITER001\\sinusoidu", None)

 

 

Get recorded values in bulk using the StreamSet/GetRecordedAdHoc

 

 

    webIds = list()
    webIds.append(point1.web_id);
    webIds.append(point2.web_id);
    webIds.append(point3.web_id);
    piItemsStreamValues = client.streamSet.get_recorded_ad_hoc(webIds, None, "*", None, True, 1000, None, "*-3d", None);

   

Send values in bulk using the StreamSet/UpdateValuesAdHoc

 

 

    streamValuesItems = PIItemsStreamValues()
    streamValue1 = PIStreamValues()
    streamValue2 = PIStreamValues()
    streamValue3 = PIStreamValues()

    value1 = PITimedValue()
    value2 = PITimedValue()
    value3 = PITimedValue()
    value4 = PITimedValue()
    value5 = PITimedValue()
    value6 = PITimedValue()

    value1.value = 2
    value1.timestamp = ("*-1d")
    value2.value = 3
    value2.timestamp = ("*-2d")
    value3.value = 4
    value3.timestamp = ("*-1d")
    value4.value = 5
    value4.timestamp = ("*-2d")
    value5.value = 6
    value5.timestamp = ("*-1d")
    value6.value = 7
    value6.timestamp = ("*-2d")


    streamValue1.web_id = point1.web_id
    streamValue2.web_id = point2.web_id
    streamValue3.web_id = point3.web_id


    values1 = list()
    values1.append(value1)
    values1.append(value2)
    streamValue1.items = values1


    values2 = list()
    values2.append(value3)
    values2.append(value4)
    streamValue2.items = values2


    values3 = list()
    values3.append(value5)
    values3.append(value6)
    streamValue3.items = values3


    streamValues = list()
    streamValues.append(streamValue1)
    streamValues.append(streamValue2)
    streamValues.append(streamValue3)
    response = client.streamSet.update_values_ad_hoc_with_http_info(streamValues, None, None)

 

 

Get an element and an attribute by path

 

    element = client.element.get_by_path("\\\\JUPITER001\\Universities\\UC Davis", None)
    attribute = client.attribute.get_by_path("\\\\JUPITER001\\Universities\\UC Davis\\Buildings|Campus Average EUI", "Name")

 

Final Remarks

 

It has never been easier to integrate the PI System with Python. By writing just some lines of code, it is very easy to retrieve PI data into Python through PI Web API.

 

Please share your comments and suggestions below!

Filter Blog

By date: By tag: