李繼偉,李雪強,遲海龍,李亦凡
(北京中水科水電科技開發有限公司,北京 100085)
隨著智能化水電站、一體化平臺的不斷建設,計算機軟件、硬件性能的提高,業主對水電站監控系統人機交互的需求越來越復雜,不同業務之間的交互功能要求也越來越高,運行人員希望在一體化平臺中獲取更多的業務展示。水電站業務數據主要分水調、電調兩類,其中水調業務專業性較強,成果展示手段非常豐富,而電調業務實時性較強,數據也比較全。一體化平臺的建設需要深入融合水調和電調業務,雙方的業務數據需要實時交互;同時為了支持、簡化第三方應用的接入以及為滿足未來擴展的需要,保護業主已有投資,需支持后續業務的無縫接入,最終實現多業務模型與數據在跨平臺、跨主機上數據展示層的集中統一展示。
在現有的水電一體化平臺中,普遍采用中間庫的方式實現數據交換,存在數據實時性不高、交互邏輯組態復雜的困難,因此本文基于數據信息流模型,設計了一套水電站多業務一體化人機交互模型框架,為水電站復雜業務交互提供了一種簡單、有效的集成手段。本框架通過對信息流數據的構建、接口轉換、后臺引擎驅動、集成展示等多項技術,使得水電調一體化平臺可以簡單有效地進行水電調業務組態、數據集成,支持不同業務之間的復雜交互需求,滿足了新平臺多業務數據在統一平臺內共享的要求。
水電站多業務人機交互框架主要有模型建立、信息數據流化、數據處理、腳本引擎驅動、模型展示、信息交互等多方面,其整體設計圖如圖1所示。其中模型建立負責確定業務之間交互的接口,信息數據流化按照固定的協議規則負責接口數據與流數據之間的相互轉換,數據處理是指在數據到達業務服務端后,業務端對業務請求分析后的響應。腳本引擎驅動是利用腳本引擎驅動交互腳本,實現數據的獲取及業務交互展示,是整個框架的核心。模型展示以及信息交互主要負責對業務返回數據的統一展示,以及在數據修改后的數據回存。

圖1 水電站多業務交互框架設計圖
交互模型是不同業務之間數據轉換、交互的核心。為整合不同業務之間的異構數據源,簡單地將多個應用系統連接起來是遠遠不夠的,軟件的數據交換標準化才是業務融合的前提條件。因此在人機交互框架中,本平臺設計并提供了統一的數據建立接口、數據流化接口,同時為滿足多編程語言使用、跨平臺調用的需求,提供標準的C語言庫接口函數,提高了接口使用的易用性,降低了第三方集成人員的使用難度。
在水電站業務平臺中,不同業務應用平臺多由不同廠家開發,相互之間直接調用的難度很大,增加了一體化平臺適配的難度。借鑒微服務及SOA的架構,不同業務模型間應該盡量解耦合,服務之間通用接口實現弱耦合調用,服務提供方與調用者只依賴于接口定義描述。根據服務接口定義文件,集成工具可以生成框架代碼,服務方負責提供具體的響應實現,客戶端代碼只需要根據接口直接調用即可,數據轉換、目標獲取等統一由平臺內部的數據服務總線統一提供,應用系統只需要基于被動響應合理、合法的請求返回對應數據,不需要關心數據請求來自哪個系統,也不用了解該系統的連接協議等信息。業務使用方只需要使用標準接口進行調用即可,故而對數據應用系統是透明的。
為支持跨語言調用的需要,接口定義的數據類型只支持簡單類型及由簡單類型的樹狀結構組合,即int、long、double、string及這些簡單類型構成的數組,以及這些簡單類型的組合。業務雙方交互時只需要設計具體的服務交互接口、相關參數(輸入、輸出參數),形成業務交互的協議(交互協議主要由服務交互接口名,由不同數據類型組合構成的輸入、輸出參數)。交互參數設計圖如圖 2所示,復雜結構體之間支持嵌套,但是不允許結構體之間的循環嵌套,在生成接口協議時支持對循環嵌套的接口定義做合理性檢查,以避免運行時錯誤。

圖2 交互參數設計圖
對具體的業務協議,經過標準的打包拆包操作,最終轉換為跨平臺的C數據結構,實現信息的數據流化。
序列化格式為:固定消息格式的消息頭加上消息內容。
消息頭主要包括消息類型(請求還是回應),消息長度以及消息校驗和;消息內容按又細分為服務名字段、服務請求名字段、參數打包字段集合序列化內容。
具體打包某一字段時又包括字段類型、字段名、字段數據等,同時在數據流化時,為提高傳輸效率,對int、long數值型數據采用變長方式流化。
在人機交互配置界面中可以配置界面交互圖元點擊后的交互邏輯,以及服務取得的數據展現到展示圖元。對每一類型的顯示圖元,統一定義圖元數據源數據格式,以標準輸出流格式由圖元自身動態解析服務交互結果,并展示成合適的格式。對圖元間可以關聯二級圖元,支持數據間聯動,支持model/view模型,一個數據源可以關聯多個數據視圖,在數據有變化時支持多個數據源的同時更新,有修改后支持數據結果的回存。
不管是客戶端還是服務端,交互的數據都需要處理方能使用,對于服務端業務,只需要根據服務協議動態解析信息流數據,并將服務響應結果按照服務協議打包返回到客戶端即可,服務端框架里核心內容是如何支持多客戶端訪問的線程安全及負載均衡。對客戶端平臺,需要考慮接續的是不同業務之間的交互模型,尤其是后續第三方業務的集成,故必須支持后續業務的無限擴展需求。設計時考慮了對序列化消息支持腳本動態解析,在協議擴展時實現消息內容的動態獲取,這些功能必須依賴可靠的腳本引擎才具可行性。
相對于編譯型語言(C++、Java、C#等),腳本語言存在著計算性能低的先天不足,以前在電力SCADA系統里也僅在性能要求不高的系統綜合計算等非核心邏輯中使用,而且其驅動引擎也多采用自研腳本語言,以提高性能,但也同時犧牲了腳本語言的靈活性。隨著計算機計算水平的提高,分布式應用在網絡帶寬足夠大的情況下引入腳本語言,利用腳本語言提供的靈活性僅需要工程人員簡單的配置能夠實現復雜的交互功能,這在以前依賴編譯型語言實現的系統里必須要研發人員依據客戶的需求定制,增加了工程集成的難度。
當前主流的腳本語言有JS、Python、Lua等,其中JS主要使用于前端開發,Python作為強大的腳本語言,其依賴眾多的第三方庫可實現非常復雜的功能,也比較重量級,而Lua語言一方面具有性能高、與其他語言黏合性好的特點,在游戲領域應用較多,目前初步應用在了水電站監控系統中,擴大了腳本的應用范圍;另一方面,當前SCADA系統普遍采用性能較高的C/C++語言開發,而Lua作為純C開發的腳本語言,同樣具有較強的跨平臺特性,在對腳本性能有特殊要求時還可以采用LuaJIT的方式。
在水電調一體化平臺人機交互框架中,在業務執行多個服務請求、響應分析的同時,還需要保證常規畫面的正常刷新,故必須要選擇一種能支持大量腳本引擎可同時運行、執行性能高的語言,對比JS、Python,Lua作為框架人機交互語言是不二之選。
水電站多業務人機交互主要體現在不同業務模型在統一展示平臺的數據展示、方案制作、保存等,主要由前期服務數據的工程配置和運行時的動態獲取解析兩部分構成,都需要腳本引擎對配置文件的解析功能,前者屬于腳本文件的靜態解析,后者屬于腳本文件的運行解析。
為屏蔽不同圖元交互時的配置差異,集成工具提供了一套統一的界面以實現數據源的統一配置,由腳本語言動態存取,對保存后的配置,圖元解析功能設計時選擇用腳本引擎解析圖元的自定義配置,利用腳本語言解析的靈活性實現圖元屬性的易擴展性,降低了模型間的耦合,圖元數據源配置有服務名、服務函數名、服務請求參數集合、服務結果數據集綁定、請求類型(周期、發布/訂閱等)。
腳本引擎作為人機交互業務的腳本語言解釋器和執行器,其支持的腳本類似于高級編程語言,在具體應用時還需要針對特殊用途擴展特定的接口,以實現與平臺內其他應用的實時交互。腳本引擎的常規工作流程是:①腳本引擎的解釋器將一定格式的腳本程序翻譯成中間代碼,這些中間代碼主要由組態中其他模塊的訪問接口和相應的數據結構組成;②系統投入運行時,系統根據工程配置,主動加載相應的腳本程序,交給引擎執行器動態解析并執行。
當前人機交互界面的刷新,多采用發布/訂閱技術或周期刷新技術,取決并依賴于數據源數據的刷新方式,發布/訂閱技術比較靈活,實現技術也較為復雜;而周期刷新技術數據通常來自實時內存庫,性能很高,但需要提前定義固定的數據結構,適用有其局限性。框架在設計時同時支持上述兩種刷新方式,對實時性能要求較高的服務調用,采用實時庫周期刷新的方式,對每個控件綁定唯一的數據源ID,多個數據展示圖元(曲線、棒圖、表格等)支持綁定同一數據源;對采用發布/訂閱機制的數據源刷新方式,一般具有請求響應的數據量比較大、計算周期較長、刷新不頻繁、響應結果展示復雜的特點,還需要支持同一數據源不同的展示方式,支持數據源的model/view展示機制,以提高刷新顯示性能。
框架對展示圖元(曲線、棒圖、表格等)、交互圖元(按鈕等)的包裝,采用封裝開源控件庫的方式實現,以支持控件事件的觸發,但控件操作一般是不可重入的,相應操作也必須在GUI主線程完成。為不影響界面的正常刷新,對發布訂閱的請求,必須支持異步調用的方式,其實現時主要分為以下3個步驟:
(1)對待刷新的控件,在GUI主線程中讀取對應的控件數據,并將取得的數據打包發到統一的子線程池;
(2)每一個子線程對應一個獨立的腳本引擎,并由腳本引擎負責對服務請求內容進行統一打包并執行;
(3)對異步返回結果的處理分兩種情況,周期刷新的數據只需要將數據保存到全局緩存中,由界面刷新定時取用即可;對發布訂閱的數據,需要將返回的執行狀態/實際數據打包發送信號到主線程,由主線程對返回結果進行統一分析處理。
腳本引擎作為通用的解釋性語言,與其他語言交互時一般也只提供了較為簡單的庫函數,特殊應用使用時必須依賴語言提供的標準API進行封裝。腳本引擎與一體化平臺的交互,既需要腳本引擎對平臺功能的正向調用/交互,也需要平臺功能對腳本引擎函數的逆向調用。
與一體化平臺交互時,必須注冊相應的函數到腳本引擎,腳本動態解析時方能識別,對Lua引擎,所有注冊給Lua的C函數具有typedef int (*lua_CFunction) (lua_State *L)的原型;框架設計時,已針對公用需求,將一體化平臺內的常規平臺交互函數注冊到腳本引擎,主要分為以下幾種功能:
(1)實時庫操作:腳本可以調用實時庫中的讀寫函數,并調用消息總線接口實現數據的實時同步;
(2)歷史庫服務操作:實現歷史數據的寫庫以及數據查詢;
(3)日志分析:記錄服務請求、讀取的處理流程,對數據的關鍵路徑,記錄其執行流程,供日后查詢、日志統計及分析以及在請求異常后的故障分析;
(4)平臺權限管理:在腳本引擎里的操作,可調用平臺權限的統一判斷函數,對用戶操作進行判斷并記錄,并通過一體化系統的數據總線同步操作判斷結果;
(5)高級應用功能:為其他高級應用功能提供邏輯運算支撐,以及復雜邏輯功能的組態。
平臺功能對腳本引擎的解析調用,采用固定功能key的方式,平臺讀取腳本數據時,按照對象名、特定功能key的方法讀取腳本中的數據,當前系統定義的功能key主要有以下幾個:PlatFormName(平臺名)、ServiceName(服務名)、FuncName(函數名)、InputParas(輸入參數集合配置)、OutputParas(輸出參數集合配置)、bPeriodRefresh(是否周期刷新)、FreshPeriod(刷新周期)等。
一體化人機交互模型滿足了多業務數據在水電調一體化平臺中數據共享和集成展示的要求。在水電調一體化SOA平臺架構中,基于服務總線提供的統一數據傳輸機制,結合自身業務特點,對人機交互界面提供了一套操作簡單的配置、顯示畫面,利用腳本驅動引擎驅動復雜業務的交互邏輯,滿足了不同業務間的復雜交互需求,為水電調一體化平臺多業務數據在統一平臺內數據共享、集中展示、平臺的可靠運行提供了技術支撐。