Kenji Hashimoto

PI Coresight 2016 R2 Put Value Custom Symbol by PI Web API

Blog Post created by Kenji Hashimoto on Dec 1, 2016

I created write value custom symbol by PI Coresight 2016.

The specified item was not found.

Since PI Coresight 2016 R2 and this old custom symbol does not work anymore, I created new one. (Edit 2017/05/30 : Changed the code to PI Vision 2017)

Also for writing value, we have a good example on

Thank you Anna Perry. It works by PI Vision 2017 too.


This example calls PI Web API to write value. So you can create custom symbol with PI Web API from now on.

You can download the code from GitHub. (Changed the code to PI Vision 2017)

GitHub - kenji0711/PICoresight2016R2-CustomSymbol-PutValue


(In this display I put "250" value to cdt158 tag.) It is possible to write value to AF attribute too if the attribute is from PI tags!

Put the new value to the box and click "Put New Value" text. It uploads the new value to PI data Archive or AF with current timestamp by PI Web API.

It can be hided by right click > Format Symbol

The point is that this code uses PI Web API Batch request.

Copy following 3 files to %PIHOME64%\PIVision\Scripts\app\editor\symbols\ext folder.

Also copy the image (attaced pen.svg) to Scripts\app\editor\symbols\ext\Icons folder.

sym-putvalue.js (Please change var piwebapiaddress = "MachineName"; to your PI Web API machine name. PI Coresight machine contains PI Web API. So it should be PI Vision machine name)

Also a lot of people interested in to register the custom symbol to the specific user.

So I tried the code to check browser user name. if the user is 'KHASHIMOTO' then this custom symbol appears however, the other users open it, it does not shows up if you put the following code on the sym-putvalue.js file.

if (userNamewithoutDomain == 'KHASHIMOTO')



(function (PV) {  
    var userName = PV.IdentityContext.FriendlyUserName.toUpperCase();  
    var index = userName.indexOf("\\",0);  
    var userNamewithoutDomain = userName.substr(index + 1);  
    function symbolVis() { }  
    symbolVis.prototype.init = function (scope) {  
     this.onDataUpdate = dataUpdate; 
     //default value for timestamp
     scope.config.TimeBox = '*';
     function dataUpdate(data) {  
    if(data) {  
        scope.value = data.Value;  
        scope.time = data.Time;  
         scope.path = data.Path;  
        if(data.Label) {  
            scope.label = data.Label;  

     scope.putvalue = function() {    
            var piwebapiaddress = "khashimotoe6440";    
            //scope.path contains pi:\\servername\tagname or af:\\servername\databasename\element...|attribute    
            var ini = scope.path.substr(0,3);    
            var orgpath = scope.path.substr(3,10000);    
            //To double the backslash -  \\\\servername\\tagname    
            var path = orgpath.replace(/\\|\\/g,"\\\\");    
                var urladdress = "\"https://" + piwebapiaddress + "/piwebapi/points?path="+path+"\"";    
            else if(ini=="af:"){    
                var urladdress = "\"https://" + piwebapiaddress + "/piwebapi/attributes?path="+path+"\"";    
            //Get text box value    
            var valueboxval = new String(scope.config.ValueBox, { "type" : "text/plain" });
            var timeboxval = new String(scope.config.TimeBox, { "type" : "text/plain" });    
            //Create value contents as json    
            var jsonval = '"{Timestamp : \'' + timeboxval + '\', Value:\'' + valueboxval + '\'}"';
            //var jsonval = '"{Value:' + valueboxval + '}"';    
            // Create contents of PI Web API batch request
            var contents = '{"GetWebID":{"Method": "GET","Resource": '+ urladdress + '},"WriteValuetoPI":{"Method":"POST","Resource": "{0}","Content":' + jsonval + ',"Parameters": ["$.GetWebID.Content.Links.Value"],"ParentIds": ["GetWebID"]}}';    
            //PI Web API Request    
            var batchurl = "https://" + piwebapiaddress + "/piwebapi/batch";
            var xhr= new XMLHttpRequest();    
            //true = Async call    
            //Set credential for Kerberos    
            xhr.withCredentials = true;    
            //Send request    
    var definition = {  
        typeName: 'putvalue',  
        datasourceBehavior: PV.Extensibility.Enums.DatasourceBehaviors.Single,  
        visObjectType: symbolVis,  
        getDefaultConfig: function() {  
            return {  
                DataShape: 'Value',  
                Height: 170,  
                Width: 180,  
            TextColor: 'rgb(255,255,255)',  
         ShowLabel: true,  
         ShowTime: true,  
         ShowPutValue: true  
    configTitle: 'Format Symbol',  
    StateVariables: [ 'MultistateColor' ]  



<div class="c-side-pane t-toolbar">
    <span style="color:#fff; margin-left:15px">Text Color</span>
<div class="config-option-format"><cs-color-picker id="textcolor" ng-model="config.TextColor"></cs-color-picker></div>
<div class="c-side-pane t-toolbar">
    <span style="color:#fff; margin-left:15px">Background Color</span>
<div class="config-option-format"><cs-color-picker id="backgroundcolor" ng-model="config.BackgroundColor"></cs-color-picker></div>
<div class="c-side-pane t-toolbar">
    <span style="color:#fff; margin-left:15px">Show Options</span>
<div class="c-config-content">Show Label:
    <input type="checkbox" ng-model="config.ShowLabel">
<div class="c-config-content">Show Time:
    <input type="checkbox" ng-model="config.ShowTime">
<div class="c-config-content">Show PutValue:  
    <input type="checkbox" ng-model="config.ShowPutValue">  



<div ng-style="{background: config.BackgroundColor, color: MultistateColor || config.TextColor}">  
    <div ng-show="config.ShowLabel">{{label}}</div>  
    <div ng-show="config.ShowTime">{{time}}</div>  
    <div id='putvalue' ng-show="config.ShowPutValue">  
        Enter Timestamp :<br>
        <input type="text" style="margin-left:5px; width:120px;" name="timebox" ng-model="config.TimeBox" /><br>  
        Enter new Value :<br>
        <input type="text" style="margin-left:5px; width:120px;" name="valuebox" ng-model="config.ValueBox" /><br>  
        <a name='putvalue' type="button" ng-click="putvalue()">Put New Value</a><br>  

For using PI Web API from custom symbols, I needed to change CoresMethods = *, CorsHeaders = *, CorsOrigins = * and CorsSupportsCredentials = True in the AF configuration database. (I use Kerberos as Authentication Methods)

Enjoy the write value to PI from PI Vision!