# 北榮 PI 伺服器教育訓練 1.PI Web API:Piwebapiuser/p@ssw0rd@PI 1.1 API外部文件 : https://techsupport.osisoft.com/Documentation/PI-Web-API/help.html 1.2 API內部文件 : https://10.97.235.103/piwebapi/help 2.PI Server: 10.97.235.103 / 10.97.235.104 Administrator/p@ssw0rd#PI API Piwebapiuser /p@ssw0rd@PI 1.3 取得洗腎機台 取得洗腎機台 ID URI : http{s}://{hostname}:{port}/piwebapi/search/query?q=*bedid&count=100 均需先透過 bedid查詢取得個洗腎機台 查詢取得個洗腎機台 ID資訊及 webId 下面以獲取某特定床位之數據為例: 使用搜尋功能查找所有血液透析儀之在床位記錄點,訪問 URL範例: https://localhost/piwebapi/search/query?q=*bedid&count=100 URL參數列表中, q=*bedid代表點名以 bedid結尾; count=100代表單頁返回結果最多 代表單頁返回結果最多 https://10.97.235.103/piwebapi/search/query?q=2HDU*&count=100 1.4 URI : http{s}://{hostname}:{port}/piwebapi/{WebID}/value 獲取BedID點列表後,記錄點位之WebID,如 F1DPqdt6BsThFU-w3NhPIcyHDwGBYAAAUEktSURFU1w1VkNBMEpKS19CRURJRA 之後使用如下 URL獲取點位當前數據: https://localhost/piwebapi/streams/F1DPqdt6BsThFU-w3NhPIcyHDwGBYAAAUEktSURFU1w1VkNBMEpKS19CRURJRA/value 1.5 Batch API https://10.97.235.103:443/piwebapi/Batch 1.6 Excel plugin https://vghteams-my.sharepoint.com/:u:/g/personal/ycchu5_vghtpe_gov_tw/EeUZr5ZzQ29MmapXKUDxG_ABa6-owiAeXVxA7Kzteysk4A?e=i4nWxw 1.6.1取得PI tag ![](https://i.imgur.com/PaRj4GW.png) 1.6.2建立PI tag head ![](https://i.imgur.com/dwmjjqT.png) 1.6.3 抓資料 ![](https://i.imgur.com/55hrJXB.png) 1.6.4 OK ![](https://i.imgur.com/KbXrJPr.png) # 1 PI System 系統基礎 ## 1.1 PI System 系統結構 典型軟體系統結構: ![](https://i.imgur.com/JMe2Qs7.png) PI Interface or PI Connector: 從資料源收集資料 PI Data Archive: 儲存資料 PI Asset Framework: 組織資料結構&運行計算 PI Visualization Tool: 將數據呈現給用戶 PI Integrators: 將數據整理後呈送給其他資料分析系統 #### 典型硬體系統結構: ![](https://i.imgur.com/hGigkPX.png) ## 1.2 PI Points 任意隨時間變化之數值都可被收集進入 PI Data Archive,在工業領域,這種數值 (數據流)可能是: ⚫ 某存罐溫度 ⚫ 某發電機功率 ⚫ 某冷卻水泵流速 以上這些數據存入 PI Data Archive 時,每一個數據流構成一個 PI Point,也稱為 PI Tag,當有新的數據流需要接入 PI System 時,PI 系統管理員會創建一個新的 PI Point。 練習 – 使用 PI SMT 搜索 PI 點,查看當前數值 ⚫ 開始菜單->PI System->PI System Management Tools ⚫ 左側導航欄選 Data -> Current Values ⚫ 點擊 Tag Search 圖標 ⚫ Tag Mask 欄位輸入 sin*,點擊 Search ⚫ 點擊 Select All 然後點擊 OK *註 1:點搜索大小寫不區分。 *註 2:可用通配符:*=任意數量任意字符;?=一個任意字符。 ## 1.3 PI 時間戳 ### 1.3.1 固定時間戳 固定時間戳用於表示某固定之時刻 |時間戳| 表達含義| |-------- |-------- | |23-aug-2017 15:00:00| 2017 年 8 月 23 日 下午 03:00:00| |25-aug-17| 2017 年 8 月 25 日 凌晨 00:00:00 | 一些 PI System 組件(主要是客戶端組件)也可以識別 Windows 時間格式之時間戳,具體識別方式依 Windows 系統地區語言之設定。 ### 1.3.2動態時間戳 動態時間戳(動態時間表達式)可以表示與當前時間相對之時間,例如 *-1h 表示一個小時之前。表達式由兩部分組成:相對時間 & 時間偏移量相對時間: |簡寫 |全寫| 意義| |--------|--------|--------| |*| |當前時刻| |t| today |當天凌晨 0 點 | |y| yesterday| 前一天凌晨 0 點| |mon| monday |最近剛過去的週一凌晨 0 點| |tue| tuesday | 最近剛過去的週二凌晨 0 點| |wed| wednesday| 最近剛過去的週三凌晨 0 點 | |thu| thursday | 最近剛過去的週四凌晨 0 點| |fri| friday |最近剛過去的週五凌晨 0 點 | |sat| saturday | 最近剛過去的週六凌晨 0 點| |sun| sunday |最近剛過去的週日凌晨 0 點 | 時間偏移量(time offset)單位: |縮寫 |全寫 |意義| |--------|--------|--------| |s |second |秒 | |m |minute |分| |h |hour |時 | |d |day |天 | |w |week |週 | |mo | month| 月| |y |year |年 | ⚫ 秒,分,時三個時間單位可配合浮點數(帶小數點)使用 ⚫ 天,週,月,年只可配合整數使用 ⚫ 應避免使用連續加減時間偏移量,如 *-1d-8h 練習 – PI 時間戳 時間戳互譯: |表達式 |含義| |--------|--------| |* - 30m || |y + 8h|| |T || |Thu || |Tuesday - 2d || |18 || |y - 1y || |表達式 |含義| |--------|--------| || 今天早上 6 點 | || 週一早上 6:30| || 12 小時以前 | || 本月 1 日凌晨 0 點| || 本週四凌晨 0 點| || 昨天早上 7 點| || 15 分鐘之前| # 2 PI System 數據流 ![](https://i.imgur.com/bYlLnmD.png) ## 2.1 Exception – 過濾 過濾在 Interface 上發生,用於過濾數值穩定保持幾乎不變之數據。被過濾機制刪除之 event 不會被發送至 PI Data Archive,以降低網路流量及伺服器儲存壓力。 ![](https://i.imgur.com/6glZBLB.png) 對於每個 PI Point,都可以單獨設定其過濾算法之允差(Exception Deviation)及最長時間(Exception Max Time)。 ## 2.2 Compression – 壓縮 用於壓縮沿同一直線趨勢變化之數據,被壓縮算法刪除之 event 會在 snapshot 中出現,但是不會被保存至 archive,以降低伺服器儲存壓力。 ![](https://i.imgur.com/TO3YziQ.png) 每個 PI Point,都可以單獨設定其過濾算法之允差(Compression Deviation)及最長時間(Compression Max Time)。 # 3. 創建和管理 PI Point ## 3.1 PI Point Attributes 每個 PI Point 都有數十個屬性用於描述此點,這些屬性主要的作用如下: ⚫ 描述點的意義以便用戶進行搜索和了解其資料的作用 ⚫ 確定由哪個 Interface 進行資料收集動作 ⚫ 確定 Interface 收集資料時的行為規則 主要屬性介紹: ⚫ Name:點名稱(獨一名稱) ⚫ Description:說明字符 ⚫ Point Type:資料類型,決定點所儲存資料的資料類似,如 32 位浮點數等 ⚫ Point Source:資料來源標記,通常標識用於收集此點之 Interface ⚫ Location1:資料來源標記,常用於標識用於收集此點之 Interface ID ⚫ Location4:通常對應點獲取資料時的掃描頻率 ⚫ Compressing:壓縮算法開關 ⚫ ExcDev:過濾算法允差 ⚫ CompDev:壓縮算法允差 ## 3.2 PI Point 管理工具 PI Point 的管理主要通過 PI SMT 的 Point Builder 組件和 Excel 插件 PI Builder 進行,前者適合單一或者少量點作業,後者可以進行大量點作業。 練習 – PI SMT Point Builder vs. PI Builder ⚫ 開始菜單->PI System->PI System Management Tools ⚫ 左側導航欄至 Point -> Point Builder ⚫ 點擊 Tag Search 圖標 , 尋找名為 CDT158 的 PI 點,選中後點擊 OK ⚫ 在下方選項卡中閱讀各 PI Point Attribute ![](https://i.imgur.com/mQK0OmT.png) ⚫ 在 Name 欄位中直接將 cdt158 改為 Training_<你的英文名>,然後保存以創建一個你自己的課堂訓練用 PI 點 ⚫ 將 Descriptor 改為你的中文名,點擊保存 ⚫ 打開 Excel,開啟一張空白表格,點擊上方 PI Builder 選項卡![](https://i.imgur.com/iNSjG9x.png) ⚫ 左上角 Data Server 選單中選擇 PI Data Archive 名稱![](https://i.imgur.com/9idWaGZ.png) ⚫ 點擊 PI Points->Find PI Points 通過搜索找到之前創建的點,點擊 OK ⚫ 彈出的選單中勾選全部選項,點擊確定 ⚫ 觀察 Excel 表內容顯示的 PI Point Attributes,與 SMT 界面中內容對比 ⚫ 將 exdesc 欄位內容修改為你的單位名稱,點擊 Publish,選擇 Edit Only,點擊 OK,以修改此點 ⚫ 回到 PI SMT->Points->Point Builder 觀察此點的變化 # 4. PI Data Archive Security 安全性包括兩部分: ⚫ 身分驗證(Authentication) 用戶是誰? 如何確認用戶身分? ⚫ 授權(Authorization) 確認用戶後,該如何確認該用戶操作權限? ## 4.1 身分驗證(Authentication) ### 4.1.1 PI Trust 通過機器名,機器 IP 等訊息自動賦予連線程式身份,多用於 Interface 連線 管理頁面見 PI SMT->Security->Mappings & Trusts -> Trusts ![](https://i.imgur.com/i2zK4ex.png) ### 4.1.2 PI Mapping 通過登錄的 windows 用戶訊息自動賦予連線程式身份 管理頁面見 PI SMT->Security->Mappings & Trusts -> Mappings 推薦用戶登錄使用此驗證方法,安全性高,方便一鍵登錄,方便安全性管理 ![](https://i.imgur.com/If5KrqX.png) ### 4.1.3 Explicit Login 通過直接輸入 PI User 的帳密登錄,不推薦使用 練習 – 查看伺服器連線訊息 ⚫ 開始菜單->PI System->About PI-SDK/PISDKUtility![](https://i.imgur.com/MOGNJ8F.png) ⚫ 左側導航欄至 PI SDK->Connections ⚫ 勾選服務器名稱左側框進行連接,右側窗體會顯示伺服器連線訊息,其中包含連線使用之驗證方法和登錄身份 ⚫ 找出:伺服器 IP 地址_______________________ 版本號______________________________ OS 版本______________________________ 驗證方法____________________________ 登錄身份____________________________ ## 4.2 授權(Authorization) ### 4.2.1 PI Point 訪問權限 對 Tag 的訪問由 Database Security 工具的 PIPOINT 項目所控制。您可以進一步限制單個 Tag 的訪問權限,但授予的權限不能高於 PIPOINT 授予的權限。 管理界面位於 PI SMT->Points->Point Builder->Security ![](https://i.imgur.com/DhUmXYk.png) Data Security 指定哪些用戶有權訪問 tag 的數值(Snapshot 和 Archive 數據) Point Security 指定哪些用戶有權訪問 tag 的屬性配置(Zero、Span…等所有屬性) ### 4.2.2 Database 訪問權限 控制 PI Data Archive 各功能模塊(如 Archive 文檔創建,用戶身份建立)。管理界面位於 PI SMT->Security->Database Security 各部分管理內容詳細見其 Decription 說明。 ![](https://i.imgur.com/0KYumMd.png) # 5. PI 數據緩存 PI Buffer Subsystem 安裝於 Interface 機器上,將 Interface 傳出之數據放入緩存佇列並即時推送給 PI Data Archive。 ![](https://i.imgur.com/x4hvtX3.png) 當系統斷線發生時緩存佇列儲存無法送達之資料,待系統恢復後全部發送給 PI Data Archive,以避免資料丟失(data loss)。 ![](https://i.imgur.com/707Pqu7.png) ※ PI Buffer Subsystem 將緩存資料存於硬碟,緩存空間上限由硬碟剩餘空間大小決定。 討論 – PI Buffer System 系統架構 ![](https://i.imgur.com/QDSGFIl.png) # 6. PI 備份 ## 6.1 備份機制 ⚫ 採用 Microsoft 的磁區影像複製服務(Volume Shadow Copy Services, VSS),支援備份作業操作中仍可讀取磁碟。 ⚫ 採取增量備份(incremental backup)策略,即每次運行備份時備份上次備份到此次備份間系統發生變化之部分。 ⚫ 建議用第三方軟體再備份已完成的備份文件(本身也有再備份功能可設定)。 ## 6.2 備份設定方法 Command 切換至 PI\adm 目錄下,運行: pibackup E:\pibackup -install 運行成功後顯示:![](https://i.imgur.com/xeFPLfs.png) 此時至 Windows 工作排程器查看,可發現新增排程任務,自動於每日 3:15 將系統備份至 E:\pibackup 路徑(此路徑同上文命令之路徑) ![](https://i.imgur.com/Q0kvQNy.png) 練習 – 查看伺服器備份記錄 ⚫ 開始菜單->PI System->PI System Management Tools![](https://i.imgur.com/O0yN1oi.png) ⚫ 左側導航欄至 Operation->Backups 查看備份歷史紀錄 ## 6.3 還原方法 在新的 Server 機器上安裝與原 Server 同版本之 PI Data Archive;安裝完畢後啟動 PI Data Archive: 在 PI\adm 下執行 pisrvstart.bat 停止 PI Data Archive: 在 PI\adm 下执行 pisrvstop.bat 拷貝備份資料夾,覆蓋至 PI Server 安裝路徑,替換所有重名文件。在 PI\adm 下執行 pisrvstart.bat 以啟動 PI Data Archive 即完成恢復。 # 7. PI Collective(雙/多機熱備) ![](https://i.imgur.com/LMa55vL.png) 軟體層面的熱備結構,無需硬體配置一致,不限制兩機器同地點部署,只需要兩台機器安裝同版本之 PI Data Archive。 PI Collective 遵從主從結構,即 Primary Server 為主其餘為從,絕大多數設定動作(PI Tag 增刪等)只能在主伺服器完成,再自動同步至 Secondary。由 Interface 端設定 Buffer 進行多路資料發送保證資料同步。客戶端連線時自動尋找負載低之 Server 連線獲取資料。 # 8. PI System 開發簡介 ## 8.1 OSIsoft 開發工具簡介 OSIsoft 支援使用多種工具進行針對 PI System 資料存取的程式開發,統稱為 PI System Access(PSA),主要包括下列工具。 ### 8.1.1 AF SDK 基於 Windows .Net Framework 的編程工具,全面,高效能地存取 PI System 資料,其特點如下: ⚫ 效能最強 ⚫ 支援的方法和選項最多 ⚫ 只能在 Windows .Net Framework 的電腦上運行 ### 8.1.2 PI Web API 通過這個 REST API,可以支援跨作業系統,設備類型的數據存取要求。其特點如下: ⚫ 不限制作業系統或編程語言種類 ⚫ 與 AF SDK 相比,支援的方法和選項較少 ### 8.1.3 PI SQL Framework 將 PI System 的資料以 SQL 格式向外發佈,方便熟悉 SQL 語法的編程人員使用,其特點如下: ⚫ 與其他使用 Structured Query Language(SQL)語法的系統相容 ⚫ 與 AF SDK 相比,支援的方法和選項較少 ⚫ 對 AF Server 僅可讀,(對 PI Data Archive 可讀寫) ## 8.2 PI Web API 與 Python AF SDK 作為 REST API,可在多種平台上使用,也可以在 Python 中通過標準的 requests 和 json 庫進行操作。 ## 8.3 幫助文檔 線上幫助文檔可見於 https://livelibrary.osisoft.com/LiveLibrary/content/en/web-api-v8/GUID- 9330057FC995-4721-A10F-29F3C1EB3E8E 您也可以在 PI Web API 網頁上直接找到相關內容的幫助。 通過點擊頁眉處的鏈接可以進入幫助頁面 ![](https://i.imgur.com/ivr0k9x.png) PI Developers Club 是 PI System 開發者論壇,您也可以上網搜尋開發的相關訊息: https://pisquare.osisoft.com/community/developers-club # 9. 設定作業 本課程中使用 Jupyter Notebook 作為 Python 的開發測試環境,對於未接觸過此 軟體的新用戶,推薦使用 Anaconda3 進行簡便的安裝。 https://www.anaconda.com/products/individual ## 9.1 安裝庫文件 本次練習中由於 PI Web API 有安全驗證,我們使用 requests_negotiate_sspi 這 個庫進行安全驗證的動作。 安裝此庫文件,請打開命令行或者 Windows Powershell,執行下列命令: pip install requests pip install requests_negotiate_sspi ## 9.2 創建新 Python3 Notebook ⚫ 打開 Jupyter Notebook,新建 Python3 Notebook 文件 ⚫ 將文件命名為 PI Web API Exercise ## 9.3 添加引用的庫文件 ⚫ 在文件最上方插入下列代碼: import requests import json from requests_negotiate_sspi import HttpNegotiateAuth # 10. 連接 PI Web API ## 10.1 聲明伺服器連線信息 為了連線到 PI Web API Server,需要指定其 URL: baseURL = 'https://<PI Web API Server>/piwebapi' 以及連線使用的身份信息: myAuth = HttpNegotiateAuth(username='<username>', password='<password>', domain='<domain>') ## 10.2 Json 格式輸出函數 為在 Jupyter Notebook 上優化 Json 內容的格式,方便觀察之後各步驟的結果,添加下列代碼,產生名為 JsonPrint 的函數: def JsonPrint(json_object): print(json.dumps(json_object, indent=2)) ## 10.3 獲取伺服器列表 通過一個 request 來獲取 PI Web API Server 可以連線的 PI Data Archive 或者 PI AF Server 的列表,下面列出 PI Data Archive 列表: ```=python r = requests.get(baseURL, auth=myAuth, verify=False).json() piServers = requests.get(r['Links']['DataServers'], auth=myAuth, verify=False).json() JsonPrint(piServers) ``` # 11 讀取 PI 點資料 ## 11.1 列舉 PI 點 通過一個命令列列舉出PI Server上的前10個PI點: ```=python piServer = piServers[‘Items’][0] points = requests.get(piServer['Links']['Points']+ '?maxCount=10&selectedFields=Items.WebID;Items.Path;Items.Links', auth=myAuth, verify=False).json() JsonPrint(points) ``` ## 11.2 WebID PI Web API 使用 WebID 作為獲取 PI 或者 AF 資料的指針,在 URL 中使用。 WebID 可以適應對象名稱或 ID 的更改,可以在應用程序中存儲並使用它們,而不必擔心 AF Attribute 或 PI Point 被移動/更名導致丟失連接。 WebID 由目標名稱/路徑以及其 GUID 通過編碼生成,關於 WebID 的詳細介紹,可以參考: https://pisquare.osisoft.com/community/developers-club/blog/2018/01/26/pi-web-apiusing-web-id-20-to-optimize-your-applications ## 11.3 讀取單點單筆資料 PI Web API 中大量使用 Web ID 作為各個物件的索引,在 URL 中需要經常使用,在簡單的讀取單筆資料的範例裡,我們演示常用的兩種讀取資料方法: ⚫ 使用鏈接中的 URL ```=python point = points['Items'][1] currvalue1 = requests.get(point['Links']['Value'], auth=myAuth, verify=False).json() JsonPrint(currvalue1) ``` ⚫ 使用 Web ID 拼出 URL ```=python currvalue2 = requests.get(baseURL+'/streams/'+point['WebId']+'/value', auth=myAuth, verify=False).json() JsonPrint(currvalue2) ``` 通常使用鏈接的 URL 比較方便開發,但是在實際開發中,使用 Web ID 拼出 URL 更加高效,在下面的課程中,為了簡便易懂,主要使用鏈接的 URL。 ## 11.4 讀取採樣值資料 下面讀取單點昨日一整天,每 1 小時 1 筆數據,PI Web API 支援的時間戳格式 主要是 PI 時間戳,以及 ISO 8601 格式(https://en.wikipedia.org/wiki/ISO_8601) ```=python interpvals = requests.get(point['Links']['InterpolatedData']+ '?starttime=y&endtime=t&interval=1h&selectedFields=Items.Timestamp;Items. Value', auth=myAuth, verify=False).json() JsonPrint(interpvals) ``` ## 11.5 獲取計算數值 獲取單點最近 24 小時之內的平均值以及最大值。 ```=python summaries = requests.get(point['Links']['SummaryData']+'?starttime=y&endtime=t&summary Type=Average&summaryType=Maximum', auth=myAuth, verify=False).json() JsonPrint(summaries) ``` # 12 讀取 AF Server ## 12.1 獲取 AF Attribute 信息 使用 Attribute Controller,加上 path 參數可以直接尋找到指定路徑之 AF Attribute。 ```=python attr = requests.get(baseURL+ '/attributes?path=\\\\JIRTPMSSAFS1\\Configuration\\OSIsoft\\PI%20Web%20A PI\\JIRTPMSSPIWA\\System Configuration|CorsMethods', auth=myAuth, verify=False).json() JsonPrint(attr) ``` ## 12.2 讀取資料 自獲取 Web ID 之後,讀取 AF 資料的作業與讀取 PI 點之作業完全一致,可參考第 11 章相關內容 # 13 搜索和嵌套查詢 ## 13.1 搜索 PI 點 搜索所有點名為 SINU 開頭的 PI 點: ```=python result = requests.get(baseURL+'/search/query?q=name:SINU*&count=100', auth=myAuth, verify=False).json() JsonPrint(result) ``` ## 13.2 嵌套查詢 使用一個嵌套式(批次/Batch)的查詢,讀取所有點名為 SINU 開頭的 PI 點,以及它們的當前值: ```=python query="""{ "tags":{ "Method": "GET", "Resource": "%s/search/query?q=name:SINU*&count=1000&fields=WebId;name" }, "data":{ "Method": "GET", "RequestTemplate":{ "Resource": "%s/streams/{0}/value?selectedfields=timestamp;value" }, "ParentIds":["tags"], "Parameters":["$.tags.Content.Items[*].WebId"] } } """ % (baseURL, baseURL) print(query) headers= {'Content-type': 'application/json'} currvals = requests.post(baseURL+'/batch', data=query, auth=myAuth, verify=False, headers=headers).json() JsonPrint(currvals) ```