Marcos Vainer Loeff

Announcing PI Web API R package

Blog Post created by Marcos Vainer Loeff Employee on Dec 12, 2017

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!

Outcomes