Kenji Hashimoto

PI Web APIを使用したPI Coresight 2016 R2 カスタムシンボルによる値書き込み

Blog Post created by Kenji Hashimoto on Dec 1, 2016

This post is Japanese version of PI Coresight 2016 R2 Put Value Custom Symbol by PI Web API . (このブログはリンク先の日本語版です)

以前にPI Coresight 2016のカスタムシンボルでPIWebAPIを使用して値を書き込む方法を紹介しました。

The specified item was not found.

PICoresight2016R2がリリースされ、このPI Coresight 2016向けのカスタムシンボルはR2では動作しないため、コードを修正しました。(PI Vision用に変更してあります)

このコードを参考にしていただくことでPI CoresightからPI Web APIを使用するカスタムシンボルを作成していただけると思います。

コードはGitHubからダウンロードしていただけます。

GitHub - kenji0711/PICoresight2016R2-CustomSymbol-PutValue

また別のサンプルもございます。

https://pisquare.osisoft.com/community/developers-club/blog/2017/03/17/the-pi-developers-club-pod-uc-2017

 

 

以下の画面では250という値を現在のタイムスタンプでcdt158のタグに書き込んでいます。属性がタグに紐づいていれば属性にも値を書くことができます。

新しい値をボックスに入力し、"Put New Value"をクリックします。新しい値はPI Web APIにより、PI Data ArchiveかAFに現在時刻のタイムスタンプとともに書き込まれます。

書き込み用のボックスは 右クリック > Format Symbolより隠すことも可能です。

コードのポイントはPI Web APIのBatch リクエストを使用している点です。

バッチリクエストについては以下をご参照ください。

PI Web API Batchリクエストの紹介

 

以下3つのファイルを%PIHOME64%\Coresight\Scripts\app\editor\symbols\extフォルダにコピーします。

添付されたイメージpen.svgは%PIHOME64%\Coresight\Imagesフォルダにコピーします。

 

sym-putvalue.js (コード内のvar piwebapiaddress = "MachineName"は適切なPI Web APIマシン名に変更してください。PI CoresightマシンはPI Web APIが含まれるので、ここではPI Coreisghtマシンが該当します。)

(function (PV) {    
    var userName = PV.IdentityContext.FriendlyUserName.toUpperCase();    
    var index = userName.indexOf("\\",0);    
    var userNamewithoutDomain = userName.substr(index + 1);    
    function symbolVis() { }    
    PV.deriveVisualizationFromBase(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;    
        if(data.Path){    
         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,"\\\\");      
            if(ini=="pi:"){      
                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      
            xhr.open("POST",batchurl,true);      
            //Set credential for Kerberos      
            xhr.withCredentials = true;      
            xhr.setRequestHeader('Content-Type','application/json');      
            //Send request      
            xhr.send(contents);      
                
        };      
  };    
    var definition = {    
        typeName: 'putvalue',    
        iconUrl:'/Scripts/app/editor/symbols/ext/Icons/pen.svg',    
        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' ]    
    };  
    PV.symbolCatalog.register(definition);    
})(window.PIVisualization);    

sym-putvalue-config.html

<div class="c-side-pane t-toolbar">  
    <span style="color:#fff; margin-left:15px">Text Color</span>  
</div>  
<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>  
<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>  
<div class="c-config-content">Show Label:  
    <input type="checkbox" ng-model="config.ShowLabel">  
</div>  
<div class="c-config-content">Show Time:  
    <input type="checkbox" ng-model="config.ShowTime">  
</div>  
<div class="c-config-content">Show PutValue:    
    <input type="checkbox" ng-model="config.ShowPutValue">    
</div>    

sym-putvalue-template.html

<div ng-style="{background: config.BackgroundColor, color: MultistateColor || config.TextColor}">    
    <div ng-show="config.ShowLabel">{{label}}</div>    
    <div>{{value}}</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>    
    </div>    
</div>    

このコードを実行するためにAFのConfigurationデータベースのPI Web APIの設定を変更する必要がありました。

CoresMethods = *, CorsHeaders = *, CorsOrigins = * , CorsSupportsCredentials = True (私はAuthentication MethodsにKerberosを使用しています )

HTTPSの証明書はグローバルサインのものを使用するべきです。または自己証明書の場合、クライアントマシンにてその証明書を登録し、証明書のエラーにならないようにする必要があります。

是非PI Visionから値を書き込んでみてください。

Attachments

Outcomes