Marcos Vainer Loeff

Announcing PI Web API client library for Angular 4

Blog Post created by Marcos Vainer Loeff Employee on Oct 30, 2017



Today we release our first version of the PI Web API client library for Angular 4 (the newest version of AngularJS) . The purpose of using this library is to make it easier the integration of an Angular web 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.


You can visit the web page about this npm package here.


Although this library was tested with Angular 4, it should also be compatible with Angular 2.


The version for AngularJS was already released.


What is Angular?


According to the Angular official documentation:


"Angular is a platform that makes it easy to build applications with the web. Angular combines declarative templates, dependency injection, end to end tooling, and integrated best practices to solve development challenges. Angular empowers developers to build applications that live on the web, mobile, or the desktop."




  • NodeJS (npm is going to be used to download the library)
  • Text Editor (Visual Studio Code is recommended)
  • Angular 4+




To install this library, run:


npm install angular-piwebapi --save


Consuming your library


Update your Angular AppModule by adding the PIWebAPIService as a provider:


import { PIWebAPIService } from 'angular-piwebapi';
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { HttpModule } from '@angular/http';
import { AppComponent } from './app.component';

  declarations: [
  imports: [
  providers: [PIWebAPIService],
  bootstrap: [AppComponent]
export class AppModule { }





All classes and methods are described on the DOCUMENTATION.



Please check the sample_main.ts from this repository. Below there are also code snippets written in Angular 4 for you to get started using this library:


Set up the instance of the PI Web API top level object.

If you want to use basic authentication instead of Kerberos, set useKerberos to false and set the username and password as shown below:


Basic authentication


    this.piWebApiHttpService.configureInstance("", false, "username", "password");


Kerberos authentication


    this.piWebApiHttpService.configureInstance("", true);


If you want to test if it connects, just execute the code below:


    this.piWebApiHttpService.home.get().subscribe(res => {
    }, error => {


Get the PI Data Archive WebId


    this.piWebApiHttpService.dataServer.getByPath('\\\\SERVERNAME').subscribe(res => {
    }, error => {


Create a new PI Point


    var pointName = "SINUSOID_TEST74" + Math.trunc(100000*Math.random());
    var newPoint = new PIPoint(null, null, pointName, null, "Test PI Point for Angular PI Web API Client", "classic", "float32", null, null, null, false);    
    this.piWebApiHttpService.dataServer.createPoint(res.WebId, newPoint).subscribe(res => {
}, error => {



Get PI Point WebId


    this.piWebApiHttpService.point.getByPath("\\\\MARC-PI2016\\sinusoid").subscribe(res => {
    }, error => {


Get recorded values in bulk using the StreamSet/GetRecordedAdHoc


    var point1webId = "P0QuorgJ0MskeiLb6TmEmH5gAQAAAATUFSQy1QSTIwMTZcU0lOVVNPSUQ";
    var point2webId = "P0QuorgJ0MskeiLb6TmEmH5gAgAAAATUFSQy1QSTIwMTZcU0lOVVNPSURV";
    var point3webId = "P0QuorgJ0MskeiLb6TmEmH5g9AQAAATUFSQy1QSTIwMTZcQ0RUMTU4";

    var webIds = []

    this.piWebApiHttpService.streamSet.getRecordedAdHoc(webIds, null, "*", null, true, 1000, null, "*-3d", null).subscribe(res => {
    }, error => {


Send values in bulk using the StreamSet/UpdateValuesAdHoc


    let streamValuesItems : PIItemsStreamValues = new PIItemsStreamValues()
    let streamValue1 : PIStreamValues = new PIStreamValues()
    let streamValue2 : PIStreamValues = new PIStreamValues()
    let streamValue3 : PIStreamValues = new PIStreamValues()

    let value1 : PITimedValue = new PITimedValue()
    let value2 : PITimedValue = new PITimedValue()
    let value3 : PITimedValue = new PITimedValue()
    let value4 : PITimedValue = new PITimedValue()
    let value5 : PITimedValue = new PITimedValue()
    let value6 : PITimedValue = new 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.WebId = point1webId
    streamValue2.WebId = point2webId
    streamValue3.WebId = point3webId

    var values1 = [];
    streamValue1.Items = values1

    var values2 = [];
    streamValue2.Items = values2

    var values3 = [];
    streamValue3.Items = values3

    var streamValues = []
    this.piWebApiHttpService.streamSet.updateValuesAdHoc(streamValues, null, null).subscribe(res => {
    }, error => {


Using PI Web API Batch


 var pirequest = {};
    pirequest["4"] = {
        "Method": "GET",
        "Resource": "\\\\MARC-PI2016\\sinusoid",
        "Headers": {
            "Cache-Control": "no-cache"
    pirequest["5"] = {
        "Method": "GET",
        "Resource": "\\\\MARC-PI2016\\cdt158",
        "Headers": {
            "Cache-Control": "no-cache"
    pirequest["6"] = {
        "Method": "GET",
        "Resource": "{0}&webid={1}",
        "Parameters": [
        "ParentIds": [
    this.piWebApiHttpService.batch.execute(pirequest).subscribe(res => {
    }, error => {



If you know the name of the action and controller, you probably need to make a call similar to:




Please read the PI Web API programming reference to find out the names of the actions, controllers and inputs.


If you want to find out the order of the inputs, please refer to DOCUMENTATION and search for the method you want to use.


Developing a modern app with PI Web API client library for Angular


Do you remember my old blog post about Using PI Web API with Angular 2?


On that blog post, we have created a PIWebAPIService class in order to make HTTP requests against PI Web API.


This time let's rewrite the file app.component.ts in order to use the library methods instead. This is a good example about how this library should be used after downloading it with npm and updating the file app.module.ts.


import { Component } from '@angular/core';
import { PIWebAPIService, PIItemsStreamValues, PIPoint, PITimedValue, PIStreamValues } from 'angular-piwebapi';

export class ComboboxOption {
  value: boolean;
  name: string;

  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
export class AppComponent {
  requestMode = true;
  piServerName: string;
  piPointName: string;
  startTime: string;
  endTime: '*';
  interval: '1h';
  yesOrNoOptions: ComboboxOption[] = [{ 'value': true, 'name': 'Yes' }, { 'value': false, 'name': 'No' }];
  getSnap: ComboboxOption = this.yesOrNoOptions[0];
  getRec: ComboboxOption = this.yesOrNoOptions[0];
  getInt: ComboboxOption = this.yesOrNoOptions[0];
  piServerData: any;
  piServerExistsValue: boolean;
  piServerError: any;
  piPointData: any;
  piPointExistsValue: boolean;
  webId: string;
  snapshotData: any;
  snapshotError: any;
  recordedData: any;
  interpolatedData: any;
  recordedError: any;
  interpolatedError: any;
  piPointError: any;

  constructor(private piWebApiHttpService: PIWebAPIService) { }

  defaultValues(): void {
    this.piServerName = 'PISRV1';
    this.piPointName = 'SINUSOID';
    this.startTime = '*-1d';
    this.endTime = '*';
    this.interval = '1h';
    this.getSnap = this.yesOrNoOptions[0];
    this.getRec = this.yesOrNoOptions[0];
    this.getInt = this.yesOrNoOptions[0];
  // get data by making http calls
  getData(): void {
    this.piWebApiHttpService.configureInstance("", false, "webapiuser", "!try3.14webapi!");

    // switch div to display the results
    this.requestMode = false;
    // all HTTP requests are done through the  piWebApiHttpService factory object
    this.piWebApiHttpService.dataServer.getByPath('\\\\' + this.piServerName)  
      .subscribe(res => {
        this.piServerData = res;
        this.piServerExistsValue = true;
      error => {
        this.piServerError = error;
        this.piServerExistsValue = false;

      this.piWebApiHttpService.point.getByPath('\\\\' + this.piServerName + '\\' + this.piPointName, null, null).subscribe(res => {
        this.piPointData = res
        this.piPointExistsValue = true
        //in case of success, we will get the webId of the PI Point which will be used by other requests
        this.webId = res.WebId; => {
            //Response of the snapshot is stored on the snapshotData
            this.snapshotData = res
        }, error => {
            this.snapshotError = error

, null, null, this.endTime, null, null, null, null, this.startTime).subscribe(res => {
            this.recordedData = res
          }, error => {
            this.recordedError = error
        });, null, this.endTime, null, null, this.interval, null, this.startTime, null).subscribe(res => {
            this.interpolatedData = res
          }, error => {
            this.interpolatedError = error.json();
      }, error => {
        this.piPointError =
        this.piPointExistsValue = false



Final Remarks


It is a great enhancement the fact that you can download this library through npm. I hope that with this new release, developing modern apps on top of the PI System will become even easier!


Please share your comments and suggestions below!