ナビゲーションをスキップする
All Places > All Things PI - Ask, Discuss, Connect > Japan PI Square > ブログ > 2016 > July
2016

PI Web APIではBatchリクエストという機能があります。 PI Web API 2016から正式サポートされています。

通常、PI Web APIで値を取得したい場合、以下の流れとなります。

1 オブジェクト (PIタグ, 属性)のWebIDを取得するクエリ

2 そのWebIDを使用して値取得のクエリ

 

このように最低でも2回クエリを出さなければならないですが、Batchリクエストを使用すれば1度のクエリで値取得まで可能です。

ヘルプにてこの機能を確認できます。

https://PIWebAPIMachineName/piwebapi/help/

Controllers > Batch > Execute

最も簡単なサンプルは以下です。3 つのクエリが含まれています。

{  
 "GetPIServer": {  
   "Method": "GET",  
   "Resource": "https://localhost/piwebapi/dataservers?path=\\\\localhost"  
 },  
 "GetPoints": {  
   "Method": "GET",  
   "Resource": "{0}?nameFilter=sinusoid",  
   "Parameters": [  
     "$.GetPIServer.Content.Links.Points"  
   ],  
   "ParentIds": [  
     "GetPIServer"  
   ]  
 },  
 "GetValues": {    
   "Method": "GET",   
   "RequestTemplate": {  
        "Resource": "https://localhost/piwebapi/streams/{0}/value"  
   },  
   "Parameters": ["$.GetPoints.Content.Items[*].WebId" ],  
   "ParentIds": [    
     "GetPoints"    
   ]  
 }  
}  

たとえばPostmanを使用する場合、

https://PIWebAPIMachineName/piwebapi/batch のアドレスにPOSTリクエストします。

Bodyはraw > JSON (application/json)とし、上記クエリをそのまま貼り付けます。(サーバーlocalhostは変えてください)

実行結果は以下となります。

まず、"GetPIServer"では以下が返されます。

{
  "GetPIServer": {
    "Status": 200,
    "Headers": {
      "Content-Type": "application/json; charset=utf-8",
      "Content-Length": "500"
    },
    "Content": {
      "WebId": "s0HpFdn0K2z0uPQL0sTSJJEQS0hBU0hJTU9UT0U2NDQw",
      "Id": "9f5d911e-b642-4bcf-8f40-bd2c4d224911",
      "Name": "xx”
      "IsConnected": true,
      "ServerVersion": "3.4.400.1162",
      "Links": {
        "Self": "https://localhost/piwebapi/dataservers/s0HpFdn0K2z0uPQL0sTSJJEQS0hBU0hJTU9UT0U2NDQw",
        "Points": "https://localhost/piwebapi/dataservers/s0HpFdn0K2z0uPQL0sTSJJEQS0hBU0hJTU9UT0U2NDQw/points",
        "EnumerationSets": "https://localhost/piwebapi/dataservers/s0HpFdn0K2z0uPQL0sTSJJEQS0hBU0hJTU9UT0U2NDQw/enumerationsets"
      }
    }
  },

”GetPoints"では"Parameters":で"$.GetPIServer.Content.Links.Points"が指定されているため、上記GetPIServerの返り値のPointsのリンクが使用されます。

("https://localhost/piwebapi/dataservers/s0HpFdn0K2z0uPQL0sTSJJEQS0hBU0hJTU9UT0U2NDQw/points")

"Resource": "{0}?nameFilter=sinusoid"となっているため、以下がGetPointsでのクエリです。

https://localhost/piwebapi/dataservers/s0HpFdn0K2z0uPQL0sTSJJEQS0hBU0hJTU9UT0U2NDQw/points?nameFilter=sinusoid

以下が返されます。

"GetPoints": {
    "Status": 200,
    "Headers": {
      "Content-Type": "application/json; charset=utf-8",
      "Content-Length": "1247"
    },
    "Content": {
      "Links": {},
      "Items": [
        {
          "WebId": "P0HpFdn0K2z0uPQL0sTSJJEQFioAAAS0hBU0hJTU9UT0U2NDQwXFNJTlVTT0lE",
          "Id": 10774,
          "Name": "sinusoid",
          "PointClass": "classic",
          "PointType": "Float32",
          "Future": false,
          "Links": {
            "Self": "https://localhost/piwebapi/points/P0HpFdn0K2z0uPQL0sTSJJEQFioAAAS0hBU0hJTU9UT0U2NDQwXFNJTlVTT0lE",
            "DataServer": "https://localhost/piwebapi/dataservers/s0HpFdn0K2z0uPQL0sTSJJEQS0hBU0hJTU9UT0U2NDQw",
            "Attributes": "https://localhost/piwebapi/points/P0HpFdn0K2z0uPQL0sTSJJEQFioAAAS0hBU0hJTU9UT0U2NDQwXFNJTlVTT0lE/attributes",
            "Value": "https://localhost/piwebapi/streams/P0HpFdn0K2z0uPQL0sTSJJEQFioAAAS0hBU0hJTU9UT0U2NDQwXFNJTlVTT0lE/value",
            "InterpolatedData": "https://localhost/piwebapi/streams/P0HpFdn0K2z0uPQL0sTSJJEQFioAAAS0hBU0hJTU9UT0U2NDQwXFNJTlVTT0lE/interpolated",
            "RecordedData": "https://localhost/piwebapi/streams/P0HpFdn0K2z0uPQL0sTSJJEQFioAAAS0hBU0hJTU9UT0U2NDQwXFNJTlVTT0lE/recorded",
            "PlotData": "https://localhost/piwebapi/streams/P0HpFdn0K2z0uPQL0sTSJJEQFioAAAS0hBU0hJTU9UT0U2NDQwXFNJTlVTT0lE/plot",
            "SummaryData": "https://localhost/piwebapi/streams/P0HpFdn0K2z0uPQL0sTSJJEQFioAAAS0hBU0hJTU9UT0U2NDQwXFNJTlVTT0lE/summary",
            "EndValue": "https://localhost/piwebapi/streams/P0HpFdn0K2z0uPQL0sTSJJEQFioAAAS0hBU0hJTU9UT0U2NDQwXFNJTlVTT0lE/end"
          }
        }
      ]
    }
  },

最後に"GetValues"が実行され、以下がその返り値です。

"GetValues": {
    "Status": 207,
    "Headers": {},
    "Content": {
      "Total": 1,
      "Items": [
        {
          "Status": 200,
          "Headers": {
            "Content-Type": "application/json; charset=utf-8",
            "Content-Length": "129"
          },
          "Content": {
            "Timestamp": "2016-07-13T07:55:57Z",
            "Value": 76.51479,
            "UnitsAbbreviation": "",
            "Good": true,
            "Questionable": false,
            "Substituted": false
          }
        }
      ]
    }
  }

これらの3つの結果はすべてまとめて1つの返り値として返されます。

よって最終的な値76.51479は一度のクエリで取得できるのです。

 

Sinusoidタグに値を書くBatchの例は以下です。

{  
 "GetPIServer": {  
   "Method": "GET",  
   "Resource": "https://localhost/piwebapi/dataservers?path=\\\\localhost" 
 },  
 "GetPoints": {  
   "Method": "GET",  
   "Resource": "{0}?nameFilter=sinusoid",  
   "Parameters": [  
     "$.GetPIServer.Content.Links.Points" 
   ], 
   "ParentIds": [  
     "GetPIServer" 
   ] 
 },  
 "GetValues": {    
   "Method": "POST",   
   "RequestTemplate": {  
        "Resource": "https://localhost/piwebapi/streams/{0}/value" 
   },
 "Content": "{Value:777}",
 "Parameters": ["$.GetPoints.Content.Items[*].WebId" ],  
   "ParentIds": [    
     "GetPoints" 
   ] 
 }  
}  

 

以下はPythonを使ったPI Web APIのbatchクエリサンプルです。

import requests
requests.packages.urllib3.disable_warnings()

s = requests.session()


data = {  
 "GetPIRandomTags": {  
   "Method": "GET",  
   "Resource": "https://PIWebAPIMachineName/piwebapi/search/query?q=pointsource:R"  
 },   
 "GetValues": {    
   "Method": "GET",   
   "RequestTemplate": {  
        "Resource": "https://PIWebAPIMachineName/piwebapi/streams/{0}/value"  
   },  
   "Parameters": ["$.GetPIRandomTags.Content.Items[*].WebID" ],  
   "ParentIds": [    
     "GetPIRandomTags"    
   ]  
 }  
} 

s.auth = ('username', 'password')

# You should remove verify=False if the certificate used is a trusted one.
response = s.post("https://PIWebAPIMachineName/piwebapi/batch", json=data, verify=False)

tags = [tag['Name'] for tag in response.json()['GetPIRandomTags']['Content']['Items']]
print(tags)
values = [tag['Content']['Value'] for tag in response.json()['GetValues']['Content']['Items']]
print(values)

本ポストはJerome Lefebvreと一緒に作成しました。